-/* $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
* PROJECT: ReactOS kernel
#endif
#include <ntdll/ntdll.h>
+/* GLOBALS *******************************************************************/
+
+static HANDLE LdrpKnownDllsDirHandle = NULL;
+static UNICODE_STRING LdrpKnownDllPath = {0, 0, NULL};
+
+
/* PROTOTYPES ****************************************************************/
static NTSTATUS LdrFindEntryForName(PUNICODE_STRING Name, PLDR_MODULE *Module);
#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
* LdrAdjustDllName
}
PLDR_MODULE
-LdrAddModuleEntry(PVOID ImageBase, PIMAGE_NT_HEADERS NTHeaders,
- PWSTR FullDosName)
+LdrAddModuleEntry(PVOID ImageBase,
+ PIMAGE_NT_HEADERS NTHeaders,
+ PWSTR FullDosName)
{
PLDR_MODULE Module;
Module = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof (LDR_MODULE));
return(Module);
}
-/***************************************************************************
- * 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)
+static NTSTATUS
+LdrpMapKnownDll(IN PUNICODE_STRING DllName,
+ OUT PUNICODE_STRING FullDosName,
+ OUT PHANDLE SectionHandle)
+{
+ 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 FullDosName[MAX_PATH];
- UNICODE_STRING AdjustedName;
+ WCHAR DosName[MAX_PATH];
UNICODE_STRING FullNtFileName;
OBJECT_ATTRIBUTES FileObjectAttributes;
+ HANDLE FileHandle;
char BlockBuffer [1024];
PIMAGE_DOS_HEADER DosHeader;
- NTSTATUS Status;
PIMAGE_NT_HEADERS NTHeaders;
- ULONG ImageSize;
- ULONG InitialViewSize;
PVOID ImageBase;
- HANDLE FileHandle;
- HANDLE SectionHandle;
- PDLLMAIN_FUNC Entrypoint = NULL;
- PLDR_MODULE Module;
-
- if (Name == NULL)
- {
- *BaseAddress = NtCurrentPeb()->ImageBaseAddress;
- return STATUS_SUCCESS;
- }
+ ULONG ImageSize;
+ NTSTATUS Status;
-
- *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);
+ DPRINT("LdrpMapDllImageFile() called\n");
if (SearchPath == NULL)
{
}
DPRINT("SearchPath %S\n", SearchPath);
-
+
if (RtlDosSearchPath_U (SearchPath,
- AdjustedName.Buffer,
+ DllName->Buffer,
NULL,
MAX_PATH,
- FullDosName,
+ DosName,
NULL) == 0)
return STATUS_DLL_NOT_FOUND;
-
- DPRINT("FullDosName %S\n", FullDosName);
-
- RtlFreeUnicodeString (&AdjustedName);
-
- if (!RtlDosPathNameToNtPathName_U (FullDosName,
+
+ DPRINT("DosName %S\n", DosName);
+
+ if (!RtlDosPathNameToNtPathName_U (DosName,
&FullNtFileName,
NULL,
NULL))
return STATUS_DLL_NOT_FOUND;
-
+
DPRINT("FullNtFileName %wZ\n", &FullNtFileName);
-
+
InitializeObjectAttributes(&FileObjectAttributes,
&FullNtFileName,
0,
NULL,
NULL);
-
+
DPRINT("Opening dll \"%wZ\"\n", &FullNtFileName);
-
+
Status = ZwOpenFile(&FileHandle,
FILE_ALL_ACCESS,
- &FileObjectAttributes,
+ &FileObjectAttributes,
NULL,
0,
0);
return Status;
}
RtlFreeUnicodeString (&FullNtFileName);
-
+
Status = ZwReadFile(FileHandle,
0,
0,
ImageSize = NTHeaders->OptionalHeader.SizeOfImage;
DPRINT("ImageBase 0x%08x\n", ImageBase);
-
+
/*
* Create a section for dll.
*/
- Status = ZwCreateSection(&SectionHandle,
+ Status = ZwCreateSection(SectionHandle,
SECTION_ALL_ACCESS,
NULL,
NULL,
PAGE_READWRITE,
SEC_COMMIT | SEC_IMAGE,
FileHandle);
+ ZwClose(FileHandle);
+
if (!NT_SUCCESS(Status))
{
DPRINT("NTDLL create section failed: Status = 0x%08x\n", Status);
- ZwClose(FileHandle);
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.
*/
- InitialViewSize = 0;
+ ViewSize = 0;
ImageBase = 0;
- Status = ZwMapViewOfSection(SectionHandle,
+ Status = NtMapViewOfSection(SectionHandle,
NtCurrentProcess(),
&ImageBase,
0,
- InitialViewSize,
+ 0,
NULL,
- &InitialViewSize,
+ &ViewSize,
0,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
DbgPrint("NTDLL.LDR: map view of section failed (Status %x)\n", Status);
- ZwClose(FileHandle);
+ RtlFreeUnicodeString(&FullDosName);
+ NtClose(SectionHandle);
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 */
if ((NTHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) ==
{
Entrypoint =
(PDLLMAIN_FUNC) LdrPEStartup(ImageBase, SectionHandle, &Module,
- FullDosName);
+ FullDosName.Buffer);
if (Entrypoint == NULL)
{
+ RtlFreeUnicodeString(&FullDosName);
return(STATUS_UNSUCCESSFUL);
}
}
-
+
+ RtlFreeUnicodeString(&FullDosName);
+
#ifdef DBG
LdrpLoadUserModuleSymbols(Module);
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
LdrDisableThreadCalloutsForDll(IN PVOID BaseAddress)
return Status;
}
-#if 0 /*MOVED_TO_FILE_RES_C*/
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,
IN ULONG Unknown2,
IN PUNICODE_STRING DllName,
LdrQueryProcessModuleInformation(IN PMODULE_INFORMATION ModuleInformation OPTIONAL,
IN ULONG Size OPTIONAL,
OUT PULONG ReturnedSize)
-
{
PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry;
-/* $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
*
}
+static NTSTATUS STDCALL
+SmKnownDllsQueryRoutine(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;
+
+#ifndef NDEBUG
+ PrintString("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
+ PrintString("ValueData '%S' Context %p EntryContext %p\n", (PWSTR)ValueData, Context, EntryContext);
+#endif
+
+ /* 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
-SmPreloadDlls(VOID)
+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("SmPreloadDlls() called\n");
+ PrintString("SmLoadKnownDlls() called\n");
#endif
- /* FIXME: implement it! */
+ /* 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("SmPreloadDlls() done\n");
+ PrintString("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
#endif
+ return Status;
+ }
- return(STATUS_SUCCESS);
+#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;
}
MaximumSize.QuadPart = 80 * 4096;
}
- if (!RtlDosPathNameToNtPathName_U ((LPWSTR)ValueData,
+ if (!RtlDosPathNameToNtPathName_U ((LPWSTR)ValueData,
&FileName,
NULL,
NULL))
{
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);
Status = NtCreatePagingFile(&FileName,
&InitialSize,
wcscpy(ValueBuffer,
SharedUserData->NtSystemRoot);
- /* Cet SystemRoot = "C:\reactos" */
+ /* Set SystemRoot = "C:\reactos" */
RtlInitUnicodeStringFromLiteral(&EnvVariable,
L"SystemRoot");
RtlInitUnicodeString(&EnvValue,
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) */
Status = SmInitDosDevices();
if (!NT_SUCCESS(Status))
}
/* Load the well known DLLs */
- Status = SmPreloadDlls();
+ Status = SmLoadKnownDlls();
if (!NT_SUCCESS(Status))
{
PrintString("SM: Failed to preload system DLLs (Status %lx)\n", Status);
NtInitializeRegistry(FALSE);
/* Set environment variables from registry */
- Status = SmSetEnvironmentVariables();
+#if 0
+ Status = SmUpdateEnvironment();
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);
}
+#endif
/* Load the subsystems */
Status = SmLoadSubsystems();
/* Run csrss.exe */
RtlInitUnicodeStringFromLiteral(&UnicodeString,
- L"\\CsrssInitDone");
+ L"\\CsrssInitDone");
InitializeObjectAttributes(&ObjectAttributes,
&UnicodeString,
EVENT_ALL_ACCESS,