[FREELDR]
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Sun, 9 Feb 2014 18:05:00 +0000 (18:05 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Sun, 9 Feb 2014 18:05:00 +0000 (18:05 +0000)
Improve performance of registry enumeration by returning the enumerated subkey in RegEnumKey, instead of searching it by name again.

svn path=/trunk/; revision=62079

reactos/boot/freeldr/freeldr/include/registry.h
reactos/boot/freeldr/freeldr/reactos/registry.c
reactos/boot/freeldr/freeldr/windows/wlregistry.c

index da2ef1d..4bc7eee 100644 (file)
@@ -78,10 +78,12 @@ RegDeleteKey(FRLDRHKEY Key,
          PCWSTR Name);
 
 LONG
-RegEnumKey(FRLDRHKEY Key,
-       ULONG Index,
-       PWCHAR Name,
-       ULONG* NameSize);
+RegEnumKey(
+    _In_ FRLDRHKEY Key,
+    _In_ ULONG Index,
+    _Out_ PWCHAR Name,
+    _Inout_ ULONG* NameSize,
+    _Out_opt_ FRLDRHKEY *SubKey);
 
 LONG
 RegOpenKey(FRLDRHKEY ParentKey,
index 8126a5c..d88688a 100644 (file)
@@ -259,13 +259,13 @@ RegpFindSubkeyInIndex(
     return NULL;
 }
 
-// FIXME: optionally return the subkey node/handle as optimization
 LONG
 RegEnumKey(
     _In_ FRLDRHKEY Key,
     _In_ ULONG Index,
     _Out_ PWCHAR Name,
-    _Inout_ ULONG* NameSize)
+    _Inout_ ULONG* NameSize,
+    _Out_opt_ FRLDRHKEY *SubKey)
 {
     PHHIVE Hive = &CmHive->Hive;
     PCM_KEY_NODE KeyNode, SubKeyNode;
@@ -305,6 +305,11 @@ RegEnumKey(
 
     *NameSize = CmCopyKeyName(SubKeyNode, Name, *NameSize);
 
+    if (SubKey != NULL)
+    {
+        *SubKey = (FRLDRHKEY)SubKeyNode;
+    }
+
     TRACE("RegEnumKey done -> %u, '%.*s'\n", *NameSize, *NameSize, Name);
     return STATUS_SUCCESS;
 }
index c9b3528..1ccbb01 100644 (file)
@@ -537,7 +537,7 @@ WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead,
             {
                 /* Get the Driver's Name */
                 ValueSize = sizeof(ServiceName);
-                rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);
+                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 */
@@ -550,89 +550,6 @@ WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead,
                 }
                 //TRACE_CH(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;
-                    //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 suceeded, else prepare to fail */
-                            if (rc != ERROR_SUCCESS) {
-                                TRACE_CH(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);
-                                TRACE_CH(REACTOS, "ImagePath: '%s'\n", ImagePath);
-                            }
-
-                            TRACE("Adding boot driver: '%s'\n", ImagePath);
-
-                            Status = WinLdrAddDriverToList(BootDriverListHead,
-                                L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
-                                TempImagePath,
-                                ServiceName);
-
-                            if (!Status)
-                                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);
-                    }
-                }
-
-                Index++;
-            }
-        }
-
-        Index = 0;
-        while (TRUE)
-        {
-            /* Get the Driver's Name */
-            ValueSize = sizeof(ServiceName);
-            rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);
-
-            //TRACE_CH(REACTOS, "RegEnumKey(): rc %d\n", (int)rc);
-            if (rc == ERROR_NO_MORE_ITEMS)
-                break;
-            if (rc != ERROR_SUCCESS)
-            {
-                FrLdrHeapFree(GroupNameBuffer, TAG_WLDR_NAME);
-                return;
-            }
-            TRACE("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);
@@ -650,27 +567,28 @@ WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead,
                 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;
-                }
-
+                /* Make sure it should be started */
                 if ((StartValue == 0) &&
-                    (TagIndex > OrderList[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) {
                             TRACE_CH(REACTOS, "ImagePath: not found\n");
                             TempImagePath[0] = 0;
-                            sprintf(ImagePath, "%ssystem32\\drivers\\%S.sys", DirectoryPath, ServiceName);
+                            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);
                             TRACE_CH(REACTOS, "ImagePath: '%s'\n", ImagePath);
                         }
-                        TRACE("  Adding boot driver: '%s'\n", ImagePath);
+
+                        TRACE("Adding boot driver: '%s'\n", ImagePath);
 
                         Status = WinLdrAddDriverToList(BootDriverListHead,
                             L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
@@ -678,12 +596,86 @@ WinLdrScanRegistry(IN OUT PLIST_ENTRY BootDriverListHead,
                             ServiceName);
 
                         if (!Status)
-                            ERR(" Failed to add boot driver\n");
-                } else
+                            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);
+                    //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);
                 }
+
+                Index++;
+            }
+        }
+
+        Index = 0;
+        while (TRUE)
+        {
+            /* 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)
+            {
+                FrLdrHeapFree(GroupNameBuffer, TAG_WLDR_NAME);
+                return;
+            }
+            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;
+                        sprintf(ImagePath, "%ssystem32\\drivers\\%S.sys", DirectoryPath, ServiceName);
+                    } else if (TempImagePath[0] != L'\\') {
+                        sprintf(ImagePath, "%s%S", DirectoryPath, TempImagePath);
+                    } else {
+                        sprintf(ImagePath, "%S", TempImagePath);
+                        TRACE_CH(REACTOS, "ImagePath: '%s'\n", ImagePath);
+                    }
+                    TRACE("  Adding boot driver: '%s'\n", ImagePath);
+
+                    Status = WinLdrAddDriverToList(BootDriverListHead,
+                        L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
+                        TempImagePath,
+                        ServiceName);
+
+                    if (!Status)
+                        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);
             }
 
             Index++;