[ros-diffs] [cwittich] 41093: sync RegQueryValueExA, RegQueryValueA, RegQueryValueW and RegSetValueExA to wine patch by Giannis Adamopoulos <johnyadams at hotmail dot com> See issue #4528 for more details.

cwittich at svn.reactos.org cwittich at svn.reactos.org
Sun May 24 10:45:06 CEST 2009


Author: cwittich
Date: Sun May 24 12:45:05 2009
New Revision: 41093

URL: http://svn.reactos.org/svn/reactos?rev=41093&view=rev
Log:
sync RegQueryValueExA, RegQueryValueA, RegQueryValueW and RegSetValueExA to wine
patch by Giannis Adamopoulos <johnyadams at hotmail dot com>
See issue #4528 for more details.

Modified:
    trunk/reactos/dll/win32/advapi32/reg/reg.c

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=41093&r1=41092&r2=41093&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] Sun May 24 12:45:05 2009
@@ -3964,110 +3964,96 @@
  *
  * @implemented
  */
-LONG WINAPI
-RegQueryValueExA(HKEY hKey,
-                 LPCSTR lpValueName,
-                 LPDWORD lpReserved,
-                 LPDWORD lpType,
-                 LPBYTE  lpData,
-                 LPDWORD lpcbData)
-{
-    UNICODE_STRING ValueName;
-    UNICODE_STRING ValueData;
-    ANSI_STRING AnsiString;
-    LONG ErrorCode;
-    DWORD Length;
-    DWORD Type;
-
-    TRACE("hKey 0x%X  lpValueName %s  lpData 0x%X  lpcbData %d\n",
-          hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0);
-
-    if (lpData != NULL && lpcbData == NULL)
-    {
-        return ERROR_INVALID_PARAMETER;
-    }
-
-    if (lpData)
-    {
-        ValueData.Length = 0;
-        ValueData.MaximumLength = (*lpcbData + 1) * sizeof(WCHAR);
-        ValueData.Buffer = RtlAllocateHeap(ProcessHeap,
-                                           0,
-                                           ValueData.MaximumLength);
-        if (!ValueData.Buffer)
-        {
-            return ERROR_OUTOFMEMORY;
-        }
-    }
-    else
-    {
-        ValueData.Buffer = NULL;
-        ValueData.Length = 0;
-        ValueData.MaximumLength = 0;
-
-        if (lpcbData)
-            *lpcbData = 0;
-    }
-
-    RtlCreateUnicodeStringFromAsciiz(&ValueName,
-                                     (LPSTR)lpValueName);
-
-    Length = (lpcbData == NULL) ? 0 : *lpcbData * sizeof(WCHAR);
-    ErrorCode = RegQueryValueExW(hKey,
-                                 ValueName.Buffer,
-                                 lpReserved,
-                                 &Type,
-                                 (lpData == NULL) ? NULL : (LPBYTE)ValueData.Buffer,
-                                 &Length);
-    TRACE("ErrorCode %lu\n", ErrorCode);
-    RtlFreeUnicodeString(&ValueName);
-
-    if (ErrorCode == ERROR_SUCCESS ||
-        ErrorCode == ERROR_MORE_DATA)
-    {
-        if (lpType != NULL)
-        {
-            *lpType = Type;
-        }
-
-        if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ))
-        {
-            if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL)
+LSTATUS WINAPI RegQueryValueExA( HKEY hkey, LPCSTR name, LPDWORD reserved, LPDWORD type,
+                              LPBYTE data, LPDWORD count )
+{
+    NTSTATUS status;
+    ANSI_STRING nameA;
+    DWORD total_size, datalen = 0;
+    char buffer[256], *buf_ptr = buffer;
+    KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer;
+    static const int info_size = offsetof( KEY_VALUE_PARTIAL_INFORMATION, Data );
+
+    TRACE("(%p,%s,%p,%p,%p,%p=%d)\n",
+          hkey, debugstr_a(name), reserved, type, data, count, count ? *count : 0 );
+
+    if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;
+
+    status = MapDefaultKey( (PHANDLE)&hkey, hkey);
+    if (!NT_SUCCESS(status))
+    {
+        return RtlNtStatusToDosError(status);
+    }
+
+    if (count) datalen = *count;
+    if (!data && count) *count = 0;
+
+    /* this matches Win9x behaviour - NT sets *type to a random value */
+    if (type) *type = REG_NONE;
+
+    RtlInitAnsiString( &nameA, name );
+    if ((status = RtlAnsiStringToUnicodeString( &NtCurrentTeb()->StaticUnicodeString,
+                                                &nameA, FALSE )))
+        return RtlNtStatusToDosError(status);
+
+    status = NtQueryValueKey( hkey, &NtCurrentTeb()->StaticUnicodeString,
+                              KeyValuePartialInformation, buffer, sizeof(buffer), &total_size );
+    if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
+
+    /* we need to fetch the contents for a string type even if not requested,
+     * because we need to compute the length of the ASCII string. */
+    if (data || is_string(info->Type))
+    {
+        /* retry with a dynamically allocated buffer */
+        while (status == STATUS_BUFFER_OVERFLOW)
+        {
+            if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+            if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size )))
             {
-                RtlInitAnsiString(&AnsiString, NULL);
-                AnsiString.Buffer = (LPSTR)lpData;
-                AnsiString.MaximumLength = *lpcbData;
-                ValueData.Length = Length;
-                ValueData.MaximumLength = ValueData.Length + sizeof(WCHAR);
-                RtlUnicodeStringToAnsiString(&AnsiString, &ValueData, FALSE);
+                status = STATUS_NO_MEMORY;
+                goto done;
             }
