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