[FREELDR:NTLDR] Use NTOS kernel's CMBOOT functions to enumerate and build the boot...
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Tue, 22 Mar 2022 03:14:35 +0000 (04:14 +0100)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 17 Apr 2022 02:57:42 +0000 (04:57 +0200)
They are correct and are more performant.

- Rewrite WinLdrAddDriverToList() on the model of CmpAddDriverToList()
  with support for CmpIsDriverInList().

- Disable RegEnumKey() as it is now unused.

boot/freeldr/freeldr/CMakeLists.txt
boot/freeldr/freeldr/ntldr/registry.c
boot/freeldr/freeldr/ntldr/registry.h
boot/freeldr/freeldr/ntldr/setupldr.c
boot/freeldr/freeldr/ntldr/winldr.c
boot/freeldr/freeldr/ntldr/winldr.h
boot/freeldr/freeldr/ntldr/wlregistry.c

index 592f0af..00d6dc8 100644 (file)
@@ -48,6 +48,7 @@ list(APPEND FREELDR_BOOTLIB_SOURCE
     lib/mm/heap.c)
 
 list(APPEND FREELDR_NTLDR_SOURCE
+    ${REACTOS_SOURCE_DIR}/ntoskrnl/config/cmboot.c
     ntldr/conversion.c
     ntldr/registry.c
     ntldr/winldr.c
index 132309e..8804603 100644 (file)
@@ -242,6 +242,7 @@ GetNextPathElement(
     return TRUE;
 }
 
+#if 0
 LONG
 RegEnumKey(
     _In_ HKEY Key,
@@ -312,6 +313,7 @@ RegEnumKey(
     TRACE("RegEnumKey done -> %u, '%.*S'\n", *NameSize, *NameSize, Name);
     return ERROR_SUCCESS;
 }
+#endif
 
 LONG
 RegOpenKey(
index 028f750..2362675 100644 (file)
@@ -44,6 +44,7 @@ extern HKEY CurrentControlSetKey;
  */
 #define RegCloseKey(hKey)   (ERROR_SUCCESS)
 
+#if 0
 LONG
 RegEnumKey(
     _In_ HKEY Key,
@@ -51,6 +52,7 @@ RegEnumKey(
     _Out_ PWCHAR Name,
     _Inout_ PULONG NameSize,
     _Out_opt_ PHKEY SubKey);
+#endif
 
 LONG
 RegOpenKey(
index b300be5..5762223 100644 (file)
@@ -135,17 +135,22 @@ SetupLdrInitErrataInf(
 }
 
 static VOID
-SetupLdrScanBootDrivers(PLIST_ENTRY BootDriverListHead, HINF InfHandle, PCSTR SearchPath)
+SetupLdrScanBootDrivers(
+    _Inout_ PLIST_ENTRY BootDriverListHead,
+    _In_ HINF InfHandle,
+    _In_ PCSTR SearchPath)
 {
     INFCONTEXT InfContext, dirContext;
-    BOOLEAN Success;
     PCSTR Media, DriverName, dirIndex, ImagePath;
-    WCHAR ServiceName[256];
-    WCHAR ImagePathW[256];
+    BOOLEAN Success;
+    WCHAR ImagePathW[MAX_PATH];
+    WCHAR DriverNameW[256];
 
-    /* Open inf section */
+    UNREFERENCED_PARAMETER(SearchPath);
+
+    /* Open INF section */
     if (!InfFindFirstLine(InfHandle, "SourceDisksFiles", NULL, &InfContext))
-        return;
+        goto Quit;
 
     /* Load all listed boot drivers */
     do
@@ -158,30 +163,51 @@ SetupLdrScanBootDrivers(PLIST_ENTRY BootDriverListHead, HINF InfHandle, PCSTR Se
                 InfFindFirstLine(InfHandle, "Directories", dirIndex, &dirContext) &&
                 InfGetDataField(&dirContext, 1, &ImagePath))
             {
-                /* Convert name to widechar */
-                swprintf(ServiceName, L"%S", DriverName);
-
                 /* Prepare image path */
-                swprintf(ImagePathW, L"%S", ImagePath);
-                wcscat(ImagePathW, L"\\");
-                wcscat(ImagePathW, ServiceName);
+                RtlStringCbPrintfW(ImagePathW, sizeof(ImagePathW),
+                                   L"%S\\%S", ImagePath, DriverName);
 
-                /* Remove .sys extension */
-                ServiceName[wcslen(ServiceName) - 4] = 0;
+                /* Convert name to unicode and remove .sys extension */
+                RtlStringCbPrintfW(DriverNameW, sizeof(DriverNameW),
+                                   L"%S", DriverName);
+                DriverNameW[wcslen(DriverNameW) - 4] = UNICODE_NULL;
 
                 /* Add it to the list */
                 Success = WinLdrAddDriverToList(BootDriverListHead,
-                                                L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
+                                                FALSE,
+                                                DriverNameW,
                                                 ImagePathW,
-                                                ServiceName);
+                                                NULL,
+                                                SERVICE_ERROR_NORMAL,
+                                                -1);
                 if (!Success)
                 {
-                    ERR("Could not add boot driver '%s', '%s'\n", SearchPath, DriverName);
-                    return;
+                    ERR("Could not add boot driver '%s'\n", DriverName);
+                    /* Ignore and continue adding other drivers */
                 }
             }
         }
     } while (InfFindNextLine(&InfContext, &InfContext));
+
+Quit:
+    /* Finally, add the boot filesystem driver to the list */
+    if (BootFileSystem)
+    {
+        TRACE("Adding filesystem driver %S\n", BootFileSystem);
+        Success = WinLdrAddDriverToList(BootDriverListHead,
+                                        FALSE,
+                                        BootFileSystem,
+                                        NULL,
+                                        L"Boot File System",
+                                        SERVICE_ERROR_CRITICAL,
+                                        -1);
+        if (!Success)
+            ERR("Failed to add filesystem driver %S\n", BootFileSystem);
+    }
+    else
+    {
+        TRACE("No required filesystem driver\n");
+    }
 }
 
 
index 5427b14..9f51a54 100644 (file)
@@ -10,6 +10,7 @@
 #include "winldr.h"
 #include "ntldropts.h"
 #include "registry.h"
+#include <internal/cmboot.h>
 
 #include <debug.h>
 DBG_DEFAULT_CHANNEL(WINDOWS);
@@ -26,6 +27,7 @@ extern BOOLEAN WinLdrTerminalConnected;
 extern VOID WinLdrSetupEms(IN PCSTR BootOptions);
 
 PLOADER_SYSTEM_BLOCK WinLdrSystemBlock;
+/**/PCWSTR BootFileSystem = NULL;/**/
 
 BOOLEAN VirtualBias = FALSE;
 BOOLEAN SosEnabled = FALSE;
@@ -363,23 +365,30 @@ WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
                       PCSTR BootPath)
 {
     PLIST_ENTRY NextBd;
+    PBOOT_DRIVER_NODE DriverNode;
     PBOOT_DRIVER_LIST_ENTRY BootDriver;
     BOOLEAN Success;
     BOOLEAN ret = TRUE;
 
-    // Walk through the boot drivers list
+    /* Walk through the boot drivers list */
     NextBd = LoaderBlock->BootDriverListHead.Flink;
-
     while (NextBd != &LoaderBlock->BootDriverListHead)
     {
-        BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, Link);
+        DriverNode = CONTAINING_RECORD(NextBd,
+                                       BOOT_DRIVER_NODE,
+                                       ListEntry.Link);
+        BootDriver = &DriverNode->ListEntry;
 
-        TRACE("BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
-            BootDriver->LdrEntry, &BootDriver->RegistryPath);
+        /* Get the next list entry as we may remove the current one on failure */
+        NextBd = BootDriver->Link.Flink;
+
+        TRACE("BootDriver %wZ DTE %08X RegPath: %wZ\n",
+              &BootDriver->FilePath, BootDriver->LdrEntry,
+              &BootDriver->RegistryPath);
 
         // Paths are relative (FIXME: Are they always relative?)
 
-        // Load it
+        /* Load it */
         UiIndicateProgress();
         Success = WinLdrLoadDeviceDriver(&LoaderBlock->LoadOrderListHead,
                                          BootPath,
@@ -388,23 +397,25 @@ WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
                                          &BootDriver->LdrEntry);
         if (Success)
         {
-            // Convert the RegistryPath and DTE addresses to VA since we are not going to use it anymore
+            /* Convert the addresses to VA since we are not going to use them anymore */
             BootDriver->RegistryPath.Buffer = PaToVa(BootDriver->RegistryPath.Buffer);
             BootDriver->FilePath.Buffer = PaToVa(BootDriver->FilePath.Buffer);
             BootDriver->LdrEntry = PaToVa(BootDriver->LdrEntry);
+
+            if (DriverNode->Group.Buffer)
+                DriverNode->Group.Buffer = PaToVa(DriverNode->Group.Buffer);
+            DriverNode->Name.Buffer = PaToVa(DriverNode->Name.Buffer);
         }
         else
         {
-            // Loading failed - cry loudly
-            ERR("Can't load boot driver '%wZ'!\n", &BootDriver->FilePath);
-            UiMessageBox("Can't load boot driver '%wZ'!", &BootDriver->FilePath);
+            /* Loading failed: cry loudly */
+            ERR("Cannot load boot driver '%wZ'!\n", &BootDriver->FilePath);
+            UiMessageBox("Cannot load boot driver '%wZ'!", &BootDriver->FilePath);
             ret = FALSE;
 
-            // Remove it from the list and try to continue
-            RemoveEntryList(NextBd);
+            /* Remove it from the list and try to continue */
+            RemoveEntryList(&BootDriver->Link);
         }
-
-        NextBd = BootDriver->Link.Flink;
     }
 
     return ret;
index ab06855..20a20ba 100644 (file)
@@ -61,6 +61,7 @@ typedef struct _LOADER_SYSTEM_BLOCK
 } LOADER_SYSTEM_BLOCK, *PLOADER_SYSTEM_BLOCK;
 
 extern PLOADER_SYSTEM_BLOCK WinLdrSystemBlock;
+/**/extern PCWSTR BootFileSystem;/**/
 
 
 // conversion.c
@@ -71,7 +72,6 @@ VOID List_PaToVa(_In_ LIST_ENTRY *ListEntry);
 #endif
 VOID ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start);
 
-
 // winldr.c
 extern BOOLEAN SosEnabled;
 #ifdef _M_IX86
@@ -117,14 +117,6 @@ WinLdrInitSystemHive(
 BOOLEAN WinLdrScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
                              IN PCSTR SystemRoot);
 
-// winldr.c
-VOID
-WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
-                       PCSTR Options,
-                       PCSTR SystemPath,
-                       PCSTR BootPath,
-                       USHORT VersionToBoot);
-
 BOOLEAN
 WinLdrLoadNLSData(
     _Inout_ PLOADER_PARAMETER_BLOCK LoaderBlock,
@@ -135,10 +127,22 @@ WinLdrLoadNLSData(
     _In_ PCUNICODE_STRING OemHalFileName);
 
 BOOLEAN
-WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
-                      PWSTR RegistryPath,
-                      PWSTR ImagePath,
-                      PWSTR ServiceName);
+WinLdrAddDriverToList(
+    _Inout_ PLIST_ENTRY DriverListHead,
+    _In_ BOOLEAN InsertAtHead,
+    _In_ PCWSTR DriverName,
+    _In_opt_ PCWSTR ImagePath,
+    _In_opt_ PCWSTR GroupName,
+    _In_ ULONG ErrorControl,
+    _In_ ULONG Tag);
+
+// winldr.c
+VOID
+WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
+                       PCSTR Options,
+                       PCSTR SystemPath,
+                       PCSTR BootPath,
+                       USHORT VersionToBoot);
 
 VOID
 WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock);
