mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 09:11:42 +00:00
- 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. svn path=/trunk/; revision=24331
This commit is contained in:
parent
fbe45c7180
commit
380f89c205
6 changed files with 130 additions and 125 deletions
|
@ -44,8 +44,6 @@ typedef struct _ROS_LOADER_PARAMETER_BLOCK
|
|||
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;
|
||||
|
|
|
@ -35,6 +35,7 @@ extern ULONG_PTR FirstKrnlPhysAddr;
|
|||
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;
|
||||
|
|
|
@ -77,7 +77,7 @@ VOID
|
|||
KdbSymUnloadDriverSymbols(IN PLDR_DATA_TABLE_ENTRY ModuleObject);
|
||||
|
||||
VOID
|
||||
KdbSymProcessBootSymbols(IN PCHAR FileName);
|
||||
KdbSymProcessBootSymbols(IN PUNICODE_STRING FileName);
|
||||
|
||||
VOID
|
||||
KdbSymInit(
|
||||
|
|
|
@ -462,9 +462,10 @@ IopLoadServiceModule(
|
|||
|
||||
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 @@ IopLoadServiceModule(
|
|||
* stored in registry entry ImageName and use the whole path
|
||||
* (requires change in FreeLoader).
|
||||
*/
|
||||
swprintf(SearchNameBuffer, L"%wZ.sys", ServiceName);
|
||||
RtlInitUnicodeString(&SearchName, SearchNameBuffer);
|
||||
|
||||
_snprintf(SearchName, sizeof(SearchName), "%wZ.sys", ServiceName);
|
||||
for (i = 1; i < KeLoaderModuleCount; i++)
|
||||
/* 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 */
|
||||
LdrEntry->Flags |= LDRP_ENTRY_INSERTED;
|
||||
|
||||
/* Tell, that the module is already loaded */
|
||||
KeLoaderModules[i].Reserved = 1;
|
||||
Status = LdrProcessModule(LdrEntry->DllBase,
|
||||
&ServiceImagePath,
|
||||
ModuleObject);
|
||||
|
||||
Status = LdrProcessModule(
|
||||
(PVOID)KeLoaderModules[i].ModStart,
|
||||
&ServiceImagePath,
|
||||
ModuleObject);
|
||||
|
||||
KDB_SYMBOLFILE_HOOK(SearchName);
|
||||
|
||||
break;
|
||||
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 @@ NTSTATUS FASTCALL INIT_FUNCTION
|
|||
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 @@ IopInitializeBuiltinDriver(
|
|||
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 @@ IopInitializeBuiltinDriver(
|
|||
* 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 @@ IopInitializeBuiltinDriver(
|
|||
{
|
||||
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 @@ IopInitializeBuiltinDriver(
|
|||
* 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;
|
||||
PLIST_ENTRY ListHead, NextEntry;
|
||||
PLDR_DATA_TABLE_ENTRY LdrEntry;
|
||||
UNICODE_STRING NtosSymName = RTL_CONSTANT_STRING(L"ntoskrnl.sym");
|
||||
|
||||
DPRINT("IopInitializeBootDrivers()\n");
|
||||
/* Hack for NTOSKRNL.SYM */
|
||||
KDB_SYMBOLFILE_HOOK(&NtosSymName);
|
||||
|
||||
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 = "";
|
||||
/* 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);
|
||||
|
||||
if (!_stricmp(Extension, ".sym") || !_stricmp(Extension, ".dll"))
|
||||
{
|
||||
/* Process symbols for *.exe and *.dll */
|
||||
KDB_SYMBOLFILE_HOOK(ModuleName);
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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++;
|
||||
}
|
||||
}
|
||||
/* Go to the next driver */
|
||||
NextEntry = NextEntry->Flink;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
/* Loop modules again */
|
||||
NextEntry = ListHead->Flink->Flink;
|
||||
while (ListHead != NextEntry)
|
||||
{
|
||||
/* Get the entry */
|
||||
LdrEntry = CONTAINING_RECORD(NextEntry,
|
||||
LDR_DATA_TABLE_ENTRY,
|
||||
InLoadOrderLinks);
|
||||
|
||||
KeLoaderModuleCount = 0;
|
||||
/* Free memory */
|
||||
MiFreeBootDriverMemory(LdrEntry->DllBase, LdrEntry->SizeOfImage);
|
||||
|
||||
if (BootDriverCount == 0)
|
||||
{
|
||||
DbgPrint("No boot drivers available.\n");
|
||||
KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE);
|
||||
}
|
||||
/* Go to the next driver */
|
||||
NextEntry = NextEntry->Flink;
|
||||
}
|
||||
|
||||
/* In old ROS, the loader list became empty after this point. Simulate. */
|
||||
InitializeListHead(&KeLoaderBlock->LoadOrderListHead);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -588,29 +588,28 @@ KdbSymUnloadDriverSymbols(IN PLDR_DATA_TABLE_ENTRY ModuleObject)
|
|||
* \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;
|
||||
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);
|
||||
|
||||
DPRINT("KdbSymProcessBootSymbols(%s)\n", FileName);
|
||||
|
||||
if (0 == _stricmp(FileName, "ntoskrnl.sym"))
|
||||
if (RtlEqualUnicodeString(FileName, &NtosSymName, TRUE))
|
||||
{
|
||||
RtlInitAnsiString(&AnsiString, "ntoskrnl.exe");
|
||||
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 @@ KdbSymProcessBootSymbols(IN PCHAR FileName)
|
|||
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 @@ KdbSymProcessBootSymbols(IN PCHAR FileName)
|
|||
|
||||
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 @@ KdbSymProcessBootSymbols(IN PCHAR FileName)
|
|||
}
|
||||
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 @@ KdbSymProcessBootSymbols(IN PCHAR FileName)
|
|||
}
|
||||
|
||||
/* add file to cache */
|
||||
RtlInitAnsiString(&AnsiString, FileName);
|
||||
RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
|
||||
KdbpSymAddCachedFile(&UnicodeString, ModuleObject->PatchInformation);
|
||||
RtlFreeUnicodeString(&UnicodeString);
|
||||
KdbpSymAddCachedFile(FileName, ModuleObject->PatchInformation);
|
||||
|
||||
DPRINT("Installed symbols: %s@%08x-%08x %p\n",
|
||||
DPRINT("Installed symbols: %wZ@%08x-%08x %p\n",
|
||||
FileName,
|
||||
ModuleObject->DllBase,
|
||||
ModuleObject->SizeOfImage + (ULONG)ModuleObject->DllBase,
|
||||
|
|
|
@ -379,7 +379,7 @@ AppCpuInit:
|
|||
KiInitializeKernel(&KiInitialProcess.Pcb,
|
||||
InitialThread,
|
||||
InitialStack,
|
||||
&Pcr->PrcbData, //(PKPRCB)__readfsdword(KPCR_PRCB),
|
||||
(PKPRCB)__readfsdword(KPCR_PRCB),
|
||||
Cpu,
|
||||
LoaderBlock);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue