Author: jgardou Date: Fri Oct 3 22:18:49 2014 New Revision: 64515
URL: http://svn.reactos.org/svn/reactos?rev=64515&view=rev Log: [ADVAPI32] - Add parameter checks to RegEnumValueW/A - Implement RegEnumValueW for HKCR subkeys CORE-8582
Modified: trunk/reactos/dll/win32/advapi32/reg/hkcr.c trunk/reactos/dll/win32/advapi32/reg/reg.c trunk/reactos/dll/win32/advapi32/reg/reg.h
Modified: trunk/reactos/dll/win32/advapi32/reg/hkcr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/reg/hkcr... ============================================================================== --- trunk/reactos/dll/win32/advapi32/reg/hkcr.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/advapi32/reg/hkcr.c [iso-8859-1] Fri Oct 3 22:18:49 2014 @@ -799,3 +799,216 @@
return ErrorCode; } + +/* HKCR version of RegEnumValueW */ +LONG +WINAPI +EnumHKCRValue( + _In_ HKEY hKey, + _In_ DWORD dwIndex, + _Out_ LPWSTR lpName, + _Inout_ PDWORD lpcbName, + _Reserved_ PDWORD lpReserved, + _Out_opt_ PDWORD lpdwType, + _Out_opt_ LPBYTE lpData, + _Inout_opt_ PDWORD lpcbData) +{ + HKEY PreferredKey, FallbackKey; + DWORD NumPreferredValues; + DWORD MaxFallbackValueNameLen; + DWORD FallbackIndex; + WCHAR* FallbackValueName = NULL; + LONG ErrorCode; + + ASSERT(IsHKCRKey(hKey)); + + /* Remove the HKCR flag while we're working */ + hKey = (HKEY)(((ULONG_PTR)hKey) & ~0x2); + + /* Get the preferred key */ + ErrorCode = GetPreferredHKCRKey(hKey, &PreferredKey); + if (ErrorCode != ERROR_SUCCESS) + { + if (ErrorCode == ERROR_FILE_NOT_FOUND) + { + /* Only the HKLM key exists */ + return RegEnumValueW( + hKey, + dwIndex, + lpName, + lpcbName, + lpReserved, + lpdwType, + lpData, + lpcbData); + } + return ErrorCode; + } + + /* Get the fallback key */ + ErrorCode = GetFallbackHKCRKey(hKey, &FallbackKey, FALSE); + if (ErrorCode != ERROR_SUCCESS) + { + if (PreferredKey != hKey) + RegCloseKey(PreferredKey); + if (ErrorCode == ERROR_FILE_NOT_FOUND) + { + /* Only the HKCU key exists */ + return RegEnumValueW( + hKey, + dwIndex, + lpName, + lpcbName, + lpReserved, + lpdwType, + lpData, + lpcbData); + } + return ErrorCode; + } + + /* Get some info on the HKCU side */ + ErrorCode = RegQueryInfoKeyW( + PreferredKey, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &NumPreferredValues, + NULL, + NULL, + NULL, + NULL); + if (ErrorCode != ERROR_SUCCESS) + goto Exit; + + if (dwIndex < NumPreferredValues) + { + /* HKCU side takes precedence */ + return RegEnumValueW( + PreferredKey, + dwIndex, + lpName, + lpcbName, + lpReserved, + lpdwType, + lpData, + lpcbData); + goto Exit; + } + + /* Here it gets tricky. We must enumerate the values from the HKLM side, + * without reporting those which are present on the HKCU side */ + + /* Squash out the indices from HKCU */ + dwIndex -= NumPreferredValues; + + /* Get some info */ + ErrorCode = RegQueryInfoKeyW( + FallbackKey, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &MaxFallbackValueNameLen, + NULL, + NULL, + NULL); + if (ErrorCode != ERROR_SUCCESS) + { + ERR("Could not query info of key %p (Err: %d)\n", FallbackKey, ErrorCode); + goto Exit; + } + + ERR("Maxfallbacksubkeylen: %d\n", MaxFallbackValueNameLen); + + /* Allocate our buffer */ + FallbackValueName = RtlAllocateHeap( + RtlGetProcessHeap(), 0, (MaxFallbackValueNameLen + 1) * sizeof(WCHAR)); + if (!FallbackValueName) + { + ErrorCode = ERROR_NOT_ENOUGH_MEMORY; + goto Exit; + } + + /* We must begin at the very first subkey of the fallback key, + * and then see if we meet keys that already are in the preferred key. + * In that case, we must bump dwIndex, as otherwise we would enumerate a key we already + * saw in a previous call. + */ + FallbackIndex = 0; + while (TRUE) + { + DWORD FallbackValueNameLen = MaxFallbackValueNameLen; + + /* Try enumerating */ + ErrorCode = RegEnumValueW( + FallbackKey, + FallbackIndex, + FallbackValueName, + &FallbackValueNameLen, + NULL, + NULL, + NULL, + NULL); + if (ErrorCode != ERROR_SUCCESS) + { + /* Most likely ERROR_NO_MORE_ITEMS */ + ERR("Returning %d.\n", ErrorCode); + goto Exit; + } + FallbackValueName[FallbackValueNameLen] = L'\0'; + + /* See if there is such a value on HKCU side */ + ErrorCode = RegQueryValueExW( + PreferredKey, + FallbackValueName, + NULL, + NULL, + NULL, + NULL); + + if (ErrorCode == ERROR_SUCCESS) + { + /* So we already enumerated it on HKCU side. */ + dwIndex++; + } + else if (ErrorCode != ERROR_FILE_NOT_FOUND) + { + ERR("Got error %d while querying for %s on HKCU side.\n", ErrorCode, FallbackValueName); + goto Exit; + } + + /* See if we caught up */ + if (FallbackIndex == dwIndex) + break; + + FallbackIndex++; + } + + /* We can finally enumerate on the fallback side */ + ErrorCode = RegEnumValueW( + FallbackKey, + dwIndex, + lpName, + lpcbName, + lpReserved, + lpdwType, + lpData, + lpcbData); + +Exit: + if (PreferredKey != hKey) + RegCloseKey(PreferredKey); + if (FallbackKey != hKey) + RegCloseKey(FallbackKey); + if (FallbackValueName) + RtlFreeHeap(RtlGetProcessHeap(), 0, FallbackValueName); + + return ErrorCode; +}
Modified: trunk/reactos/dll/win32/advapi32/reg/reg.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/reg/reg.... ============================================================================== --- trunk/reactos/dll/win32/advapi32/reg/reg.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/advapi32/reg/reg.c [iso-8859-1] Fri Oct 3 22:18:49 2014 @@ -2705,7 +2705,7 @@ _Reserved_ LPDWORD lpdwReserved, _Out_opt_ LPDWORD lpdwType, _Out_opt_ LPBYTE lpData, - _Out_opt_ LPDWORD lpcbData) + _Inout_opt_ LPDWORD lpcbData) { WCHAR* NameBuffer; DWORD NameBufferSize, NameLength; @@ -2714,6 +2714,9 @@ BOOL NameOverflow = FALSE;
/* Do parameter checks now, once and for all. */ + if (!lpName || !lpcbName) + return ERROR_INVALID_PARAMETER; + if ((lpData && !lpcbData) || lpdwReserved) return ERROR_INVALID_PARAMETER;
@@ -2851,15 +2854,17 @@ * Success: ERROR_SUCCESS * Failure: nonzero error code from Winerror.h */ -LONG WINAPI -RegEnumValueW(HKEY hKey, - DWORD index, - LPWSTR value, - PDWORD val_count, - PDWORD reserved, - PDWORD type, - LPBYTE data, - PDWORD count) +LONG +WINAPI +RegEnumValueW( + _In_ HKEY hKey, + _In_ DWORD index, + _Out_ LPWSTR value, + _Inout_ PDWORD val_count, + _Reserved_ PDWORD reserved, + _Out_opt_ PDWORD type, + _Out_opt_ LPBYTE data, + _Inout_opt_ PDWORD count) { HANDLE KeyHandle; NTSTATUS status; @@ -2868,16 +2873,34 @@ KEY_VALUE_FULL_INFORMATION *info = (KEY_VALUE_FULL_INFORMATION *)buffer; static const int info_size = FIELD_OFFSET( KEY_VALUE_FULL_INFORMATION, Name );
- //TRACE("(%p,%ld,%p,%p,%p,%p,%p,%p)\n", - // hkey, index, value, val_count, reserved, type, data, count ); - - /* NT only checks count, not val_count */ - if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER; + TRACE("(%p,%ld,%p,%p,%p,%p,%p,%p)\n", + hKey, index, value, val_count, reserved, type, data, count ); + + if (!value || !val_count) + return ERROR_INVALID_PARAMETER; + + if ((data && !count) || reserved) + return ERROR_INVALID_PARAMETER;
status = MapDefaultKey(&KeyHandle, hKey); if (!NT_SUCCESS(status)) { return RtlNtStatusToDosError(status); + } + + if (IsHKCRKey(KeyHandle)) + { + LONG ErrorCode = EnumHKCRValue( + KeyHandle, + index, + value, + val_count, + reserved, + type, + data, + count); + ClosePredefKey(KeyHandle); + return ErrorCode; }
total_size = info_size + (MAX_PATH + 1) * sizeof(WCHAR);
Modified: trunk/reactos/dll/win32/advapi32/reg/reg.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/advapi32/reg/reg.... ============================================================================== --- trunk/reactos/dll/win32/advapi32/reg/reg.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/advapi32/reg/reg.h [iso-8859-1] Fri Oct 3 22:18:49 2014 @@ -84,3 +84,15 @@ _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime);
+LONG +WINAPI +EnumHKCRValue( + _In_ HKEY hKey, + _In_ DWORD index, + _Out_ LPWSTR value, + _Inout_ PDWORD val_count, + _Reserved_ PDWORD reserved, + _Out_opt_ PDWORD type, + _Out_opt_ LPBYTE data, + _Inout_opt_ PDWORD count); +