index cc139b7..e36aae1 100644 (file)
@@ -11,6 +11,7 @@
 #include <freeldr.h>
 #include "winldr.h"
 #include "registry.h"
+#include <internal/cmboot.h>
 
 #include <debug.h>
 DBG_DEFAULT_CHANNEL(WINDOWS);
@@ -26,9 +27,9 @@ WinLdrGetNLSNames(
     _Inout_ PUNICODE_STRING LangFileName, // CaseTable
     _Inout_ PUNICODE_STRING OemHalFileName);
 
-static VOID
-WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead,
-                   IN PCSTR SystemRoot);
+static BOOLEAN
+WinLdrScanRegistry(
+    IN OUT PLIST_ENTRY BootDriverListHead);
 
 
 /* FUNCTIONS **************************************************************/
@@ -47,7 +48,6 @@ WinLdrLoadSystemHive(
     PVOID HiveDataPhysical;
     PVOID HiveDataVirtual;
     ULONG BytesRead;
-    PCWSTR FsService;
 
     /* Concatenate path and filename to get the full name */
     RtlStringCbCopyA(FullHiveName, sizeof(FullHiveName), DirectoryPath);
@@ -99,23 +99,8 @@ WinLdrLoadSystemHive(
         return FALSE;
     }
 
-    /* Add boot filesystem driver to the list */
-    FsService = FsGetServiceName(FileId);
-    if (FsService)
-    {
-        BOOLEAN Success;
-        TRACE("Adding filesystem service %S\n", FsService);
-        Success = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead,
-                                        L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
-                                        NULL,
-                                        (PWSTR)FsService);
-        if (!Success)
-            TRACE("Failed to add filesystem service\n");
-    }
-    else
-    {
-        TRACE("No required filesystem service\n");
-    }
+    // FIXME: HACK: Get the boot filesystem driver name now...
+    BootFileSystem = FsGetServiceName(FileId);
 
     ArcClose(FileId);
     return TRUE;
@@ -184,7 +169,12 @@ BOOLEAN WinLdrScanSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
     CHAR SearchPath[1024];
 
     /* Scan registry and prepare boot drivers list */
-    WinLdrScanRegistry(&LoaderBlock->BootDriverListHead, SystemRoot);
+    Success = WinLdrScanRegistry(&LoaderBlock->BootDriverListHead);
+    if (!Success)
+    {
+        UiMessageBox("Failed to load boot drivers!");
+        return FALSE;
+    }
 
     /* Get names of NLS files */
     Success = WinLdrGetNLSNames(CurrentControlSetKey,
@@ -517,412 +507,280 @@ Quit:
     return (Status == ESUCCESS);
 }
 
