[ros-diffs] [fireball] 24444: - 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

fireball at svn.reactos.org fireball at svn.reactos.org
Sun Oct 8 12:06:07 CEST 2006


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/windows/winldr.c?rev=24444&r1=24443&r2=24444&view=diff
==============================================================================
--- 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/windows/wlregistry.c?rev=24444&r1=24443&r2=24444&view=diff
==============================================================================
--- 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;
+}




More information about the Ros-diffs mailing list