From 5a930877dd7547493e592af288bd385f087fd147 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 9 Feb 2014 18:05:00 +0000 Subject: [PATCH] [FREELDR] Improve performance of registry enumeration by returning the enumerated subkey in RegEnumKey, instead of searching it by name again. svn path=/trunk/; revision=62079 --- .../boot/freeldr/freeldr/include/registry.h | 10 +- .../boot/freeldr/freeldr/reactos/registry.c | 9 +- .../boot/freeldr/freeldr/windows/wlregistry.c | 184 +++++++++--------- 3 files changed, 101 insertions(+), 102 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/include/registry.h b/reactos/boot/freeldr/freeldr/include/registry.h index da2ef1d9f89..4bc7eee7cf2 100644 --- a/reactos/boot/freeldr/freeldr/include/registry.h +++ b/reactos/boot/freeldr/freeldr/include/registry.h @@ -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, diff --git a/reactos/boot/freeldr/freeldr/reactos/registry.c b/reactos/boot/freeldr/freeldr/reactos/registry.c index 8126a5c00b6..d88688a92b6 100644 --- a/reactos/boot/freeldr/freeldr/reactos/registry.c +++ b/reactos/boot/freeldr/freeldr/reactos/registry.c @@ -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; } diff --git a/reactos/boot/freeldr/freeldr/windows/wlregistry.c b/reactos/boot/freeldr/freeldr/windows/wlregistry.c index c9b35283da5..1ccbb013607 100644 --- a/reactos/boot/freeldr/freeldr/windows/wlregistry.c +++ b/reactos/boot/freeldr/freeldr/windows/wlregistry.c @@ -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 - { - //TRACE(" Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n", - // ServiceName, StartValue, TagValue, DriverGroup, GroupName); + 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, &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++;