-static VOID
-WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead,
-                   IN PCSTR SystemRoot)
+static BOOLEAN
+WinLdrScanRegistry(
+    IN OUT PLIST_ENTRY BootDriverListHead)
 {
-    LONG rc = 0;
-    HKEY hOrderKey, hServiceKey, hGroupKey, hDriverKey;
-    PWSTR GroupNameBuffer = NULL;
-    WCHAR ServiceName[256];
-    ULONG OrderList[128];
-    ULONG BufferSize;
-    ULONG Index;
-    ULONG TagIndex;
-    PWSTR GroupName;
-
-    ULONG ValueSize;
-    ULONG ValueType;
-    ULONG StartValue;
-    ULONG TagValue;
-    WCHAR DriverGroup[256];
-    ULONG DriverGroupSize;
-
-    CHAR ImagePath[256];
-    WCHAR TempImagePath[256];
-
     BOOLEAN Success;
 
-    /* Get 'group order list' key */
-    rc = RegOpenKey(CurrentControlSetKey, L"Control\\GroupOrderList", &hOrderKey);
-    if (rc != ERROR_SUCCESS)
-    {
-        TRACE_CH(REACTOS, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc);
-        return;
-    }
-
-    /* Get 'services' key */
-    rc = RegOpenKey(CurrentControlSetKey, L"Services", &hServiceKey);
-    if (rc != ERROR_SUCCESS)
-    {
-        TRACE_CH(REACTOS, "Failed to open the 'Services' key (rc %d)\n", (int)rc);
-        RegCloseKey(hOrderKey);
-        return;
-    }
-
-    /* Get 'service group order' key */
-    rc = RegOpenKey(CurrentControlSetKey, L"Control\\ServiceGroupOrder", &hGroupKey);
-    if (rc != ERROR_SUCCESS)
-    {
-        TRACE_CH(REACTOS, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc);
+    /* Find all boot drivers */
+    Success = CmpFindDrivers(SystemHive,
+                             (HCELL_INDEX)CurrentControlSetKey,
+                             BootLoad,
+                             BootFileSystem,
+                             BootDriverListHead);
+    if (!Success)
         goto Quit;
-    }
 
-    /* Get the Group Order List */
-    BufferSize = 4096;
-    GroupNameBuffer = FrLdrHeapAlloc(BufferSize, TAG_WLDR_NAME);
-    if (!GroupNameBuffer)
-    {
-        TRACE_CH(REACTOS, "Failed to allocate buffer\n");
-        RegCloseKey(hGroupKey);
+    /* Sort by group/tag */
+    Success = CmpSortDriverList(SystemHive,
+                                (HCELL_INDEX)CurrentControlSetKey,
+                                BootDriverListHead);
+    if (!Success)
         goto Quit;
-    }
-    rc = RegQueryValue(hGroupKey, L"List", NULL, (PUCHAR)GroupNameBuffer, &BufferSize);
-    RegCloseKey(hGroupKey);
 
-    if (rc != ERROR_SUCCESS)
-    {
-        TRACE_CH(REACTOS, "Failed to query the 'List' value (rc %d)\n", (int)rc);
+    /* Remove circular dependencies (cycles) and sort */
+    Success = CmpResolveDriverDependencies(BootDriverListHead);
+    if (!Success)
         goto Quit;
-    }
-    TRACE_CH(REACTOS, "BufferSize: %d\n", (int)BufferSize);
-    TRACE_CH(REACTOS, "GroupNameBuffer: '%S'\n", GroupNameBuffer);
-
-    /* Loop through each group */
-    GroupName = GroupNameBuffer;
-    while (*GroupName)
-    {
-        TRACE("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++)
-        {
-            for (Index = 0; TRUE; Index++)
-            {
-                /* Get the Driver's Name */
-                ValueSize = sizeof(ServiceName);
-                rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize, &hDriverKey);
-                TRACE("RegEnumKey(): rc %d\n", (int)rc);
-
-                /* Make sure it's valid, and check if we're done */
-                if (rc == ERROR_NO_MORE_ITEMS)
-                    break;
-                if (rc != ERROR_SUCCESS)
-                    goto Quit;
-                //TRACE_CH(REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName);
-
-                /* Read the Start Value */
-                ValueSize = sizeof(ULONG);
-                rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
-                if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
-                //TRACE_CH(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;
-                //TRACE_CH(REACTOS, "  Tag:   %x\n", (int)TagValue);
-
-                /* Read the driver's group */
-                DriverGroupSize = sizeof(DriverGroup);
-                rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
-                //TRACE_CH(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 succeeded, else prepare to fail */
-                    if (rc != ERROR_SUCCESS)
-                    {
-                        TRACE_CH(REACTOS, "ImagePath: not found\n");
-                        TempImagePath[0] = 0;
-                        RtlStringCbPrintfA(ImagePath, sizeof(ImagePath), "%s\\system32\\drivers\\%S.sys", SystemRoot, ServiceName);
-                    }
-                    else if (TempImagePath[0] != L'\\')
-                    {
-                        RtlStringCbPrintfA(ImagePath, sizeof(ImagePath), "%s%S", SystemRoot, TempImagePath);
-                    }
-                    else
-                    {
-                        RtlStringCbPrintfA(ImagePath, sizeof(ImagePath), "%S", TempImagePath);
-                        TRACE_CH(REACTOS, "ImagePath: '%s'\n", ImagePath);
-                    }
-
-                    TRACE("Adding boot driver: '%s'\n", ImagePath);
-
-                    Success = WinLdrAddDriverToList(BootDriverListHead,
-                                                    L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
-                                                    TempImagePath,
-                                                    ServiceName);
-                    if (!Success)
-                        ERR("Failed to add boot driver\n");
-                }
-                else
-                {
-                    //TRACE("  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);
-                }
-
-                RegCloseKey(hDriverKey);
-            }
-        }
-
-        for (Index = 0; TRUE; Index++)
-        {
-            /* Get the Driver's Name */
-            ValueSize = sizeof(ServiceName);
-            rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize, &hDriverKey);
-
-            //TRACE_CH(REACTOS, "RegEnumKey(): rc %d\n", (int)rc);
-            if (rc == ERROR_NO_MORE_ITEMS)
-                break;
-            if (rc != ERROR_SUCCESS)
-                goto Quit;
-            TRACE("Service %d: '%S'\n", (int)Index, ServiceName);
-
-            /* Read the Start Value */
-            ValueSize = sizeof(ULONG);
-            rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
-            if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
-            //TRACE_CH(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;
-            //TRACE_CH(REACTOS, "  Tag:   %x\n", (int)TagValue);
-
-            /* Read the driver's group */
-            DriverGroupSize = sizeof(DriverGroup);
-            rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
-            //TRACE_CH(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)
-                {
-                    TRACE_CH(REACTOS, "ImagePath: not found\n");
-                    TempImagePath[0] = 0;
-                    RtlStringCbPrintfA(ImagePath, sizeof(ImagePath), "%ssystem32\\drivers\\%S.sys", SystemRoot, ServiceName);
-                }
-                else if (TempImagePath[0] != L'\\')
-                {
-                    RtlStringCbPrintfA(ImagePath, sizeof(ImagePath), "%s%S", SystemRoot, TempImagePath);
-                }
-                else
-                {
-                    RtlStringCbPrintfA(ImagePath, sizeof(ImagePath), "%S", TempImagePath);
-                    TRACE_CH(REACTOS, "ImagePath: '%s'\n", ImagePath);
-                }
-                TRACE("  Adding boot driver: '%s'\n", ImagePath);
-
-                Success = WinLdrAddDriverToList(BootDriverListHead,
-                                                L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
-                                                TempImagePath,
-                                                ServiceName);
-                if (!Success)
-                    ERR(" Failed to add boot driver\n");
-            }
-            else
-            {
-                //TRACE("  Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n",
-                //    ServiceName, StartValue, TagValue, DriverGroup, GroupName);
-            }
-
-            RegCloseKey(hDriverKey);
-        }
-
-        /* Move to the next group name */
-        GroupName = GroupName + wcslen(GroupName) + 1;
-    }
 
 Quit:
