📄 startup.c
字号:
/* $Id: startup.c 24017 2006-09-10 08:35:30Z fireball $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: lib/ntdll/ldr/startup.c
* PURPOSE: Process startup for PE executables
* PROGRAMMERS: Jean Michault
* Rex Jolliff (rex@lvcablemodem.com)
*/
/* INCLUDES *****************************************************************/
#include <ntdll.h>
#define NDEBUG
#include <debug.h>
#include <win32k/callback.h>
VOID RtlInitializeHeapManager (VOID);
VOID LdrpInitLoader(VOID);
VOID NTAPI RtlpInitDeferedCriticalSection(VOID);
/* GLOBALS *******************************************************************/
extern unsigned int _image_base__;
static RTL_CRITICAL_SECTION PebLock;
static RTL_CRITICAL_SECTION LoaderLock;
static RTL_BITMAP TlsBitMap;
PLDR_DATA_TABLE_ENTRY ExeModule;
NTSTATUS LdrpAttachThread (VOID);
VOID RtlpInitializeVectoredExceptionHandling(VOID);
#define VALUE_BUFFER_SIZE 256
BOOLEAN FASTCALL
ReadCompatibilitySetting(HANDLE Key, LPWSTR Value, PKEY_VALUE_PARTIAL_INFORMATION ValueInfo, DWORD *Buffer)
{
UNICODE_STRING ValueName;
NTSTATUS Status;
ULONG Length;
RtlInitUnicodeString(&ValueName, Value);
Status = NtQueryValueKey(Key,
&ValueName,
KeyValuePartialInformation,
ValueInfo,
VALUE_BUFFER_SIZE,
&Length);
if (!NT_SUCCESS(Status) || (ValueInfo->Type != REG_DWORD))
{
RtlFreeUnicodeString(&ValueName);
return FALSE;
}
RtlCopyMemory(Buffer, &ValueInfo->Data[0], sizeof(DWORD));
RtlFreeUnicodeString(&ValueName);
return TRUE;
}
VOID FASTCALL
LoadImageFileExecutionOptions(PPEB Peb)
{
NTSTATUS Status = STATUS_SUCCESS;
ULONG Value = 0;
UNICODE_STRING ValueString;
UNICODE_STRING ImageName;
UNICODE_STRING ImagePathName;
WCHAR ValueBuffer[64];
ULONG ValueSize;
if (Peb->ProcessParameters &&
Peb->ProcessParameters->ImagePathName.Length > 0)
{
DPRINT("%wZ\n", &Peb->ProcessParameters->ImagePathName);
ImagePathName = Peb->ProcessParameters->ImagePathName;
ImageName.Buffer = ImagePathName.Buffer + ImagePathName.Length / sizeof(WCHAR);
ImageName.Length = 0;
while (ImagePathName.Buffer < ImageName.Buffer)
{
ImageName.Buffer--;
if (*ImageName.Buffer == L'\\')
{
ImageName.Buffer++;
break;
}
}
ImageName.Length = ImagePathName.Length - (ImageName.Buffer - ImagePathName.Buffer) * sizeof(WCHAR);
ImageName.MaximumLength = ImageName.Length + ImagePathName.MaximumLength - ImagePathName.Length;
DPRINT("%wZ\n", &ImageName);
/* global flag */
Status = LdrQueryImageFileExecutionOptions (&ImageName,
L"GlobalFlag",
REG_SZ,
(PVOID)ValueBuffer,
sizeof(ValueBuffer),
&ValueSize);
if (NT_SUCCESS(Status))
{
ValueString.Buffer = ValueBuffer;
ValueString.Length = ValueSize - sizeof(WCHAR);
ValueString.MaximumLength = sizeof(ValueBuffer);
Status = RtlUnicodeStringToInteger(&ValueString, 16, &Value);
if (NT_SUCCESS(Status))
{
Peb->NtGlobalFlag |= Value;
DPRINT("GlobalFlag: Key='%S', Value=0x%lx\n", ValueBuffer, Value);
}
}
/*
* FIXME:
* read more options
*/
}
}
BOOLEAN FASTCALL
LoadCompatibilitySettings(PPEB Peb)
{
NTSTATUS Status;
HANDLE UserKey = NULL;
HANDLE KeyHandle;
HANDLE SubKeyHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName = RTL_CONSTANT_STRING(
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers");
UNICODE_STRING ValueName;
UCHAR ValueBuffer[VALUE_BUFFER_SIZE];
PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
ULONG Length;
DWORD MajorVersion, MinorVersion, BuildNumber, PlatformId,
SPMajorVersion, SPMinorVersion= 0;
if(Peb->ProcessParameters &&
(Peb->ProcessParameters->ImagePathName.Length > 0))
{
Status = RtlOpenCurrentUser(KEY_READ,
&UserKey);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
UserKey,
NULL);
Status = NtOpenKey(&KeyHandle,
KEY_QUERY_VALUE,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
if (UserKey) NtClose(UserKey);
return FALSE;
}
/* query version name for application */
ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ValueBuffer;
Status = NtQueryValueKey(KeyHandle,
&Peb->ProcessParameters->ImagePathName,
KeyValuePartialInformation,
ValueBuffer,
VALUE_BUFFER_SIZE,
&Length);
if (!NT_SUCCESS(Status) || (ValueInfo->Type != REG_SZ))
{
NtClose(KeyHandle);
if (UserKey) NtClose(UserKey);
return FALSE;
}
ValueName.Length = ValueInfo->DataLength;
ValueName.MaximumLength = ValueInfo->DataLength;
ValueName.Buffer = (PWSTR)ValueInfo->Data;
/* load version info */
InitializeObjectAttributes(&ObjectAttributes,
&ValueName,
OBJ_CASE_INSENSITIVE,
KeyHandle,
NULL);
Status = NtOpenKey(&SubKeyHandle,
KEY_QUERY_VALUE,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
NtClose(KeyHandle);
if (UserKey) NtClose(UserKey);
return FALSE;
}
DPRINT("Loading version information for: %wZ\n", &ValueName);
/* read settings from registry */
if(!ReadCompatibilitySetting(SubKeyHandle, L"MajorVersion", ValueInfo, &MajorVersion))
goto finish;
if(!ReadCompatibilitySetting(SubKeyHandle, L"MinorVersion", ValueInfo, &MinorVersion))
goto finish;
if(!ReadCompatibilitySetting(SubKeyHandle, L"BuildNumber", ValueInfo, &BuildNumber))
goto finish;
if(!ReadCompatibilitySetting(SubKeyHandle, L"PlatformId", ValueInfo, &PlatformId))
goto finish;
/* now assign the settings */
Peb->OSMajorVersion = (ULONG)MajorVersion;
Peb->OSMinorVersion = (ULONG)MinorVersion;
Peb->OSBuildNumber = (USHORT)BuildNumber;
Peb->OSPlatformId = (ULONG)PlatformId;
/* optional service pack version numbers */
if(ReadCompatibilitySetting(SubKeyHandle, L"SPMajorVersion", ValueInfo, &SPMajorVersion) &&
ReadCompatibilitySetting(SubKeyHandle, L"SPMinorVersion", ValueInfo, &SPMinorVersion))
Peb->OSCSDVersion = ((SPMajorVersion & 0xFF) << 8) | (SPMinorVersion & 0xFF);
finish:
/* we're finished */
NtClose(SubKeyHandle);
NtClose(KeyHandle);
if (UserKey) NtClose(UserKey);
return TRUE;
}
return FALSE;
}
/* FUNCTIONS *****************************************************************/
VOID
NTAPI
LdrpInit(PCONTEXT Context,
PVOID SystemArgument1,
PVOID SystemArgument2)
{
PIMAGE_NT_HEADERS NTHeaders;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -