Author: ion Date: Sun Oct 1 09:05:57 2006 New Revision: 24331
URL: http://svn.reactos.org/svn/reactos?rev=24331&view=rev Log: - Fully use KeLoaderBlock->InLoadOrderListHead for driver loading and symbol lookups, instead of KeLoaderModules/KeLoaderModuleCount. Still not 100% compatible with NTLDR (since it uses BootDriverListHead with a special structure), but much closer to a portable design that doesn't rely on static kernel data. - Change some internal functions to use UNICODE_STRING instead of PCHAR since this is how LdrEntry->BaseDllName is, and also it's closer to NT Design.
Modified: trunk/reactos/include/reactos/rosldr.h trunk/reactos/ntoskrnl/ex/init.c trunk/reactos/ntoskrnl/include/internal/kd.h trunk/reactos/ntoskrnl/io/iomgr/driver.c trunk/reactos/ntoskrnl/kdbg/kdb_symbols.c trunk/reactos/ntoskrnl/ke/i386/kiinit.c
Modified: trunk/reactos/include/reactos/rosldr.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/rosldr.h?re... ============================================================================== --- trunk/reactos/include/reactos/rosldr.h (original) +++ trunk/reactos/include/reactos/rosldr.h Sun Oct 1 09:05:57 2006 @@ -44,8 +44,6 @@ ULONG KernelBase; } ROS_LOADER_PARAMETER_BLOCK, *PROS_LOADER_PARAMETER_BLOCK;
-extern LOADER_MODULE KeLoaderModules[64]; -extern ULONG KeLoaderModuleCount; extern ULONG MmFreeLdrMemHigher, MmFreeLdrMemLower; extern BOOLEAN AcpiTableDetected; extern ULONG MmFreeLdrPageDirectoryStart, MmFreeLdrPageDirectoryEnd;
Modified: trunk/reactos/ntoskrnl/ex/init.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/init.c?rev=2433... ============================================================================== --- trunk/reactos/ntoskrnl/ex/init.c (original) +++ trunk/reactos/ntoskrnl/ex/init.c Sun Oct 1 09:05:57 2006 @@ -35,6 +35,7 @@ extern ULONG_PTR LastKrnlPhysAddr; extern ULONG_PTR LastKernelAddress; extern LOADER_MODULE KeLoaderModules[64]; +extern ULONG KeLoaderModuleCount; extern PRTL_MESSAGE_RESOURCE_DATA KiBugCodeMessages;
BOOLEAN NoGuiBoot = FALSE;
Modified: trunk/reactos/ntoskrnl/include/internal/kd.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/k... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/kd.h (original) +++ trunk/reactos/ntoskrnl/include/internal/kd.h Sun Oct 1 09:05:57 2006 @@ -77,7 +77,7 @@ KdbSymUnloadDriverSymbols(IN PLDR_DATA_TABLE_ENTRY ModuleObject);
VOID -KdbSymProcessBootSymbols(IN PCHAR FileName); +KdbSymProcessBootSymbols(IN PUNICODE_STRING FileName);
VOID KdbSymInit(
Modified: trunk/reactos/ntoskrnl/io/iomgr/driver.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/driver.c?... ============================================================================== --- trunk/reactos/ntoskrnl/io/iomgr/driver.c (original) +++ trunk/reactos/ntoskrnl/io/iomgr/driver.c Sun Oct 1 09:05:57 2006 @@ -462,9 +462,10 @@
if (ServiceStart == 0) { - ULONG i; - CHAR SearchName[256]; - PCHAR ModuleName; + WCHAR SearchNameBuffer[256]; + UNICODE_STRING SearchName; + PLIST_ENTRY ListHead, NextEntry; + PLDR_DATA_TABLE_ENTRY LdrEntry;
/* * FIXME: @@ -472,28 +473,37 @@ * stored in registry entry ImageName and use the whole path * (requires change in FreeLoader). */ - - _snprintf(SearchName, sizeof(SearchName), "%wZ.sys", ServiceName); - for (i = 1; i < KeLoaderModuleCount; i++) + swprintf(SearchNameBuffer, L"%wZ.sys", ServiceName); + RtlInitUnicodeString(&SearchName, SearchNameBuffer); + + /* Loop the boot modules */ + ListHead = &KeLoaderBlock->LoadOrderListHead; + NextEntry = ListHead->Flink->Flink; + while (ListHead != NextEntry) { - ModuleName = (PCHAR)KeLoaderModules[i].String; - if (!_stricmp(ModuleName, SearchName)) + /* Get the entry */ + LdrEntry = CONTAINING_RECORD(NextEntry, + LDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + + /* Compare names */ + if (RtlEqualUnicodeString(&LdrEntry->BaseDllName, &SearchName, TRUE)) { - DPRINT("Initializing boot module\n"); - - /* Tell, that the module is already loaded */ - KeLoaderModules[i].Reserved = 1; - - Status = LdrProcessModule( - (PVOID)KeLoaderModules[i].ModStart, - &ServiceImagePath, - ModuleObject); - - KDB_SYMBOLFILE_HOOK(SearchName); - - break; + /* Tell, that the module is already loaded */ + LdrEntry->Flags |= LDRP_ENTRY_INSERTED; + + Status = LdrProcessModule(LdrEntry->DllBase, + &ServiceImagePath, + ModuleObject); + + KDB_SYMBOLFILE_HOOK(&SearchName); + break; } + + /* Go to the next driver */ + NextEntry = NextEntry->Flink; } + if (!NT_SUCCESS(Status)) /* Try to load it. It may just have been installed by PnP manager */ Status = LdrLoadModule(&ServiceImagePath, ModuleObject); @@ -817,23 +827,23 @@ IopInitializeBuiltinDriver( PDEVICE_NODE ModuleDeviceNode, PVOID ModuleLoadBase, - PCHAR FileName, + PUNICODE_STRING ModuleName, ULONG ModuleLength) { PLDR_DATA_TABLE_ENTRY ModuleObject; PDEVICE_NODE DeviceNode; PDRIVER_OBJECT DriverObject; NTSTATUS Status; - PCHAR FileNameWithoutPath; + PWCHAR FileNameWithoutPath; LPWSTR FileExtension;
- DPRINT("Initializing driver '%s' at %08lx, length 0x%08lx\n", - FileName, ModuleLoadBase, ModuleLength); + DPRINT("Initializing driver '%wZ' at %08lx, length 0x%08lx\n", + ModuleName, ModuleLoadBase, ModuleLength);
/* * Display 'Loading XXX...' message */ - IopDisplayLoadingMessage(FileName, FALSE); + IopDisplayLoadingMessage(ModuleName->Buffer, TRUE);
/* * Determine the right device object @@ -845,7 +855,7 @@ Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &DeviceNode); if (!NT_SUCCESS(Status)) { - CPRINT("Driver '%s' load failed, status (%x)\n", FileName, Status); + CPRINT("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status); return(Status); } } else @@ -857,30 +867,28 @@ * Generate filename without path (not needed by freeldr) */
- FileNameWithoutPath = strrchr(FileName, '\'); + FileNameWithoutPath = wcsrchr(ModuleName->Buffer, L'\'); if (FileNameWithoutPath == NULL) { - FileNameWithoutPath = FileName; + FileNameWithoutPath = ModuleName->Buffer; }
/* * Load the module */ - - RtlCreateUnicodeStringFromAsciiz(&DeviceNode->ServiceName, - FileNameWithoutPath); + RtlCreateUnicodeString(&DeviceNode->ServiceName, FileNameWithoutPath); Status = LdrProcessModule(ModuleLoadBase, &DeviceNode->ServiceName, &ModuleObject); if (!NT_SUCCESS(Status)) { if (ModuleDeviceNode == NULL) IopFreeDeviceNode(DeviceNode); - CPRINT("Driver '%s' load failed, status (%x)\n", FileName, Status); + CPRINT("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status); return Status; }
/* Load symbols */ - KDB_SYMBOLFILE_HOOK(FileName); + KDB_SYMBOLFILE_HOOK(ModuleName);
/* * Strip the file extension from ServiceName @@ -904,7 +912,7 @@ { if (ModuleDeviceNode == NULL) IopFreeDeviceNode(DeviceNode); - CPRINT("Driver '%s' load failed, status (%x)\n", FileName, Status); + CPRINT("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status); return Status; }
@@ -929,75 +937,66 @@ * None */
-VOID FASTCALL +VOID +FASTCALL IopInitializeBootDrivers(VOID) { - ULONG BootDriverCount; - ULONG ModuleStart; - ULONG ModuleSize; - ULONG ModuleLoaded; - PCHAR ModuleName; - PCHAR Extension; - ULONG i; - UNICODE_STRING DriverName; - NTSTATUS Status; - - DPRINT("IopInitializeBootDrivers()\n"); - - BootDriverCount = 0; - for (i = 0; i < KeLoaderModuleCount; i++) - { - ModuleStart = KeLoaderModules[i].ModStart; - ModuleSize = KeLoaderModules[i].ModEnd - ModuleStart; - ModuleName = (PCHAR)KeLoaderModules[i].String; - ModuleLoaded = KeLoaderModules[i].Reserved; - Extension = strrchr(ModuleName, '.'); - if (Extension == NULL) - Extension = ""; - - if (!_stricmp(Extension, ".sym") || !_stricmp(Extension, ".dll")) - { - /* Process symbols for *.exe and *.dll */ - KDB_SYMBOLFILE_HOOK(ModuleName); - - /* Log *.exe and *.dll files */ - RtlCreateUnicodeStringFromAsciiz(&DriverName, ModuleName); - IopBootLog(&DriverName, TRUE); - RtlFreeUnicodeString(&DriverName); - } - else if (!_stricmp(Extension, ".sys")) - { - /* Initialize and log boot start driver */ - if (!ModuleLoaded) - { - Status = IopInitializeBuiltinDriver(NULL, - (PVOID)ModuleStart, - ModuleName, - ModuleSize); - RtlCreateUnicodeStringFromAsciiz(&DriverName, ModuleName); - IopBootLog(&DriverName, NT_SUCCESS(Status) ? TRUE : FALSE); - RtlFreeUnicodeString(&DriverName); - } - BootDriverCount++; - } - } - - /* - * Free memory for all boot files, except ntoskrnl.exe. - */ - for (i = 1; i < KeLoaderModuleCount; i++) - { - MiFreeBootDriverMemory((PVOID)KeLoaderModules[i].ModStart, - KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart); - } - - KeLoaderModuleCount = 0; - - if (BootDriverCount == 0) - { - DbgPrint("No boot drivers available.\n"); - KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE); - } + PLIST_ENTRY ListHead, NextEntry; + PLDR_DATA_TABLE_ENTRY LdrEntry; + UNICODE_STRING NtosSymName = RTL_CONSTANT_STRING(L"ntoskrnl.sym"); + + /* Hack for NTOSKRNL.SYM */ + KDB_SYMBOLFILE_HOOK(&NtosSymName); + + /* Loop the boot modules */ + ListHead = &KeLoaderBlock->LoadOrderListHead; + NextEntry = ListHead->Flink; + while (ListHead != NextEntry) + { + /* Get the entry */ + LdrEntry = CONTAINING_RECORD(NextEntry, + LDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + + /* + * HACK: Make sure we're loading a driver + * (we should be using BootDriverListHead!) + */ + if (wcsstr(LdrEntry->BaseDllName.Buffer, L".sys")) + { + /* Make sure we didn't load this driver already */ + if (!(LdrEntry->Flags & LDRP_ENTRY_INSERTED)) + { + /* Initialize it */ + IopInitializeBuiltinDriver(NULL, + LdrEntry->DllBase, + &LdrEntry->BaseDllName, + LdrEntry->SizeOfImage); + } + } + + /* Go to the next driver */ + NextEntry = NextEntry->Flink; + } + + /* Loop modules again */ + NextEntry = ListHead->Flink->Flink; + while (ListHead != NextEntry) + { + /* Get the entry */ + LdrEntry = CONTAINING_RECORD(NextEntry, + LDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + + /* Free memory */ + MiFreeBootDriverMemory(LdrEntry->DllBase, LdrEntry->SizeOfImage); + + /* Go to the next driver */ + NextEntry = NextEntry->Flink; + } + + /* In old ROS, the loader list became empty after this point. Simulate. */ + InitializeListHead(&KeLoaderBlock->LoadOrderListHead); }
/*
Modified: trunk/reactos/ntoskrnl/kdbg/kdb_symbols.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/kdbg/kdb_symbols.c... ============================================================================== --- trunk/reactos/ntoskrnl/kdbg/kdb_symbols.c (original) +++ trunk/reactos/ntoskrnl/kdbg/kdb_symbols.c Sun Oct 1 09:05:57 2006 @@ -588,29 +588,28 @@ * \param FileName Filename for which the symbols are loaded. */ VOID -KdbSymProcessBootSymbols(IN PCHAR FileName) +KdbSymProcessBootSymbols(IN PUNICODE_STRING FileName) { PLDR_DATA_TABLE_ENTRY ModuleObject; - UNICODE_STRING UnicodeString; - ANSI_STRING AnsiString; - ULONG i; + BOOLEAN Found = FALSE; BOOLEAN IsRaw; - - DPRINT("KdbSymProcessBootSymbols(%s)\n", FileName); - - if (0 == _stricmp(FileName, "ntoskrnl.sym")) - { - RtlInitAnsiString(&AnsiString, "ntoskrnl.exe"); + PLIST_ENTRY ListHead, NextEntry; + PLDR_DATA_TABLE_ENTRY LdrEntry; + UNICODE_STRING NtosSymName = RTL_CONSTANT_STRING(L"ntoskrnl.sym"); + UNICODE_STRING NtosName = RTL_CONSTANT_STRING(L"ntoskrnl.exe"); + DPRINT("KdbSymProcessBootSymbols(%wZ)\n", FileName); + + if (RtlEqualUnicodeString(FileName, &NtosSymName, TRUE)) + { + FileName = &NtosName; IsRaw = TRUE; } else { - RtlInitAnsiString(&AnsiString, FileName); IsRaw = FALSE; } - RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE); - ModuleObject = LdrGetModuleObject(&UnicodeString); - RtlFreeUnicodeString(&UnicodeString); + + ModuleObject = LdrGetModuleObject(FileName);
if (ModuleObject != NULL) { @@ -620,16 +619,27 @@ return; }
- for (i = 0; i < KeLoaderModuleCount; i++) + ListHead = &KeLoaderBlock->LoadOrderListHead; + NextEntry = ListHead->Flink; + while (ListHead != NextEntry) { - if (0 == _stricmp(FileName, (PCHAR)KeLoaderModules[i].String)) - { - break; - } - } - if (i < KeLoaderModuleCount) + /* Get the entry */ + LdrEntry = CONTAINING_RECORD(NextEntry, + LDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); + + if (RtlEqualUnicodeString(FileName, &LdrEntry->BaseDllName, TRUE)) + { + Found = TRUE; + break; + } + + /* Go to the next one */ + NextEntry = NextEntry->Flink; + } + + if (Found) { - KeLoaderModules[i].Reserved = 1; if (ModuleObject->PatchInformation != NULL) { KdbpSymRemoveCachedFile(ModuleObject->PatchInformation); @@ -637,8 +647,8 @@
if (IsRaw) { - if (! RosSymCreateFromRaw((PVOID) KeLoaderModules[i].ModStart, - KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart, + if (! RosSymCreateFromRaw(LdrEntry->DllBase, + LdrEntry->SizeOfImage, (PROSSYM_INFO*)&ModuleObject->PatchInformation)) { return; @@ -646,8 +656,8 @@ } else { - if (! RosSymCreateFromMem((PVOID) KeLoaderModules[i].ModStart, - KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart, + if (! RosSymCreateFromMem(LdrEntry->DllBase, + LdrEntry->SizeOfImage, (PROSSYM_INFO*)&ModuleObject->PatchInformation)) { return; @@ -655,12 +665,9 @@ }
/* add file to cache */ - RtlInitAnsiString(&AnsiString, FileName); - RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE); - KdbpSymAddCachedFile(&UnicodeString, ModuleObject->PatchInformation); - RtlFreeUnicodeString(&UnicodeString); - - DPRINT("Installed symbols: %s@%08x-%08x %p\n", + KdbpSymAddCachedFile(FileName, ModuleObject->PatchInformation); + + DPRINT("Installed symbols: %wZ@%08x-%08x %p\n", FileName, ModuleObject->DllBase, ModuleObject->SizeOfImage + (ULONG)ModuleObject->DllBase,
Modified: trunk/reactos/ntoskrnl/ke/i386/kiinit.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/kiinit.c?r... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/kiinit.c (original) +++ trunk/reactos/ntoskrnl/ke/i386/kiinit.c Sun Oct 1 09:05:57 2006 @@ -379,7 +379,7 @@ KiInitializeKernel(&KiInitialProcess.Pcb, InitialThread, InitialStack, - &Pcr->PrcbData, //(PKPRCB)__readfsdword(KPCR_PRCB), + (PKPRCB)__readfsdword(KPCR_PRCB), Cpu, LoaderBlock);