-    /* Free allocated memory */
-    if (GroupNameBuffer)
-        FrLdrHeapFree(GroupNameBuffer, TAG_WLDR_NAME);
+    /* In case of failure, free the boot driver list */
+    if (!Success)
+        CmpFreeDriverList(SystemHive, BootDriverListHead);
 
-    /* Close the registry key handles */
-    RegCloseKey(hServiceKey);
-    RegCloseKey(hOrderKey);
+    return Success;
 }
 
-static
+/**
+ * @brief
+ * Inserts the specified driver entry into the driver list, or updates
+ * an existing entry with new ImagePath, ErrorControl, Group and Tag values.
+ *
+ * @param[in,out]   DriverListHead
+ * The driver list where to insert the driver entry.
+ *
+ * @param[in]   InsertAtHead
+ * Whether to insert the driver at the head (TRUE) or at the tail (FALSE)
+ * of the driver list.
+ *
+ * @param[in]   DriverName
+ * The driver's name.
+ *
+ * @param[in]   ImagePath
+ * Optional path the the driver's image. If none is specified,
+ * a default path is constructed out of the driver's name.
+ *
+ * @param[in]   GroupName
+ * Optional driver group name.
+ *
+ * @param[in]   ErrorControl
+ * @param[in]   Tag
+ * The ErrorControl and group Tag values for the driver.
+ *
+ * @return
+ * TRUE if the driver has been inserted into the list or updated, FALSE if not.
+ **/
 BOOLEAN
