https://git.reactos.org/?p=reactos.git;a=commitdiff;h=413b5a0827af51e102f99f3b2cb59867cdbacb6b

commit 413b5a0827af51e102f99f3b2cb59867cdbacb6b
Author:     Whindmar Saksit <[email protected]>
AuthorDate: Mon Nov 13 18:02:41 2023 +0100
Commit:     GitHub <[email protected]>
CommitDate: Mon Nov 13 18:02:41 2023 +0100

    [ADVAPI32] Handle HKEY_CLASSES_ROOT in RegQueryInfoKeyW (#5870)
    
    CORE-8582 , CORE-14676
    
    This fixes the bug where Regedit is unable to show all the keys in HKCR 
when a key exists in both HKCU and HKLM.
---
 dll/win32/advapi32/reg/hkcr.c | 65 +++++++++++++++++++++++++++++++++++++++++++
 dll/win32/advapi32/reg/reg.c  | 10 +++++++
 dll/win32/advapi32/reg/reg.h  | 15 ++++++++++
 3 files changed, 90 insertions(+)

diff --git a/dll/win32/advapi32/reg/hkcr.c b/dll/win32/advapi32/reg/hkcr.c
index f55a783eb5d..21921ebb42b 100644
--- a/dll/win32/advapi32/reg/hkcr.c
+++ b/dll/win32/advapi32/reg/hkcr.c
@@ -1014,3 +1014,68 @@ Exit:
 
     return ErrorCode;
 }
+
+/* HKCR version of RegQueryInfoKeyW */
+LONG
+WINAPI
+QueryInfoHKCRKey(
+    _In_ HKEY hKey,
+    _Out_writes_to_opt_(*lpcchClass, *lpcchClass + 1) LPWSTR lpClass,
+    _Inout_opt_ LPDWORD lpcchClass,
+    _Reserved_ LPDWORD lpReserved,
+    _Out_opt_ LPDWORD lpcSubKeys,
+    _Out_opt_ LPDWORD lpcbMaxSubKeyLen,
+    _Out_opt_ LPDWORD lpcbMaxClassLen,
+    _Out_opt_ LPDWORD lpcValues,
+    _Out_opt_ LPDWORD lpcbMaxValueNameLen,
+    _Out_opt_ LPDWORD lpcbMaxValueLen,
+    _Out_opt_ LPDWORD lpcbSecurityDescriptor,
+    _Out_opt_ PFILETIME lpftLastWriteTime)
+{
+    HKEY PreferredKey, FallbackKey;
+    LONG retval, err;
+    DWORD OtherSubKeys = 0, OtherMaxSub = 0, OtherMaxClass = 0;
+    DWORD OtherValues = 0, OtherMaxName = 0, OtherMaxVal = 0;
+
+    ASSERT(IsHKCRKey(hKey));
+
+    /* Remove the HKCR flag while we're working */
+    hKey = (HKEY)(((ULONG_PTR)hKey) & ~0x2);
+
+    retval = GetFallbackHKCRKey(hKey, &FallbackKey, FALSE);
+    if (retval == ERROR_SUCCESS)
+    {
+        retval = RegQueryInfoKeyW(FallbackKey, lpClass, lpcchClass, lpReserved,
+                                  &OtherSubKeys, &OtherMaxSub, &OtherMaxClass,
+                                  &OtherValues, &OtherMaxName, &OtherMaxVal,
+                                  lpcbSecurityDescriptor, lpftLastWriteTime);
+        if (FallbackKey != hKey)
+            RegCloseKey(FallbackKey);
+    }
+
+    err = GetPreferredHKCRKey(hKey, &PreferredKey);
+    if (err == ERROR_SUCCESS)
+    {
+        err = RegQueryInfoKeyW(PreferredKey, lpClass, lpcchClass, lpReserved,
+                               lpcSubKeys, lpcbMaxSubKeyLen, lpcbMaxClassLen,
+                               lpcValues, lpcbMaxValueNameLen, lpcbMaxValueLen,
+                               lpcbSecurityDescriptor, lpftLastWriteTime);
+        if (PreferredKey != hKey)
+            RegCloseKey(PreferredKey);
+    }
+
+    if (lpcSubKeys)
+        *lpcSubKeys = (err ? 0 : *lpcSubKeys) + OtherSubKeys;
+    if (lpcValues)
+        *lpcValues = (err ? 0 : *lpcValues) + OtherValues;
+    if (lpcbMaxSubKeyLen)
+        *lpcbMaxSubKeyLen = max((err ? 0 : *lpcbMaxSubKeyLen), OtherMaxSub);
+    if (lpcbMaxClassLen)
+        *lpcbMaxClassLen = max((err ? 0 : *lpcbMaxClassLen), OtherMaxClass);
+    if (lpcbMaxValueNameLen)
+        *lpcbMaxValueNameLen = max((err ? 0 : *lpcbMaxValueNameLen), 
OtherMaxName);
+    if (lpcbMaxValueLen)
+        *lpcbMaxValueLen = max((err ? 0 : *lpcbMaxValueLen), OtherMaxVal);
+
+    return (err == ERROR_SUCCESS) ? ERROR_SUCCESS : retval;
+}
diff --git a/dll/win32/advapi32/reg/reg.c b/dll/win32/advapi32/reg/reg.c
index 58515793c4e..1ded4b54222 100644
--- a/dll/win32/advapi32/reg/reg.c
+++ b/dll/win32/advapi32/reg/reg.c
@@ -3718,6 +3718,16 @@ RegQueryInfoKeyW(HKEY hKey,
         return RtlNtStatusToDosError(Status);
     }
 
+    if (IsHKCRKey(KeyHandle))
+    {
+        ErrorCode = QueryInfoHKCRKey(KeyHandle, lpClass, lpcClass, lpReserved,
+                                     lpcSubKeys, lpcMaxSubKeyLen, 
lpcMaxClassLen,
+                                     lpcValues, lpcMaxValueNameLen, 
lpcMaxValueLen,
+                                     lpcbSecurityDescriptor, 
lpftLastWriteTime);
+        ClosePredefKey(KeyHandle);
+        return ErrorCode;
+    }
+
     if (lpClass != NULL)
     {
         if (*lpcClass > 0)
diff --git a/dll/win32/advapi32/reg/reg.h b/dll/win32/advapi32/reg/reg.h
index 2c5c128d38c..469f2b6fbcd 100644
--- a/dll/win32/advapi32/reg/reg.h
+++ b/dll/win32/advapi32/reg/reg.h
@@ -96,3 +96,18 @@ EnumHKCRValue(
     _Out_opt_ LPBYTE data,
     _Inout_opt_ PDWORD count);
 
+LONG
+WINAPI
+QueryInfoHKCRKey(
+    _In_ HKEY hKey,
+    _Out_writes_to_opt_(*lpcchClass, *lpcchClass + 1) LPWSTR lpClass,
+    _Inout_opt_ LPDWORD lpcchClass,
+    _Reserved_ LPDWORD lpReserved,
+    _Out_opt_ LPDWORD lpcSubKeys,
+    _Out_opt_ LPDWORD lpcbMaxSubKeyLen,
+    _Out_opt_ LPDWORD lpcbMaxClassLen,
+    _Out_opt_ LPDWORD lpcValues,
+    _Out_opt_ LPDWORD lpcbMaxValueNameLen,
+    _Out_opt_ LPDWORD lpcbMaxValueLen,
+    _Out_opt_ LPDWORD lpcbSecurityDescriptor,
+    _Out_opt_ PFILETIME lpftLastWriteTime);

Reply via email to