-
-            Length = Length / sizeof(WCHAR);
-        }
-        else if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL)
-        {
-            if (*lpcbData < Length)
+            info = (KEY_VALUE_PARTIAL_INFORMATION *)buf_ptr;
+            status = NtQueryValueKey( hkey, &NtCurrentTeb()->StaticUnicodeString,
+                                    KeyValuePartialInformation, buf_ptr, total_size, &total_size );
+        }
+
+        if (status) goto done;
+
+        if (is_string(info->Type))
+        {
+            DWORD len;
+
+            RtlUnicodeToMultiByteSize( &len, (WCHAR *)(buf_ptr + info_size),
+                                       total_size - info_size );
+            if (data && len)
             {
-                ErrorCode = ERROR_MORE_DATA;
+                if (len > datalen) status = STATUS_BUFFER_OVERFLOW;
+                else
+                {
+                    RtlUnicodeToMultiByteN( (char*)data, len, NULL, (WCHAR *)(buf_ptr + info_size),
+                                            total_size - info_size );
+                    /* if the type is REG_SZ and data is not 0-terminated
+                     * and there is enough space in the buffer NT appends a \0 */
+                    if (len < datalen && data[len-1]) data[len] = 0;
+                }
             }
-            else
-            {
-                RtlMoveMemory(lpData, ValueData.Buffer, Length);
-            }
-        }
-
-        if (lpcbData != NULL)
-        {
-            *lpcbData = Length;
-        }
-    }
-
-    if (ValueData.Buffer != NULL)
-    {
-        RtlFreeHeap(ProcessHeap, 0, ValueData.Buffer);
-    }
-
-    return ErrorCode;
+            total_size = len + info_size;
+        }
+        else if (data)
+        {
+            if (total_size - info_size > datalen) status = STATUS_BUFFER_OVERFLOW;
+            else memcpy( data, buf_ptr + info_size, total_size - info_size );
+        }
+    }
+    else status = STATUS_SUCCESS;
+
+    if (type) *type = info->Type;
+    if (count) *count = total_size - info_size;
+
+ done:
+    if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+    return RtlNtStatusToDosError(status);
 }
 
 
