[ros-diffs] [fireball] 36623: - Sync RegGetValueA/W implementation (no functional changes though, mostly comments). - Port RegQueryValueExW from Wine (but leaving RegQueryValueExA as a wrapper, with a fix). - Implement RegSetValueA/W based on Wine's implementation, and removing old, different (A and W) versions of RegSetValue.

fireball at svn.reactos.org fireball at svn.reactos.org
Thu Oct 2 13:30:45 CEST 2008


Author: fireball
Date: Thu Oct  2 06:30:44 2008
New Revision: 36623

URL: http://svn.reactos.org/svn/reactos?rev=36623&view=rev
Log:
- Sync RegGetValueA/W implementation (no functional changes though, mostly comments).
- Port RegQueryValueExW from Wine (but leaving RegQueryValueExA as a wrapper, with a fix).
- Implement RegSetValueA/W based on Wine's implementation, and removing old, different (A and W) versions of RegSetValue.

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=36623&r1=36622&r2=36623&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] Thu Oct  2 06:30:44 2008
@@ -1809,8 +1809,8 @@
 /******************************************************************************
  * RegGetValueW   [ADVAPI32.@]
  *
- * Retrieves the type and data for a value name associated with a key
- * optionally expanding it's content and restricting it's type.
+ * Retrieves the type and data for a value name associated with a key,
+ * optionally expanding its content and restricting its type.
  *
  * PARAMS
  *  hKey      [I] Handle to an open key.
@@ -1819,23 +1819,25 @@
  *  dwFlags   [I] Flags restricting the value type to retrieve.
  *  pdwType   [O] Destination for the values type, may be NULL.
  *  pvData    [O] Destination for the values content, may be NULL.
- *  pcbData   [I/O] Size of pvData, updated with the size required to
- *                  retrieve the whole content.
+ *  pcbData   [I/O] Size of pvData, updated with the size in bytes required to
+ *                  retrieve the whole content, including the trailing '\0'
+ *                  for strings.
  *
  * RETURNS
  *  Success: ERROR_SUCCESS
  *  Failure: nonzero error code from Winerror.h
  *
  * NOTES
- *  - Unless RRF_NOEXPAND is specified REG_EXPAND_SZ is automatically expanded
- *    and REG_SZ is retrieved instead.
- *  - Restrictions are applied after expanding, using RRF_RT_REG_EXPAND_SZ
+ *  - Unless RRF_NOEXPAND is specified, REG_EXPAND_SZ values are automatically
+ *    expanded and pdwType is set to REG_SZ instead.
+ *  - Restrictions are applied after expanding, using RRF_RT_REG_EXPAND_SZ 
  *    without RRF_NOEXPAND is thus not allowed.
- */
-LONG WINAPI
-RegGetValueW( HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue,
-              DWORD dwFlags, LPDWORD pdwType, PVOID pvData,
-              LPDWORD pcbData )
+ *    An exception is the case where RRF_RT_ANY is specified, because then
+ *    RRF_NOEXPAND is allowed.
+ */
+LSTATUS WINAPI RegGetValueW( HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue,
+                             DWORD dwFlags, LPDWORD pdwType, PVOID pvData,
+                             LPDWORD pcbData )
 {
     DWORD dwType, cbData = pcbData ? *pcbData : 0;
     PVOID pvBuf = NULL;
@@ -1847,7 +1849,6 @@
 
     if (pvData && !pcbData)
         return ERROR_INVALID_PARAMETER;
-
     if ((dwFlags & RRF_RT_REG_EXPAND_SZ) && !(dwFlags & RRF_NOEXPAND) &&
             ((dwFlags & RRF_RT_ANY) != RRF_RT_ANY))
         return ERROR_INVALID_PARAMETER;
@@ -1864,7 +1865,7 @@
      * if the passed buffer was too small as the expanded string might be
      * smaller than the unexpanded one and could fit into cbData bytes. */
     if ((ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) &&
-        (dwType == REG_EXPAND_SZ && !(dwFlags & RRF_NOEXPAND)))
+        dwType == REG_EXPAND_SZ && !(dwFlags & RRF_NOEXPAND))
     {
         do {
             HeapFree(GetProcessHeap(), 0, pvBuf);
@@ -1930,10 +1931,9 @@
  *
  * See RegGetValueW.
  */
-LONG WINAPI
-RegGetValueA( HKEY hKey, LPCSTR pszSubKey, LPCSTR pszValue,
-              DWORD dwFlags, LPDWORD pdwType, PVOID pvData,
-              LPDWORD pcbData )
+LSTATUS WINAPI RegGetValueA( HKEY hKey, LPCSTR pszSubKey, LPCSTR pszValue,
+                          DWORD dwFlags, LPDWORD pdwType, PVOID pvData, 
+                          LPDWORD pcbData )
 {
     DWORD dwType, cbData = pcbData ? *pcbData : 0;
     PVOID pvBuf = NULL;
@@ -1945,7 +1945,6 @@
 
     if (pvData && !pcbData)
         return ERROR_INVALID_PARAMETER;
-
     if ((dwFlags & RRF_RT_REG_EXPAND_SZ) && !(dwFlags & RRF_NOEXPAND) &&
             ((dwFlags & RRF_RT_ANY) != RRF_RT_ANY))
         return ERROR_INVALID_PARAMETER;
@@ -3793,120 +3792,84 @@
  *
  * @implemented
  */
-LONG STDCALL
-RegQueryValueExW (HKEY hKey,
-		  LPCWSTR lpValueName,
-		  LPDWORD lpReserved,
-		  LPDWORD lpType,
-		  LPBYTE lpData,
-		  LPDWORD lpcbData)
-{
-  PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
-  UNICODE_STRING ValueName;
-  NTSTATUS Status;
-  ULONG BufferSize;
-  ULONG ResultSize;
-  HANDLE KeyHandle;
-  LONG ErrorCode = ERROR_SUCCESS;
-  ULONG MaxCopy = lpcbData != NULL && lpData != NULL ? *lpcbData : 0;
-
-  TRACE("hKey 0x%X  lpValueName %S  lpData 0x%X  lpcbData %d\n",
-	 hKey, lpValueName, lpData, lpcbData ? *lpcbData : 0);
-
-  Status = MapDefaultKey (&KeyHandle,
-			  hKey);
-  if (!NT_SUCCESS(Status))
-    {
-      return RtlNtStatusToDosError (Status);
-    }
-
-  if (lpData != NULL && lpcbData == NULL)
-    {
-      ErrorCode = ERROR_INVALID_PARAMETER;
-      goto Cleanup;
-    }
-
-  RtlInitUnicodeString (&ValueName,
-			lpValueName);
-  BufferSize = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]) + MaxCopy;
-  ValueInfo = RtlAllocateHeap (ProcessHeap,
-			       0,
-			       BufferSize);
-  if (ValueInfo == NULL)
-    {
-      ErrorCode = ERROR_OUTOFMEMORY;
-      goto Cleanup;
-    }
-
-  Status = NtQueryValueKey (KeyHandle,
-			    &ValueName,
-			    KeyValuePartialInformation,
-			    ValueInfo,
-			    BufferSize,
-			    &ResultSize);
-  TRACE("Status 0x%X\n", Status);
-  if (Status == STATUS_BUFFER_OVERFLOW)
-    {
-      /* Return ERROR_SUCCESS and the buffer space needed for a successful call */
-      MaxCopy = 0;
-      ErrorCode = lpData ? ERROR_MORE_DATA : ERROR_SUCCESS;
-    }
-  else if (!NT_SUCCESS(Status))
-    {
-      ErrorCode = RtlNtStatusToDosError (Status);
-      MaxCopy = 0;
-      if (lpcbData != NULL)
-	{
-	  ResultSize = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]) + *lpcbData;
-	}
-    }
-
-  if ((lpType != NULL) && (NT_SUCCESS(Status) || (Status == STATUS_BUFFER_OVERFLOW)))
-    {
-      *lpType = ValueInfo->Type;
-    }
-
-  if (NT_SUCCESS(Status) && lpData != NULL)
-    {
-      RtlMoveMemory (lpData,
-		     ValueInfo->Data,
-		     min(ValueInfo->DataLength, MaxCopy));
-    }
-
-  if ((ValueInfo->Type == REG_SZ) ||
-      (ValueInfo->Type == REG_MULTI_SZ) ||
-      (ValueInfo->Type == REG_EXPAND_SZ))
-    {
-      if (lpData != NULL && MaxCopy > ValueInfo->DataLength)
-	{
-	  ((PWSTR)lpData)[ValueInfo->DataLength / sizeof(WCHAR)] = 0;
-	}
-
-      if (lpcbData != NULL)
-	{
-	  *lpcbData = (ResultSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]));
-	  TRACE("(string) Returning Size: %lu\n", *lpcbData);
-	}
-    }
-  else
-    {
-      if (lpcbData != NULL)
-	{
-	  *lpcbData = ResultSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]);
-	  TRACE("(other) Returning Size: %lu\n", *lpcbData);
-	}
-    }
-
-  TRACE("Type %d  Size %d\n", ValueInfo->Type, ValueInfo->DataLength);
-
-  RtlFreeHeap (ProcessHeap,
-	       0,
-	       ValueInfo);
-
-Cleanup:
-  ClosePredefKey(KeyHandle);
-
-  return ErrorCode;
+LONG
+WINAPI
+RegQueryValueExW(HKEY hkeyorg,
+                 LPCWSTR name,
+                 LPDWORD reserved,
+                 LPDWORD type,
+                 LPBYTE data,
+                 LPDWORD count)
+{
+    HANDLE hkey;
+    NTSTATUS status;
+    UNICODE_STRING name_str;
+    DWORD total_size;
+    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_w(name), reserved, type, data, count,
+          (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))
+    {
+        return RtlNtStatusToDosError(status);
+    }
+
+    RtlInitUnicodeString( &name_str, name );
+
+    if (data) total_size = min( sizeof(buffer), *count + info_size );
+    else
+    {
+        total_size = info_size;
+        if (count) *count = 0;
+    }
+
+    status = NtQueryValueKey( hkey, &name_str, KeyValuePartialInformation,
+                              buffer, total_size, &total_size );
+    if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
+
+    if (data)
+    {
+        /* retry with a dynamically allocated buffer */
+        while (status == STATUS_BUFFER_OVERFLOW && total_size - info_size <= *count)
+        {
+            if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+            if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size )))
+                return ERROR_NOT_ENOUGH_MEMORY;
+            info = (KEY_VALUE_PARTIAL_INFORMATION *)buf_ptr;
+            status = NtQueryValueKey( hkey, &name_str, KeyValuePartialInformation,
+                                      buf_ptr, total_size, &total_size );
+        }
+
+        if (!status)
+        {
+            memcpy( data, 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 (total_size - info_size <= *count-sizeof(WCHAR) && is_string(info->Type))
+            {
+                WCHAR *ptr = (WCHAR *)(data + total_size - info_size);
+                if (ptr > (WCHAR *)data && ptr[-1]) *ptr = 0;
+            }
+        }
+        else if (status != STATUS_BUFFER_OVERFLOW) goto done;
+    }
+    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 );
+    ClosePredefKey(hkey);
+    return RtlNtStatusToDosError(status);
 }
 
 
