mirror of
https://github.com/reactos/reactos.git
synced 2024-11-09 16:20:37 +00:00
9ea495ba33
svn path=/branches/header-work/; revision=45691
241 lines
5.9 KiB
C
241 lines
5.9 KiB
C
/*
|
|
* PROJECT: ReactOS Session Manager
|
|
* LICENSE: GPL v2 or later - See COPYING in the top level directory
|
|
* FILE: base/system/smss/initwkdll.c
|
|
* PURPOSE: Load the well known DLLs.
|
|
* PROGRAMMERS: ReactOS Development Team
|
|
*/
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
#include "smss.h"
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
static NTSTATUS NTAPI
|
|
SmpKnownDllsQueryRoutine(PWSTR ValueName,
|
|
ULONG ValueType,
|
|
PVOID ValueData,
|
|
ULONG ValueLength,
|
|
PVOID Context,
|
|
PVOID EntryContext)
|
|
{
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
UNICODE_STRING ImageName;
|
|
HANDLE FileHandle;
|
|
HANDLE SectionHandle;
|
|
NTSTATUS Status;
|
|
|
|
DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
|
|
DPRINT("ValueData '%S' Context %p EntryContext %p\n", (PWSTR)ValueData, Context, EntryContext);
|
|
|
|
/* Ignore the 'DllDirectory' value */
|
|
if (!_wcsicmp(ValueName, L"DllDirectory"))
|
|
return STATUS_SUCCESS;
|
|
|
|
/* Open the DLL image file */
|
|
RtlInitUnicodeString(&ImageName,
|
|
ValueData);
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
&ImageName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
(HANDLE)Context,
|
|
NULL);
|
|
Status = NtOpenFile(&FileHandle,
|
|
SYNCHRONIZE | FILE_EXECUTE | FILE_READ_DATA,
|
|
&ObjectAttributes,
|
|
&IoStatusBlock,
|
|
FILE_SHARE_READ,
|
|
FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
DPRINT("Opened file %wZ successfully\n", &ImageName);
|
|
|
|
/* Check for valid image checksum */
|
|
Status = LdrVerifyImageMatchesChecksum (FileHandle,
|
|
0,
|
|
0,
|
|
0);
|
|
if (Status == STATUS_IMAGE_CHECKSUM_MISMATCH)
|
|
{
|
|
/* Raise a hard error (crash the system/BSOD) */
|
|
NtRaiseHardError (Status,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0);
|
|
}
|
|
else if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("Failed to check the image checksum\n");
|
|
|
|
NtClose(FileHandle);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
&ImageName,
|
|
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
|
|
(HANDLE)EntryContext,
|
|
NULL);
|
|
Status = NtCreateSection(&SectionHandle,
|
|
SECTION_ALL_ACCESS,
|
|
&ObjectAttributes,
|
|
NULL,
|
|
PAGE_EXECUTE,
|
|
SEC_IMAGE,
|
|
FileHandle);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
DPRINT("Created section successfully\n");
|
|
NtClose(SectionHandle);
|
|
}
|
|
|
|
NtClose(FileHandle);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
SmLoadKnownDlls(VOID)
|
|
{
|
|
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
UNICODE_STRING DllDosPath;
|
|
UNICODE_STRING DllNtPath;
|
|
UNICODE_STRING Name;
|
|
HANDLE ObjectDirHandle;
|
|
HANDLE FileDirHandle;
|
|
HANDLE SymlinkHandle;
|
|
NTSTATUS Status;
|
|
|
|
|
|
DPRINT("SM: loading well-known DLLs\n");
|
|
|
|
DPRINT("SmLoadKnownDlls() called\n");
|
|
|
|
/* Create 'KnownDlls' object directory */
|
|
RtlInitUnicodeString(&Name,
|
|
L"\\KnownDlls");
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
&Name,
|
|
OBJ_PERMANENT | OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
|
|
NULL,
|
|
NULL);
|
|
Status = NtCreateDirectoryObject(&ObjectDirHandle,
|
|
DIRECTORY_ALL_ACCESS,
|
|
&ObjectAttributes);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("NtCreateDirectoryObject() failed (Status %lx)\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
RtlInitUnicodeString(&DllDosPath, NULL);
|
|
|
|
RtlZeroMemory(&QueryTable,
|
|
sizeof(QueryTable));
|
|
|
|
QueryTable[0].Name = L"DllDirectory";
|
|
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
|
QueryTable[0].EntryContext = &DllDosPath;
|
|
|
|
Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
|
|
L"\\Session Manager\\KnownDlls",
|
|
QueryTable,
|
|
NULL,
|
|
SmSystemEnvironment);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
DPRINT("DllDosPath: '%wZ'\n", &DllDosPath);
|
|
|
|
if (!RtlDosPathNameToNtPathName_U(DllDosPath.Buffer,
|
|
&DllNtPath,
|
|
NULL,
|
|
NULL))
|
|
{
|
|
DPRINT1("RtlDosPathNameToNtPathName_U() failed\n");
|
|
return STATUS_OBJECT_NAME_INVALID;
|
|
}
|
|
|
|
DPRINT("DllNtPath: '%wZ'\n", &DllNtPath);
|
|
|
|
/* Open the dll path directory */
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
&DllNtPath,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL);
|
|
Status = NtOpenFile(&FileDirHandle,
|
|
SYNCHRONIZE | FILE_READ_DATA,
|
|
&ObjectAttributes,
|
|
&IoStatusBlock,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(),
|
|
0,
|
|
DllNtPath.Buffer);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("NtOpenFile failed (Status %lx)\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
/* Link 'KnownDllPath' the dll path directory */
|
|
RtlInitUnicodeString(&Name,
|
|
L"KnownDllPath");
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
&Name,
|
|
OBJ_PERMANENT | OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
|
|
ObjectDirHandle,
|
|
NULL);
|
|
Status = NtCreateSymbolicLinkObject(&SymlinkHandle,
|
|
SYMBOLIC_LINK_ALL_ACCESS,
|
|
&ObjectAttributes,
|
|
&DllDosPath);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("NtCreateSymbolicLink() failed (Status %lx)\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
NtClose(SymlinkHandle);
|
|
|
|
RtlZeroMemory(&QueryTable,
|
|
sizeof(QueryTable));
|
|
|
|
QueryTable[0].QueryRoutine = SmpKnownDllsQueryRoutine;
|
|
QueryTable[0].EntryContext = ObjectDirHandle;
|
|
|
|
Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
|
|
L"\\Session Manager\\KnownDlls",
|
|
QueryTable,
|
|
(PVOID)FileDirHandle,
|
|
NULL);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
|
|
}
|
|
|
|
DPRINT("SmLoadKnownDlls() done\n");
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
/* EOF */
|