@@ -4098,7 +4084,6 @@
           (count && data) ? *count : 0 );
 
     if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;
-    //if (!(hkey = get_special_root_hkey( hkey ))) return ERROR_INVALID_HANDLE;
 
     status = MapDefaultKey(&hkey, hkeyorg);
     if (!NT_SUCCESS(status))
@@ -4162,93 +4147,27 @@
  *
  * @implemented
  */
-LONG WINAPI
-RegQueryValueA(HKEY hKey,
-               LPCSTR lpSubKey,
-               LPSTR lpValue,
-               PLONG lpcbValue)
-{
-    WCHAR SubKeyNameBuffer[MAX_PATH+1];
-    UNICODE_STRING SubKeyName;
-    UNICODE_STRING Value;
-    ANSI_STRING AnsiString;
-    LONG ValueSize;
-    LONG ErrorCode;
-
-    TRACE("hKey 0x%X lpSubKey %s lpValue %p lpcbValue %d\n",
-          hKey, lpSubKey, lpValue, lpcbValue ? *lpcbValue : 0);
-
-    if (lpValue != NULL &&
-        lpcbValue == NULL)
-    {
-        return ERROR_INVALID_PARAMETER;
-    }
-
-    RtlInitUnicodeString(&SubKeyName,
-                         NULL);
-    RtlInitUnicodeString(&Value,
-                         NULL);
-    if (lpSubKey != NULL &&
-        strlen(lpSubKey) != 0)
-    {
-        RtlInitAnsiString(&AnsiString,
-                          (LPSTR)lpSubKey);
-      SubKeyName.Buffer = &SubKeyNameBuffer[0];
-      SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer);
-      RtlAnsiStringToUnicodeString(&SubKeyName,
-                                   &AnsiString,
-                                   FALSE);
-    }
-
-    if (lpValue != NULL)
-    {
-        ValueSize = *lpcbValue * sizeof(WCHAR);
-        Value.MaximumLength = ValueSize;
-        Value.Buffer = RtlAllocateHeap(ProcessHeap,
-                                       0,
-                                       ValueSize);
-        if (Value.Buffer == NULL)
-        {
-            return ERROR_OUTOFMEMORY;
-        }
-    }
-    else
-    {
-        ValueSize = 0;
-    }
-
-    ErrorCode = RegQueryValueW(hKey,
-                               (LPCWSTR)SubKeyName.Buffer,
-                               Value.Buffer,
-                               &ValueSize);
-    if (ErrorCode == ERROR_SUCCESS)
-    {
-        if (lpValue != NULL)
-        {
-            Value.Length = ValueSize;
-            RtlInitAnsiString(&AnsiString,
-                              NULL);
-            AnsiString.Buffer = lpValue;
-            AnsiString.MaximumLength = *lpcbValue;
-            RtlUnicodeStringToAnsiString(&AnsiString,
-                                         &Value,
-                                         FALSE);
-            *lpcbValue = ValueSize;
-        }
-        else if (lpcbValue != NULL)
-        {
-            *lpcbValue = ValueSize;
-        }
-    }
-
-    if (Value.Buffer != NULL)
-    {
-        RtlFreeHeap(ProcessHeap,
-                    0,
-                    Value.Buffer);
-    }
-
-    return ErrorCode;
+LSTATUS WINAPI RegQueryValueA( HKEY hkey, LPCSTR name, LPSTR data, LPLONG count )
+{
+    DWORD ret;
+    HKEY subkey = hkey;
+
+    TRACE("(%p,%s,%p,%d)\n", hkey, debugstr_a(name), data, count ? *count : 0 );
+
+    if (name && name[0])
+    {
+    if ((ret = RegOpenKeyA( hkey, name, &subkey )) != ERROR_SUCCESS) return ret;
+    }
+    ret = RegQueryValueExA( subkey, NULL, NULL, NULL, (LPBYTE)data, (LPDWORD)count );
+    if (subkey != hkey) RegCloseKey( subkey );
+    if (ret == ERROR_FILE_NOT_FOUND)
+    {
+    /* return empty string if default value not found */
+    if (data) *data = 0;
+    if (count) *count = 1;
+    ret = ERROR_SUCCESS;
+    }
+    return ret;
 }
 
 
