[FORMATTING] Fix indentation.

svn path=/trunk/; revision=38354
This commit is contained in:
Dmitry Gorbachev 2008-12-26 13:50:35 +00:00
parent fd4de76baf
commit 4d4d9e60fb

View file

@ -1,7 +1,7 @@
/* /*
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: lib/ntdll/ldr/startup.c * FILE: dll/ntdll/ldr/startup.c
* PURPOSE: Process startup for PE executables * PURPOSE: Process startup for PE executables
* PROGRAMMERS: Jean Michault * PROGRAMMERS: Jean Michault
* Rex Jolliff (rex@lvcablemodem.com) * Rex Jolliff (rex@lvcablemodem.com)
@ -14,52 +14,56 @@
#include <debug.h> #include <debug.h>
#include <win32k/callback.h> #include <win32k/callback.h>
VOID RtlInitializeHeapManager (VOID); VOID RtlInitializeHeapManager(VOID);
VOID LdrpInitLoader(VOID); VOID LdrpInitLoader(VOID);
VOID NTAPI RtlpInitDeferedCriticalSection(VOID); VOID NTAPI RtlpInitDeferedCriticalSection(VOID);
NTSTATUS LdrpAttachThread(VOID);
VOID RtlpInitializeVectoredExceptionHandling(VOID);
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
PLDR_DATA_TABLE_ENTRY ExeModule;
static RTL_CRITICAL_SECTION PebLock; static RTL_CRITICAL_SECTION PebLock;
static RTL_CRITICAL_SECTION LoaderLock; static RTL_CRITICAL_SECTION LoaderLock;
static RTL_BITMAP TlsBitMap; static RTL_BITMAP TlsBitMap;
static RTL_BITMAP TlsExpansionBitMap; static RTL_BITMAP TlsExpansionBitMap;
PLDR_DATA_TABLE_ENTRY ExeModule;
NTSTATUS LdrpAttachThread (VOID);
VOID RtlpInitializeVectoredExceptionHandling(VOID);
#define VALUE_BUFFER_SIZE 256 #define VALUE_BUFFER_SIZE 256
BOOLEAN FASTCALL /* FUNCTIONS *****************************************************************/
ReadCompatibilitySetting(HANDLE Key, LPWSTR Value, PKEY_VALUE_PARTIAL_INFORMATION ValueInfo, DWORD *Buffer)
BOOLEAN
FASTCALL
ReadCompatibilitySetting(HANDLE Key,
LPWSTR Value,
PKEY_VALUE_PARTIAL_INFORMATION ValueInfo,
DWORD * Buffer)
{ {
UNICODE_STRING ValueName; UNICODE_STRING ValueName;
NTSTATUS Status; NTSTATUS Status;
ULONG Length; ULONG Length;
RtlInitUnicodeString(&ValueName, Value); RtlInitUnicodeString(&ValueName, Value);
Status = NtQueryValueKey(Key, Status = NtQueryValueKey(Key,
&ValueName, &ValueName,
KeyValuePartialInformation, KeyValuePartialInformation,
ValueInfo, ValueInfo,
VALUE_BUFFER_SIZE, VALUE_BUFFER_SIZE,
&Length); &Length);
if (!NT_SUCCESS(Status) || (ValueInfo->Type != REG_DWORD)) if (!NT_SUCCESS(Status) || (ValueInfo->Type != REG_DWORD))
{ {
RtlFreeUnicodeString(&ValueName); RtlFreeUnicodeString(&ValueName);
return FALSE; return FALSE;
} }
RtlCopyMemory(Buffer, &ValueInfo->Data[0], sizeof(DWORD));
RtlFreeUnicodeString(&ValueName); RtlCopyMemory(Buffer, &ValueInfo->Data[0], sizeof(DWORD));
return TRUE; RtlFreeUnicodeString(&ValueName);
return TRUE;
} }
VOID FASTCALL VOID
FASTCALL
LoadImageFileExecutionOptions(PPEB Peb) LoadImageFileExecutionOptions(PPEB Peb)
{ {
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
@ -72,170 +76,179 @@ LoadImageFileExecutionOptions(PPEB Peb)
if (Peb->ProcessParameters && if (Peb->ProcessParameters &&
Peb->ProcessParameters->ImagePathName.Length > 0) Peb->ProcessParameters->ImagePathName.Length > 0)
{ {
DPRINT("%wZ\n", &Peb->ProcessParameters->ImagePathName); DPRINT("%wZ\n", &Peb->ProcessParameters->ImagePathName);
ImagePathName = Peb->ProcessParameters->ImagePathName; ImagePathName = Peb->ProcessParameters->ImagePathName;
ImageName.Buffer = ImagePathName.Buffer + ImagePathName.Length / sizeof(WCHAR); ImageName.Buffer = ImagePathName.Buffer + ImagePathName.Length / sizeof(WCHAR);
ImageName.Length = 0; ImageName.Length = 0;
while (ImagePathName.Buffer < ImageName.Buffer) while (ImagePathName.Buffer < ImageName.Buffer)
{ {
ImageName.Buffer--; ImageName.Buffer--;
if (*ImageName.Buffer == L'\\') if (*ImageName.Buffer == L'\\')
{ {
ImageName.Buffer++; ImageName.Buffer++;
break; break;
} }
} }
ImageName.Length = ImagePathName.Length - (ImageName.Buffer - ImagePathName.Buffer) * sizeof(WCHAR);
ImageName.MaximumLength = ImageName.Length + ImagePathName.MaximumLength - ImagePathName.Length; ImageName.Length = ImagePathName.Length -
(ImageName.Buffer - ImagePathName.Buffer) * sizeof(WCHAR);
ImageName.MaximumLength = ImageName.Length +
ImagePathName.MaximumLength - ImagePathName.Length;
DPRINT("%wZ\n", &ImageName); DPRINT("%wZ\n", &ImageName);
/* global flag */ /* global flag */
Status = LdrQueryImageFileExecutionOptions (&ImageName, Status = LdrQueryImageFileExecutionOptions(&ImageName,
L"GlobalFlag", L"GlobalFlag",
REG_SZ, REG_SZ,
(PVOID)ValueBuffer, (PVOID)ValueBuffer,
sizeof(ValueBuffer), sizeof(ValueBuffer),
&ValueSize); &ValueSize);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
ValueString.Buffer = ValueBuffer; ValueString.Buffer = ValueBuffer;
ValueString.Length = ValueSize - sizeof(WCHAR); ValueString.Length = ValueSize - sizeof(WCHAR);
ValueString.MaximumLength = sizeof(ValueBuffer); ValueString.MaximumLength = sizeof(ValueBuffer);
Status = RtlUnicodeStringToInteger(&ValueString, 16, &Value); Status = RtlUnicodeStringToInteger(&ValueString, 16, &Value);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
Peb->NtGlobalFlag |= Value; Peb->NtGlobalFlag |= Value;
DPRINT("GlobalFlag: Key='%S', Value=0x%lx\n", ValueBuffer, Value); DPRINT("GlobalFlag: Key='%S', Value=0x%lx\n", ValueBuffer, Value);
} }
} }
/* /*
* FIXME: * FIXME:
* read more options * read more options
*/ */
} }
} }
BOOLEAN
FASTCALL
BOOLEAN FASTCALL
LoadCompatibilitySettings(PPEB Peb) LoadCompatibilitySettings(PPEB Peb)
{ {
NTSTATUS Status; NTSTATUS Status;
HANDLE UserKey = NULL; HANDLE UserKey = NULL;
HANDLE KeyHandle; HANDLE KeyHandle;
HANDLE SubKeyHandle; HANDLE SubKeyHandle;
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName = RTL_CONSTANT_STRING( UNICODE_STRING KeyName = RTL_CONSTANT_STRING(
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"); L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers");
UNICODE_STRING ValueName; UNICODE_STRING ValueName;
UCHAR ValueBuffer[VALUE_BUFFER_SIZE]; UCHAR ValueBuffer[VALUE_BUFFER_SIZE];
PKEY_VALUE_PARTIAL_INFORMATION ValueInfo; PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
ULONG Length; ULONG Length;
DWORD MajorVersion, MinorVersion, BuildNumber, PlatformId, DWORD MajorVersion, MinorVersion, BuildNumber, PlatformId,
SPMajorVersion, SPMinorVersion= 0; SPMajorVersion, SPMinorVersion = 0;
if(Peb->ProcessParameters && if (Peb->ProcessParameters &&
(Peb->ProcessParameters->ImagePathName.Length > 0)) (Peb->ProcessParameters->ImagePathName.Length > 0))
{ {
Status = RtlOpenCurrentUser(KEY_READ, Status = RtlOpenCurrentUser(KEY_READ, &UserKey);
&UserKey); if (!NT_SUCCESS(Status))
if (!NT_SUCCESS(Status)) {
{ return FALSE;
return FALSE; }
}
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
&KeyName, &KeyName,
OBJ_CASE_INSENSITIVE, OBJ_CASE_INSENSITIVE,
UserKey, UserKey,
NULL); NULL);
Status = NtOpenKey(&KeyHandle, Status = NtOpenKey(&KeyHandle, KEY_QUERY_VALUE, &ObjectAttributes);
KEY_QUERY_VALUE,
&ObjectAttributes);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
if (UserKey) NtClose(UserKey); if (UserKey)
return FALSE; NtClose(UserKey);
} return FALSE;
}
/* query version name for application */ /* query version name for application */
ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer; ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION) ValueBuffer;
Status = NtQueryValueKey(KeyHandle, Status = NtQueryValueKey(KeyHandle,
&Peb->ProcessParameters->ImagePathName, &Peb->ProcessParameters->ImagePathName,
KeyValuePartialInformation, KeyValuePartialInformation,
ValueBuffer, ValueBuffer,
VALUE_BUFFER_SIZE, VALUE_BUFFER_SIZE,
&Length); &Length);
if (!NT_SUCCESS(Status) || (ValueInfo->Type != REG_SZ)) if (!NT_SUCCESS(Status) || (ValueInfo->Type != REG_SZ))
{ {
NtClose(KeyHandle); NtClose(KeyHandle);
if (UserKey) NtClose(UserKey); if (UserKey)
return FALSE; NtClose(UserKey);
} return FALSE;
}
ValueName.Length = ValueInfo->DataLength; ValueName.Length = ValueInfo->DataLength;
ValueName.MaximumLength = ValueInfo->DataLength; ValueName.MaximumLength = ValueInfo->DataLength;
ValueName.Buffer = (PWSTR)ValueInfo->Data; ValueName.Buffer = (PWSTR) ValueInfo->Data;
/* load version info */ /* load version info */
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
&ValueName, &ValueName,
OBJ_CASE_INSENSITIVE, OBJ_CASE_INSENSITIVE,
KeyHandle, KeyHandle,
NULL); NULL);
Status = NtOpenKey(&SubKeyHandle, Status = NtOpenKey(&SubKeyHandle, KEY_QUERY_VALUE, &ObjectAttributes);
KEY_QUERY_VALUE,
&ObjectAttributes);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
NtClose(KeyHandle); NtClose(KeyHandle);
if (UserKey) NtClose(UserKey); if (UserKey)
return FALSE; NtClose(UserKey);
} return FALSE;
}
DPRINT("Loading version information for: %wZ\n", &ValueName); DPRINT("Loading version information for: %wZ\n", &ValueName);
/* read settings from registry */ /* read settings from registry */
if(!ReadCompatibilitySetting(SubKeyHandle, L"MajorVersion", ValueInfo, &MajorVersion)) if (!ReadCompatibilitySetting(SubKeyHandle, L"MajorVersion", ValueInfo, &MajorVersion))
goto finish; goto finish;
if(!ReadCompatibilitySetting(SubKeyHandle, L"MinorVersion", ValueInfo, &MinorVersion)) if (!ReadCompatibilitySetting(SubKeyHandle, L"MinorVersion", ValueInfo, &MinorVersion))
goto finish; goto finish;
if(!ReadCompatibilitySetting(SubKeyHandle, L"BuildNumber", ValueInfo, &BuildNumber)) if (!ReadCompatibilitySetting(SubKeyHandle, L"BuildNumber", ValueInfo, &BuildNumber))
goto finish; goto finish;
if(!ReadCompatibilitySetting(SubKeyHandle, L"PlatformId", ValueInfo, &PlatformId)) if (!ReadCompatibilitySetting(SubKeyHandle, L"PlatformId", ValueInfo, &PlatformId))
goto finish; goto finish;
/* now assign the settings */ /* now assign the settings */
Peb->OSMajorVersion = (ULONG)MajorVersion; Peb->OSMajorVersion = (ULONG) MajorVersion;
Peb->OSMinorVersion = (ULONG)MinorVersion; Peb->OSMinorVersion = (ULONG) MinorVersion;
Peb->OSBuildNumber = (USHORT)BuildNumber; Peb->OSBuildNumber = (USHORT) BuildNumber;
Peb->OSPlatformId = (ULONG)PlatformId; Peb->OSPlatformId = (ULONG) PlatformId;
/* optional service pack version numbers */ /* optional service pack version numbers */
if(ReadCompatibilitySetting(SubKeyHandle, L"SPMajorVersion", ValueInfo, &SPMajorVersion) && if (ReadCompatibilitySetting(SubKeyHandle,
ReadCompatibilitySetting(SubKeyHandle, L"SPMinorVersion", ValueInfo, &SPMinorVersion)) L"SPMajorVersion",
Peb->OSCSDVersion = ((SPMajorVersion & 0xFF) << 8) | (SPMinorVersion & 0xFF); ValueInfo,
&SPMajorVersion) &&
ReadCompatibilitySetting(SubKeyHandle,
L"SPMinorVersion",
ValueInfo,
&SPMinorVersion))
{
Peb->OSCSDVersion = ((SPMajorVersion & 0xFF) << 8) |
(SPMinorVersion & 0xFF);
}
finish: finish:
/* we're finished */ /* we're finished */
NtClose(SubKeyHandle); NtClose(SubKeyHandle);
NtClose(KeyHandle); NtClose(KeyHandle);
if (UserKey) NtClose(UserKey); if (UserKey)
return TRUE; NtClose(UserKey);
} return TRUE;
return FALSE; }
}
/* FUNCTIONS *****************************************************************/ return FALSE;
}
VOID VOID
NTAPI NTAPI
@ -243,259 +256,256 @@ LdrpInit(PCONTEXT Context,
PVOID SystemArgument1, PVOID SystemArgument1,
PVOID SystemArgument2) PVOID SystemArgument2)
{ {
PIMAGE_NT_HEADERS NTHeaders; PIMAGE_NT_HEADERS NTHeaders;
PEPFUNC EntryPoint; PEPFUNC EntryPoint;
PIMAGE_DOS_HEADER PEDosHeader; PIMAGE_DOS_HEADER PEDosHeader;
PVOID ImageBase; PVOID ImageBase;
PPEB Peb = NtCurrentPeb(); PPEB Peb = NtCurrentPeb();
PLDR_DATA_TABLE_ENTRY NtModule; // ntdll PLDR_DATA_TABLE_ENTRY NtModule; // ntdll
NLSTABLEINFO NlsTable; NLSTABLEINFO NlsTable;
WCHAR FullNtDllPath[MAX_PATH]; WCHAR FullNtDllPath[MAX_PATH];
SYSTEM_BASIC_INFORMATION SystemInformation; SYSTEM_BASIC_INFORMATION SystemInformation;
NTSTATUS Status; NTSTATUS Status;
PVOID BaseAddress = SystemArgument1; PVOID BaseAddress = SystemArgument1;
DPRINT("LdrpInit()\n"); DPRINT("LdrpInit()\n");
DPRINT("Peb %p\n", Peb); DPRINT("Peb %p\n", Peb);
ImageBase = Peb->ImageBaseAddress; ImageBase = Peb->ImageBaseAddress;
DPRINT("ImageBase %p\n", ImageBase); DPRINT("ImageBase %p\n", ImageBase);
if (NtCurrentPeb()->Ldr == NULL) if (NtCurrentPeb()->Ldr == NULL)
{ {
if (ImageBase <= (PVOID)0x1000) if (ImageBase <= (PVOID) 0x1000)
{ {
DPRINT("ImageBase is null\n"); DPRINT("ImageBase is null\n");
ZwTerminateProcess(NtCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT); ZwTerminateProcess(NtCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT);
} }
/* If MZ header exists */ /* If MZ header exists */
PEDosHeader = (PIMAGE_DOS_HEADER) ImageBase; PEDosHeader = (PIMAGE_DOS_HEADER) ImageBase;
DPRINT("PEDosHeader %p\n", PEDosHeader); DPRINT("PEDosHeader %p\n", PEDosHeader);
if (PEDosHeader->e_magic != IMAGE_DOS_SIGNATURE || if (PEDosHeader->e_magic != IMAGE_DOS_SIGNATURE ||
PEDosHeader->e_lfanew == 0L || PEDosHeader->e_lfanew == 0L ||
*(PULONG)((PUCHAR)ImageBase + PEDosHeader->e_lfanew) != IMAGE_NT_SIGNATURE) *(PULONG)((PUCHAR)ImageBase + PEDosHeader->e_lfanew) != IMAGE_NT_SIGNATURE)
{ {
DPRINT1("Image has bad header\n"); DPRINT1("Image has bad header\n");
ZwTerminateProcess(NtCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT); ZwTerminateProcess(NtCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT);
} }
/* normalize process parameters */ /* normalize process parameters */
RtlNormalizeProcessParams (Peb->ProcessParameters); RtlNormalizeProcessParams(Peb->ProcessParameters);
/* Initialize NLS data */ /* Initialize NLS data */
RtlInitNlsTables (Peb->AnsiCodePageData, RtlInitNlsTables(Peb->AnsiCodePageData,
Peb->OemCodePageData, Peb->OemCodePageData,
Peb->UnicodeCaseTableData, Peb->UnicodeCaseTableData,
&NlsTable); &NlsTable);
RtlResetRtlTranslations (&NlsTable); RtlResetRtlTranslations(&NlsTable);
NTHeaders = (PIMAGE_NT_HEADERS)((ULONG_PTR)ImageBase + PEDosHeader->e_lfanew); NTHeaders = (PIMAGE_NT_HEADERS)((ULONG_PTR)ImageBase + PEDosHeader->e_lfanew);
/* Get number of processors */ /* Get number of processors */
DPRINT("Here\n"); DPRINT("Here\n");
Status = ZwQuerySystemInformation(SystemBasicInformation, Status = ZwQuerySystemInformation(SystemBasicInformation,
&SystemInformation, &SystemInformation,
sizeof(SYSTEM_BASIC_INFORMATION), sizeof(SYSTEM_BASIC_INFORMATION),
NULL); NULL);
DPRINT("Here2\n"); DPRINT("Here2\n");
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ZwTerminateProcess(NtCurrentProcess(), Status); ZwTerminateProcess(NtCurrentProcess(), Status);
} }
Peb->NumberOfProcessors = SystemInformation.NumberOfProcessors; Peb->NumberOfProcessors = SystemInformation.NumberOfProcessors;
/* Initialize Critical Section Data */ /* Initialize Critical Section Data */
RtlpInitDeferedCriticalSection(); RtlpInitDeferedCriticalSection();
/* create process heap */ /* create process heap */
RtlInitializeHeapManager(); RtlInitializeHeapManager();
Peb->ProcessHeap = RtlCreateHeap(HEAP_GROWABLE, Peb->ProcessHeap = RtlCreateHeap(HEAP_GROWABLE,
NULL, NULL,
NTHeaders->OptionalHeader.SizeOfHeapReserve, NTHeaders->OptionalHeader.SizeOfHeapReserve,
NTHeaders->OptionalHeader.SizeOfHeapCommit, NTHeaders->OptionalHeader.SizeOfHeapCommit,
NULL, NULL,
NULL); NULL);
if (Peb->ProcessHeap == 0) if (Peb->ProcessHeap == 0)
{ {
DPRINT1("Failed to create process heap\n"); DPRINT1("Failed to create process heap\n");
ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES); ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
} }
/* initialized vectored exception handling */ /* initialized vectored exception handling */
RtlpInitializeVectoredExceptionHandling(); RtlpInitializeVectoredExceptionHandling();
/* initalize peb lock support */ /* initalize peb lock support */
RtlInitializeCriticalSection (&PebLock); RtlInitializeCriticalSection(&PebLock);
Peb->FastPebLock = &PebLock; Peb->FastPebLock = &PebLock;
Peb->FastPebLockRoutine = (PPEBLOCKROUTINE)RtlEnterCriticalSection; Peb->FastPebLockRoutine = (PPEBLOCKROUTINE)RtlEnterCriticalSection;
Peb->FastPebUnlockRoutine = (PPEBLOCKROUTINE)RtlLeaveCriticalSection; Peb->FastPebUnlockRoutine = (PPEBLOCKROUTINE)RtlLeaveCriticalSection;
/* initialize tls bitmaps */ /* initialize tls bitmaps */
RtlInitializeBitMap (&TlsBitMap, RtlInitializeBitMap(&TlsBitMap, Peb->TlsBitmapBits, TLS_MINIMUM_AVAILABLE);
Peb->TlsBitmapBits, RtlInitializeBitMap(&TlsExpansionBitMap, Peb->TlsExpansionBitmapBits, TLS_EXPANSION_SLOTS);
TLS_MINIMUM_AVAILABLE);
RtlInitializeBitMap (&TlsExpansionBitMap,
Peb->TlsExpansionBitmapBits,
TLS_EXPANSION_SLOTS);
Peb->TlsBitmap = &TlsBitMap; Peb->TlsBitmap = &TlsBitMap;
Peb->TlsExpansionBitmap = &TlsExpansionBitMap; Peb->TlsExpansionBitmap = &TlsExpansionBitMap;
Peb->TlsExpansionCounter = TLS_MINIMUM_AVAILABLE; Peb->TlsExpansionCounter = TLS_MINIMUM_AVAILABLE;
/* Initialize table of callbacks for the kernel. */ /* Initialize table of callbacks for the kernel. */
Peb->KernelCallbackTable = Peb->KernelCallbackTable = RtlAllocateHeap(RtlGetProcessHeap(),
RtlAllocateHeap(RtlGetProcessHeap(), 0,
0, sizeof(PVOID) *
sizeof(PVOID) * (USER32_CALLBACK_MAXIMUM + 1)); (USER32_CALLBACK_MAXIMUM + 1));
if (Peb->KernelCallbackTable == NULL) if (Peb->KernelCallbackTable == NULL)
{ {
DPRINT1("Failed to create callback table\n"); DPRINT1("Failed to create callback table\n");
ZwTerminateProcess(NtCurrentProcess(),STATUS_INSUFFICIENT_RESOURCES); ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
} }
/* initalize loader lock */ /* initalize loader lock */
RtlInitializeCriticalSection (&LoaderLock); RtlInitializeCriticalSection(&LoaderLock);
Peb->LoaderLock = &LoaderLock; Peb->LoaderLock = &LoaderLock;
/* create loader information */ /* create loader information */
Peb->Ldr = (PPEB_LDR_DATA)RtlAllocateHeap (Peb->ProcessHeap, Peb->Ldr = (PPEB_LDR_DATA) RtlAllocateHeap(Peb->ProcessHeap,
0, 0,
sizeof(PEB_LDR_DATA)); sizeof(PEB_LDR_DATA));
if (Peb->Ldr == NULL) if (Peb->Ldr == NULL)
{ {
DPRINT1("Failed to create loader data\n"); DPRINT1("Failed to create loader data\n");
ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES); ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
} }
Peb->Ldr->Length = sizeof(PEB_LDR_DATA);
Peb->Ldr->Initialized = FALSE;
Peb->Ldr->SsHandle = NULL;
InitializeListHead(&Peb->Ldr->InLoadOrderModuleList);
InitializeListHead(&Peb->Ldr->InMemoryOrderModuleList);
InitializeListHead(&Peb->Ldr->InInitializationOrderModuleList);
/* Load compatibility settings */ Peb->Ldr->Length = sizeof(PEB_LDR_DATA);
LoadCompatibilitySettings(Peb); Peb->Ldr->Initialized = FALSE;
Peb->Ldr->SsHandle = NULL;
InitializeListHead(&Peb->Ldr->InLoadOrderModuleList);
InitializeListHead(&Peb->Ldr->InMemoryOrderModuleList);
InitializeListHead(&Peb->Ldr->InInitializationOrderModuleList);
/* Load execution options */ /* Load compatibility settings */
LoadImageFileExecutionOptions(Peb); LoadCompatibilitySettings(Peb);
/* build full ntdll path */ /* Load execution options */
wcscpy (FullNtDllPath, SharedUserData->NtSystemRoot); LoadImageFileExecutionOptions(Peb);
wcscat (FullNtDllPath, L"\\system32\\ntdll.dll");
/* add entry for ntdll */ /* build full ntdll path */
NtModule = (PLDR_DATA_TABLE_ENTRY)RtlAllocateHeap (Peb->ProcessHeap, wcscpy(FullNtDllPath, SharedUserData->NtSystemRoot);
0, wcscat(FullNtDllPath, L"\\system32\\ntdll.dll");
sizeof(LDR_DATA_TABLE_ENTRY));
if (NtModule == NULL)
{
DPRINT1("Failed to create loader module entry (NTDLL)\n");
ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
}
memset(NtModule, 0, sizeof(LDR_DATA_TABLE_ENTRY));
NtModule->DllBase = BaseAddress; /* add entry for ntdll */
NtModule->EntryPoint = 0; /* no entry point */ NtModule = (PLDR_DATA_TABLE_ENTRY)
RtlCreateUnicodeString (&NtModule->FullDllName, RtlAllocateHeap(Peb->ProcessHeap,
FullNtDllPath); 0,
RtlCreateUnicodeString (&NtModule->BaseDllName, sizeof(LDR_DATA_TABLE_ENTRY));
L"ntdll.dll"); if (NtModule == NULL)
NtModule->Flags = LDRP_IMAGE_DLL|LDRP_ENTRY_PROCESSED; {
DPRINT1("Failed to create loader module entry (NTDLL)\n");
ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
}
memset(NtModule, 0, sizeof(LDR_DATA_TABLE_ENTRY));
NtModule->LoadCount = -1; /* don't unload */ NtModule->DllBase = BaseAddress;
NtModule->TlsIndex = -1; NtModule->EntryPoint = 0; /* no entry point */
NtModule->SectionPointer = NULL; RtlCreateUnicodeString(&NtModule->FullDllName, FullNtDllPath);
NtModule->CheckSum = 0; RtlCreateUnicodeString(&NtModule->BaseDllName, L"ntdll.dll");
NtModule->Flags = LDRP_IMAGE_DLL | LDRP_ENTRY_PROCESSED;
NTHeaders = RtlImageNtHeader (NtModule->DllBase); NtModule->LoadCount = -1; /* don't unload */
NtModule->SizeOfImage = LdrpGetResidentSize(NTHeaders); NtModule->TlsIndex = -1;
NtModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp; NtModule->SectionPointer = NULL;
NtModule->CheckSum = 0;
InsertTailList(&Peb->Ldr->InLoadOrderModuleList, NTHeaders = RtlImageNtHeader(NtModule->DllBase);
&NtModule->InLoadOrderLinks); NtModule->SizeOfImage = LdrpGetResidentSize(NTHeaders);
InsertTailList(&Peb->Ldr->InInitializationOrderModuleList, NtModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
&NtModule->InInitializationOrderModuleList);
InsertTailList(&Peb->Ldr->InLoadOrderModuleList,
&NtModule->InLoadOrderLinks);
InsertTailList(&Peb->Ldr->InInitializationOrderModuleList,
&NtModule->InInitializationOrderModuleList);
#if defined(DBG) || defined(KDBG) #if defined(DBG) || defined(KDBG)
LdrpLoadUserModuleSymbols(NtModule); LdrpLoadUserModuleSymbols(NtModule);
#endif /* DBG || KDBG */ #endif /* DBG || KDBG */
} }
if (NtCurrentPeb()->Ldr->Initialized == FALSE) if (NtCurrentPeb()->Ldr->Initialized == FALSE)
{ {
/* add entry for executable (becomes first list entry) */ /* add entry for executable (becomes first list entry) */
ExeModule = (PLDR_DATA_TABLE_ENTRY)RtlAllocateHeap (Peb->ProcessHeap, ExeModule = (PLDR_DATA_TABLE_ENTRY)
0, RtlAllocateHeap(Peb->ProcessHeap,
sizeof(LDR_DATA_TABLE_ENTRY)); 0,
if (ExeModule == NULL) sizeof(LDR_DATA_TABLE_ENTRY));
{ if (ExeModule == NULL)
DPRINT1("Failed to create loader module infomation\n"); {
ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES); DPRINT1("Failed to create loader module infomation\n");
} ZwTerminateProcess(NtCurrentProcess(), STATUS_INSUFFICIENT_RESOURCES);
ExeModule->DllBase = Peb->ImageBaseAddress; }
if ((Peb->ProcessParameters == NULL) || ExeModule->DllBase = Peb->ImageBaseAddress;
(Peb->ProcessParameters->ImagePathName.Length == 0))
{
DPRINT1("Failed to access the process parameter block\n");
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
}
RtlCreateUnicodeString(&ExeModule->FullDllName, if ((Peb->ProcessParameters == NULL) ||
Peb->ProcessParameters->ImagePathName.Buffer); (Peb->ProcessParameters->ImagePathName.Length == 0))
RtlCreateUnicodeString(&ExeModule->BaseDllName, {
wcsrchr(ExeModule->FullDllName.Buffer, L'\\') + 1); DPRINT1("Failed to access the process parameter block\n");
ZwTerminateProcess(NtCurrentProcess(), STATUS_UNSUCCESSFUL);
}
DPRINT("BaseDllName '%wZ' FullDllName '%wZ'\n", RtlCreateUnicodeString(&ExeModule->FullDllName,
&ExeModule->BaseDllName, Peb->ProcessParameters->ImagePathName.Buffer);
&ExeModule->FullDllName); RtlCreateUnicodeString(&ExeModule->BaseDllName,
wcsrchr(ExeModule->FullDllName.Buffer, L'\\') + 1);
ExeModule->Flags = LDRP_ENTRY_PROCESSED; DPRINT("BaseDllName '%wZ' FullDllName '%wZ'\n", &ExeModule->BaseDllName, &ExeModule->FullDllName);
ExeModule->LoadCount = -1; /* don't unload */
ExeModule->TlsIndex = -1;
ExeModule->SectionPointer = NULL;
ExeModule->CheckSum = 0;
NTHeaders = RtlImageNtHeader (ExeModule->DllBase); ExeModule->Flags = LDRP_ENTRY_PROCESSED;
ExeModule->SizeOfImage = LdrpGetResidentSize(NTHeaders); ExeModule->LoadCount = -1; /* don't unload */
ExeModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp; ExeModule->TlsIndex = -1;
ExeModule->SectionPointer = NULL;
ExeModule->CheckSum = 0;
InsertHeadList(&Peb->Ldr->InLoadOrderModuleList, NTHeaders = RtlImageNtHeader(ExeModule->DllBase);
&ExeModule->InLoadOrderLinks); ExeModule->SizeOfImage = LdrpGetResidentSize(NTHeaders);
ExeModule->TimeDateStamp = NTHeaders->FileHeader.TimeDateStamp;
LdrpInitLoader(); InsertHeadList(&Peb->Ldr->InLoadOrderModuleList,
&ExeModule->InLoadOrderLinks);
LdrpInitLoader();
#if defined(DBG) || defined(KDBG) #if defined(DBG) || defined(KDBG)
LdrpLoadUserModuleSymbols(ExeModule); LdrpLoadUserModuleSymbols(ExeModule);
#endif /* DBG || KDBG */ #endif /* DBG || KDBG */
EntryPoint = LdrPEStartup((PVOID)ImageBase, NULL, NULL, NULL); EntryPoint = LdrPEStartup((PVOID)ImageBase, NULL, NULL, NULL);
ExeModule->EntryPoint = EntryPoint; ExeModule->EntryPoint = EntryPoint;
/* all required dlls are loaded now */ /* all required dlls are loaded now */
Peb->Ldr->Initialized = TRUE; Peb->Ldr->Initialized = TRUE;
/* Check before returning that we can run the image safely. */ /* Check before returning that we can run the image safely. */
if (EntryPoint == NULL) if (EntryPoint == NULL)
{ {
DPRINT1("Failed to initialize image\n"); DPRINT1("Failed to initialize image\n");
ZwTerminateProcess(NtCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT); ZwTerminateProcess(NtCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT);
} }
/* Break into debugger */ /* Break into debugger */
if (Peb->BeingDebugged) DbgBreakPoint(); if (Peb->BeingDebugged)
} DbgBreakPoint();
}
/* attach the thread */ /* attach the thread */
RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock); RtlEnterCriticalSection(NtCurrentPeb()->LoaderLock);
LdrpAttachThread(); LdrpAttachThread();
RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock); RtlLeaveCriticalSection(NtCurrentPeb()->LoaderLock);
} }
/* EOF */ /* EOF */