@@ -3955,6 +3918,9 @@
       ValueData.Buffer = NULL;
       ValueData.Length = 0;
       ValueData.MaximumLength = 0;
+
+      if (lpcbData)
+          *lpcbData = 0;
     }
 
   RtlCreateUnicodeStringFromAsciiz (&ValueName,
@@ -4754,47 +4720,39 @@
  * @implemented
  */
 LONG STDCALL
-RegSetValueA (HKEY hKey,
+RegSetValueA (HKEY hKeyOriginal,
 	      LPCSTR lpSubKey,
 	      DWORD dwType,
 	      LPCSTR lpData,
 	      DWORD cbData)
 {
-  LONG ret;
-  HKEY hSubKey;
-
-  if (dwType != REG_SZ)
-  {
-     return ERROR_INVALID_PARAMETER;
-  }
-
-  if (lpSubKey != NULL && lpSubKey[0] != '\0')
-  {
-     ret = RegCreateKeyA(hKey,
-                         lpSubKey,
-                         &hSubKey);
-
-     if (ret != ERROR_SUCCESS)
-     {
-        return ret;
-     }
-  }
-  else
-     hSubKey = hKey;
-
-  ret = RegSetValueExA(hSubKey,
-                       NULL,
-                       0,
-                       REG_SZ,
-                       (CONST BYTE*)lpData,
-                       strlen(lpData) + 1);
-
-  if (hSubKey != hKey)
-  {
-     RegCloseKey(hSubKey);
-  }
-
-  return ret;
+    HKEY subkey;
+    HANDLE hKey;
+    DWORD ret;
+    NTSTATUS Status;
+
+    TRACE("(%p,%s,%d,%s,%d)\n", hKey, debugstr_a(lpSubKey), dwType, debugstr_a(lpData), cbData );
+
+    if (dwType != REG_SZ || !lpData) return ERROR_INVALID_PARAMETER;
+
+    Status = MapDefaultKey(&hKey, hKeyOriginal);
+    if (!NT_SUCCESS(Status))
+    {
+        return RtlNtStatusToDosError (Status);
+    }
+    subkey = hKey;
+
+    if (lpSubKey && lpSubKey[0])  /* need to create the subkey */
+    {
+        if ((ret = RegCreateKeyA( hKey, lpSubKey, &subkey )) != ERROR_SUCCESS) goto Cleanup;
+    }
+    ret = RegSetValueExA( subkey, NULL, 0, REG_SZ, (const BYTE*)lpData, strlen(lpData)+1 );
+    if (subkey != hKey) RegCloseKey( subkey );
+
+Cleanup:
+    ClosePredefKey(hKey);
+
+    return ret;
 }
 
 
@@ -4804,67 +4762,41 @@
  * @implemented
  */
 LONG STDCALL
-RegSetValueW (HKEY hKey,
+RegSetValueW (HKEY hKeyOriginal,
 	      LPCWSTR lpSubKey,
 	      DWORD dwType,
 	      LPCWSTR lpData,
 	      DWORD cbData)
 {
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  UNICODE_STRING SubKeyString;
-  HANDLE KeyHandle;
-  HANDLE RealKey;
-  BOOL CloseRealKey;
-  NTSTATUS Status;
-  LONG ErrorCode;
-
-  Status = MapDefaultKey (&KeyHandle,
-                          hKey);
-  if (!NT_SUCCESS(Status))
-    {
-      return RtlNtStatusToDosError (Status);
-    }
-
-  if ((lpSubKey) && (wcslen(lpSubKey) != 0))
-    {
-      RtlInitUnicodeString (&SubKeyString,
-			    (LPWSTR)lpSubKey);
-      InitializeObjectAttributes (&ObjectAttributes,
-				  &SubKeyString,
-				  OBJ_CASE_INSENSITIVE,
-				  KeyHandle,
-				  NULL);
-      Status = NtOpenKey (&RealKey,
-			  KEY_SET_VALUE,
-			  &ObjectAttributes);
-      if (!NT_SUCCESS(Status))
-	{
-	  ErrorCode = RtlNtStatusToDosError (Status);
-	  goto Cleanup;
-	}
-      CloseRealKey = TRUE;
-    }
-  else
-    {
-      RealKey = hKey;
-      CloseRealKey = FALSE;
-    }
-
-  ErrorCode = RegSetValueExW (RealKey,
-			      NULL,
-			      0,
-			      dwType,
-			      (LPBYTE)lpData,
-			      cbData);
-  if (CloseRealKey == TRUE)
-    {
-      NtClose (RealKey);
-    }
+    HKEY subkey;
+    HANDLE hKey;
+    DWORD ret;
+    NTSTATUS Status;
+
+    TRACE("(%p,%s,%d,%s,%d)\n", hKeyOriginal, debugstr_w(lpSubKey), dwType, debugstr_w(lpData), cbData );
+
+    if (dwType != REG_SZ || !lpData) return ERROR_INVALID_PARAMETER;
+
+    Status = MapDefaultKey(&hKey, hKeyOriginal);
+    if (!NT_SUCCESS(Status))
+    {
+        return RtlNtStatusToDosError (Status);
+    }
+    subkey = hKey;
+
+    if (lpSubKey && lpSubKey[0])  /* need to create the subkey */
+    {
+        if ((ret = RegCreateKeyW( hKey, lpSubKey, &subkey )) != ERROR_SUCCESS) goto Cleanup;
+    }
+
+    ret = RegSetValueExW( subkey, NULL, 0, REG_SZ, (const BYTE*)lpData,
+                          (wcslen( lpData ) + 1) * sizeof(WCHAR) );
+    if (subkey != hKey) RegCloseKey( subkey );
 
 Cleanup:
-  ClosePredefKey(KeyHandle);
-
-  return ErrorCode;
+    ClosePredefKey(hKey);
+
+    return ret;
 }
 
 



More information about the Ros-diffs mailing list