Author: fireball
Date: Sun Oct 8 14:06:06 2006
New Revision: 24444
URL:
http://svn.reactos.org/svn/reactos?rev=24444&view=rev
Log:
- Add dumping boot drivers list, remove unneded comment
- Implement WinLdrScanRegistry() (based on freeldr's already existing implementation)
which searches for boot-loading drivers
- Implement WinLdrAddDriverToList() - it correctly fills an entry in the BootDriversList
in LoaderParameterBlock
Modified:
trunk/reactos/boot/freeldr/freeldr/windows/winldr.c
trunk/reactos/boot/freeldr/freeldr/windows/wlregistry.c
Modified: trunk/reactos/boot/freeldr/freeldr/windows/winldr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/windo…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/windows/winldr.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/windows/winldr.c Sun Oct 8 14:06:06 2006
@@ -26,8 +26,10 @@
//#define NDEBUG
#include <debug.h>
+// debug stuff
VOID DumpMemoryAllocMap(VOID);
VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock);
+VOID WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock);
void InitializeHWConfig(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock)
{
@@ -338,8 +340,6 @@
Status = WinLdrLoadAndScanSystemHive(LoaderBlock, BootPath);
DbgPrint((DPRINT_WINDOWS, "SYSTEM hive loaded and scanned with status %d\n",
Status));
- /* FIXME: Load OEM HAL font, should be moved to WinLdrLoadAndScanSystemHive() */
-
/* Load boot drivers */
//WinLdrLoadBootDrivers();
@@ -361,6 +361,7 @@
KiSystemStartup, LoaderBlockVA));
WinLdrpDumpMemoryDescriptors(LoaderBlockVA);
+ WinLdrpDumpBootDriver(LoaderBlockVA);
//FIXME: If I substitute this debugging checkpoint, GCC will "optimize away"
the code below
//while (1) {};
@@ -394,3 +395,22 @@
NextMd = MemoryDescriptor->ListEntry.Flink;
}
}
+
+VOID
+WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ PLIST_ENTRY NextBd;
+ PBOOT_DRIVER_LIST_ENTRY BootDriver;
+
+ NextBd = LoaderBlock->BootDriverListHead.Flink;
+
+ while (NextBd != &LoaderBlock->BootDriverListHead)
+ {
+ BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, ListEntry);
+
+ DbgPrint((DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n",
&BootDriver->FilePath,
+ BootDriver->DataTableEntry, &BootDriver->RegistryPath));
+
+ NextBd = BootDriver->ListEntry.Flink;
+ }
+}
Modified: trunk/reactos/boot/freeldr/freeldr/windows/wlregistry.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/windo…
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/windows/wlregistry.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/windows/wlregistry.c Sun Oct 8 14:06:06 2006
@@ -13,6 +13,10 @@
#define NDEBUG
#include <debug.h>
+BOOLEAN WinLdrGetNLSNames(LPSTR AnsiName,
+ LPSTR OemName,
+ LPSTR LangName);
+
BOOLEAN
WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
IN LPCSTR DirectoryPath,
@@ -20,6 +24,15 @@
IN LPCSTR OemFileName,
IN LPCSTR LanguageFileName);
+VOID
+WinLdrScanRegistry(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
+ IN LPCSTR DirectoryPath);
+
+BOOLEAN
+WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
+ LPWSTR RegistryPath,
+ LPWSTR ImagePath,
+ LPWSTR ServiceName);
/* FUNCTIONS **************************************************************/
@@ -87,6 +100,71 @@
return TRUE;
}
+BOOLEAN WinLdrLoadAndScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
+ IN LPCSTR DirectoryPath)
+{
+ CHAR SearchPath[1024];
+ CHAR AnsiName[256], OemName[256], LangName[256];
+ BOOLEAN Status;
+
+ // There is a simple logic here: try to load usual hive (system), if it
+ // fails, then give system.alt a try, and finally try a system.sav
+
+ // FIXME: For now we only try system
+ strcpy(SearchPath, DirectoryPath);
+ strcat(SearchPath, "SYSTEM32\\CONFIG\\");
+ Status = WinLdrLoadSystemHive(LoaderBlock, SearchPath, "SYSTEM");
+
+ // Fail if failed...
+ if (!Status)
+ return FALSE;
+
+ // Initialize in-memory registry
+ RegInitializeRegistry();
+
+ // Import what was loaded
+ Status = RegImportBinaryHive((PCHAR)VaToPa(LoaderBlock->RegistryBase),
LoaderBlock->RegistryLength);
+ if (!Status)
+ {
+ UiMessageBox("Importing binary hive failed!");
+ return FALSE;
+ }
+
+ // Initialize the 'CurrentControlSet' link
+ if (RegInitCurrentControlSet(FALSE) != ERROR_SUCCESS)
+ {
+ UiMessageBox("Initializing CurrentControlSet link failed!");
+ return FALSE;
+ }
+
+ // Scan registry and prepare boot drivers list
+ WinLdrScanRegistry(LoaderBlock, DirectoryPath);
+
+ // Get names of NLS files
+ Status = WinLdrGetNLSNames(AnsiName, OemName, LangName);
+ if (!Status)
+ {
+ UiMessageBox("Getting NLS names from registry failed!");
+ return FALSE;
+ }
+
+ DbgPrint((DPRINT_WINDOWS, "NLS data %s %s %s\n", AnsiName, OemName,
LangName));
+
+ // Load NLS data
+ strcpy(SearchPath, DirectoryPath);
+ strcat(SearchPath, "SYSTEM32\\");
+ Status = WinLdrLoadNLSData(LoaderBlock, SearchPath, AnsiName, OemName, LangName);
+ DbgPrint((DPRINT_WINDOWS, "NLS data loaded with status %d\n", Status));
+
+ /* TODO: Load OEM HAL font */
+
+
+ return TRUE;
+}
+
+
+/* PRIVATE FUNCTIONS ******************************************************/
+
// Queries registry for those three file names
BOOLEAN WinLdrGetNLSNames(LPSTR AnsiName,
LPSTR OemName,
@@ -175,63 +253,6 @@
return TRUE;
}
-BOOLEAN WinLdrLoadAndScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
- IN LPCSTR DirectoryPath)
-{
- CHAR SearchPath[1024];
- CHAR AnsiName[256], OemName[256], LangName[256];
- BOOLEAN Status;
-
- // There is a simple logic here: try to load usual hive (system), if it
- // fails, then give system.alt a try, and finally try a system.sav
-
- // FIXME: For now we only try system
- strcpy(SearchPath, DirectoryPath);
- strcat(SearchPath, "SYSTEM32\\CONFIG\\");
- Status = WinLdrLoadSystemHive(LoaderBlock, SearchPath, "SYSTEM");
-
- // Fail if failed...
- if (!Status)
- return FALSE;
-
- // Initialize in-memory registry
- RegInitializeRegistry();
-
- // Import what was loaded
- Status = RegImportBinaryHive((PCHAR)VaToPa(LoaderBlock->RegistryBase),
LoaderBlock->RegistryLength);
- if (!Status)
- {
- UiMessageBox("Importing binary hive failed!");
- return FALSE;
- }
-
- // Initialize the 'CurrentControlSet' link
- if (RegInitCurrentControlSet(FALSE) != ERROR_SUCCESS)
- {
- UiMessageBox("Initializing CurrentControlSet link failed!");
- return FALSE;
- }
-
- Status = WinLdrGetNLSNames(AnsiName, OemName, LangName);
- if (!Status)
- {
- UiMessageBox("Getting NLS names from registry failed!");
- return FALSE;
- }
-
- DbgPrint((DPRINT_WINDOWS, "NLS data %s %s %s\n", AnsiName, OemName,
LangName));
-
- /* Load NLS data, should be moved to WinLdrLoadAndScanSystemHive() */
- strcpy(SearchPath, DirectoryPath);
- strcat(SearchPath, "SYSTEM32\\");
- Status = WinLdrLoadNLSData(LoaderBlock, SearchPath, AnsiName, OemName, LangName);
- DbgPrint((DPRINT_WINDOWS, "NLS data loaded with status %d\n", Status));
-
- return TRUE;
-}
-
-
-/* PRIVATE FUNCTIONS ******************************************************/
BOOLEAN
WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
@@ -388,3 +409,317 @@
UiMessageBox("Error reading NLS file!");
return FALSE;
}
+
+VOID
+WinLdrScanRegistry(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
+ IN LPCSTR DirectoryPath)
+{
+ LONG rc = 0;
+ FRLDRHKEY hGroupKey, hOrderKey, hServiceKey, hDriverKey;
+ WCHAR GroupNameBuffer[512];
+ WCHAR ServiceName[256];
+ ULONG OrderList[128];
+ ULONG BufferSize;
+ ULONG Index;
+ ULONG TagIndex;
+ LPWSTR GroupName;
+
+ ULONG ValueSize;
+ ULONG ValueType;
+ ULONG StartValue;
+ ULONG TagValue;
+ WCHAR DriverGroup[256];
+ ULONG DriverGroupSize;
+
+ CHAR ImagePath[256];
+ WCHAR TempImagePath[256];
+
+ BOOLEAN Status;
+
+ /* get 'service group order' key */
+ rc = RegOpenKey(NULL,
+ L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
+ &hGroupKey);
+ if (rc != ERROR_SUCCESS) {
+
+ DbgPrint((DPRINT_REACTOS, "Failed to open the 'ServiceGroupOrder' key (rc
%d)\n", (int)rc));
+ return;
+ }
+
+ /* get 'group order list' key */
+ rc = RegOpenKey(NULL,
+ L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList",
+ &hOrderKey);
+ if (rc != ERROR_SUCCESS) {
+
+ DbgPrint((DPRINT_REACTOS, "Failed to open the 'GroupOrderList' key (rc
%d)\n", (int)rc));
+ return;
+ }
+
+ /* enumerate drivers */
+ rc = RegOpenKey(NULL,
+ L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
+ &hServiceKey);
+ if (rc != ERROR_SUCCESS) {
+
+ DbgPrint((DPRINT_REACTOS, "Failed to open the 'Services' key (rc
%d)\n", (int)rc));
+ return;
+ }
+
+ /* Get the Name Group */
+ BufferSize = sizeof(GroupNameBuffer);
+ rc = RegQueryValue(hGroupKey, L"List", NULL, (PUCHAR)GroupNameBuffer,
&BufferSize);
+ DbgPrint((DPRINT_REACTOS, "RegQueryValue(): rc %d\n", (int)rc));
+ if (rc != ERROR_SUCCESS)
+ return;
+ DbgPrint((DPRINT_REACTOS, "BufferSize: %d \n", (int)BufferSize));
+ DbgPrint((DPRINT_REACTOS, "GroupNameBuffer: '%S' \n",
GroupNameBuffer));
+
+ /* Loop through each group */
+ GroupName = GroupNameBuffer;
+ while (*GroupName)
+ {
+ DbgPrint((DPRINT_WINDOWS, "Driver group: '%S'\n", GroupName));
+
+ /* Query the Order */
+ BufferSize = sizeof(OrderList);
+ rc = RegQueryValue(hOrderKey, GroupName, NULL, (PUCHAR)OrderList, &BufferSize);
+ if (rc != ERROR_SUCCESS) OrderList[0] = 0;
+
+ /* enumerate all drivers */
+ for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++)
+ {
+ Index = 0;
+
+ while (TRUE)
+ {
+ /* Get the Driver's Name */
+ ValueSize = sizeof(ServiceName);
+ rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);
+ //DbgPrint((DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc));
+
+ /* Makre sure it's valid, and check if we're done */
+ if (rc == ERROR_NO_MORE_ITEMS)
+ break;
+ if (rc != ERROR_SUCCESS)
+ return;
+ //DbgPrint((DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index,
ServiceName));
+
+ /* open driver Key */
+ rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey);
+ if (rc == ERROR_SUCCESS)
+ {
+ /* Read the Start Value */
+ ValueSize = sizeof(ULONG);
+ rc = RegQueryValue(hDriverKey, L"Start", &ValueType,
(PUCHAR)&StartValue, &ValueSize);
+ if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
+ //DbgPrint((DPRINT_REACTOS, " Start: %x \n", (int)StartValue));
+
+ /* Read the Tag */
+ ValueSize = sizeof(ULONG);
+ rc = RegQueryValue(hDriverKey, L"Tag", &ValueType,
(PUCHAR)&TagValue, &ValueSize);
+ if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
+ //DbgPrint((DPRINT_REACTOS, " Tag: %x \n", (int)TagValue));
+
+ /* Read the driver's group */
+ DriverGroupSize = sizeof(DriverGroup);
+ rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup,
&DriverGroupSize);
+ //DbgPrint((DPRINT_REACTOS, " Group: '%S' \n", DriverGroup));
+
+ /* Make sure it should be started */
+ if ((StartValue == 0) &&
+ (TagValue == OrderList[TagIndex]) &&
+ (_wcsicmp(DriverGroup, GroupName) == 0)) {
+
+ /* Get the Driver's Location */
+ ValueSize = sizeof(TempImagePath);
+ rc = RegQueryValue(hDriverKey, L"ImagePath", NULL,
(PUCHAR)TempImagePath, &ValueSize);
+
+ /* Write the whole path if it suceeded, else prepare to fail */
+ if (rc != ERROR_SUCCESS) {
+ DbgPrint((DPRINT_REACTOS, " ImagePath: not found\n"));
+ TempImagePath[0] = 0;
+ sprintf(ImagePath, "%s\\system32\\drivers\\%S.sys", DirectoryPath,
ServiceName);
+ } else if (TempImagePath[0] != L'\\') {
+ sprintf(ImagePath, "%s%S", DirectoryPath, TempImagePath);
+ } else {
+ sprintf(ImagePath, "%S", TempImagePath);
+ DbgPrint((DPRINT_REACTOS, " ImagePath: '%s'\n", ImagePath));
+ }
+
+ DbgPrint((DPRINT_WINDOWS, " Adding boot driver: '%s'\n",
ImagePath));
+
+ Status = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead,
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
+ TempImagePath,
+ ServiceName);
+
+ if (!Status)
+ DbgPrint((DPRINT_WINDOWS, " Failed to add boot driver\n"));
+ } else
+ {
+ //DbgPrint((DPRINT_REACTOS, " Skipping driver '%S' with Start %d, Tag
%d and Group '%S' (Current Tag %d, current group '%S')\n",
+ // ServiceName, StartValue, TagValue, DriverGroup, OrderList[TagIndex],
GroupName));
+ }
+ }
+
+ Index++;
+ }
+ }
+
+ Index = 0;
+ while (TRUE)
+ {
+ /* Get the Driver's Name */
+ ValueSize = sizeof(ServiceName);
+ rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);
+
+ //DbgPrint((DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc));
+ if (rc == ERROR_NO_MORE_ITEMS)
+ break;
+ if (rc != ERROR_SUCCESS)
+ return;
+ //DbgPrint((DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index,
ServiceName));
+
+ /* open driver Key */
+ rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey);
+ if (rc == ERROR_SUCCESS)
+ {
+ /* Read the Start Value */
+ ValueSize = sizeof(ULONG);
+ rc = RegQueryValue(hDriverKey, L"Start", &ValueType,
(PUCHAR)&StartValue, &ValueSize);
+ if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
+ //DbgPrint((DPRINT_REACTOS, " Start: %x \n", (int)StartValue));
+
+ /* Read the Tag */
+ ValueSize = sizeof(ULONG);
+ rc = RegQueryValue(hDriverKey, L"Tag", &ValueType,
(PUCHAR)&TagValue, &ValueSize);
+ if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
+ //DbgPrint((DPRINT_REACTOS, " Tag: %x \n", (int)TagValue));
+
+ /* Read the driver's group */
+ DriverGroupSize = sizeof(DriverGroup);
+ rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup,
&DriverGroupSize);
+ //DbgPrint((DPRINT_REACTOS, " Group: '%S' \n", DriverGroup));
+
+ for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++) {
+ if (TagValue == OrderList[TagIndex]) break;
+ }
+
+ if ((StartValue == 0) &&
+ (TagIndex > OrderList[0]) &&
+ (_wcsicmp(DriverGroup, GroupName) == 0)) {
+
+ ValueSize = sizeof(TempImagePath);
+ rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath,
&ValueSize);
+ if (rc != ERROR_SUCCESS) {
+ DbgPrint((DPRINT_REACTOS, " ImagePath: not found\n"));
+ TempImagePath[0] = 0;
+ sprintf(ImagePath, "%ssystem32\\drivers\\%S.sys", DirectoryPath,
ServiceName);
+ } else if (TempImagePath[0] != L'\\') {
+ sprintf(ImagePath, "%s%S", DirectoryPath, TempImagePath);
+ } else {
+ sprintf(ImagePath, "%S", TempImagePath);
+ DbgPrint((DPRINT_REACTOS, " ImagePath: '%s'\n", ImagePath));
+ }
+ DbgPrint((DPRINT_WINDOWS, " Adding boot driver: '%s'\n",
ImagePath));
+
+ Status = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead,
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
+ TempImagePath,
+ ServiceName);
+
+ if (!Status)
+ DbgPrint((DPRINT_WINDOWS, " Failed to add boot driver\n"));
+ } else
+ {
+ //DbgPrint((DPRINT_REACTOS, " Skipping driver '%S' with Start %d, Tag
%d and Group '%S' (Current group '%S')\n",
+ // ServiceName, StartValue, TagValue, DriverGroup, GroupName));
+ }
+ }
+
+ Index++;
+ }
+
+ /* Move to the next group name */
+ GroupName = GroupName + wcslen(GroupName) + 1;
+ }
+}
+
+BOOLEAN
+WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
+ LPWSTR RegistryPath,
+ LPWSTR ImagePath,
+ LPWSTR ServiceName)
+{
+ PBOOT_DRIVER_LIST_ENTRY BootDriverEntry;
+ NTSTATUS Status;
+ ULONG PathLength;
+
+ BootDriverEntry = MmAllocateMemory(sizeof(BOOT_DRIVER_LIST_ENTRY));
+
+ if (!BootDriverEntry)
+ return FALSE;
+
+ // DTE will be filled during actual load of the driver
+ BootDriverEntry->DataTableEntry = NULL;
+
+ // Check - if we have a valid ImagePath, if not - we need to build it
+ // like "System32\\Drivers\\blah.sys"
+ if (ImagePath && (wcslen(ImagePath) > 0))
+ {
+ // Just copy ImagePath to the corresponding field in the structure
+ PathLength = wcslen(ImagePath) * sizeof(WCHAR);
+
+ BootDriverEntry->FilePath.Length = 0;
+ BootDriverEntry->FilePath.MaximumLength = PathLength + sizeof(WCHAR);
+ BootDriverEntry->FilePath.Buffer = MmAllocateMemory(PathLength);
+
+ if (!BootDriverEntry->FilePath.Buffer)
+ return FALSE;
+
+ Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ImagePath);
+ if (!NT_SUCCESS(Status))
+ return FALSE;
+ }
+ else
+ {
+ // we have to construct ImagePath ourselves
+ PathLength = wcslen(ServiceName)*sizeof(WCHAR) +
sizeof(L"system32\\drivers\\.sys");;
+ BootDriverEntry->FilePath.Length = 0;
+ BootDriverEntry->FilePath.MaximumLength = PathLength+sizeof(WCHAR);
+ BootDriverEntry->FilePath.Buffer = MmAllocateMemory(PathLength);
+
+ if (!BootDriverEntry->FilePath.Buffer)
+ return FALSE;
+
+ Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath,
L"system32\\drivers\\");
+ if (!NT_SUCCESS(Status))
+ return FALSE;
+
+ Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ServiceName);
+ if (!NT_SUCCESS(Status))
+ return FALSE;
+
+ Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath,
L".sys");
+ if (!NT_SUCCESS(Status))
+ return FALSE;
+ }
+
+ // Add registry path
+ PathLength = wcslen(RegistryPath)*sizeof(WCHAR);
+ BootDriverEntry->RegistryPath.Length = 0;
+ BootDriverEntry->RegistryPath.MaximumLength = PathLength+sizeof(WCHAR);
+ BootDriverEntry->RegistryPath.Buffer = MmAllocateMemory(PathLength);
+ if (!BootDriverEntry->RegistryPath.Buffer)
+ return FALSE;
+
+ Status = RtlAppendUnicodeToString(&BootDriverEntry->RegistryPath, RegistryPath);
+ if (!NT_SUCCESS(Status))
+ return FALSE;
+
+ // Insert entry at top of the list
+ InsertHeadList(BootDriverListHead, &BootDriverEntry->ListEntry);
+
+ return TRUE;
+}