[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.
This commit is contained in:
Whindmar Saksit 2023-11-13 18:02:41 +01:00 committed by GitHub
parent 6eb8a1d0c7
commit 413b5a0827
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 90 additions and 0 deletions

View file

@ -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;
}

View file

@ -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)

View file

@ -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);