-InsertInBootDriverList(
-    PLIST_ENTRY BootDriverListHead,
-    PBOOT_DRIVER_LIST_ENTRY BootDriverEntry)
+WinLdrAddDriverToList(
+    _Inout_ PLIST_ENTRY DriverListHead,
+    _In_ BOOLEAN InsertAtHead,
+    _In_ PCWSTR DriverName,
+    _In_opt_ PCWSTR ImagePath,
+    _In_opt_ PCWSTR GroupName,
+    _In_ ULONG ErrorControl,
+    _In_ ULONG Tag)
 {
+    PBOOT_DRIVER_NODE DriverNode;
     PBOOT_DRIVER_LIST_ENTRY DriverEntry;
-    PLIST_ENTRY ListEntry;
-
-    ASSERT(BootDriverEntry->FilePath.Buffer != NULL);
-    ASSERT(BootDriverEntry->RegistryPath.Buffer != NULL);
-
-    for (ListEntry = BootDriverListHead->Flink;
-         ListEntry != BootDriverListHead;
-         ListEntry = ListEntry->Flink)
-    {
-        DriverEntry = CONTAINING_RECORD(ListEntry,
-                                        BOOT_DRIVER_LIST_ENTRY,
-                                        Link);
-        if ((DriverEntry->FilePath.Buffer != NULL) &&
-            RtlEqualUnicodeString(&BootDriverEntry->FilePath,
-                                  &DriverEntry->FilePath,
-                                  TRUE))
-        {
-            return FALSE;
-        }
-
-        if ((DriverEntry->RegistryPath.Buffer != NULL) &&
-            RtlEqualUnicodeString(&BootDriverEntry->RegistryPath,
-                                  &DriverEntry->RegistryPath,
-                                  TRUE))
-        {
-            return FALSE;
-        }
+    BOOLEAN AlreadyInserted;
+    USHORT PathLength;
+    UNICODE_STRING DriverNameU;
+    UNICODE_STRING RegistryPath;
+    UNICODE_STRING FilePath = {0};
+    UNICODE_STRING RegistryString = {0};
+    UNICODE_STRING GroupString = {0};
+
+    /* Check whether the driver is already in the list */
+    RtlInitUnicodeString(&DriverNameU, DriverName);
+    AlreadyInserted = CmpIsDriverInList(DriverListHead,
+                                        &DriverNameU,
+                                        &DriverNode);
+    if (AlreadyInserted)
+    {
+        /* If so, we have obtained its node */
+        ASSERT(DriverNode);
+        DriverEntry = &DriverNode->ListEntry;
     }
+    else
+    {
+        /* Allocate a driver node and initialize it */
+        DriverNode = CmpAllocate(sizeof(BOOT_DRIVER_NODE), FALSE, TAG_CM);
+        if (!DriverNode)
+            return FALSE;
 
-    InsertTailList(BootDriverListHead, &BootDriverEntry->Link);
-    return TRUE;
-}
-
-BOOLEAN
-WinLdrAddDriverToList(LIST_ENTRY *BootDriverListHead,
-                      PWSTR RegistryPath,
-                      PWSTR ImagePath,
-                      PWSTR ServiceName)
-{
-    PBOOT_DRIVER_LIST_ENTRY BootDriverEntry;
-    NTSTATUS Status;
-    USHORT PathLength;
+        RtlZeroMemory(DriverNode, sizeof(BOOT_DRIVER_NODE));
+        DriverEntry = &DriverNode->ListEntry;
 
-    BootDriverEntry = FrLdrHeapAlloc(sizeof(BOOT_DRIVER_LIST_ENTRY), TAG_WLDR_BDE);
-    if (!BootDriverEntry)
-        return FALSE;
+        /* Driver Name */
+        RtlInitEmptyUnicodeString(&DriverNode->Name,
+                                  CmpAllocate(DriverNameU.Length, FALSE, TAG_CM),
+                                  DriverNameU.Length);
+        if (!DriverNode->Name.Buffer)
+            goto Failure;
 
-    // DTE will be filled during actual load of the driver
-    BootDriverEntry->LdrEntry = NULL;
+        if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&DriverNode->Name, &DriverNameU)))
+            goto Failure;
+    }
 
-    // Check - if we have a valid ImagePath, if not - we need to build it
-    // like "System32\\Drivers\\blah.sys"
-    if (ImagePath && (ImagePath[0] != 0))
+    /* Check whether we have a valid ImagePath. If not, we need
+     * to build it like "System32\\Drivers\\blah.sys" */
+    if (ImagePath && *ImagePath)
     {
-        // Just copy ImagePath to the corresponding field in the structure
-        PathLength = (USHORT)wcslen(ImagePath) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
+        /* Just copy ImagePath to the corresponding field in the structure */
+        PathLength = (USHORT)(wcslen(ImagePath)) * sizeof(WCHAR);
+        RtlInitEmptyUnicodeString(&FilePath,
+                                  CmpAllocate(PathLength, FALSE, TAG_WLDR_NAME),
+                                  PathLength);
+        if (!FilePath.Buffer)
+            goto Failure;
 
-        BootDriverEntry->FilePath.Length = 0;
-        BootDriverEntry->FilePath.MaximumLength = PathLength;
-        BootDriverEntry->FilePath.Buffer = FrLdrHeapAlloc(PathLength, TAG_WLDR_NAME);
-        if (!BootDriverEntry->FilePath.Buffer)
-        {
-            FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
-            return FALSE;
-        }
-
-        Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ImagePath);
-        if (!NT_SUCCESS(Status))
-        {
-            FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
-            FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
-            return FALSE;
-        }
+        if (!NT_SUCCESS(RtlAppendUnicodeToString(&FilePath, ImagePath)))
+            goto Failure;
     }
     else
     {
-        // we have to construct ImagePath ourselves
-        PathLength = (USHORT)wcslen(ServiceName)*sizeof(WCHAR) + sizeof(L"system32\\drivers\\.sys");
-        BootDriverEntry->FilePath.Length = 0;
-        BootDriverEntry->FilePath.MaximumLength = PathLength;
-        BootDriverEntry->FilePath.Buffer = FrLdrHeapAlloc(PathLength, TAG_WLDR_NAME);
-        if (!BootDriverEntry->FilePath.Buffer)
+        /* We have to construct ImagePath ourselves */
+        PathLength = DriverNode->Name.Length + sizeof(L"system32\\drivers\\.sys");
+        RtlInitEmptyUnicodeString(&FilePath,
+                                  CmpAllocate(PathLength, FALSE, TAG_WLDR_NAME),
+                                  PathLength);
+        if (!FilePath.Buffer)
+            goto Failure;
+
+        if (!NT_SUCCESS(RtlAppendUnicodeToString(&FilePath, L"system32\\drivers\\"))  ||
+            !NT_SUCCESS(RtlAppendUnicodeStringToString(&FilePath, &DriverNode->Name)) ||
+            !NT_SUCCESS(RtlAppendUnicodeToString(&FilePath, L".sys")))
         {
-            FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
-            return FALSE;
+            goto Failure;
         }
+    }
 
-        Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L"system32\\drivers\\");
-        if (!NT_SUCCESS(Status))
-        {
-            FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
-            FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
-            return FALSE;
-        }
+    /* Registry path */
+    RtlInitUnicodeString(&RegistryPath,
+                         L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
+    PathLength = RegistryPath.Length + DriverNode->Name.Length;
+    RtlInitEmptyUnicodeString(&RegistryString,
+                              CmpAllocate(PathLength, FALSE, TAG_WLDR_NAME),
+                              PathLength);
+    if (!RegistryString.Buffer)
+        goto Failure;
 
-        Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, ServiceName);
-        if (!NT_SUCCESS(Status))
-        {
-            FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
-            FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
-            return FALSE;
-        }
+    if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&RegistryString, &RegistryPath)) ||
+        !NT_SUCCESS(RtlAppendUnicodeStringToString(&RegistryString, &DriverNode->Name)))
+    {
+        goto Failure;
+    }
 
-        Status = RtlAppendUnicodeToString(&BootDriverEntry->FilePath, L".sys");
-        if (!NT_SUCCESS(Status))
-        {
-            FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
-            FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
-            return FALSE;
-        }
+    /* Group */
+    if (GroupName && *GroupName)
+    {
+        /*
+         * NOTE: Here we can use our own allocator as we alone maintain the
+         * group string. This is different from the other allocated strings,
+         * where we instead need to use the same (hive) allocator as the
+         * one used by CmpAddDriverToList(), for interoperability purposes.
+         */
+        RtlCreateUnicodeString(&GroupString, GroupName);
+        if (!GroupString.Buffer)
+            goto Failure;
+    }
+    else
+    {
+        RtlInitEmptyUnicodeString(&GroupString, NULL, 0);
     }
 
-    // Add registry path
-    PathLength = (USHORT)(wcslen(RegistryPath) + wcslen(ServiceName))*sizeof(WCHAR) + sizeof(UNICODE_NULL);
-    BootDriverEntry->RegistryPath.Length = 0;
-    BootDriverEntry->RegistryPath.MaximumLength = PathLength;
-    BootDriverEntry->RegistryPath.Buffer = FrLdrHeapAlloc(PathLength, TAG_WLDR_NAME);
-    if (!BootDriverEntry->RegistryPath.Buffer)
+    /* Set or replace the driver node's file path */
+    if (DriverEntry->FilePath.Buffer)
     {
-        FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
-        FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
-        return FALSE;
+        CmpFree(DriverEntry->FilePath.Buffer,
+                DriverEntry->FilePath.MaximumLength);
     }
+    DriverEntry->FilePath = FilePath;
+    FilePath.Buffer = NULL;
 
-    Status = RtlAppendUnicodeToString(&BootDriverEntry->RegistryPath, RegistryPath);
-    if (!NT_SUCCESS(Status))
+    /* Set or replace the driver node's registry path */
+    if (DriverEntry->RegistryPath.Buffer)
     {
-        FrLdrHeapFree(BootDriverEntry->RegistryPath.Buffer, TAG_WLDR_NAME);
-        FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
-        FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
-        return FALSE;
+        CmpFree(DriverEntry->RegistryPath.Buffer,
+                DriverEntry->RegistryPath.MaximumLength);
     }
+    DriverEntry->RegistryPath = RegistryString;
+    RegistryString.Buffer = NULL;
 
-    Status = RtlAppendUnicodeToString(&BootDriverEntry->RegistryPath, ServiceName);
-    if (!NT_SUCCESS(Status))
+    /* Set or replace the driver node's group */
+    if (DriverNode->Group.Buffer)
     {
-        FrLdrHeapFree(BootDriverEntry->RegistryPath.Buffer, TAG_WLDR_NAME);
-        FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
-        FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
-        return FALSE;
+        /*
+         * If the buffer is inside the registry hive's memory, this means that
+         * it has been set by CmpAddDriverToList() to point to some data within
+         * the hive; thus we should not free the buffer but just replace it.
+         * Otherwise, this is a buffer previously allocated by ourselves, that
+         * we can free.
+         *
+         * NOTE: This function does not have an explicit LoaderBlock input
+         * parameter pointer, since it does not need it, except for this
+         * very place. So instead, use the global WinLdrSystemBlock pointer.
+         */
+        PLOADER_PARAMETER_BLOCK LoaderBlock =
+            (WinLdrSystemBlock ? &WinLdrSystemBlock->LoaderBlock : NULL);
+
+        if (!LoaderBlock || !LoaderBlock->RegistryBase || !LoaderBlock->RegistryLength ||
+            ((ULONG_PTR)DriverNode->Group.Buffer <
+                (ULONG_PTR)VaToPa(LoaderBlock->RegistryBase)) ||
+            ((ULONG_PTR)DriverNode->Group.Buffer >=
+                (ULONG_PTR)VaToPa(LoaderBlock->RegistryBase) + LoaderBlock->RegistryLength))
+        {
+            RtlFreeUnicodeString(&DriverNode->Group);
+        }
     }
+    DriverNode->Group = GroupString;
+    GroupString.Buffer = NULL;
+
+    /* ErrorControl and Tag */
+    DriverNode->ErrorControl = ErrorControl;
+    DriverNode->Tag = Tag;
 
-    // Insert entry into the list
-    if (!InsertInBootDriverList(BootDriverListHead, BootDriverEntry))
+    /* Insert the entry into the list if it does not exist there already */
+    if (!AlreadyInserted)
     {
-        // It was already there, so delete our entry
-        FrLdrHeapFree(BootDriverEntry->RegistryPath.Buffer, TAG_WLDR_NAME);
-        FrLdrHeapFree(BootDriverEntry->FilePath.Buffer, TAG_WLDR_NAME);
-        FrLdrHeapFree(BootDriverEntry, TAG_WLDR_BDE);
+        if (InsertAtHead)
+            InsertHeadList(DriverListHead, &DriverEntry->Link);
+        else
+            InsertTailList(DriverListHead, &DriverEntry->Link);
     }
 
     return TRUE;
+
+Failure:
+    if (GroupString.Buffer)
+        RtlFreeUnicodeString(&GroupString);
+    if (RegistryString.Buffer)
+        CmpFree(RegistryString.Buffer, RegistryString.MaximumLength);
+    if (FilePath.Buffer)
+        CmpFree(FilePath.Buffer, FilePath.MaximumLength);
+
+    /* If it does not exist in the list already, free the allocated
+     * driver node, otherwise keep the original one in place. */
+    if (!AlreadyInserted)
+    {
+        if (DriverEntry->RegistryPath.Buffer)
+        {
+            CmpFree(DriverEntry->RegistryPath.Buffer,
+                    DriverEntry->RegistryPath.MaximumLength);
+        }
+        if (DriverEntry->FilePath.Buffer)
+        {
+            CmpFree(DriverEntry->FilePath.Buffer,
+                    DriverEntry->FilePath.MaximumLength);
+        }
+        if (DriverNode->Name.Buffer)
+        {
+            CmpFree(DriverNode->Name.Buffer,
+                    DriverNode->Name.MaximumLength);
+        }
+        CmpFree(DriverNode, sizeof(BOOT_DRIVER_NODE));
+    }
+
+    return FALSE;
 }