https://git.reactos.org/?p=reactos.git;a=commitdiff;h=413b5a0827af51e102f99…
commit 413b5a0827af51e102f99f3b2cb59867cdbacb6b
Author: Whindmar Saksit <whindsaks(a)proton.me>
AuthorDate: Mon Nov 13 18:02:41 2023 +0100
Commit: GitHub <noreply(a)github.com>
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);