mirror of
https://github.com/reactos/reactos.git
synced 2025-04-25 08:00:24 +00:00
[FORMATTING] Fix indentation.
svn path=/trunk/; revision=38354
This commit is contained in:
parent
fd4de76baf
commit
4d4d9e60fb
1 changed files with 365 additions and 355 deletions
|
@ -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 */
|
||||||
|
|
Loading…
Reference in a new issue