@@ -4257,75 +4176,42 @@
  *
  * @implemented
  */
-LONG WINAPI
-RegQueryValueW(HKEY hKey,
-               LPCWSTR lpSubKey,
-               LPWSTR lpValue,
-               PLONG lpcbValue)
-{
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    UNICODE_STRING SubKeyString;
-    HANDLE KeyHandle;
-    HANDLE RealKey;
-    LONG ErrorCode;
-    BOOL CloseRealKey;
-    NTSTATUS Status;
-
-    TRACE("hKey 0x%X lpSubKey %S lpValue %p lpcbValue %d\n",
-          hKey, lpSubKey, lpValue, lpcbValue ? *lpcbValue : 0);
-    if (hKey == NULL)
+LSTATUS WINAPI RegQueryValueW( HKEY hkey, LPCWSTR name, LPWSTR data, LPLONG count )
+{
+    DWORD ret;
+    HKEY subkey = hkey;
+
+    TRACE("(%p,%s,%p,%d)\n", hkey, debugstr_w(name), data, count ? *count : 0 );
+    if (hkey == NULL)
     {
        return ERROR_INVALID_HANDLE;
     }
-    Status = MapDefaultKey(&KeyHandle,
-                           hKey);
-    if (!NT_SUCCESS(Status))
-    {
-        return RtlNtStatusToDosError(Status);
-    }
-
-    if (lpSubKey != NULL &&
-        wcslen(lpSubKey) != 0)
-    {
-        RtlInitUnicodeString(&SubKeyString,
-                             (LPWSTR)lpSubKey);
-        InitializeObjectAttributes(&ObjectAttributes,
-                                   &SubKeyString,
-                                   OBJ_CASE_INSENSITIVE,
-                                   KeyHandle,
-                                   NULL);
-        Status = NtOpenKey(&RealKey,
-                           KEY_QUERY_VALUE,
-                           &ObjectAttributes);
-        if (!NT_SUCCESS(Status))
-        {
-            ErrorCode = RtlNtStatusToDosError(Status);
-            goto Cleanup;
-        }
-
-        CloseRealKey = TRUE;
-    }
-    else
-    {
-        RealKey = hKey;
-        CloseRealKey = FALSE;
-    }
-
-    ErrorCode = RegQueryValueExW(RealKey,
-                                 NULL,
-                                 NULL,
-                                 NULL,
-                                 (LPBYTE)lpValue,
-                                 (LPDWORD)lpcbValue);
-    if (CloseRealKey)
-    {
-        NtClose(RealKey);
-    }
-
-Cleanup:
-    ClosePredefKey(KeyHandle);
-
-    return ErrorCode;
+    if (name && name[0])
+    {
+        ret = RegOpenKeyW( hkey, name, &subkey);
+        if (ret != ERROR_SUCCESS) 
+        {
+            return ret;
+        }
+    }
+
+    ret = RegQueryValueExW( subkey, NULL, NULL, NULL, (LPBYTE)data, (LPDWORD)count );
+    
+    if (subkey != hkey) 
+    {
+        RegCloseKey( subkey );
+    }
+
+    if (ret == ERROR_FILE_NOT_FOUND)
+    {
+        /* return empty string if default value not found */
+        if (data) 
+            *data = 0;
+        if (count) 
+            *count = sizeof(WCHAR);
+        ret = ERROR_SUCCESS;
+    }
+    return ret;
 }
 
 
@@ -4806,86 +4692,43 @@
  *
  * @implemented
  */
-LONG WINAPI
-RegSetValueExA(HKEY hKey,
-               LPCSTR lpValueName,
-               DWORD Reserved,
-               DWORD dwType,
-               CONST BYTE* lpData,
-               DWORD cbData)
-{
-    UNICODE_STRING ValueName;
-    LPWSTR pValueName;
-    ANSI_STRING AnsiString;
-    UNICODE_STRING Data;
-    LONG ErrorCode;
-    LPBYTE pData;
-    DWORD DataSize;
-
-    if (lpValueName != NULL &&
-        strlen(lpValueName) != 0)
-    {
-        RtlCreateUnicodeStringFromAsciiz(&ValueName,
-                                         (PSTR)lpValueName);
-    }
-    else
-    {
-        ValueName.Buffer = NULL;
-    }
-
-    pValueName = (LPWSTR)ValueName.Buffer;
-
-    if (((dwType == REG_SZ) ||
-         (dwType == REG_MULTI_SZ) ||
-         (dwType == REG_EXPAND_SZ)) &&
-        (cbData != 0))
-    {
-        /* NT adds one if the caller forgot the NULL-termination character */
-        if (lpData[cbData - 1] != '\0')
-        {
-            cbData++;
-        }
-
-        RtlInitAnsiString(&AnsiString,
-                          NULL);
-        AnsiString.Buffer = (PSTR)lpData;
-        AnsiString.Length = cbData - 1;
-        AnsiString.MaximumLength = cbData;
-        RtlAnsiStringToUnicodeString(&Data,
-                                     &AnsiString,
-                                     TRUE);
-        pData = (LPBYTE)Data.Buffer;
-        DataSize = cbData * sizeof(WCHAR);
-    }
-    else
-    {
-        RtlInitUnicodeString(&Data,
-                             NULL);
-        pData = (LPBYTE)lpData;
-        DataSize = cbData;
-    }
-
-    ErrorCode = RegSetValueExW(hKey,
-                               pValueName,
-                               Reserved,
-                               dwType,
-                               pData,
-                               DataSize);
-    if (pValueName != NULL)
-    {
-        RtlFreeHeap(ProcessHeap,
-                    0,
-                    ValueName.Buffer);
-    }
-
-    if (Data.Buffer != NULL)
-    {
-        RtlFreeHeap(ProcessHeap,
-                    0,
-                    Data.Buffer);
-    }
-
-    return ErrorCode;
+LSTATUS WINAPI RegSetValueExA( HKEY hkey, LPCSTR name, DWORD reserved, DWORD type,
+                            CONST BYTE *data, DWORD count )
+{
+    ANSI_STRING nameA;
+    WCHAR *dataW = NULL;
+    NTSTATUS status;
+
+    if (count && is_string(type))
+    {
+        /* if user forgot to count terminating null, add it (yes NT does this) */
+        if (data[count-1] && !data[count]) count++;
+    }
+
+    status = MapDefaultKey( (PHANDLE)&hkey, hkey);
+    if (!NT_SUCCESS(status))
+    {
+        return RtlNtStatusToDosError(status);
+    }
+
+    if (is_string( type )) /* need to convert to Unicode */
+    {
+        DWORD lenW;
+        RtlMultiByteToUnicodeSize( &lenW, (const char *)data, count );
+        if (!(dataW = HeapAlloc( GetProcessHeap(), 0, lenW ))) return ERROR_OUTOFMEMORY;
+        RtlMultiByteToUnicodeN( dataW, lenW, NULL, (const char *)data, count );
+        count = lenW;
+        data = (BYTE *)dataW;
+    }
+
+    RtlInitAnsiString( &nameA, name );
+    if (!(status = RtlAnsiStringToUnicodeString( &NtCurrentTeb()->StaticUnicodeString,
+                                                 &nameA, FALSE )))
+    {
+        status = NtSetValueKey( hkey, &NtCurrentTeb()->StaticUnicodeString, 0, type, (PVOID)data, count );
+    }
+    HeapFree( GetProcessHeap(), 0, dataW );
+    return RtlNtStatusToDosError( status );
 }
 
 



More information about the Ros-diffs mailing list