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/hkc…
==============================================================================
--- 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);
+