/* * 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 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 */