mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Implemented dll preloading and mapping.
svn path=/trunk/; revision=4681
This commit is contained in:
parent
b5b83b1d47
commit
107725f820
3 changed files with 527 additions and 375 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: startup.c,v 1.50 2003/04/27 14:45:52 chorns Exp $
|
/* $Id: startup.c,v 1.51 2003/05/12 19:47:53 ekohl Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -24,6 +24,8 @@
|
||||||
|
|
||||||
|
|
||||||
VOID RtlInitializeHeapManager (VOID);
|
VOID RtlInitializeHeapManager (VOID);
|
||||||
|
VOID LdrpInitLoader(VOID);
|
||||||
|
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
|
@ -259,6 +261,8 @@ __true_LdrInitializeThunk (ULONG Unknown1,
|
||||||
InsertHeadList(&Peb->Ldr->InLoadOrderModuleList,
|
InsertHeadList(&Peb->Ldr->InLoadOrderModuleList,
|
||||||
&ExeModule->InLoadOrderModuleList);
|
&ExeModule->InLoadOrderModuleList);
|
||||||
|
|
||||||
|
LdrpInitLoader();
|
||||||
|
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
|
|
||||||
LdrpLoadUserModuleSymbols(ExeModule);
|
LdrpLoadUserModuleSymbols(ExeModule);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: utils.c,v 1.64 2003/04/30 22:04:12 gvg Exp $
|
/* $Id: utils.c,v 1.65 2003/05/12 19:47:53 ekohl Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -31,6 +31,12 @@
|
||||||
#endif
|
#endif
|
||||||
#include <ntdll/ntdll.h>
|
#include <ntdll/ntdll.h>
|
||||||
|
|
||||||
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
|
static HANDLE LdrpKnownDllsDirHandle = NULL;
|
||||||
|
static UNICODE_STRING LdrpKnownDllPath = {0, 0, NULL};
|
||||||
|
|
||||||
|
|
||||||
/* PROTOTYPES ****************************************************************/
|
/* PROTOTYPES ****************************************************************/
|
||||||
|
|
||||||
static NTSTATUS LdrFindEntryForName(PUNICODE_STRING Name, PLDR_MODULE *Module);
|
static NTSTATUS LdrFindEntryForName(PUNICODE_STRING Name, PLDR_MODULE *Module);
|
||||||
|
@ -58,6 +64,87 @@ LdrpLoadUserModuleSymbols(PLDR_MODULE LdrModule)
|
||||||
#endif /* DBG */
|
#endif /* DBG */
|
||||||
|
|
||||||
|
|
||||||
|
VOID
|
||||||
|
LdrpInitLoader(VOID)
|
||||||
|
{
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
UNICODE_STRING LinkTarget;
|
||||||
|
UNICODE_STRING Name;
|
||||||
|
HANDLE LinkHandle;
|
||||||
|
ULONG Length;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
DPRINT("LdrpInitLoader() called\n");
|
||||||
|
|
||||||
|
/* Get handle to the 'KnownDlls' directory */
|
||||||
|
RtlInitUnicodeString(&Name,
|
||||||
|
L"\\KnownDlls");
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&Name,
|
||||||
|
OBJ_CASE_INSENSITIVE,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
Status = NtOpenDirectoryObject(&LdrpKnownDllsDirHandle,
|
||||||
|
DIRECTORY_QUERY | DIRECTORY_TRAVERSE,
|
||||||
|
&ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("NtOpenDirectoryObject() failed (Status %lx)\n", Status);
|
||||||
|
LdrpKnownDllsDirHandle = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate target name string */
|
||||||
|
LinkTarget.Length = 0;
|
||||||
|
LinkTarget.MaximumLength = MAX_PATH * sizeof(WCHAR);
|
||||||
|
LinkTarget.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||||
|
0,
|
||||||
|
MAX_PATH * sizeof(WCHAR));
|
||||||
|
if (LinkTarget.Buffer == NULL)
|
||||||
|
{
|
||||||
|
NtClose(LdrpKnownDllsDirHandle);
|
||||||
|
LdrpKnownDllsDirHandle = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&Name,
|
||||||
|
L"KnownDllPath");
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&Name,
|
||||||
|
OBJ_CASE_INSENSITIVE | OBJ_OPENLINK,
|
||||||
|
LdrpKnownDllsDirHandle,
|
||||||
|
NULL);
|
||||||
|
Status = NtOpenSymbolicLinkObject(&LinkHandle,
|
||||||
|
SYMBOLIC_LINK_ALL_ACCESS,
|
||||||
|
&ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
RtlFreeUnicodeString(&LinkTarget);
|
||||||
|
NtClose(LdrpKnownDllsDirHandle);
|
||||||
|
LdrpKnownDllsDirHandle = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = NtQuerySymbolicLinkObject(LinkHandle,
|
||||||
|
&LinkTarget,
|
||||||
|
&Length);
|
||||||
|
NtClose(LinkHandle);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
RtlFreeUnicodeString(&LinkTarget);
|
||||||
|
NtClose(LdrpKnownDllsDirHandle);
|
||||||
|
LdrpKnownDllsDirHandle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlCreateUnicodeString(&LdrpKnownDllPath,
|
||||||
|
LinkTarget.Buffer);
|
||||||
|
|
||||||
|
RtlFreeUnicodeString(&LinkTarget);
|
||||||
|
|
||||||
|
DPRINT("LdrpInitLoader() done\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* NAME LOCAL
|
* NAME LOCAL
|
||||||
* LdrAdjustDllName
|
* LdrAdjustDllName
|
||||||
|
@ -140,8 +227,9 @@ LdrAdjustDllName (PUNICODE_STRING FullDllName,
|
||||||
}
|
}
|
||||||
|
|
||||||
PLDR_MODULE
|
PLDR_MODULE
|
||||||
LdrAddModuleEntry(PVOID ImageBase, PIMAGE_NT_HEADERS NTHeaders,
|
LdrAddModuleEntry(PVOID ImageBase,
|
||||||
PWSTR FullDosName)
|
PIMAGE_NT_HEADERS NTHeaders,
|
||||||
|
PWSTR FullDosName)
|
||||||
{
|
{
|
||||||
PLDR_MODULE Module;
|
PLDR_MODULE Module;
|
||||||
Module = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof (LDR_MODULE));
|
Module = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof (LDR_MODULE));
|
||||||
|
@ -183,75 +271,83 @@ LdrAddModuleEntry(PVOID ImageBase, PIMAGE_NT_HEADERS NTHeaders,
|
||||||
return(Module);
|
return(Module);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* NAME EXPORTED
|
|
||||||
* LdrLoadDll
|
|
||||||
*
|
|
||||||
* DESCRIPTION
|
|
||||||
*
|
|
||||||
* ARGUMENTS
|
|
||||||
*
|
|
||||||
* RETURN VALUE
|
|
||||||
*
|
|
||||||
* REVISIONS
|
|
||||||
*
|
|
||||||
* NOTE
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
static NTSTATUS
|
||||||
LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
|
LdrpMapKnownDll(IN PUNICODE_STRING DllName,
|
||||||
IN ULONG LoadFlags,
|
OUT PUNICODE_STRING FullDosName,
|
||||||
IN PUNICODE_STRING Name,
|
OUT PHANDLE SectionHandle)
|
||||||
OUT PVOID *BaseAddress OPTIONAL)
|
{
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
UNICODE_STRING ObjectDirName;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
DPRINT("LdrpMapKnownDll() called\n");
|
||||||
|
|
||||||
|
if (LdrpKnownDllsDirHandle == NULL)
|
||||||
|
{
|
||||||
|
DPRINT("Invalid 'KnownDlls' directory\n");
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("LdrpKnownDllPath '%wZ'\n", &LdrpKnownDllPath);
|
||||||
|
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
DllName,
|
||||||
|
OBJ_CASE_INSENSITIVE,
|
||||||
|
LdrpKnownDllsDirHandle,
|
||||||
|
NULL);
|
||||||
|
Status = NtOpenSection(SectionHandle,
|
||||||
|
SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE,
|
||||||
|
&ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("NtOpenSection() failed for '%wZ' (Status %lx)\n", DllName, Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
FullDosName->Length = LdrpKnownDllPath.Length + DllName->Length + sizeof(WCHAR);
|
||||||
|
FullDosName->MaximumLength = FullDosName->Length + sizeof(WCHAR);
|
||||||
|
FullDosName->Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||||
|
0,
|
||||||
|
FullDosName->MaximumLength);
|
||||||
|
if (FullDosName->Buffer == NULL)
|
||||||
|
{
|
||||||
|
FullDosName->Length = 0;
|
||||||
|
FullDosName->MaximumLength = 0;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
wcscpy(FullDosName->Buffer, LdrpKnownDllPath.Buffer);
|
||||||
|
wcscat(FullDosName->Buffer, L"\\");
|
||||||
|
wcscat(FullDosName->Buffer, DllName->Buffer);
|
||||||
|
|
||||||
|
DPRINT("FullDosName '%wZ'\n", FullDosName);
|
||||||
|
|
||||||
|
DPRINT("LdrpMapKnownDll() done\n");
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
LdrpMapDllImageFile(IN PWSTR SearchPath OPTIONAL,
|
||||||
|
IN PUNICODE_STRING DllName,
|
||||||
|
OUT PUNICODE_STRING FullDosName,
|
||||||
|
OUT PHANDLE SectionHandle)
|
||||||
{
|
{
|
||||||
WCHAR SearchPathBuffer[MAX_PATH];
|
WCHAR SearchPathBuffer[MAX_PATH];
|
||||||
WCHAR FullDosName[MAX_PATH];
|
WCHAR DosName[MAX_PATH];
|
||||||
UNICODE_STRING AdjustedName;
|
|
||||||
UNICODE_STRING FullNtFileName;
|
UNICODE_STRING FullNtFileName;
|
||||||
OBJECT_ATTRIBUTES FileObjectAttributes;
|
OBJECT_ATTRIBUTES FileObjectAttributes;
|
||||||
|
HANDLE FileHandle;
|
||||||
char BlockBuffer [1024];
|
char BlockBuffer [1024];
|
||||||
PIMAGE_DOS_HEADER DosHeader;
|
PIMAGE_DOS_HEADER DosHeader;
|
||||||
NTSTATUS Status;
|
|
||||||
PIMAGE_NT_HEADERS NTHeaders;
|
PIMAGE_NT_HEADERS NTHeaders;
|
||||||
ULONG ImageSize;
|
|
||||||
ULONG InitialViewSize;
|
|
||||||
PVOID ImageBase;
|
PVOID ImageBase;
|
||||||
HANDLE FileHandle;
|
ULONG ImageSize;
|
||||||
HANDLE SectionHandle;
|
NTSTATUS Status;
|
||||||
PDLLMAIN_FUNC Entrypoint = NULL;
|
|
||||||
PLDR_MODULE Module;
|
|
||||||
|
|
||||||
if (Name == NULL)
|
|
||||||
{
|
|
||||||
*BaseAddress = NtCurrentPeb()->ImageBaseAddress;
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
DPRINT("LdrpMapDllImageFile() called\n");
|
||||||
*BaseAddress = NULL;
|
|
||||||
|
|
||||||
DPRINT("LdrLoadDll(Name \"%wZ\" BaseAddress %x)\n",
|
|
||||||
Name, BaseAddress);
|
|
||||||
|
|
||||||
/* adjust the full dll name */
|
|
||||||
LdrAdjustDllName (&AdjustedName,
|
|
||||||
Name,
|
|
||||||
FALSE);
|
|
||||||
DPRINT("AdjustedName: %wZ\n", &AdjustedName);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Test if dll is already loaded.
|
|
||||||
*/
|
|
||||||
if (LdrFindEntryForName(&AdjustedName, &Module) == STATUS_SUCCESS)
|
|
||||||
{
|
|
||||||
DPRINT("DLL %wZ already loaded.\n", &AdjustedName);
|
|
||||||
if (Module->LoadCount != -1)
|
|
||||||
Module->LoadCount++;
|
|
||||||
*BaseAddress = Module->BaseAddress;
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
DPRINT("Loading \"%wZ\"\n", Name);
|
|
||||||
|
|
||||||
if (SearchPath == NULL)
|
if (SearchPath == NULL)
|
||||||
{
|
{
|
||||||
|
@ -263,38 +359,36 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("SearchPath %S\n", SearchPath);
|
DPRINT("SearchPath %S\n", SearchPath);
|
||||||
|
|
||||||
if (RtlDosSearchPath_U (SearchPath,
|
if (RtlDosSearchPath_U (SearchPath,
|
||||||
AdjustedName.Buffer,
|
DllName->Buffer,
|
||||||
NULL,
|
NULL,
|
||||||
MAX_PATH,
|
MAX_PATH,
|
||||||
FullDosName,
|
DosName,
|
||||||
NULL) == 0)
|
NULL) == 0)
|
||||||
return STATUS_DLL_NOT_FOUND;
|
return STATUS_DLL_NOT_FOUND;
|
||||||
|
|
||||||
DPRINT("FullDosName %S\n", FullDosName);
|
DPRINT("DosName %S\n", DosName);
|
||||||
|
|
||||||
RtlFreeUnicodeString (&AdjustedName);
|
if (!RtlDosPathNameToNtPathName_U (DosName,
|
||||||
|
|
||||||
if (!RtlDosPathNameToNtPathName_U (FullDosName,
|
|
||||||
&FullNtFileName,
|
&FullNtFileName,
|
||||||
NULL,
|
NULL,
|
||||||
NULL))
|
NULL))
|
||||||
return STATUS_DLL_NOT_FOUND;
|
return STATUS_DLL_NOT_FOUND;
|
||||||
|
|
||||||
DPRINT("FullNtFileName %wZ\n", &FullNtFileName);
|
DPRINT("FullNtFileName %wZ\n", &FullNtFileName);
|
||||||
|
|
||||||
InitializeObjectAttributes(&FileObjectAttributes,
|
InitializeObjectAttributes(&FileObjectAttributes,
|
||||||
&FullNtFileName,
|
&FullNtFileName,
|
||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
DPRINT("Opening dll \"%wZ\"\n", &FullNtFileName);
|
DPRINT("Opening dll \"%wZ\"\n", &FullNtFileName);
|
||||||
|
|
||||||
Status = ZwOpenFile(&FileHandle,
|
Status = ZwOpenFile(&FileHandle,
|
||||||
FILE_ALL_ACCESS,
|
FILE_ALL_ACCESS,
|
||||||
&FileObjectAttributes,
|
&FileObjectAttributes,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
0);
|
0);
|
||||||
|
@ -306,7 +400,7 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
RtlFreeUnicodeString (&FullNtFileName);
|
RtlFreeUnicodeString (&FullNtFileName);
|
||||||
|
|
||||||
Status = ZwReadFile(FileHandle,
|
Status = ZwReadFile(FileHandle,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
@ -345,46 +439,147 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
|
||||||
ImageSize = NTHeaders->OptionalHeader.SizeOfImage;
|
ImageSize = NTHeaders->OptionalHeader.SizeOfImage;
|
||||||
|
|
||||||
DPRINT("ImageBase 0x%08x\n", ImageBase);
|
DPRINT("ImageBase 0x%08x\n", ImageBase);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a section for dll.
|
* Create a section for dll.
|
||||||
*/
|
*/
|
||||||
Status = ZwCreateSection(&SectionHandle,
|
Status = ZwCreateSection(SectionHandle,
|
||||||
SECTION_ALL_ACCESS,
|
SECTION_ALL_ACCESS,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
SEC_COMMIT | SEC_IMAGE,
|
SEC_COMMIT | SEC_IMAGE,
|
||||||
FileHandle);
|
FileHandle);
|
||||||
|
ZwClose(FileHandle);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("NTDLL create section failed: Status = 0x%08x\n", Status);
|
DPRINT("NTDLL create section failed: Status = 0x%08x\n", Status);
|
||||||
ZwClose(FileHandle);
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RtlCreateUnicodeString(FullDosName,
|
||||||
|
DosName);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* NAME EXPORTED
|
||||||
|
* LdrLoadDll
|
||||||
|
*
|
||||||
|
* DESCRIPTION
|
||||||
|
*
|
||||||
|
* ARGUMENTS
|
||||||
|
*
|
||||||
|
* RETURN VALUE
|
||||||
|
*
|
||||||
|
* REVISIONS
|
||||||
|
*
|
||||||
|
* NOTE
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
|
||||||
|
IN ULONG LoadFlags,
|
||||||
|
IN PUNICODE_STRING Name,
|
||||||
|
OUT PVOID *BaseAddress OPTIONAL)
|
||||||
|
{
|
||||||
|
UNICODE_STRING FullDosName;
|
||||||
|
UNICODE_STRING AdjustedName;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PIMAGE_NT_HEADERS NTHeaders;
|
||||||
|
ULONG ViewSize;
|
||||||
|
PVOID ImageBase;
|
||||||
|
HANDLE SectionHandle;
|
||||||
|
PDLLMAIN_FUNC Entrypoint = NULL;
|
||||||
|
PLDR_MODULE Module;
|
||||||
|
|
||||||
|
|
||||||
|
if (Name == NULL)
|
||||||
|
{
|
||||||
|
*BaseAddress = NtCurrentPeb()->ImageBaseAddress;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
*BaseAddress = NULL;
|
||||||
|
|
||||||
|
DPRINT("LdrLoadDll(Name \"%wZ\" BaseAddress %x)\n",
|
||||||
|
Name, BaseAddress);
|
||||||
|
|
||||||
|
/* adjust the full dll name */
|
||||||
|
LdrAdjustDllName (&AdjustedName,
|
||||||
|
Name,
|
||||||
|
FALSE);
|
||||||
|
DPRINT("AdjustedName: %wZ\n", &AdjustedName);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test if dll is already loaded.
|
||||||
|
*/
|
||||||
|
if (LdrFindEntryForName(&AdjustedName, &Module) == STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
DPRINT("DLL %wZ already loaded.\n", &AdjustedName);
|
||||||
|
if (Module->LoadCount != -1)
|
||||||
|
Module->LoadCount++;
|
||||||
|
*BaseAddress = Module->BaseAddress;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
DPRINT("Loading \"%wZ\"\n", Name);
|
||||||
|
|
||||||
|
/* Open or create dll image section */
|
||||||
|
Status = LdrpMapKnownDll(&AdjustedName,
|
||||||
|
&FullDosName,
|
||||||
|
&SectionHandle);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
Status = LdrpMapDllImageFile(SearchPath,
|
||||||
|
&AdjustedName,
|
||||||
|
&FullDosName,
|
||||||
|
&SectionHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlFreeUnicodeString(&AdjustedName);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to create or open dll section (Status %lx)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Map the dll into the process.
|
* Map the dll into the process.
|
||||||
*/
|
*/
|
||||||
InitialViewSize = 0;
|
ViewSize = 0;
|
||||||
ImageBase = 0;
|
ImageBase = 0;
|
||||||
Status = ZwMapViewOfSection(SectionHandle,
|
Status = NtMapViewOfSection(SectionHandle,
|
||||||
NtCurrentProcess(),
|
NtCurrentProcess(),
|
||||||
&ImageBase,
|
&ImageBase,
|
||||||
0,
|
0,
|
||||||
InitialViewSize,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
&InitialViewSize,
|
&ViewSize,
|
||||||
0,
|
0,
|
||||||
MEM_COMMIT,
|
MEM_COMMIT,
|
||||||
PAGE_READWRITE);
|
PAGE_READWRITE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("NTDLL.LDR: map view of section failed (Status %x)\n", Status);
|
DbgPrint("NTDLL.LDR: map view of section failed (Status %x)\n", Status);
|
||||||
ZwClose(FileHandle);
|
RtlFreeUnicodeString(&FullDosName);
|
||||||
|
NtClose(SectionHandle);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
ZwClose(FileHandle);
|
|
||||||
|
/* Get and check the NT headers */
|
||||||
|
NTHeaders = RtlImageNtHeader(ImageBase);
|
||||||
|
if (NTHeaders == NULL)
|
||||||
|
{
|
||||||
|
DPRINT1("RtlImageNtHeaders() failed\n");
|
||||||
|
RtlFreeUnicodeString(&FullDosName);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
/* relocate dll and fixup import table */
|
/* relocate dll and fixup import table */
|
||||||
if ((NTHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) ==
|
if ((NTHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) ==
|
||||||
|
@ -392,13 +587,16 @@ LdrLoadDll (IN PWSTR SearchPath OPTIONAL,
|
||||||
{
|
{
|
||||||
Entrypoint =
|
Entrypoint =
|
||||||
(PDLLMAIN_FUNC) LdrPEStartup(ImageBase, SectionHandle, &Module,
|
(PDLLMAIN_FUNC) LdrPEStartup(ImageBase, SectionHandle, &Module,
|
||||||
FullDosName);
|
FullDosName.Buffer);
|
||||||
if (Entrypoint == NULL)
|
if (Entrypoint == NULL)
|
||||||
{
|
{
|
||||||
|
RtlFreeUnicodeString(&FullDosName);
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RtlFreeUnicodeString(&FullDosName);
|
||||||
|
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
|
|
||||||
LdrpLoadUserModuleSymbols(Module);
|
LdrpLoadUserModuleSymbols(Module);
|
||||||
|
@ -1355,174 +1553,6 @@ LdrUnloadDll (IN PVOID BaseAddress)
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /*MOVED_TO_FILE_RES_C*/
|
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
|
||||||
LdrFindResource_U(PVOID BaseAddress,
|
|
||||||
PLDR_RESOURCE_INFO ResourceInfo,
|
|
||||||
ULONG Level,
|
|
||||||
PIMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry)
|
|
||||||
{
|
|
||||||
PIMAGE_RESOURCE_DIRECTORY ResDir;
|
|
||||||
PIMAGE_RESOURCE_DIRECTORY ResBase;
|
|
||||||
PIMAGE_RESOURCE_DIRECTORY_ENTRY ResEntry;
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
ULONG EntryCount;
|
|
||||||
PWCHAR ws;
|
|
||||||
ULONG i;
|
|
||||||
ULONG Id;
|
|
||||||
|
|
||||||
DPRINT ("LdrFindResource_U()\n");
|
|
||||||
|
|
||||||
/* Get the pointer to the resource directory */
|
|
||||||
ResDir = (PIMAGE_RESOURCE_DIRECTORY)
|
|
||||||
RtlImageDirectoryEntryToData (BaseAddress,
|
|
||||||
TRUE,
|
|
||||||
IMAGE_DIRECTORY_ENTRY_RESOURCE,
|
|
||||||
&i);
|
|
||||||
if (ResDir == NULL)
|
|
||||||
{
|
|
||||||
return STATUS_RESOURCE_DATA_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("ResourceDirectory: %x\n", (ULONG)ResDir);
|
|
||||||
|
|
||||||
ResBase = ResDir;
|
|
||||||
|
|
||||||
/* Let's go into resource tree */
|
|
||||||
for (i = 0; i < Level; i++)
|
|
||||||
{
|
|
||||||
DPRINT("ResDir: %x\n", (ULONG)ResDir);
|
|
||||||
Id = ((PULONG)ResourceInfo)[i];
|
|
||||||
EntryCount = ResDir->NumberOfNamedEntries;
|
|
||||||
ResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(ResDir + 1);
|
|
||||||
DPRINT("ResEntry %x\n", (ULONG)ResEntry);
|
|
||||||
if (Id & 0xFFFF0000)
|
|
||||||
{
|
|
||||||
/* Resource name is a unicode string */
|
|
||||||
for (; EntryCount--; ResEntry++)
|
|
||||||
{
|
|
||||||
/* Scan entries for equal name */
|
|
||||||
if (ResEntry->Name & 0x80000000)
|
|
||||||
{
|
|
||||||
ws = (PWCHAR)((ULONG)ResDir + (ResEntry->Name & 0x7FFFFFFF));
|
|
||||||
if (!wcsncmp((PWCHAR)Id, ws + 1, *ws ) &&
|
|
||||||
wcslen((PWCHAR)Id) == (int)*ws )
|
|
||||||
{
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* We use ID number instead of string */
|
|
||||||
ResEntry += EntryCount;
|
|
||||||
EntryCount = ResDir->NumberOfIdEntries;
|
|
||||||
for (; EntryCount--; ResEntry++)
|
|
||||||
{
|
|
||||||
/* Scan entries for equal name */
|
|
||||||
if (ResEntry->Name == Id)
|
|
||||||
{
|
|
||||||
DPRINT("ID entry found %x\n", Id);
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DPRINT("Error %lu\n", i);
|
|
||||||
|
|
||||||
switch (i)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
return STATUS_RESOURCE_TYPE_NOT_FOUND;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
return STATUS_RESOURCE_NAME_NOT_FOUND;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
if (ResDir->NumberOfNamedEntries || ResDir->NumberOfIdEntries)
|
|
||||||
{
|
|
||||||
/* Use the first available language */
|
|
||||||
ResEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(ResDir + 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return STATUS_RESOURCE_LANG_NOT_FOUND;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
return STATUS_RESOURCE_DATA_NOT_FOUND;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
found:;
|
|
||||||
ResDir = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)ResBase +
|
|
||||||
(ResEntry->OffsetToData & 0x7FFFFFFF));
|
|
||||||
}
|
|
||||||
DPRINT("ResourceDataEntry: %x\n", (ULONG)ResDir);
|
|
||||||
|
|
||||||
if (ResourceDataEntry)
|
|
||||||
{
|
|
||||||
*ResourceDataEntry = (PVOID)ResDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
|
||||||
LdrAccessResource(IN PVOID BaseAddress,
|
|
||||||
IN PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry,
|
|
||||||
OUT PVOID *Resource OPTIONAL,
|
|
||||||
OUT PULONG Size OPTIONAL)
|
|
||||||
{
|
|
||||||
PIMAGE_SECTION_HEADER Section;
|
|
||||||
PIMAGE_NT_HEADERS NtHeader;
|
|
||||||
ULONG SectionRva;
|
|
||||||
ULONG SectionVa;
|
|
||||||
ULONG DataSize;
|
|
||||||
ULONG Offset = 0;
|
|
||||||
ULONG Data;
|
|
||||||
|
|
||||||
Data = (ULONG)RtlImageDirectoryEntryToData (BaseAddress,
|
|
||||||
TRUE,
|
|
||||||
IMAGE_DIRECTORY_ENTRY_RESOURCE,
|
|
||||||
&DataSize);
|
|
||||||
if (Data == 0)
|
|
||||||
return STATUS_RESOURCE_DATA_NOT_FOUND;
|
|
||||||
|
|
||||||
if ((ULONG)BaseAddress & 1)
|
|
||||||
{
|
|
||||||
/* loaded as ordinary file */
|
|
||||||
NtHeader = RtlImageNtHeader((PVOID)((ULONG)BaseAddress & ~1UL));
|
|
||||||
Offset = (ULONG)BaseAddress - Data + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
|
|
||||||
Section = RtlImageRvaToSection (NtHeader, BaseAddress, NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress);
|
|
||||||
if (Section == NULL)
|
|
||||||
{
|
|
||||||
return STATUS_RESOURCE_DATA_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Section->Misc.VirtualSize < ResourceDataEntry->OffsetToData)
|
|
||||||
{
|
|
||||||
SectionRva = RtlImageRvaToSection (NtHeader, BaseAddress, ResourceDataEntry->OffsetToData)->VirtualAddress;
|
|
||||||
SectionVa = RtlImageRvaToVa(NtHeader, BaseAddress, SectionRva, NULL);
|
|
||||||
Offset = SectionRva - SectionVa + Data - Section->VirtualAddress;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Resource)
|
|
||||||
{
|
|
||||||
*Resource = (PVOID)(ResourceDataEntry->OffsetToData - Offset + (ULONG)BaseAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Size)
|
|
||||||
{
|
|
||||||
*Size = ResourceDataEntry->Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /*MOVED_TO_FILE_RES_C*/
|
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
LdrDisableThreadCalloutsForDll(IN PVOID BaseAddress)
|
LdrDisableThreadCalloutsForDll(IN PVOID BaseAddress)
|
||||||
|
@ -1554,106 +1584,8 @@ LdrDisableThreadCalloutsForDll(IN PVOID BaseAddress)
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /*MOVED_TO_FILE_RES_C*/
|
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
LdrFindResourceDirectory_U (IN PVOID BaseAddress,
|
|
||||||
WCHAR **name,
|
|
||||||
DWORD level,
|
|
||||||
OUT PVOID *addr)
|
|
||||||
{
|
|
||||||
PIMAGE_RESOURCE_DIRECTORY ResDir;
|
|
||||||
PIMAGE_RESOURCE_DIRECTORY_ENTRY ResEntry;
|
|
||||||
ULONG EntryCount;
|
|
||||||
ULONG i;
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
WCHAR *ws;
|
|
||||||
|
|
||||||
/* Get the pointer to the resource directory */
|
|
||||||
ResDir = (PIMAGE_RESOURCE_DIRECTORY)
|
|
||||||
RtlImageDirectoryEntryToData (BaseAddress,
|
|
||||||
TRUE,
|
|
||||||
IMAGE_DIRECTORY_ENTRY_RESOURCE,
|
|
||||||
&i);
|
|
||||||
if (ResDir == NULL)
|
|
||||||
{
|
|
||||||
return STATUS_RESOURCE_DATA_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Let's go into resource tree */
|
|
||||||
for (i = 0; i < level; i++, name++)
|
|
||||||
{
|
|
||||||
EntryCount = ResDir->NumberOfNamedEntries;
|
|
||||||
ResEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(ResDir + 1);
|
|
||||||
if ((ULONG)(*name) & 0xFFFF0000)
|
|
||||||
{
|
|
||||||
/* Resource name is a unicode string */
|
|
||||||
for (; EntryCount--; ResEntry++)
|
|
||||||
{
|
|
||||||
/* Scan entries for equal name */
|
|
||||||
if (ResEntry->Name & 0x80000000)
|
|
||||||
{
|
|
||||||
ws = (WCHAR*)((ULONG)ResDir + (ResEntry->Name & 0x7FFFFFFF));
|
|
||||||
if (!wcsncmp( *name, ws + 1, *ws ) && wcslen( *name ) == (int)*ws )
|
|
||||||
{
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* We use ID number instead of string */
|
|
||||||
ResEntry += EntryCount;
|
|
||||||
EntryCount = ResDir->NumberOfIdEntries;
|
|
||||||
for (; EntryCount--; ResEntry++)
|
|
||||||
{
|
|
||||||
/* Scan entries for equal name */
|
|
||||||
if (ResEntry->Name == (ULONG)(*name))
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (i)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
return STATUS_RESOURCE_TYPE_NOT_FOUND;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
return STATUS_RESOURCE_NAME_NOT_FOUND;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
Status = STATUS_RESOURCE_LANG_NOT_FOUND;
|
|
||||||
/* Just use first language entry */
|
|
||||||
if (ResDir->NumberOfNamedEntries || ResDir->NumberOfIdEntries)
|
|
||||||
{
|
|
||||||
ResEntry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)(ResDir + 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return Status;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
return STATUS_RESOURCE_DATA_NOT_FOUND;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return STATUS_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
found:;
|
|
||||||
ResDir = (PIMAGE_RESOURCE_DIRECTORY)((ULONG)ResDir + ResEntry->OffsetToData);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addr)
|
|
||||||
{
|
|
||||||
*addr = (PVOID)ResDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /*MOVED_TO_FILE_RES_C*/
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
STDCALL
|
|
||||||
LdrGetDllHandle(IN ULONG Unknown1,
|
LdrGetDllHandle(IN ULONG Unknown1,
|
||||||
IN ULONG Unknown2,
|
IN ULONG Unknown2,
|
||||||
IN PUNICODE_STRING DllName,
|
IN PUNICODE_STRING DllName,
|
||||||
|
@ -1867,7 +1799,6 @@ NTSTATUS STDCALL
|
||||||
LdrQueryProcessModuleInformation(IN PMODULE_INFORMATION ModuleInformation OPTIONAL,
|
LdrQueryProcessModuleInformation(IN PMODULE_INFORMATION ModuleInformation OPTIONAL,
|
||||||
IN ULONG Size OPTIONAL,
|
IN ULONG Size OPTIONAL,
|
||||||
OUT PULONG ReturnedSize)
|
OUT PULONG ReturnedSize)
|
||||||
|
|
||||||
{
|
{
|
||||||
PLIST_ENTRY ModuleListHead;
|
PLIST_ENTRY ModuleListHead;
|
||||||
PLIST_ENTRY Entry;
|
PLIST_ENTRY Entry;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: init.c,v 1.45 2003/02/25 23:08:52 gvg Exp $
|
/* $Id: init.c,v 1.46 2003/05/12 19:46:17 ekohl Exp $
|
||||||
*
|
*
|
||||||
* init.c - Session Manager initialization
|
* init.c - Session Manager initialization
|
||||||
*
|
*
|
||||||
|
@ -357,20 +357,227 @@ SmProcessFileRenameList(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS STDCALL
|
||||||
SmPreloadDlls(VOID)
|
SmKnownDllsQueryRoutine(PWSTR ValueName,
|
||||||
|
ULONG ValueType,
|
||||||
|
PVOID ValueData,
|
||||||
|
ULONG ValueLength,
|
||||||
|
PVOID Context,
|
||||||
|
PVOID EntryContext)
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
PrintString("SmPreloadDlls() called\n");
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
#endif
|
UNICODE_STRING ImageName;
|
||||||
|
HANDLE FileHandle;
|
||||||
/* FIXME: implement it! */
|
HANDLE SectionHandle;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
PrintString("SmPreloadDlls() done\n");
|
PrintString("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
|
||||||
|
PrintString("ValueData '%S' Context %p EntryContext %p\n", (PWSTR)ValueData, Context, EntryContext);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
/* 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,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&IoStatusBlock,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
PrintString("NtOpenFile() failed (Status %lx)\n", Status);
|
||||||
|
#endif
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
PrintString("Opened file %wZ successfully\n", &ImageName);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* FIXME: Check dll image file */
|
||||||
|
|
||||||
|
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
PrintString("Created section successfully\n");
|
||||||
|
#endif
|
||||||
|
NtClose(SectionHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
NtClose(FileHandle);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static 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;
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
PrintString("SmLoadKnownDlls() called\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 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))
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
PrintString("NtCreateDirectoryObject() failed (Status %lx)\n", Status);
|
||||||
|
#endif
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
PrintString("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
|
||||||
|
#endif
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
PrintString("DllDosPath: '%wZ'\n", &DllDosPath);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!RtlDosPathNameToNtPathName_U(DllDosPath.Buffer,
|
||||||
|
&DllNtPath,
|
||||||
|
NULL,
|
||||||
|
NULL))
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
PrintString("RtlDosPathNameToNtPathName_U() failed\n");
|
||||||
|
#endif
|
||||||
|
return STATUS_OBJECT_NAME_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintString("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);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
PrintString("NtOpenFile() failed (Status %lx)\n", Status);
|
||||||
|
#endif
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
PrintString("NtCreateSymbolicLink() failed (Status %lx)\n", Status);
|
||||||
|
#endif
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtClose(SymlinkHandle);
|
||||||
|
|
||||||
|
RtlZeroMemory(&QueryTable,
|
||||||
|
sizeof(QueryTable));
|
||||||
|
|
||||||
|
QueryTable[0].QueryRoutine = SmKnownDllsQueryRoutine;
|
||||||
|
QueryTable[0].EntryContext = ObjectDirHandle;
|
||||||
|
|
||||||
|
Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
|
||||||
|
L"\\Session Manager\\KnownDlls",
|
||||||
|
QueryTable,
|
||||||
|
(PVOID)FileDirHandle,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
PrintString("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
PrintString("SmLoadKnownDlls() done\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -418,15 +625,15 @@ SmPagingFilesQueryRoutine(PWSTR ValueName,
|
||||||
MaximumSize.QuadPart = 80 * 4096;
|
MaximumSize.QuadPart = 80 * 4096;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!RtlDosPathNameToNtPathName_U ((LPWSTR)ValueData,
|
if (!RtlDosPathNameToNtPathName_U ((LPWSTR)ValueData,
|
||||||
&FileName,
|
&FileName,
|
||||||
NULL,
|
NULL,
|
||||||
NULL))
|
NULL))
|
||||||
{
|
{
|
||||||
return (STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgPrint("SMSS: Created paging file %wZ with size %dKB\n",
|
DbgPrint("SMSS: Created paging file %wZ with size %dKB\n",
|
||||||
&FileName, InitialSize.QuadPart / 1024);
|
&FileName, InitialSize.QuadPart / 1024);
|
||||||
Status = NtCreatePagingFile(&FileName,
|
Status = NtCreatePagingFile(&FileName,
|
||||||
&InitialSize,
|
&InitialSize,
|
||||||
|
@ -516,7 +723,7 @@ SmSetEnvironmentVariables(VOID)
|
||||||
wcscpy(ValueBuffer,
|
wcscpy(ValueBuffer,
|
||||||
SharedUserData->NtSystemRoot);
|
SharedUserData->NtSystemRoot);
|
||||||
|
|
||||||
/* Cet SystemRoot = "C:\reactos" */
|
/* Set SystemRoot = "C:\reactos" */
|
||||||
RtlInitUnicodeStringFromLiteral(&EnvVariable,
|
RtlInitUnicodeStringFromLiteral(&EnvVariable,
|
||||||
L"SystemRoot");
|
L"SystemRoot");
|
||||||
RtlInitUnicodeString(&EnvValue,
|
RtlInitUnicodeString(&EnvValue,
|
||||||
|
@ -618,6 +825,14 @@ InitSessionManager(HANDLE Children[])
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set environment variables */
|
||||||
|
Status = SmSetEnvironmentVariables();
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
PrintString("SM: Failed to set system environment variables (Status %lx)\n", Status);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
/* Define symbolic links to kernel devices (MS-DOS names) */
|
/* Define symbolic links to kernel devices (MS-DOS names) */
|
||||||
Status = SmInitDosDevices();
|
Status = SmInitDosDevices();
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -643,7 +858,7 @@ InitSessionManager(HANDLE Children[])
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the well known DLLs */
|
/* Load the well known DLLs */
|
||||||
Status = SmPreloadDlls();
|
Status = SmLoadKnownDlls();
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
PrintString("SM: Failed to preload system DLLs (Status %lx)\n", Status);
|
PrintString("SM: Failed to preload system DLLs (Status %lx)\n", Status);
|
||||||
|
@ -662,12 +877,14 @@ InitSessionManager(HANDLE Children[])
|
||||||
NtInitializeRegistry(FALSE);
|
NtInitializeRegistry(FALSE);
|
||||||
|
|
||||||
/* Set environment variables from registry */
|
/* Set environment variables from registry */
|
||||||
Status = SmSetEnvironmentVariables();
|
#if 0
|
||||||
|
Status = SmUpdateEnvironment();
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
PrintString("SM: Failed to set system environment variables (Status %lx)\n", Status);
|
PrintString("SM: Failed to update environment variables (Status %lx)\n", Status);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Load the subsystems */
|
/* Load the subsystems */
|
||||||
Status = SmLoadSubsystems();
|
Status = SmLoadSubsystems();
|
||||||
|
@ -679,7 +896,7 @@ InitSessionManager(HANDLE Children[])
|
||||||
|
|
||||||
/* Run csrss.exe */
|
/* Run csrss.exe */
|
||||||
RtlInitUnicodeStringFromLiteral(&UnicodeString,
|
RtlInitUnicodeStringFromLiteral(&UnicodeString,
|
||||||
L"\\CsrssInitDone");
|
L"\\CsrssInitDone");
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
&UnicodeString,
|
&UnicodeString,
|
||||||
EVENT_ALL_ACCESS,
|
EVENT_ALL_ACCESS,
|
||||||
|
|
Loading…
Reference in a new issue