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.c?rev=64515&r1=64514&r2=64515&view=diff
==============================================================================
--- 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.c?rev=64515&r1=64514&r2=64515&view=diff
==============================================================================
--- 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.h?rev=64515&r1=64514&r2=64515&view=diff
==============================================================================
--- 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);
+


Reply via email to