Fix formatting. No code changes!
[reactos.git] / reactos / dll / win32 / advapi32 / reg / reg.c
index 741660c..5c6928d 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
  * FILE:            lib/advapi32/reg/reg.c
 /* INCLUDES *****************************************************************/
 
 #include <advapi32.h>
-#define NDEBUG
 #include <wine/debug.h>
 
+WINE_DEFAULT_DEBUG_CHANNEL(reg);
+
 /* DEFINES ******************************************************************/
 
 #define MAX_DEFAULT_HANDLES   6
@@ -62,16 +62,16 @@ __inline static int is_string( DWORD type )
  *  RegInitDefaultHandles
  */
 BOOL
-RegInitialize (VOID)
+RegInitialize(VOID)
 {
-  TRACE("RegInitialize()\n");
+    TRACE("RegInitialize()\n");
 
-  ProcessHeap = RtlGetProcessHeap();
-  RtlZeroMemory (DefaultHandleTable,
-                MAX_DEFAULT_HANDLES * sizeof(HANDLE));
-  RtlInitializeCriticalSection (&HandleTableCS);
+    ProcessHeap = RtlGetProcessHeap();
+    RtlZeroMemory(DefaultHandleTable,
+                  MAX_DEFAULT_HANDLES * sizeof(HANDLE));
+    RtlInitializeCriticalSection(&HandleTableCS);
 
-  return TRUE;
+    return TRUE;
 }
 
 
@@ -79,14 +79,14 @@ RegInitialize (VOID)
  *  RegInit
  */
 BOOL
-RegCleanup (VOID)
+RegCleanup(VOID)
 {
-  TRACE("RegCleanup()\n");
+    TRACE("RegCleanup()\n");
 
-  CloseDefaultKeys ();
-  RtlDeleteCriticalSection (&HandleTableCS);
+    CloseDefaultKeys();
+    RtlDeleteCriticalSection(&HandleTableCS);
 
-  return TRUE;
+    return TRUE;
 }
 
 
@@ -133,170 +133,173 @@ OpenPredefinedKey(IN ULONG Index,
             Status = STATUS_INVALID_PARAMETER;
             break;
     }
-    
+
     return Status;
 }
 
 
 static NTSTATUS
-MapDefaultKey (OUT PHANDLE RealKey,
-               IN HKEY Key)
+MapDefaultKey(OUT PHANDLE RealKey,
+              IN HKEY Key)
 {
-  PHANDLE Handle;
-  ULONG Index;
-  BOOLEAN DoOpen, DefDisabled;
-  NTSTATUS Status = STATUS_SUCCESS;
+    PHANDLE Handle;
+    ULONG Index;
+    BOOLEAN DoOpen, DefDisabled;
+    NTSTATUS Status = STATUS_SUCCESS;
 
-  TRACE("MapDefaultKey (Key %x)\n", Key);
+    TRACE("MapDefaultKey (Key %x)\n", Key);
 
-  if (!IsPredefKey(Key))
+    if (!IsPredefKey(Key))
     {
-      *RealKey = (HANDLE)((ULONG_PTR)Key & ~0x1);
-      return STATUS_SUCCESS;
+        *RealKey = (HANDLE)((ULONG_PTR)Key & ~0x1);
+        return STATUS_SUCCESS;
     }
 
-  /* Handle special cases here */
-  Index = GetPredefKeyIndex(Key);
-  if (Index >= MAX_DEFAULT_HANDLES)
+    /* Handle special cases here */
+    Index = GetPredefKeyIndex(Key);
+    if (Index >= MAX_DEFAULT_HANDLES)
     {
-      return STATUS_INVALID_PARAMETER;
+        return STATUS_INVALID_PARAMETER;
     }
 
-  RtlEnterCriticalSection (&HandleTableCS);
+    RtlEnterCriticalSection (&HandleTableCS);
 
-  if (Key == HKEY_CURRENT_USER)
-      DefDisabled = DefaultHandleHKUDisabled;
-  else
-      DefDisabled = DefaultHandlesDisabled;
+    if (Key == HKEY_CURRENT_USER)
+        DefDisabled = DefaultHandleHKUDisabled;
+    else
+        DefDisabled = DefaultHandlesDisabled;
 
-  if (!DefDisabled)
+    if (!DefDisabled)
+    {
+        Handle = &DefaultHandleTable[Index];
+        DoOpen = (*Handle == NULL);
+    }
+    else
     {
-      Handle = &DefaultHandleTable[Index];
-      DoOpen = (*Handle == NULL);
+        Handle = RealKey;
+        DoOpen = TRUE;
     }
-  else
+
+    if (DoOpen)
     {
-      Handle = RealKey;
-      DoOpen = TRUE;
+        /* create/open the default handle */
+        Status = OpenPredefinedKey(Index,
+                                   Handle);
     }
-  
-  if (DoOpen)
+
+    if (NT_SUCCESS(Status))
     {
-      /* create/open the default handle */
-      Status = OpenPredefinedKey(Index,
-                                 Handle);
+        if (!DefDisabled)
+            *RealKey = *Handle;
+        else
+            *(PULONG_PTR)Handle |= 0x1;
     }
 
-   if (NT_SUCCESS(Status))
-     {
-       if (!DefDisabled)
-          *RealKey = *Handle;
-       else
-          *(PULONG_PTR)Handle |= 0x1;
-     }
-  
-   RtlLeaveCriticalSection (&HandleTableCS);
+    RtlLeaveCriticalSection (&HandleTableCS);
 
-   return Status;
+    return Status;
 }
 
 
 static VOID
-CloseDefaultKeys (VOID)
+CloseDefaultKeys(VOID)
 {
-  ULONG i;
+    ULONG i;
 
-  RtlEnterCriticalSection (&HandleTableCS);
-  for (i = 0; i < MAX_DEFAULT_HANDLES; i++)
+    RtlEnterCriticalSection(&HandleTableCS);
+
+    for (i = 0; i < MAX_DEFAULT_HANDLES; i++)
     {
-      if (DefaultHandleTable[i] != NULL)
-       {
-         NtClose (DefaultHandleTable[i]);
-         DefaultHandleTable[i] = NULL;
-       }
+        if (DefaultHandleTable[i] != NULL)
+        {
+            NtClose(DefaultHandleTable[i]);
+            DefaultHandleTable[i] = NULL;
+        }
     }
-  RtlLeaveCriticalSection (&HandleTableCS);
+
+    RtlLeaveCriticalSection(&HandleTableCS);
 }
 
 
 static NTSTATUS
-OpenClassesRootKey (PHANDLE KeyHandle)
+OpenClassesRootKey(PHANDLE KeyHandle)
 {
-  OBJECT_ATTRIBUTES Attributes;
-  UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\CLASSES");
-
-  TRACE("OpenClassesRootKey()\n");
-
-  InitializeObjectAttributes (&Attributes,
-                             &KeyName,
-                             OBJ_CASE_INSENSITIVE,
-                             NULL,
-                             NULL);
-  return NtOpenKey (KeyHandle,
-                   MAXIMUM_ALLOWED,
-                   &Attributes);
+    OBJECT_ATTRIBUTES Attributes;
+    UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\CLASSES");
+
+    TRACE("OpenClassesRootKey()\n");
+
+    InitializeObjectAttributes(&Attributes,
+                               &KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+    return NtOpenKey(KeyHandle,
+                     MAXIMUM_ALLOWED,
+                     &Attributes);
 }
 
 
 static NTSTATUS
-OpenLocalMachineKey (PHANDLE KeyHandle)
+OpenLocalMachineKey(PHANDLE KeyHandle)
 {
-  OBJECT_ATTRIBUTES Attributes;
-  UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine");
-  NTSTATUS Status;
-
-  TRACE("OpenLocalMachineKey()\n");
-
-  InitializeObjectAttributes (&Attributes,
-                             &KeyName,
-                             OBJ_CASE_INSENSITIVE,
-                             NULL,
-                             NULL);
-  Status = NtOpenKey (KeyHandle,
-                     MAXIMUM_ALLOWED,
-                     &Attributes);
-
-  TRACE("NtOpenKey(%wZ) => %08x\n", &KeyName, Status);
-  return Status;
+    OBJECT_ATTRIBUTES Attributes;
+    UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine");
+    NTSTATUS Status;
+
+    TRACE("OpenLocalMachineKey()\n");
+
+    InitializeObjectAttributes(&Attributes,
+                               &KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+    Status = NtOpenKey(KeyHandle,
+                       MAXIMUM_ALLOWED,
+                       &Attributes);
+
+    TRACE("NtOpenKey(%wZ) => %08x\n", &KeyName, Status);
+
+    return Status;
 }
 
 
 static NTSTATUS
-OpenUsersKey (PHANDLE KeyHandle)
+OpenUsersKey(PHANDLE KeyHandle)
 {
-  OBJECT_ATTRIBUTES Attributes;
-  UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\User");
-
-  TRACE("OpenUsersKey()\n");
-
-  InitializeObjectAttributes (&Attributes,
-                             &KeyName,
-                             OBJ_CASE_INSENSITIVE,
-                             NULL,
-                             NULL);
-  return NtOpenKey (KeyHandle,
-                   MAXIMUM_ALLOWED,
-                   &Attributes);
+    OBJECT_ATTRIBUTES Attributes;
+    UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\User");
+
+    TRACE("OpenUsersKey()\n");
+
+    InitializeObjectAttributes(&Attributes,
+                               &KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+    return NtOpenKey(KeyHandle,
+                     MAXIMUM_ALLOWED,
+                     &Attributes);
 }
 
 
 static NTSTATUS
 OpenCurrentConfigKey (PHANDLE KeyHandle)
 {
-  OBJECT_ATTRIBUTES Attributes;
-  UNICODE_STRING KeyName =
-  RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current");
-
-  TRACE("OpenCurrentConfigKey()\n");
-
-  InitializeObjectAttributes (&Attributes,
-                             &KeyName,
-                             OBJ_CASE_INSENSITIVE,
-                             NULL,
-                             NULL);
-  return NtOpenKey (KeyHandle,
-                   MAXIMUM_ALLOWED,
-                   &Attributes);
+    OBJECT_ATTRIBUTES Attributes;
+    UNICODE_STRING KeyName =
+        RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current");
+
+    TRACE("OpenCurrentConfigKey()\n");
+
+    InitializeObjectAttributes(&Attributes,
+                               &KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+    return NtOpenKey(KeyHandle,
+                     MAXIMUM_ALLOWED,
+                     &Attributes);
 }
 
 
@@ -308,9 +311,9 @@ OpenCurrentConfigKey (PHANDLE KeyHandle)
 LONG WINAPI
 RegDisablePredefinedCache(VOID)
 {
-    RtlEnterCriticalSection (&HandleTableCS);
+    RtlEnterCriticalSection(&HandleTableCS);
     DefaultHandleHKUDisabled = TRUE;
-    RtlLeaveCriticalSection (&HandleTableCS);
+    RtlLeaveCriticalSection(&HandleTableCS);
     return ERROR_SUCCESS;
 }
 
@@ -323,10 +326,10 @@ RegDisablePredefinedCache(VOID)
 LONG STDCALL
 RegDisablePredefinedCacheEx(VOID)
 {
-    RtlEnterCriticalSection (&HandleTableCS);
+    RtlEnterCriticalSection(&HandleTableCS);
     DefaultHandlesDisabled = TRUE;
     DefaultHandleHKUDisabled = TRUE;
-    RtlLeaveCriticalSection (&HandleTableCS);
+    RtlLeaveCriticalSection(&HandleTableCS);
     return ERROR_SUCCESS;
 }
 
@@ -341,7 +344,7 @@ RegOverridePredefKey(IN HKEY hKey,
                      IN HKEY hNewHKey  OPTIONAL)
 {
     LONG ErrorCode = ERROR_SUCCESS;
-    
+
     if ((hKey == HKEY_CLASSES_ROOT ||
          hKey == HKEY_CURRENT_CONFIG ||
          hKey == HKEY_CURRENT_USER ||
@@ -365,22 +368,22 @@ RegOverridePredefKey(IN HKEY hKey,
             {
                 return RtlNtStatusToDosError(Status);
             }
-            
+
             ASSERT(hNewHKey != NULL);
         }
 
-        RtlEnterCriticalSection (&HandleTableCS);
+        RtlEnterCriticalSection(&HandleTableCS);
 
         /* close the currently mapped handle if existing */
         if (*Handle != NULL)
         {
             NtClose(*Handle);
         }
-        
+
         /* update the mapping */
         *Handle = hNewHKey;
 
-        RtlLeaveCriticalSection (&HandleTableCS);
+        RtlLeaveCriticalSection(&HandleTableCS);
     }
     else
         ErrorCode = ERROR_INVALID_HANDLE;
@@ -395,20 +398,20 @@ RegOverridePredefKey(IN HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegCloseKey (HKEY hKey)
+RegCloseKey(HKEY hKey)
 {
-  NTSTATUS Status;
+    NTSTATUS Status;
 
-  /* don't close null handle or a pseudo handle */
-  if ((!hKey) || (((ULONG)hKey & 0xF0000000) == 0x80000000))
+    /* don't close null handle or a pseudo handle */
+    if ((!hKey) || (((ULONG)hKey & 0xF0000000) == 0x80000000))
     {
-      return ERROR_INVALID_HANDLE;
+        return ERROR_INVALID_HANDLE;
     }
 
-  Status = NtClose (hKey);
-  if (!NT_SUCCESS(Status))
+    Status = NtClose(hKey);
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
   return ERROR_SUCCESS;
@@ -437,9 +440,9 @@ RegpCopyTree(IN HKEY hKeySrc,
     ULONG Index, BufferSizeRequired, BufferSize = 0x200;
     NTSTATUS Status = STATUS_SUCCESS;
     NTSTATUS Status2 = STATUS_SUCCESS;
-    
+
     InitializeListHead(&copyQueueHead);
-    
+
     Info.Buffer = RtlAllocateHeap(ProcessHeap,
                                   0,
                                   BufferSize);
@@ -447,7 +450,7 @@ RegpCopyTree(IN HKEY hKeySrc,
     {
         return STATUS_INSUFFICIENT_RESOURCES;
     }
-    
+
     copyKeys = RtlAllocateHeap(ProcessHeap,
                                0,
                                sizeof(REGP_COPY_KEYS));
@@ -457,9 +460,9 @@ RegpCopyTree(IN HKEY hKeySrc,
         copyKeys->hKeyDest = hKeyDest;
         InsertHeadList(&copyQueueHead,
                        &copyKeys->ListEntry);
-        
+
         /* FIXME - copy security from hKeySrc to hKeyDest or just for the subkeys? */
-        
+
         do
         {
             copyKeys = CONTAINING_RECORD(copyQueueHead.Flink,
@@ -480,14 +483,14 @@ RegpCopyTree(IN HKEY hKeySrc,
                 {
                     UNICODE_STRING ValueName;
                     PVOID Data;
-                    
+
                     /* don't use RtlInitUnicodeString as the string is not NULL-terminated! */
                     ValueName.Length = Info.KeyValue->NameLength;
                     ValueName.MaximumLength = ValueName.Length;
                     ValueName.Buffer = Info.KeyValue->Name;
-                    
+
                     Data = (PVOID)((ULONG_PTR)Info.KeyValue + Info.KeyValue->DataOffset);
-                    
+
                     Status2 = NtSetValueKey(copyKeys->hKeyDest,
                                             &ValueName,
                                             Info.KeyValue->TitleIndex,
@@ -523,7 +526,7 @@ RegpCopyTree(IN HKEY hKeySrc,
                         /* don't break, let's try to copy as many values as possible */
                         Status2 = STATUS_INSUFFICIENT_RESOURCES;
                         Index++;
-                        
+
                         if (NT_SUCCESS(Status))
                         {
                             Status = Status2;
@@ -538,11 +541,11 @@ RegpCopyTree(IN HKEY hKeySrc,
                     {
                         Status = Status2;
                     }
-                    
+
                     break;
                 }
             }
-            
+
             /* enumerate all subkeys and open and enqueue them */
             Index = 0;
             for (;;)
@@ -558,7 +561,7 @@ RegpCopyTree(IN HKEY hKeySrc,
                     HANDLE KeyHandle, NewKeyHandle;
                     OBJECT_ATTRIBUTES ObjectAttributes;
                     UNICODE_STRING SubKeyName, ClassName;
-                    
+
                     /* don't use RtlInitUnicodeString as the string is not NULL-terminated! */
                     SubKeyName.Length = Info.KeyNode->NameLength;
                     SubKeyName.MaximumLength = SubKeyName.Length;
@@ -566,22 +569,22 @@ RegpCopyTree(IN HKEY hKeySrc,
                     ClassName.Length = Info.KeyNode->ClassLength;
                     ClassName.MaximumLength = ClassName.Length;
                     ClassName.Buffer = (PWSTR)((ULONG_PTR)Info.KeyNode + Info.KeyNode->ClassOffset);
-                    
+
                     /* open the subkey with sufficient rights */
-                    
+
                     InitializeObjectAttributes(&ObjectAttributes,
                                                &SubKeyName,
                                                OBJ_CASE_INSENSITIVE,
                                                copyKeys->hKeySrc,
                                                NULL);
-                    
+
                     Status2 = NtOpenKey(&KeyHandle,
                                         KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
                                         &ObjectAttributes);
                     if (NT_SUCCESS(Status2))
                     {
                         /* FIXME - attempt to query the security information */
-                        
+
                         InitializeObjectAttributes(&ObjectAttributes,
                                                &SubKeyName,
                                                OBJ_CASE_INSENSITIVE,
@@ -612,7 +615,7 @@ RegpCopyTree(IN HKEY hKeySrc,
                             {
                                 NtClose(KeyHandle);
                                 NtClose(NewKeyHandle);
-                                
+
                                 Status2 = STATUS_INSUFFICIENT_RESOURCES;
                             }
                         }
@@ -621,12 +624,12 @@ RegpCopyTree(IN HKEY hKeySrc,
                             NtClose(KeyHandle);
                         }
                     }
-                    
+
                     if (!NT_SUCCESS(Status2) && NT_SUCCESS(Status))
                     {
                         Status = Status2;
                     }
-                    
+
                     Index++;
                 }
                 else if (Status2 == STATUS_BUFFER_OVERFLOW)
@@ -678,7 +681,7 @@ RegpCopyTree(IN HKEY hKeySrc,
             {
                 NtClose(copyKeys->hKeyDest);
             }
-            
+
             RemoveEntryList(&copyKeys->ListEntry);
 
             RtlFreeHeap(ProcessHeap,
@@ -688,7 +691,7 @@ RegpCopyTree(IN HKEY hKeySrc,
     }
     else
         Status = STATUS_INSUFFICIENT_RESOURCES;
-    
+
     RtlFreeHeap(ProcessHeap,
                 0,
                 Info.Buffer);
@@ -709,14 +712,14 @@ RegCopyTreeW(IN HKEY hKeySrc,
 {
     HANDLE DestKeyHandle, KeyHandle, CurKey, SubKeyHandle = NULL;
     NTSTATUS Status;
-    
+
     Status = MapDefaultKey(&KeyHandle,
                            hKeySrc);
     if (!NT_SUCCESS(Status))
     {
         return RtlNtStatusToDosError(Status);
     }
-    
+
     Status = MapDefaultKey(&DestKeyHandle,
                            hKeyDest);
     if (!NT_SUCCESS(Status))
@@ -745,30 +748,30 @@ RegCopyTreeW(IN HKEY hKeySrc,
         {
             goto Cleanup;
         }
-        
+
         CurKey = SubKeyHandle;
     }
     else
         CurKey = KeyHandle;
-    
+
     Status = RegpCopyTree(CurKey,
                           hKeyDest);
-    
+
     if (SubKeyHandle != NULL)
     {
         NtClose(SubKeyHandle);
     }
-    
+
 Cleanup:
     ClosePredefKey(DestKeyHandle);
 Cleanup2:
     ClosePredefKey(KeyHandle);
-    
+
     if (!NT_SUCCESS(Status))
     {
         return RtlNtStatusToDosError(Status);
     }
-    
+
     return ERROR_SUCCESS;
 }
 
@@ -785,7 +788,7 @@ RegCopyTreeA(IN HKEY hKeySrc,
 {
     UNICODE_STRING SubKeyName = {0};
     LONG Ret;
-    
+
     if (lpSubKey != NULL &&
         !RtlCreateUnicodeStringFromAsciiz(&SubKeyName,
                                           (LPSTR)lpSubKey))
@@ -798,7 +801,7 @@ RegCopyTreeA(IN HKEY hKeySrc,
                        hKeyDest);
 
     RtlFreeUnicodeString(&SubKeyName);
-    
+
     return Ret;
 }
 
@@ -809,13 +812,13 @@ RegCopyTreeA(IN HKEY hKeySrc,
  * @implemented
  */
 LONG STDCALL
-RegConnectRegistryA (IN LPCSTR lpMachineName,
-                     IN HKEY hKey,
-                     OUT PHKEY phkResult)
+RegConnectRegistryA(IN LPCSTR lpMachineName,
+                    IN HKEY hKey,
+                    OUT PHKEY phkResult)
 {
     UNICODE_STRING MachineName = {0};
     LONG Ret;
-    
+
     if (lpMachineName != NULL &&
         !RtlCreateUnicodeStringFromAsciiz(&MachineName,
                                           (LPSTR)lpMachineName))
@@ -828,7 +831,7 @@ RegConnectRegistryA (IN LPCSTR lpMachineName,
                               phkResult);
 
     RtlFreeUnicodeString(&MachineName);
-    
+
     return Ret;
 }
 
@@ -839,12 +842,43 @@ RegConnectRegistryA (IN LPCSTR lpMachineName,
  * @unimplemented
  */
 LONG STDCALL
-RegConnectRegistryW (LPCWSTR lpMachineName,
-                    HKEY hKey,
-                    PHKEY phkResult)
+RegConnectRegistryW(LPCWSTR lpMachineName,
+                    HKEY hKey,
+                    PHKEY phkResult)
 {
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return ERROR_CALL_NOT_IMPLEMENTED;
+    LONG ret;
+
+    TRACE("(%s,%p,%p): stub\n",debugstr_w(lpMachineName),hKey,phkResult);
+
+    if (!lpMachineName || !*lpMachineName)
+    {
+        /* Use the local machine name */
+        ret = RegOpenKeyW( hKey, NULL, phkResult );
+    }
+    else
+    {
+        WCHAR compName[MAX_COMPUTERNAME_LENGTH + 1];
+        DWORD len = sizeof(compName) / sizeof(WCHAR);
+
+        /* MSDN says lpMachineName must start with \\ : not so */
+        if( lpMachineName[0] == '\\' &&  lpMachineName[1] == '\\')
+            lpMachineName += 2;
+
+        if (GetComputerNameW(compName, &len))
+        {
+            if (!_wcsicmp(lpMachineName, compName))
+                ret = RegOpenKeyW(hKey, NULL, phkResult);
+            else
+            {
+                FIXME("Connect to %s is not supported.\n",debugstr_w(lpMachineName));
+                ret = ERROR_BAD_NETPATH;
+            }
+        }
+        else
+            ret = GetLastError();
+    }
+
+    return ret;
 }
 
 
@@ -855,105 +889,110 @@ RegConnectRegistryW (LPCWSTR lpMachineName,
  */
 static NTSTATUS
 CreateNestedKey(PHKEY KeyHandle,
-               POBJECT_ATTRIBUTES ObjectAttributes,
+                POBJECT_ATTRIBUTES ObjectAttributes,
                 PUNICODE_STRING ClassString,
                 DWORD dwOptions,
                 REGSAM samDesired,
                 DWORD *lpdwDisposition)
 {
-  OBJECT_ATTRIBUTES LocalObjectAttributes;
-  UNICODE_STRING LocalKeyName;
-  ULONG Disposition;
-  NTSTATUS Status;
-  ULONG FullNameLength;
-  ULONG Length;
-  PWCHAR Ptr;
-  HANDLE LocalKeyHandle;
-
-  Status = NtCreateKey((PHANDLE) KeyHandle,
-                       samDesired,
-                       ObjectAttributes,
-                       0,
-                       ClassString,
-                       dwOptions,
-                       (PULONG)lpdwDisposition);
-  TRACE("NtCreateKey(%wZ) called (Status %lx)\n", ObjectAttributes->ObjectName, Status);
-  if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
-    return Status;
-
-  /* Copy object attributes */
-  RtlCopyMemory (&LocalObjectAttributes,
-                ObjectAttributes,
-                sizeof(OBJECT_ATTRIBUTES));
-  RtlCreateUnicodeString (&LocalKeyName,
-                         ObjectAttributes->ObjectName->Buffer);
-  LocalObjectAttributes.ObjectName = &LocalKeyName;
-  FullNameLength = LocalKeyName.Length / sizeof(WCHAR);
+    OBJECT_ATTRIBUTES LocalObjectAttributes;
+    UNICODE_STRING LocalKeyName;
+    ULONG Disposition;
+    NTSTATUS Status;
+    ULONG FullNameLength;
+    ULONG Length;
+    PWCHAR Ptr;
+    HANDLE LocalKeyHandle;
+
+    Status = NtCreateKey((PHANDLE) KeyHandle,
+                         samDesired,
+                         ObjectAttributes,
+                         0,
+                         ClassString,
+                         dwOptions,
+                         (PULONG)lpdwDisposition);
+    TRACE("NtCreateKey(%wZ) called (Status %lx)\n", ObjectAttributes->ObjectName, Status);
+    if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
+        return Status;
+
+    /* Copy object attributes */
+    RtlCopyMemory(&LocalObjectAttributes,
+                  ObjectAttributes,
+                  sizeof(OBJECT_ATTRIBUTES));
+    RtlCreateUnicodeString(&LocalKeyName,
+                           ObjectAttributes->ObjectName->Buffer);
+    LocalObjectAttributes.ObjectName = &LocalKeyName;
+    FullNameLength = LocalKeyName.Length / sizeof(WCHAR);
+
+  LocalKeyHandle = NULL;
+
+    /* Remove the last part of the key name and try to create the key again. */
+    while (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+    {
+        Ptr = wcsrchr(LocalKeyName.Buffer, '\\');
+        if (Ptr == NULL || Ptr == LocalKeyName.Buffer)
+        {
+            Status = STATUS_UNSUCCESSFUL;
+            break;
+        }
 
-  /* Remove the last part of the key name and try to create the key again. */
-  while (Status == STATUS_OBJECT_NAME_NOT_FOUND)
-    {
-      Ptr = wcsrchr (LocalKeyName.Buffer, '\\');
-      if (Ptr == NULL || Ptr == LocalKeyName.Buffer)
-       {
-         Status = STATUS_UNSUCCESSFUL;
-         break;
-       }
-      *Ptr = (WCHAR)0;
-      LocalKeyName.Length = wcslen (LocalKeyName.Buffer) * sizeof(WCHAR);
+        *Ptr = (WCHAR)0;
+        LocalKeyName.Length = wcslen(LocalKeyName.Buffer) * sizeof(WCHAR);
 
-      Status = NtCreateKey (&LocalKeyHandle,
-                           KEY_ALL_ACCESS,
-                           &LocalObjectAttributes,
-                           0,
-                           NULL,
-                           0,
-                           &Disposition);
-      TRACE("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status);
+        Status = NtCreateKey(&LocalKeyHandle,
+                             KEY_CREATE_SUB_KEY,
+                             &LocalObjectAttributes,
+                             0,
+                             NULL,
+                             0,
+                             &Disposition);
+        TRACE("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status);
     }
 
-  if (!NT_SUCCESS(Status))
+    if (!NT_SUCCESS(Status))
     {
-      RtlFreeUnicodeString (&LocalKeyName);
-      return Status;
+        RtlFreeUnicodeString(&LocalKeyName);
+        return Status;
     }
 
-  /* Add removed parts of the key name and create them too. */
-  Length = wcslen (LocalKeyName.Buffer);
-  while (TRUE)
+    /* Add removed parts of the key name and create them too. */
+    Length = wcslen(LocalKeyName.Buffer);
+    while (TRUE)
     {
-      NtClose (LocalKeyHandle);
+        if (LocalKeyHandle)
+            NtClose (LocalKeyHandle);
 
-      LocalKeyName.Buffer[Length] = L'\\';
-      Length = wcslen (LocalKeyName.Buffer);
-      LocalKeyName.Length = Length * sizeof(WCHAR);
+        LocalKeyName.Buffer[Length] = L'\\';
+        Length = wcslen (LocalKeyName.Buffer);
+        LocalKeyName.Length = Length * sizeof(WCHAR);
 
-      if (Length == FullNameLength)
+        if (Length == FullNameLength)
         {
-          Status = NtCreateKey((PHANDLE) KeyHandle,
-                               samDesired,
-                               ObjectAttributes,
-                               0,
-                               ClassString,
-                               dwOptions,
-                               (PULONG)lpdwDisposition);
-          break;
+            Status = NtCreateKey((PHANDLE) KeyHandle,
+                                 samDesired,
+                                 ObjectAttributes,
+                                 0,
+                                 ClassString,
+                                 dwOptions,
+                                 (PULONG)lpdwDisposition);
+            break;
         }
-      Status = NtCreateKey (&LocalKeyHandle,
-                           KEY_CREATE_SUB_KEY,
-                           &LocalObjectAttributes,
-                           0,
-                           NULL,
-                           0,
-                           &Disposition);
-      TRACE("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status);
-      if (!NT_SUCCESS(Status))
-       break;
+
+        Status = NtCreateKey(&LocalKeyHandle,
+                             KEY_CREATE_SUB_KEY,
+                             &LocalObjectAttributes,
+                             0,
+                             NULL,
+                             0,
+                             &Disposition);
+        TRACE("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status);
+        if (!NT_SUCCESS(Status))
+            break;
     }
 
-  RtlFreeUnicodeString (&LocalKeyName);
+    RtlFreeUnicodeString(&LocalKeyName);
 
-  return Status;
+    return Status;
 }
 
 
@@ -963,67 +1002,71 @@ CreateNestedKey(PHKEY KeyHandle,
  * @implemented
  */
 LONG STDCALL
-RegCreateKeyExA (HKEY hKey,
-                LPCSTR lpSubKey,
-                DWORD Reserved,
-                LPSTR lpClass,
-                DWORD dwOptions,
-                REGSAM samDesired,
-                LPSECURITY_ATTRIBUTES lpSecurityAttributes,
-                PHKEY phkResult,
-                LPDWORD lpdwDisposition)
+RegCreateKeyExA(HKEY hKey,
+                LPCSTR lpSubKey,
+                DWORD Reserved,
+                LPSTR lpClass,
+                DWORD dwOptions,
+                REGSAM samDesired,
+                LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+                PHKEY phkResult,
+                LPDWORD lpdwDisposition)
 {
-  UNICODE_STRING SubKeyString;
-  UNICODE_STRING ClassString;
-  OBJECT_ATTRIBUTES Attributes;
-  HANDLE ParentKey;
-  NTSTATUS Status;
+    UNICODE_STRING SubKeyString;
+    UNICODE_STRING ClassString;
+    OBJECT_ATTRIBUTES Attributes;
+    HANDLE ParentKey;
+    NTSTATUS Status;
 
-  TRACE("RegCreateKeyExA() called\n");
+    TRACE("RegCreateKeyExA() called\n");
 
-  /* get the real parent key */
-  Status = MapDefaultKey (&ParentKey,
-                          hKey);
-  if (!NT_SUCCESS(Status))
+    if (lpSecurityAttributes && lpSecurityAttributes->nLength != sizeof(SECURITY_ATTRIBUTES))
+        return ERROR_INVALID_USER_BUFFER;
+
+    /* get the real parent key */
+    Status = MapDefaultKey(&ParentKey,
+                           hKey);
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
-  TRACE("ParentKey %x\n", (ULONG)ParentKey);
 
-  if (lpClass != NULL)
+    TRACE("ParentKey %x\n", (ULONG)ParentKey);
+
+    if (lpClass != NULL)
     {
-      RtlCreateUnicodeStringFromAsciiz (&ClassString,
-                                       lpClass);
+        RtlCreateUnicodeStringFromAsciiz(&ClassString,
+                                         lpClass);
     }
 
-  RtlCreateUnicodeStringFromAsciiz(&SubKeyString,
-                                  (LPSTR)lpSubKey);
-  InitializeObjectAttributes (&Attributes,
-                             &SubKeyString,
-                             OBJ_CASE_INSENSITIVE,
-                             (HANDLE)ParentKey,
-                             (PSECURITY_DESCRIPTOR)lpSecurityAttributes);
-  Status = CreateNestedKey(phkResult,
-                          &Attributes,
-                          (lpClass == NULL)? NULL : &ClassString,
-                          dwOptions,
-                          samDesired,
-                          lpdwDisposition);
-  RtlFreeUnicodeString (&SubKeyString);
-  if (lpClass != NULL)
+    RtlCreateUnicodeStringFromAsciiz(&SubKeyString,
+                                     (LPSTR)lpSubKey);
+    InitializeObjectAttributes(&Attributes,
+                               &SubKeyString,
+                               OBJ_CASE_INSENSITIVE,
+                               (HANDLE)ParentKey,
+                               lpSecurityAttributes ? (PSECURITY_DESCRIPTOR)lpSecurityAttributes->lpSecurityDescriptor : NULL);
+    Status = CreateNestedKey(phkResult,
+                             &Attributes,
+                             (lpClass == NULL)? NULL : &ClassString,
+                             dwOptions,
+                             samDesired,
+                             lpdwDisposition);
+    RtlFreeUnicodeString(&SubKeyString);
+    if (lpClass != NULL)
     {
-      RtlFreeUnicodeString (&ClassString);
+        RtlFreeUnicodeString(&ClassString);
     }
 
-  ClosePredefKey(ParentKey);
+    ClosePredefKey(ParentKey);
 
-  TRACE("Status %x\n", Status);
-  if (!NT_SUCCESS(Status))
+    TRACE("Status %x\n", Status);
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  return ERROR_SUCCESS;
+    return ERROR_SUCCESS;
 }
 
 
@@ -1033,58 +1076,62 @@ RegCreateKeyExA (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegCreateKeyExW (HKEY hKey,
-                LPCWSTR lpSubKey,
-                DWORD Reserved,
-                LPWSTR lpClass,
-                DWORD dwOptions,
-                REGSAM samDesired,
-                LPSECURITY_ATTRIBUTES lpSecurityAttributes,
-                PHKEY phkResult,
-                LPDWORD lpdwDisposition)
+RegCreateKeyExW(HKEY hKey,
+                LPCWSTR lpSubKey,
+                DWORD Reserved,
+                LPWSTR lpClass,
+                DWORD dwOptions,
+                REGSAM samDesired,
+                LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+                PHKEY phkResult,
+                LPDWORD lpdwDisposition)
 {
-  UNICODE_STRING SubKeyString;
-  UNICODE_STRING ClassString;
-  OBJECT_ATTRIBUTES Attributes;
-  HANDLE ParentKey;
-  NTSTATUS Status;
+    UNICODE_STRING SubKeyString;
+    UNICODE_STRING ClassString;
+    OBJECT_ATTRIBUTES Attributes;
+    HANDLE ParentKey;
+    NTSTATUS Status;
 
-  TRACE("RegCreateKeyExW() called\n");
+    TRACE("RegCreateKeyExW() called\n");
 
-  /* get the real parent key */
-  Status = MapDefaultKey (&ParentKey,
-                          hKey);
-  if (!NT_SUCCESS(Status))
+    if (lpSecurityAttributes && lpSecurityAttributes->nLength != sizeof(SECURITY_ATTRIBUTES))
+        return ERROR_INVALID_USER_BUFFER;
+
+    /* get the real parent key */
+    Status = MapDefaultKey(&ParentKey,
+                           hKey);
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError(Status);
+        return RtlNtStatusToDosError(Status);
     }
-  TRACE("ParentKey %x\n", (ULONG)ParentKey);
 
-  RtlInitUnicodeString (&ClassString,
-                       lpClass);
-  RtlInitUnicodeString (&SubKeyString,
-                       lpSubKey);
-  InitializeObjectAttributes (&Attributes,
-                             &SubKeyString,
-                             OBJ_CASE_INSENSITIVE,
-                             (HANDLE)ParentKey,
-                             (PSECURITY_DESCRIPTOR)lpSecurityAttributes);
-  Status = CreateNestedKey(phkResult,
-                          &Attributes,
-                           (lpClass == NULL)? NULL : &ClassString,
-                           dwOptions,
-                           samDesired,
-                           lpdwDisposition);
+    TRACE("ParentKey %x\n", (ULONG)ParentKey);
 
-  ClosePredefKey(ParentKey);
+    RtlInitUnicodeString(&ClassString,
+                         lpClass);
+    RtlInitUnicodeString(&SubKeyString,
+                         lpSubKey);
+    InitializeObjectAttributes(&Attributes,
+                               &SubKeyString,
+                               OBJ_CASE_INSENSITIVE,
+                               (HANDLE)ParentKey,
+                               lpSecurityAttributes ? (PSECURITY_DESCRIPTOR)lpSecurityAttributes->lpSecurityDescriptor : NULL);
+    Status = CreateNestedKey(phkResult,
+                             &Attributes,
+                             (lpClass == NULL)? NULL : &ClassString,
+                             dwOptions,
+                             samDesired,
+                             lpdwDisposition);
 
-  TRACE("Status %x\n", Status);
-  if (!NT_SUCCESS(Status))
+    ClosePredefKey(ParentKey);
+
+    TRACE("Status %x\n", Status);
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  return ERROR_SUCCESS;
+    return ERROR_SUCCESS;
 }
 
 
@@ -1094,19 +1141,19 @@ RegCreateKeyExW (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegCreateKeyA (HKEY hKey,
-              LPCSTR lpSubKey,
-              PHKEY phkResult)
+RegCreateKeyA(HKEY hKey,
+              LPCSTR lpSubKey,
+              PHKEY phkResult)
 {
-  return RegCreateKeyExA (hKey,
-                         lpSubKey,
-                         0,
-                         NULL,
-                         0,
-                         MAXIMUM_ALLOWED,
-                         NULL,
-                         phkResult,
-                         NULL);
+    return RegCreateKeyExA(hKey,
+                           lpSubKey,
+                           0,
+                           NULL,
+                           0,
+                           MAXIMUM_ALLOWED,
+                           NULL,
+                           phkResult,
+                           NULL);
 }
 
 
@@ -1116,19 +1163,19 @@ RegCreateKeyA (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegCreateKeyW (HKEY hKey,
-              LPCWSTR lpSubKey,
-              PHKEY phkResult)
+RegCreateKeyW(HKEY hKey,
+              LPCWSTR lpSubKey,
+              PHKEY phkResult)
 {
-  return RegCreateKeyExW (hKey,
-                         lpSubKey,
-                         0,
-                         NULL,
-                         0,
-                         MAXIMUM_ALLOWED,
-                         NULL,
-                         phkResult,
-                         NULL);
+    return RegCreateKeyExW(hKey,
+                           lpSubKey,
+                           0,
+                           NULL,
+                           0,
+                           MAXIMUM_ALLOWED,
+                           NULL,
+                           phkResult,
+                           NULL);
 }
 
 
@@ -1138,51 +1185,58 @@ RegCreateKeyW (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegDeleteKeyA (HKEY hKey,
-              LPCSTR lpSubKey)
+RegDeleteKeyA(HKEY hKey,
+              LPCSTR lpSubKey)
 {
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  UNICODE_STRING SubKeyName;
-  HANDLE ParentKey;
-  HANDLE TargetKey;
-  NTSTATUS Status;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING SubKeyName;
+    HANDLE ParentKey;
+    HANDLE TargetKey;
+    NTSTATUS Status;
 
-  Status = MapDefaultKey (&ParentKey,
-                          hKey);
-  if (!NT_SUCCESS(Status))
+    /* Make sure we got a subkey */
+    if (!lpSubKey)
     {
-      return RtlNtStatusToDosError (Status);
+        /* Fail */
+        return ERROR_INVALID_PARAMETER;
     }
 
-  RtlCreateUnicodeStringFromAsciiz (&SubKeyName,
-                                   (LPSTR)lpSubKey);
-  InitializeObjectAttributes(&ObjectAttributes,
-                            &SubKeyName,
-                            OBJ_CASE_INSENSITIVE,
-                            ParentKey,
-                            NULL);
+    Status = MapDefaultKey(&ParentKey,
+                           hKey);
+    if (!NT_SUCCESS(Status))
+    {
+        return RtlNtStatusToDosError(Status);
+    }
+
+    RtlCreateUnicodeStringFromAsciiz(&SubKeyName,
+                                     (LPSTR)lpSubKey);
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &SubKeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               ParentKey,
+                               NULL);
 
-  Status = NtOpenKey (&TargetKey,
-                     DELETE,
-                     &ObjectAttributes);
-  RtlFreeUnicodeString (&SubKeyName);
-  if (!NT_SUCCESS(Status))
+    Status = NtOpenKey(&TargetKey,
+                       DELETE,
+                       &ObjectAttributes);
+    RtlFreeUnicodeString(&SubKeyName);
+    if (!NT_SUCCESS(Status))
     {
-      goto Cleanup;
+        goto Cleanup;
     }
 
-  Status = NtDeleteKey (TargetKey);
-  NtClose (TargetKey);
-  
+    Status = NtDeleteKey(TargetKey);
+    NtClose (TargetKey);
+
 Cleanup:
-  ClosePredefKey(ParentKey);
+    ClosePredefKey(ParentKey);
 
-  if (!NT_SUCCESS(Status))
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError(Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  return ERROR_SUCCESS;
+    return ERROR_SUCCESS;
 }
 
 
@@ -1192,49 +1246,90 @@ Cleanup:
  * @implemented
  */
 LONG STDCALL
-RegDeleteKeyW (HKEY hKey,
-              LPCWSTR lpSubKey)
+RegDeleteKeyW(HKEY hKey,
+              LPCWSTR lpSubKey)
 {
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  UNICODE_STRING SubKeyName;
-  HANDLE ParentKey;
-  HANDLE TargetKey;
-  NTSTATUS Status;
-
-  Status = MapDefaultKey (&ParentKey,
-                          hKey);
-  if (!NT_SUCCESS(Status))
-    {
-      return RtlNtStatusToDosError (Status);
-    }
-
-  RtlInitUnicodeString (&SubKeyName,
-                       (LPWSTR)lpSubKey);
-  InitializeObjectAttributes (&ObjectAttributes,
-                             &SubKeyName,
-                             OBJ_CASE_INSENSITIVE,
-                             ParentKey,
-                             NULL);
-  Status = NtOpenKey (&TargetKey,
-                     DELETE,
-                     &ObjectAttributes);
-  if (!NT_SUCCESS(Status))
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING SubKeyName;
+    HANDLE ParentKey;
+    HANDLE TargetKey;
+    NTSTATUS Status;
+
+    /* Make sure we got a subkey */
+    if (!lpSubKey)
     {
-      goto Cleanup;
+        /* Fail */
+        return ERROR_INVALID_PARAMETER;
+    }
+
+    Status = MapDefaultKey(&ParentKey,
+                           hKey);
+    if (!NT_SUCCESS(Status))
+    {
+        return RtlNtStatusToDosError(Status);
+    }
+
+    RtlInitUnicodeString(&SubKeyName,
+                         (LPWSTR)lpSubKey);
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &SubKeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               ParentKey,
+                               NULL);
+    Status = NtOpenKey(&TargetKey,
+                       DELETE,
+                       &ObjectAttributes);
+    if (!NT_SUCCESS(Status))
+    {
+        goto Cleanup;
     }
 
-  Status = NtDeleteKey (TargetKey);
-  NtClose (TargetKey);
-  
+    Status = NtDeleteKey(TargetKey);
+    NtClose(TargetKey);
+
 Cleanup:
-  ClosePredefKey(ParentKey);
+    ClosePredefKey(ParentKey);
 
-  if (!NT_SUCCESS(Status))
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  return ERROR_SUCCESS;
+    return ERROR_SUCCESS;
+}
+
+
+/************************************************************************
+ *  RegDeleteKeyExA
+ *
+ * @unimplemented
+ */
+LONG
+WINAPI
+RegDeleteKeyExA(HKEY hKey,
+                LPCSTR lpSubKey,
+                REGSAM samDesired,
+                DWORD Reserved)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/************************************************************************
+ *  RegDeleteKeyExW
+ *
+ * @unimplemented
+ */
+LONG
+WINAPI
+RegDeleteKeyExW(HKEY hKey,
+                LPCWSTR lpSubKey,
+                REGSAM samDesired,
+                DWORD Reserved)
+{
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
@@ -1280,7 +1375,7 @@ RegDeleteKeyValueW(IN HKEY hKey,
         {
             goto Cleanup;
         }
-        
+
         CurKey = SubKeyHandle;
     }
     else
@@ -1296,7 +1391,7 @@ RegDeleteKeyValueW(IN HKEY hKey,
     {
         NtClose(SubKeyHandle);
     }
-    
+
 Cleanup:
     ClosePredefKey(KeyHandle);
 
@@ -1321,7 +1416,7 @@ RegDeleteKeyValueA(IN HKEY hKey,
 {
     UNICODE_STRING SubKey = {0}, ValueName = {0};
     LONG Ret;
-    
+
     if (lpSubKey != NULL &&
         !RtlCreateUnicodeStringFromAsciiz(&SubKey,
                                           (LPSTR)lpSubKey))
@@ -1343,11 +1438,12 @@ RegDeleteKeyValueA(IN HKEY hKey,
 
     RtlFreeUnicodeString(&SubKey);
     RtlFreeUnicodeString(&ValueName);
-    
+
     return Ret;
 }
 
-
+#if 0
+// Non-recursive RegDeleteTreeW implementation by Thomas, however it needs bugfixing
 static NTSTATUS
 RegpDeleteTree(IN HKEY hKey)
 {
@@ -1365,11 +1461,11 @@ RegpDeleteTree(IN HKEY hKey)
     PREG_DEL_KEYS KeyDelRoot;
     NTSTATUS Status = STATUS_SUCCESS;
     NTSTATUS Status2 = STATUS_SUCCESS;
-    
+
     InitializeListHead(&delQueueHead);
-    
+
     ProcessHeap = RtlGetProcessHeap();
-    
+
     /* NOTE: no need to allocate enough memory for an additional KEY_BASIC_INFORMATION
              structure for the root key, we only do that for subkeys as we need to
              allocate REGP_DEL_KEYS structures anyway! */
@@ -1406,7 +1502,7 @@ ReadFirstSubKey:
             {
                 OBJECT_ATTRIBUTES ObjectAttributes;
                 UNICODE_STRING SubKeyName;
-                
+
                 ASSERT(newDelKeys != NULL);
                 ASSERT(BasicInfo != NULL);
 
@@ -1516,7 +1612,7 @@ SubKeyFailureNoFree:
             }
 
             Status2 = NtDeleteKey(delKeys->KeyHandle);
-            
+
             /* NOTE: do NOT close the handle anymore, it's invalid already! */
 
             if (!NT_SUCCESS(Status2))
@@ -1536,7 +1632,7 @@ SubKeyFailureNoFree:
                     Status = Status2;
                 }
             }
-            
+
             /* remove the entry from the list */
             RemoveEntryList(&delKeys->ListEntry);
 
@@ -1592,7 +1688,7 @@ RegDeleteTreeW(IN HKEY hKey,
         {
             goto Cleanup;
         }
-        
+
         CurKey = SubKeyHandle;
     }
     else
@@ -1608,7 +1704,7 @@ RegDeleteTreeW(IN HKEY hKey,
         {
             ClosePredefKey(KeyHandle);
         }
-        
+
         return ERROR_SUCCESS;
     }
     else
@@ -1621,9 +1717,105 @@ RegDeleteTreeW(IN HKEY hKey,
 
 Cleanup:
         ClosePredefKey(KeyHandle);
-        
+
+        return RtlNtStatusToDosError(Status);
+    }
+}
+#endif
+
+
+/************************************************************************
+ *  RegDeleteTreeW
+ *
+ * @implemented
+ */
+LSTATUS
+WINAPI
+RegDeleteTreeW(HKEY hKey,
+               LPCWSTR lpszSubKey)
+{
+    LONG ret;
+    DWORD dwMaxSubkeyLen, dwMaxValueLen;
+    DWORD dwMaxLen, dwSize;
+    NTSTATUS Status;
+    HANDLE KeyHandle;
+    HKEY hSubKey;
+    WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
+
+    TRACE("(hkey=%p,%p %s)\n", hKey, lpszSubKey, debugstr_w(lpszSubKey));
+
+    Status = MapDefaultKey(&KeyHandle,
+                           hKey);
+    if (!NT_SUCCESS(Status))
+    {
         return RtlNtStatusToDosError(Status);
     }
+
+    hSubKey = KeyHandle;
+
+    if(lpszSubKey)
+    {
+        ret = RegOpenKeyExW(KeyHandle, lpszSubKey, 0, KEY_READ, &hSubKey);
+        if (ret)
+        {
+            ClosePredefKey(KeyHandle);
+            return ret;
+        }
+    }
+
+    /* Get highest length for keys, values */
+    ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
+            &dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
+    if (ret) goto cleanup;
+
+    dwMaxSubkeyLen++;
+    dwMaxValueLen++;
+    dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
+    if (dwMaxLen > sizeof(szNameBuf)/sizeof(WCHAR))
+    {
+        /* Name too big: alloc a buffer for it */
+        if (!(lpszName = RtlAllocateHeap( RtlGetProcessHeap(), 0, dwMaxLen*sizeof(WCHAR))))
+        {
+            ret = ERROR_NOT_ENOUGH_MEMORY;
+            goto cleanup;
+        }
+    }
+
+
+    /* Recursively delete all the subkeys */
+    while (TRUE)
+    {
+        dwSize = dwMaxLen;
+        if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL,
+                          NULL, NULL, NULL)) break;
+
+        ret = RegDeleteTreeW(hSubKey, lpszName);
+        if (ret) goto cleanup;
+    }
+
+    if (lpszSubKey)
+        ret = RegDeleteKeyW(KeyHandle, lpszSubKey);
+    else
+        while (TRUE)
+        {
+            dwSize = dwMaxLen;
+            if (RegEnumValueW(KeyHandle, 0, lpszName, &dwSize,
+                  NULL, NULL, NULL, NULL)) break;
+
+            ret = RegDeleteValueW(KeyHandle, lpszName);
+            if (ret) goto cleanup;
+        }
+
+cleanup:
+    /* Free buffer if allocated */
+    if (lpszName != szNameBuf)
+        RtlFreeHeap( RtlGetProcessHeap(), 0, lpszName);
+    if(lpszSubKey)
+        RegCloseKey(hSubKey);
+
+    ClosePredefKey(KeyHandle);
+
+    return ret;
 }
 
 
@@ -1663,7 +1855,7 @@ RegDeleteTreeA(IN HKEY hKey,
 LONG WINAPI
 RegDisableReflectionKey(IN HKEY hBase)
 {
-    DPRINT1("RegDisableReflectionKey(0x%p) UNIMPLEMENTED!\n", hBase);
+    FIXME("RegDisableReflectionKey(0x%p) UNIMPLEMENTED!\n", hBase);
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
@@ -1676,27 +1868,306 @@ RegDisableReflectionKey(IN HKEY hBase)
 LONG WINAPI
 RegEnableReflectionKey(IN HKEY hBase)
 {
-    DPRINT1("RegEnableReflectionKey(0x%p) UNIMPLEMENTED!\n", hBase);
+    FIXME("RegEnableReflectionKey(0x%p) UNIMPLEMENTED!\n", hBase);
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
-/************************************************************************
- *  RegSetKeyValueW
+/******************************************************************************
+ * RegpApplyRestrictions   [internal]
  *
- * @implemented
+ * Helper function for RegGetValueA/W.
  */
-LONG STDCALL
-RegSetKeyValueW(IN HKEY hKey,
-                IN LPCWSTR lpSubKey  OPTIONAL,
-                IN LPCWSTR lpValueName  OPTIONAL,
-                IN DWORD dwType,
-                IN LPCVOID lpData  OPTIONAL,
-                IN DWORD cbData)
+static VOID
+RegpApplyRestrictions(DWORD dwFlags,
+                      DWORD dwType,
+                      DWORD cbData,
+                      PLONG ret)
 {
-    HANDLE KeyHandle, CurKey, SubKeyHandle = NULL;
-    NTSTATUS Status;
-    LONG Ret;
+    /* Check if the type is restricted by the passed flags */
+    if (*ret == ERROR_SUCCESS || *ret == ERROR_MORE_DATA)
+    {
+        DWORD dwMask = 0;
+
+        switch (dwType)
+        {
+        case REG_NONE: dwMask = RRF_RT_REG_NONE; break;
+        case REG_SZ: dwMask = RRF_RT_REG_SZ; break;
+        case REG_EXPAND_SZ: dwMask = RRF_RT_REG_EXPAND_SZ; break;
+        case REG_MULTI_SZ: dwMask = RRF_RT_REG_MULTI_SZ; break;
+        case REG_BINARY: dwMask = RRF_RT_REG_BINARY; break;
+        case REG_DWORD: dwMask = RRF_RT_REG_DWORD; break;
+        case REG_QWORD: dwMask = RRF_RT_REG_QWORD; break;
+        }
+
+        if (dwFlags & dwMask)
+        {
+            /* Type is not restricted, check for size mismatch */
+            if (dwType == REG_BINARY)
+            {
+                DWORD cbExpect = 0;
+
+                if ((dwFlags & RRF_RT_DWORD) == RRF_RT_DWORD)
+                    cbExpect = 4;
+                else if ((dwFlags & RRF_RT_QWORD) == RRF_RT_QWORD)
+                    cbExpect = 8;
+
+                if (cbExpect && cbData != cbExpect)
+                    *ret = ERROR_DATATYPE_MISMATCH;
+            }
+        }
+        else *ret = ERROR_UNSUPPORTED_TYPE;
+    }
+}
+
+
+/******************************************************************************
+ * RegGetValueW   [ADVAPI32.@]
+ *
+ * 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.
+ *  pszSubKey [I] Name of the subkey of hKey.
+ *  pszValue  [I] Name of value under hKey/szSubKey to query.
+ *  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 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 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.
+ *    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;
+    LONG ret;
+
+    TRACE("(%p,%s,%s,%ld,%p,%p,%p=%ld)\n",
+          hKey, debugstr_w(pszSubKey), debugstr_w(pszValue), dwFlags, pdwType,
+          pvData, pcbData, cbData);
+
+    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;
+
+    if (pszSubKey && pszSubKey[0])
+    {
+        ret = RegOpenKeyExW(hKey, pszSubKey, 0, KEY_QUERY_VALUE, &hKey);
+        if (ret != ERROR_SUCCESS) return ret;
+    }
+
+    ret = RegQueryValueExW(hKey, pszValue, NULL, &dwType, pvData, &cbData);
+
+    /* If we are going to expand we need to read in the whole the value even
+     * 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))
+    {
+        do
+        {
+            HeapFree(GetProcessHeap(), 0, pvBuf);
+
+            pvBuf = HeapAlloc(GetProcessHeap(), 0, cbData);
+            if (!pvBuf)
+            {
+                ret = ERROR_NOT_ENOUGH_MEMORY;
+                break;
+            }
+
+            if (ret == ERROR_MORE_DATA || !pvData)
+                ret = RegQueryValueExW(hKey, pszValue, NULL,
+                                       &dwType, pvBuf, &cbData);
+            else
+            {
+                /* Even if cbData was large enough we have to copy the
+                 * string since ExpandEnvironmentStrings can't handle
+                 * overlapping buffers. */
+                CopyMemory(pvBuf, pvData, cbData);
+            }
+
+            /* Both the type or the value itself could have been modified in
+             * between so we have to keep retrying until the buffer is large
+             * enough or we no longer have to expand the value. */
+        }
+        while (dwType == REG_EXPAND_SZ && ret == ERROR_MORE_DATA);
+
+        if (ret == ERROR_SUCCESS)
+        {
+            /* Recheck dwType in case it changed since the first call */
+            if (dwType == REG_EXPAND_SZ)
+            {
+                cbData = ExpandEnvironmentStringsW(pvBuf, pvData,
+                                                   pcbData ? *pcbData : 0) * sizeof(WCHAR);
+                dwType = REG_SZ;
+                if (pvData && pcbData && cbData > *pcbData)
+                    ret = ERROR_MORE_DATA;
+            }
+            else if (pvData)
+                CopyMemory(pvData, pvBuf, *pcbData);
+        }
+
+        HeapFree(GetProcessHeap(), 0, pvBuf);
+    }
+
+    if (pszSubKey && pszSubKey[0])
+        RegCloseKey(hKey);
+
+    RegpApplyRestrictions(dwFlags, dwType, cbData, &ret);
+
+    if (pvData && ret != ERROR_SUCCESS && (dwFlags & RRF_ZEROONFAILURE))
+        ZeroMemory(pvData, *pcbData);
+
+    if (pdwType)
+        *pdwType = dwType;
+
+    if (pcbData)
+        *pcbData = cbData;
+
+    return ret;
+}
+
+
+/******************************************************************************
+ * RegGetValueA   [ADVAPI32.@]
+ *
+ * See RegGetValueW.
+ */
+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;
+    LONG ret;
+
+    TRACE("(%p,%s,%s,%ld,%p,%p,%p=%ld)\n",
+          hKey, pszSubKey, pszValue, dwFlags, pdwType, pvData, pcbData,
+          cbData);
+
+    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;
+
+    if (pszSubKey && pszSubKey[0])
+    {
+        ret = RegOpenKeyExA(hKey, pszSubKey, 0, KEY_QUERY_VALUE, &hKey);
+        if (ret != ERROR_SUCCESS) return ret;
+    }
+
+    ret = RegQueryValueExA(hKey, pszValue, NULL, &dwType, pvData, &cbData);
+
+    /* If we are going to expand we need to read in the whole the value even
+     * 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)))
+    {
+        do {
+            HeapFree(GetProcessHeap(), 0, pvBuf);
+
+            pvBuf = HeapAlloc(GetProcessHeap(), 0, cbData);
+            if (!pvBuf)
+            {
+                ret = ERROR_NOT_ENOUGH_MEMORY;
+                break;
+            }
+
+            if (ret == ERROR_MORE_DATA || !pvData)
+                ret = RegQueryValueExA(hKey, pszValue, NULL,
+                                       &dwType, pvBuf, &cbData);
+            else
+            {
+                /* Even if cbData was large enough we have to copy the
+                 * string since ExpandEnvironmentStrings can't handle
+                 * overlapping buffers. */
+                CopyMemory(pvBuf, pvData, cbData);
+            }
+
+            /* Both the type or the value itself could have been modified in
+             * between so we have to keep retrying until the buffer is large
+             * enough or we no longer have to expand the value. */
+        } while (dwType == REG_EXPAND_SZ && ret == ERROR_MORE_DATA);
+
+        if (ret == ERROR_SUCCESS)
+        {
+            /* Recheck dwType in case it changed since the first call */
+            if (dwType == REG_EXPAND_SZ)
+            {
+                cbData = ExpandEnvironmentStringsA(pvBuf, pvData,
+                                                   pcbData ? *pcbData : 0);
+                dwType = REG_SZ;
+                if(pvData && pcbData && cbData > *pcbData)
+                    ret = ERROR_MORE_DATA;
+            }
+            else if (pvData)
+                CopyMemory(pvData, pvBuf, *pcbData);
+        }
+
+        HeapFree(GetProcessHeap(), 0, pvBuf);
+    }
+
+    if (pszSubKey && pszSubKey[0])
+        RegCloseKey(hKey);
+
+    RegpApplyRestrictions(dwFlags, dwType, cbData, &ret);
+
+    if (pvData && ret != ERROR_SUCCESS && (dwFlags & RRF_ZEROONFAILURE))
+        ZeroMemory(pvData, *pcbData);
+
+    if (pdwType) *pdwType = dwType;
+    if (pcbData) *pcbData = cbData;
+
+    return ret;
+}
+
+
+/************************************************************************
+ *  RegSetKeyValueW
+ *
+ * @implemented
+ */
+LONG STDCALL
+RegSetKeyValueW(IN HKEY hKey,
+                IN LPCWSTR lpSubKey  OPTIONAL,
+                IN LPCWSTR lpValueName  OPTIONAL,
+                IN DWORD dwType,
+                IN LPCVOID lpData  OPTIONAL,
+                IN DWORD cbData)
+{
+    HANDLE KeyHandle, CurKey, SubKeyHandle = NULL;
+    NTSTATUS Status;
+    LONG Ret;
 
     Status = MapDefaultKey(&KeyHandle,
                            hKey);
@@ -1704,7 +2175,7 @@ RegSetKeyValueW(IN HKEY hKey,
     {
         return RtlNtStatusToDosError(Status);
     }
-    
+
     if (lpSubKey != NULL)
     {
         OBJECT_ATTRIBUTES ObjectAttributes;
@@ -1727,12 +2198,12 @@ RegSetKeyValueW(IN HKEY hKey,
             Ret = RtlNtStatusToDosError(Status);
             goto Cleanup;
         }
-        
+
         CurKey = SubKeyHandle;
     }
     else
         CurKey = KeyHandle;
-    
+
     Ret = RegSetValueExW(CurKey,
                          lpValueName,
                          0,
@@ -1744,7 +2215,7 @@ RegSetKeyValueW(IN HKEY hKey,
     {
         NtClose(SubKeyHandle);
     }
-    
+
 Cleanup:
     ClosePredefKey(KeyHandle);
 
@@ -1805,7 +2276,7 @@ RegSetKeyValueA(IN HKEY hKey,
             Ret = RtlNtStatusToDosError(Status);
             goto Cleanup;
         }
-        
+
         CurKey = SubKeyHandle;
     }
     else
@@ -1822,7 +2293,7 @@ RegSetKeyValueA(IN HKEY hKey,
     {
         NtClose(SubKeyHandle);
     }
-    
+
 Cleanup:
     ClosePredefKey(KeyHandle);
 
@@ -1836,34 +2307,34 @@ Cleanup:
  * @implemented
  */
 LONG STDCALL
-RegDeleteValueA (HKEY hKey,
-                LPCSTR lpValueName)
+RegDeleteValueA(HKEY hKey,
+                LPCSTR lpValueName)
 {
-  UNICODE_STRING ValueName;
-  HANDLE KeyHandle;
-  NTSTATUS Status;
+    UNICODE_STRING ValueName;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
 
-  Status = MapDefaultKey (&KeyHandle,
-                          hKey);
-  if (!NT_SUCCESS(Status))
+    Status = MapDefaultKey(&KeyHandle,
+                           hKey);
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  RtlCreateUnicodeStringFromAsciiz (&ValueName,
-                                   (LPSTR)lpValueName);
-  Status = NtDeleteValueKey (KeyHandle,
-                            &ValueName);
-  RtlFreeUnicodeString (&ValueName);
-  
-  ClosePredefKey(KeyHandle);
-  
-  if (!NT_SUCCESS(Status))
+    RtlCreateUnicodeStringFromAsciiz(&ValueName,
+                                     (LPSTR)lpValueName);
+    Status = NtDeleteValueKey(KeyHandle,
+                              &ValueName);
+    RtlFreeUnicodeString (&ValueName);
+
+    ClosePredefKey(KeyHandle);
+
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  return ERROR_SUCCESS;
+    return ERROR_SUCCESS;
 }
 
 
@@ -1873,34 +2344,34 @@ RegDeleteValueA (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegDeleteValueW (HKEY hKey,
-                LPCWSTR lpValueName)
+RegDeleteValueW(HKEY hKey,
+                LPCWSTR lpValueName)
 {
-  UNICODE_STRING ValueName;
-  NTSTATUS Status;
-  HANDLE KeyHandle;
+    UNICODE_STRING ValueName;
+    NTSTATUS Status;
+    HANDLE KeyHandle;
 
-  Status = MapDefaultKey (&KeyHandle,
-                          hKey);
-  if (!NT_SUCCESS(Status))
+    Status = MapDefaultKey(&KeyHandle,
+                           hKey);
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  RtlInitUnicodeString (&ValueName,
-                       (LPWSTR)lpValueName);
+    RtlInitUnicodeString(&ValueName,
+                         (LPWSTR)lpValueName);
 
-  Status = NtDeleteValueKey (KeyHandle,
-                            &ValueName);
+    Status = NtDeleteValueKey(KeyHandle,
+                              &ValueName);
 
-  ClosePredefKey(KeyHandle);
+    ClosePredefKey(KeyHandle);
 
-  if (!NT_SUCCESS(Status))
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  return ERROR_SUCCESS;
+    return ERROR_SUCCESS;
 }
 
 
@@ -1910,22 +2381,22 @@ RegDeleteValueW (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegEnumKeyA (HKEY hKey,
-            DWORD dwIndex,
-            LPSTR lpName,
-            DWORD cbName)
+RegEnumKeyA(HKEY hKey,
+            DWORD dwIndex,
+            LPSTR lpName,
+            DWORD cbName)
 {
-  DWORD dwLength;
-
-  dwLength = cbName;
-  return RegEnumKeyExA (hKey,
-                       dwIndex,
-                       lpName,
-                       &dwLength,
-                       NULL,
-                       NULL,
-                       NULL,
-                       NULL);
+    DWORD dwLength;
+
+    dwLength = cbName;
+    return RegEnumKeyExA(hKey,
+                         dwIndex,
+                         lpName,
+                         &dwLength,
+                         NULL,
+                         NULL,
+                         NULL,
+                         NULL);
 }
 
 
@@ -1935,22 +2406,22 @@ RegEnumKeyA (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegEnumKeyW (HKEY hKey,
-            DWORD dwIndex,
-            LPWSTR lpName,
-            DWORD cbName)
+RegEnumKeyW(HKEY hKey,
+            DWORD dwIndex,
+            LPWSTR lpName,
+            DWORD cbName)
 {
-  DWORD dwLength;
-
-  dwLength = cbName;
-  return RegEnumKeyExW (hKey,
-                       dwIndex,
-                       lpName,
-                       &dwLength,
-                       NULL,
-                       NULL,
-                       NULL,
-                       NULL);
+    DWORD dwLength;
+
+    dwLength = cbName;
+    return RegEnumKeyExW(hKey,
+                         dwIndex,
+                         lpName,
+                         &dwLength,
+                         NULL,
+                         NULL,
+                         NULL,
+                         NULL);
 }
 
 
@@ -1960,362 +2431,371 @@ RegEnumKeyW (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegEnumKeyExA (HKEY hKey,
-              DWORD dwIndex,
-              LPSTR lpName,
-              LPDWORD lpcbName,
-              LPDWORD lpReserved,
-              LPSTR lpClass,
-              LPDWORD lpcbClass,
-              PFILETIME lpftLastWriteTime)
+RegEnumKeyExA(HKEY hKey,
+              DWORD dwIndex,
+              LPSTR lpName,
+              LPDWORD lpcbName,
+              LPDWORD lpReserved,
+              LPSTR lpClass,
+              LPDWORD lpcbClass,
+              PFILETIME lpftLastWriteTime)
 {
-       union
-       {
-               KEY_NODE_INFORMATION Node;
-               KEY_BASIC_INFORMATION Basic;
-       } *KeyInfo;
-
-       UNICODE_STRING StringU;
-       ANSI_STRING StringA;
-       LONG ErrorCode = ERROR_SUCCESS;
-       DWORD NameLength;
-       DWORD ClassLength = 0;
-       DWORD BufferSize;
-       DWORD ResultSize;
-       HANDLE KeyHandle;
-       NTSTATUS Status;
-
-       TRACE("RegEnumKeyExA(hKey 0x%x, dwIndex %d, lpName 0x%x, *lpcbName %d, lpClass 0x%x, lpcbClass %d)\n",
-               hKey, dwIndex, lpName, *lpcbName, lpClass, lpcbClass ? *lpcbClass : 0);
-
-       if ((lpClass) && (!lpcbClass))
-       {
-               return ERROR_INVALID_PARAMETER;
-       }
-
-       Status = MapDefaultKey(&KeyHandle, hKey);
-       if (!NT_SUCCESS(Status))
-       {
-               return RtlNtStatusToDosError (Status);
-       }
-
-       if (*lpcbName > 0)
-       {
-               NameLength = min (*lpcbName - 1 , REG_MAX_NAME_SIZE) * sizeof (WCHAR);
-       }
-       else
-       {
-               NameLength = 0;
-       }
-
-       if (lpClass)
-       {
-               if (*lpcbClass > 0)
-               {
-                       ClassLength = min (*lpcbClass -1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
-               }
-               else
-               {
-                       ClassLength = 0;
-               }
-
-               /* The class name should start at a dword boundary */
-               BufferSize = ((sizeof(KEY_NODE_INFORMATION) + NameLength + 3) & ~3) + ClassLength;
-       }
-       else
-       {
-               BufferSize = sizeof(KEY_BASIC_INFORMATION) + NameLength;
-       }
-
-       KeyInfo = RtlAllocateHeap (ProcessHeap, 0, BufferSize);
-       if (KeyInfo == NULL)
-       {
-               ErrorCode = ERROR_OUTOFMEMORY;
-               goto Cleanup;
-       }
-
-       Status = NtEnumerateKey (KeyHandle,
-                                                               (ULONG)dwIndex,
-                                                               lpClass == NULL ? KeyBasicInformation : KeyNodeInformation,
-                                                               KeyInfo,
-                                                               BufferSize,
-                                                               &ResultSize);
-       TRACE("NtEnumerateKey() returned status 0x%X\n", Status);
-       if (!NT_SUCCESS(Status))
-       {
-               ErrorCode = RtlNtStatusToDosError (Status);
-       }
-       else
-       {
-               if (lpClass == NULL)
-               {
-                       if (KeyInfo->Basic.NameLength > NameLength)
-                       {
-                               ErrorCode = ERROR_BUFFER_OVERFLOW;
-                       }
-                       else
-                       {
-                               StringU.Buffer = KeyInfo->Basic.Name;
-                               StringU.Length = KeyInfo->Basic.NameLength;
-                               StringU.MaximumLength = KeyInfo->Basic.NameLength;
-                       }
-               }
-               else
-               {
-                       if (KeyInfo->Node.NameLength > NameLength ||
-                               KeyInfo->Node.ClassLength > ClassLength)
-                       {
-                               ErrorCode = ERROR_BUFFER_OVERFLOW;
-                       }
-                       else
-                       {
-                               StringA.Buffer = lpClass;
-                               StringA.Length = 0;
-                               StringA.MaximumLength = *lpcbClass;
-                               StringU.Buffer = (PWCHAR)((ULONG_PTR)KeyInfo->Node.Name + KeyInfo->Node.ClassOffset);
-                               StringU.Length = KeyInfo->Node.ClassLength;
-                               StringU.MaximumLength = KeyInfo->Node.ClassLength;
-                               RtlUnicodeStringToAnsiString (&StringA, &StringU, FALSE);
-                               lpClass[StringA.Length] = 0;
-                               *lpcbClass = StringA.Length;
-                               StringU.Buffer = KeyInfo->Node.Name;
-                               StringU.Length = KeyInfo->Node.NameLength;
-                               StringU.MaximumLength = KeyInfo->Node.NameLength;
-                       }
-               }
-
-               if (ErrorCode == ERROR_SUCCESS)
-               {
-                       StringA.Buffer = lpName;
-                       StringA.Length = 0;
-                       StringA.MaximumLength = *lpcbName;
-                       RtlUnicodeStringToAnsiString (&StringA, &StringU, FALSE);
-                       lpName[StringA.Length] = 0;
-                       *lpcbName = StringA.Length;
-                       if (lpftLastWriteTime != NULL)
-                       {
-                               if (lpClass == NULL)
-                               {
-                                       lpftLastWriteTime->dwLowDateTime = KeyInfo->Basic.LastWriteTime.u.LowPart;
-                                       lpftLastWriteTime->dwHighDateTime = KeyInfo->Basic.LastWriteTime.u.HighPart;
-                               }
-                               else
-                               {
-                                       lpftLastWriteTime->dwLowDateTime = KeyInfo->Node.LastWriteTime.u.LowPart;
-                                       lpftLastWriteTime->dwHighDateTime = KeyInfo->Node.LastWriteTime.u.HighPart;
-                               }
-                       }
-               }
-       }
-
-       TRACE("Key Namea0 Length %d\n", StringU.Length);
-       TRACE("Key Namea1 Length %d\n", NameLength);
-       TRACE("Key Namea Length %d\n", *lpcbName);
-       TRACE("Key Namea %s\n", lpName);
-
-       RtlFreeHeap (ProcessHeap,
-               0,
-               KeyInfo);
-
-Cleanup:
-    ClosePredefKey(KeyHandle);
-
-    return ErrorCode;
-}
+    union
+    {
+        KEY_NODE_INFORMATION Node;
+        KEY_BASIC_INFORMATION Basic;
+    } *KeyInfo;
 
+    UNICODE_STRING StringU;
+    ANSI_STRING StringA;
+    LONG ErrorCode = ERROR_SUCCESS;
+    DWORD NameLength;
+    DWORD ClassLength = 0;
+    DWORD BufferSize;
+    ULONG ResultSize;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
 
-/************************************************************************
- *  RegEnumKeyExW
- *
- * @implemented
- */
-LONG STDCALL
-RegEnumKeyExW (HKEY hKey,
-              DWORD dwIndex,
-              LPWSTR lpName,
-              LPDWORD lpcbName,
-              LPDWORD lpReserved,
-              LPWSTR lpClass,
-              LPDWORD lpcbClass,
-              PFILETIME lpftLastWriteTime)
-{
-  union
-  {
-    KEY_NODE_INFORMATION Node;
-    KEY_BASIC_INFORMATION Basic;
-  } *KeyInfo;
+    TRACE("RegEnumKeyExA(hKey 0x%x, dwIndex %d, lpName 0x%x, *lpcbName %d, lpClass 0x%x, lpcbClass %d)\n",
+          hKey, dwIndex, lpName, *lpcbName, lpClass, lpcbClass ? *lpcbClass : 0);
 
-  ULONG BufferSize;
-  ULONG ResultSize;
-  ULONG NameLength;
-  ULONG ClassLength = 0;
-  HANDLE KeyHandle;
-  LONG ErrorCode = ERROR_SUCCESS;
-  NTSTATUS Status;
+    if ((lpClass) && (!lpcbClass))
+    {
+        return ERROR_INVALID_PARAMETER;
+    }
 
-  Status = MapDefaultKey(&KeyHandle,
-                         hKey);
-  if (!NT_SUCCESS(Status))
+    Status = MapDefaultKey(&KeyHandle, hKey);
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  if (*lpcbName > 0)
+    if (*lpcbName > 0)
     {
-      NameLength = min (*lpcbName - 1, REG_MAX_NAME_SIZE) * sizeof (WCHAR);
+        NameLength = min (*lpcbName - 1 , REG_MAX_NAME_SIZE) * sizeof (WCHAR);
     }
-  else
+    else
     {
-      NameLength = 0;
+        NameLength = 0;
     }
 
-  if (lpClass)
+    if (lpClass)
     {
-      if (*lpcbClass > 0)
-       {
-         ClassLength = min (*lpcbClass - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
-       }
-      else
-       {
-         ClassLength = 0;
-       }
+        if (*lpcbClass > 0)
+        {
+            ClassLength = min (*lpcbClass -1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
+        }
+        else
+        {
+            ClassLength = 0;
+        }
 
-      BufferSize = ((sizeof(KEY_NODE_INFORMATION) + NameLength + 3) & ~3) + ClassLength;
+        /* The class name should start at a dword boundary */
+        BufferSize = ((sizeof(KEY_NODE_INFORMATION) + NameLength + 3) & ~3) + ClassLength;
     }
-  else
+    else
     {
-      BufferSize = sizeof(KEY_BASIC_INFORMATION) + NameLength;
+        BufferSize = sizeof(KEY_BASIC_INFORMATION) + NameLength;
     }
 
-  KeyInfo = RtlAllocateHeap (ProcessHeap,
-                            0,
-                            BufferSize);
-  if (KeyInfo == NULL)
+    KeyInfo = RtlAllocateHeap (ProcessHeap, 0, BufferSize);
+    if (KeyInfo == NULL)
     {
-      ErrorCode = ERROR_OUTOFMEMORY;
-      goto Cleanup;
+        ErrorCode = ERROR_OUTOFMEMORY;
+        goto Cleanup;
+    }
+
+    Status = NtEnumerateKey(KeyHandle,
+                            (ULONG)dwIndex,
+                            lpClass == NULL ? KeyBasicInformation : KeyNodeInformation,
+                            KeyInfo,
+                            BufferSize,
+                            &ResultSize);
+    TRACE("NtEnumerateKey() returned status 0x%X\n", Status);
+    if (!NT_SUCCESS(Status))
+    {
+        ErrorCode = RtlNtStatusToDosError (Status);
+    }
+    else
+    {
+        if (lpClass == NULL)
+        {
+            if (KeyInfo->Basic.NameLength > NameLength)
+            {
+                ErrorCode = ERROR_BUFFER_OVERFLOW;
+            }
+            else
+            {
+                StringU.Buffer = KeyInfo->Basic.Name;
+                StringU.Length = KeyInfo->Basic.NameLength;
+                StringU.MaximumLength = KeyInfo->Basic.NameLength;
+            }
+        }
+        else
+        {
+            if (KeyInfo->Node.NameLength > NameLength ||
+                KeyInfo->Node.ClassLength > ClassLength)
+            {
+                               ErrorCode = ERROR_BUFFER_OVERFLOW;
+            }
+            else
+            {
+                StringA.Buffer = lpClass;
+                StringA.Length = 0;
+                StringA.MaximumLength = *lpcbClass;
+                StringU.Buffer = (PWCHAR)((ULONG_PTR)KeyInfo->Node.Name + KeyInfo->Node.ClassOffset);
+                StringU.Length = KeyInfo->Node.ClassLength;
+                StringU.MaximumLength = KeyInfo->Node.ClassLength;
+                RtlUnicodeStringToAnsiString (&StringA, &StringU, FALSE);
+                lpClass[StringA.Length] = 0;
+                *lpcbClass = StringA.Length;
+                StringU.Buffer = KeyInfo->Node.Name;
+                StringU.Length = KeyInfo->Node.NameLength;
+                StringU.MaximumLength = KeyInfo->Node.NameLength;
+            }
+        }
+
+        if (ErrorCode == ERROR_SUCCESS)
+        {
+            StringA.Buffer = lpName;
+            StringA.Length = 0;
+            StringA.MaximumLength = *lpcbName;
+            RtlUnicodeStringToAnsiString (&StringA, &StringU, FALSE);
+            lpName[StringA.Length] = 0;
+            *lpcbName = StringA.Length;
+            if (lpftLastWriteTime != NULL)
+            {
+                if (lpClass == NULL)
+                {
+                    lpftLastWriteTime->dwLowDateTime = KeyInfo->Basic.LastWriteTime.u.LowPart;
+                    lpftLastWriteTime->dwHighDateTime = KeyInfo->Basic.LastWriteTime.u.HighPart;
+                }
+                else
+                {
+                    lpftLastWriteTime->dwLowDateTime = KeyInfo->Node.LastWriteTime.u.LowPart;
+                    lpftLastWriteTime->dwHighDateTime = KeyInfo->Node.LastWriteTime.u.HighPart;
+                }
+            }
+        }
     }
 
-  Status = NtEnumerateKey (KeyHandle,
-                          (ULONG)dwIndex,
-                          lpClass ? KeyNodeInformation : KeyBasicInformation,
-                          KeyInfo,
-                          BufferSize,
-                          &ResultSize);
-  TRACE("NtEnumerateKey() returned status 0x%X\n", Status);
-  if (!NT_SUCCESS(Status))
-    {
-      ErrorCode = RtlNtStatusToDosError (Status);
-    }
-  else
-    {
-      if (lpClass == NULL)
-       {
-         if (KeyInfo->Basic.NameLength > NameLength)
-           {
-             ErrorCode = ERROR_BUFFER_OVERFLOW;
-           }
-         else
-           {
-             RtlCopyMemory (lpName,
-                            KeyInfo->Basic.Name,
-                            KeyInfo->Basic.NameLength);
-             *lpcbName = (DWORD)(KeyInfo->Basic.NameLength / sizeof(WCHAR));
-             lpName[*lpcbName] = 0;
-           }
-       }
-      else
-       {
-         if (KeyInfo->Node.NameLength > NameLength ||
-             KeyInfo->Node.ClassLength > ClassLength)
-           {
-             ErrorCode = ERROR_BUFFER_OVERFLOW;
-           }
-         else
-           {
-             RtlCopyMemory (lpName,
-                            KeyInfo->Node.Name,
-                            KeyInfo->Node.NameLength);
-             *lpcbName = KeyInfo->Node.NameLength / sizeof(WCHAR);
-             lpName[*lpcbName] = 0;
-             RtlCopyMemory (lpClass,
-                            (PVOID)((ULONG_PTR)KeyInfo->Node.Name + KeyInfo->Node.ClassOffset),
-                            KeyInfo->Node.ClassLength);
-             *lpcbClass = (DWORD)(KeyInfo->Node.ClassLength / sizeof(WCHAR));
-             lpClass[*lpcbClass] = 0;
-           }
-       }
-
-      if (ErrorCode == ERROR_SUCCESS && lpftLastWriteTime != NULL)
-       {
-         if (lpClass == NULL)
-           {
-             lpftLastWriteTime->dwLowDateTime = KeyInfo->Basic.LastWriteTime.u.LowPart;
-             lpftLastWriteTime->dwHighDateTime = KeyInfo->Basic.LastWriteTime.u.HighPart;
-           }
-         else
-           {
-             lpftLastWriteTime->dwLowDateTime = KeyInfo->Node.LastWriteTime.u.LowPart;
-             lpftLastWriteTime->dwHighDateTime = KeyInfo->Node.LastWriteTime.u.HighPart;
-           }
-       }
-    }
-
-  RtlFreeHeap (ProcessHeap,
-              0,
-              KeyInfo);
+    /*TRACE("Key Namea0 Length %d\n", StringU.Length);*/ /* BUGBUG could be uninitialized */
+    TRACE("Key Namea1 Length %d\n", NameLength);
+    TRACE("Key Namea Length %d\n", *lpcbName);
+    TRACE("Key Namea %s\n", lpName);
+
+    RtlFreeHeap(ProcessHeap,
+                0,
+                KeyInfo);
 
 Cleanup:
-  ClosePredefKey(KeyHandle);
+    ClosePredefKey(KeyHandle);
 
-  return ErrorCode;
+    return ErrorCode;
 }
 
+
 /************************************************************************
- *  RegEnumValueA
+ *  RegEnumKeyExW
  *
  * @implemented
  */
 LONG STDCALL
-RegEnumValueA( HKEY hKey, DWORD index, LPSTR value, LPDWORD val_count,
-               LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count )
+RegEnumKeyExW(HKEY hKey,
+              DWORD dwIndex,
+              LPWSTR lpName,
+              LPDWORD lpcbName,
+              LPDWORD lpReserved,
+              LPWSTR lpClass,
+              LPDWORD lpcbClass,
+              PFILETIME lpftLastWriteTime)
 {
-       HANDLE KeyHandle;
-    NTSTATUS status;
-    DWORD total_size;
-    char buffer[256], *buf_ptr = buffer;
-    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 );
+    union
+    {
+        KEY_NODE_INFORMATION Node;
+        KEY_BASIC_INFORMATION Basic;
+    } *KeyInfo;
 
-    /* NT only checks count, not val_count */
-    if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;
-       status = MapDefaultKey (&KeyHandle, hKey);
-       if (!NT_SUCCESS(status))
-       {
-               return RtlNtStatusToDosError (status);
-       }
+    ULONG BufferSize;
+    ULONG ResultSize;
+    ULONG NameLength;
+    ULONG ClassLength = 0;
+    HANDLE KeyHandle;
+    LONG ErrorCode = ERROR_SUCCESS;
+    NTSTATUS Status;
 
-    total_size = info_size + (MAX_PATH + 1) * sizeof(WCHAR);
-    if (data) total_size += *count;
-    total_size = min( sizeof(buffer), total_size );
+    Status = MapDefaultKey(&KeyHandle,
+                           hKey);
+    if (!NT_SUCCESS(Status))
+    {
+        return RtlNtStatusToDosError(Status);
+    }
 
-    status = NtEnumerateValueKey( KeyHandle, index, KeyValueFullInformation,
-                                  buffer, total_size, &total_size );
-    if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
+    if (*lpcbName > 0)
+    {
+        NameLength = min (*lpcbName - 1, REG_MAX_NAME_SIZE) * sizeof (WCHAR);
+    }
+    else
+    {
+        NameLength = 0;
+    }
 
-    /* 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 (value || data || is_string(info->Type))
+    if (lpClass)
     {
-        /* retry with a dynamically allocated buffer */
-        while (status == STATUS_BUFFER_OVERFLOW)
+        if (*lpcbClass > 0)
         {
-            if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
-            if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size )))
-            {
+            ClassLength = min (*lpcbClass - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
+        }
+        else
+        {
+            ClassLength = 0;
+        }
+
+        BufferSize = ((sizeof(KEY_NODE_INFORMATION) + NameLength + 3) & ~3) + ClassLength;
+    }
+    else
+    {
+        BufferSize = sizeof(KEY_BASIC_INFORMATION) + NameLength;
+    }
+
+    KeyInfo = RtlAllocateHeap(ProcessHeap,
+                              0,
+                              BufferSize);
+    if (KeyInfo == NULL)
+    {
+        ErrorCode = ERROR_OUTOFMEMORY;
+        goto Cleanup;
+    }
+
+    Status = NtEnumerateKey(KeyHandle,
+                            (ULONG)dwIndex,
+                            lpClass ? KeyNodeInformation : KeyBasicInformation,
+                            KeyInfo,
+                            BufferSize,
+                            &ResultSize);
+    TRACE("NtEnumerateKey() returned status 0x%X\n", Status);
+    if (!NT_SUCCESS(Status))
+    {
+        ErrorCode = RtlNtStatusToDosError (Status);
+    }
+    else
+    {
+        if (lpClass == NULL)
+        {
+            if (KeyInfo->Basic.NameLength > NameLength)
+            {
+                ErrorCode = ERROR_BUFFER_OVERFLOW;
+            }
+            else
+            {
+                RtlCopyMemory(lpName,
+                              KeyInfo->Basic.Name,
+                              KeyInfo->Basic.NameLength);
+                *lpcbName = (DWORD)(KeyInfo->Basic.NameLength / sizeof(WCHAR));
+                lpName[*lpcbName] = 0;
+            }
+        }
+        else
+        {
+            if (KeyInfo->Node.NameLength > NameLength ||
+                KeyInfo->Node.ClassLength > ClassLength)
+            {
+                ErrorCode = ERROR_BUFFER_OVERFLOW;
+            }
+            else
+            {
+                RtlCopyMemory(lpName,
+                              KeyInfo->Node.Name,
+                              KeyInfo->Node.NameLength);
+                *lpcbName = KeyInfo->Node.NameLength / sizeof(WCHAR);
+                lpName[*lpcbName] = 0;
+                RtlCopyMemory(lpClass,
+                              (PVOID)((ULONG_PTR)KeyInfo->Node.Name + KeyInfo->Node.ClassOffset),
+                              KeyInfo->Node.ClassLength);
+                *lpcbClass = (DWORD)(KeyInfo->Node.ClassLength / sizeof(WCHAR));
+                lpClass[*lpcbClass] = 0;
+            }
+        }
+
+        if (ErrorCode == ERROR_SUCCESS && lpftLastWriteTime != NULL)
+        {
+            if (lpClass == NULL)
+            {
+                lpftLastWriteTime->dwLowDateTime = KeyInfo->Basic.LastWriteTime.u.LowPart;
+                lpftLastWriteTime->dwHighDateTime = KeyInfo->Basic.LastWriteTime.u.HighPart;
+            }
+            else
+            {
+                lpftLastWriteTime->dwLowDateTime = KeyInfo->Node.LastWriteTime.u.LowPart;
+                lpftLastWriteTime->dwHighDateTime = KeyInfo->Node.LastWriteTime.u.HighPart;
+            }
+        }
+    }
+
+    RtlFreeHeap(ProcessHeap,
+                0,
+                KeyInfo);
+
+Cleanup:
+    ClosePredefKey(KeyHandle);
+
+    return ErrorCode;
+}
+
+
+/************************************************************************
+ *  RegEnumValueA
+ *
+ * @implemented
+ */
+LONG STDCALL
+RegEnumValueA(HKEY hKey,
+              DWORD index,
+              LPSTR value,
+              LPDWORD val_count,
+              LPDWORD reserved,
+              LPDWORD type,
+              LPBYTE data,
+              LPDWORD count)
+{
+    HANDLE KeyHandle;
+    NTSTATUS status;
+    ULONG total_size;
+    char buffer[256], *buf_ptr = buffer;
+    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;
+
+    status = MapDefaultKey(&KeyHandle, hKey);
+    if (!NT_SUCCESS(status))
+    {
+        return RtlNtStatusToDosError(status);
+    }
+
+    total_size = info_size + (MAX_PATH + 1) * sizeof(WCHAR);
+    if (data) total_size += *count;
+    total_size = min( sizeof(buffer), total_size );
+
+    status = NtEnumerateValueKey( KeyHandle, index, KeyValueFullInformation,
+                                  buffer, total_size, &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 (value || 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 )))
+            {
                 status = STATUS_INSUFFICIENT_RESOURCES;
                 goto done;
             }
@@ -2328,7 +2808,7 @@ RegEnumValueA( HKEY hKey, DWORD index, LPSTR value, LPDWORD val_count,
 
         if (is_string(info->Type))
         {
-            DWORD len;
+            ULONG len;
             RtlUnicodeToMultiByteSize( &len, (WCHAR *)(buf_ptr + info->DataOffset),
                                        total_size - info->DataOffset );
             if (data && len)
@@ -2353,7 +2833,7 @@ RegEnumValueA( HKEY hKey, DWORD index, LPSTR value, LPDWORD val_count,
 
         if (value && !status)
         {
-            DWORD len;
+            ULONG len;
 
             RtlUnicodeToMultiByteSize( &len, info->Name, info->NameLength );
             if (len >= *val_count)
@@ -2385,6 +2865,7 @@ RegEnumValueA( HKEY hKey, DWORD index, LPSTR value, LPDWORD val_count,
     return RtlNtStatusToDosError(status);
 }
 
+
 /******************************************************************************
  * RegEnumValueW   [ADVAPI32.@]
  * @implemented
@@ -2404,12 +2885,18 @@ RegEnumValueA( HKEY hKey, DWORD index, LPSTR value, LPDWORD val_count,
  *  Failure: nonzero error code from Winerror.h
  */
 LONG STDCALL
-RegEnumValueW( HKEY hKey, DWORD index, LPWSTR value, PDWORD val_count,
-               PDWORD reserved, PDWORD type, LPBYTE data, PDWORD count )
+RegEnumValueW(HKEY hKey,
+              DWORD index,
+              LPWSTR value,
+              PDWORD val_count,
+              PDWORD reserved,
+              PDWORD type,
+              LPBYTE data,
+              PDWORD count)
 {
-       HANDLE KeyHandle;
+    HANDLE KeyHandle;
     NTSTATUS status;
-    DWORD total_size;
+    ULONG total_size;
     char buffer[256], *buf_ptr = buffer;
     KEY_VALUE_FULL_INFORMATION *info = (KEY_VALUE_FULL_INFORMATION *)buffer;
     static const int info_size = FIELD_OFFSET( KEY_VALUE_FULL_INFORMATION, Name );
@@ -2420,11 +2907,11 @@ RegEnumValueW( HKEY hKey, DWORD index, LPWSTR value, PDWORD val_count,
     /* NT only checks count, not val_count */
     if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;
 
-       status = MapDefaultKey (&KeyHandle, hKey);
-       if (!NT_SUCCESS(status))
-       {
-               return RtlNtStatusToDosError (status);
-       }
+    status = MapDefaultKey(&KeyHandle, hKey);
+    if (!NT_SUCCESS(status))
+    {
+        return RtlNtStatusToDosError(status);
+    }
 
     total_size = info_size + (MAX_PATH + 1) * sizeof(WCHAR);
     if (data) total_size += *count;
@@ -2493,6 +2980,7 @@ RegEnumValueW( HKEY hKey, DWORD index, LPWSTR value, PDWORD val_count,
     return RtlNtStatusToDosError(status);
 }
 
+
 /************************************************************************
  *  RegFlushKey
  *
@@ -2501,31 +2989,31 @@ RegEnumValueW( HKEY hKey, DWORD index, LPWSTR value, PDWORD val_count,
 LONG STDCALL
 RegFlushKey(HKEY hKey)
 {
-  HANDLE KeyHandle;
-  NTSTATUS Status;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
 
-  if (hKey == HKEY_PERFORMANCE_DATA)
+    if (hKey == HKEY_PERFORMANCE_DATA)
     {
-      return ERROR_SUCCESS;
+        return ERROR_SUCCESS;
     }
 
-  Status = MapDefaultKey (&KeyHandle,
-                          hKey);
-  if (!NT_SUCCESS(Status))
+    Status = MapDefaultKey(&KeyHandle,
+                           hKey);
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  Status = NtFlushKey (KeyHandle);
-  
-  ClosePredefKey(KeyHandle);
-  
-  if (!NT_SUCCESS(Status))
+    Status = NtFlushKey(KeyHandle);
+
+    ClosePredefKey(KeyHandle);
+
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  return ERROR_SUCCESS;
+    return ERROR_SUCCESS;
 }
 
 
@@ -2536,42 +3024,43 @@ RegFlushKey(HKEY hKey)
  */
 LONG STDCALL
 RegGetKeySecurity(HKEY hKey,
-                 SECURITY_INFORMATION SecurityInformation,
-                 PSECURITY_DESCRIPTOR pSecurityDescriptor,
-                 LPDWORD lpcbSecurityDescriptor)
+                  SECURITY_INFORMATION SecurityInformation,
+                  PSECURITY_DESCRIPTOR pSecurityDescriptor,
+                  LPDWORD lpcbSecurityDescriptor)
 {
-  HANDLE KeyHandle;
-  NTSTATUS Status;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
 
-  if (hKey == HKEY_PERFORMANCE_DATA)
+    if (hKey == HKEY_PERFORMANCE_DATA)
     {
-      return ERROR_INVALID_HANDLE;
+        return ERROR_INVALID_HANDLE;
     }
 
-  Status = MapDefaultKey(&KeyHandle,
-                         hKey);
-  if (!NT_SUCCESS(Status))
+    Status = MapDefaultKey(&KeyHandle,
+                           hKey);
+    if (!NT_SUCCESS(Status))
     {
-      TRACE("MapDefaultKey() failed (Status %lx)\n", Status);
-      return RtlNtStatusToDosError (Status);
+        TRACE("MapDefaultKey() failed (Status %lx)\n", Status);
+        return RtlNtStatusToDosError(Status);
     }
+
 #if 0
-  Status = NtQuerySecurityObject(KeyHandle,
-                                SecurityInformation,
-                                pSecurityDescriptor,
-                                *lpcbSecurityDescriptor,
-                                lpcbSecurityDescriptor);
+    Status = NtQuerySecurityObject(KeyHandle,
+                                   SecurityInformation,
+                                   pSecurityDescriptor,
+                                   *lpcbSecurityDescriptor,
+                                   lpcbSecurityDescriptor);
 #endif
 
-  ClosePredefKey(KeyHandle);
+    ClosePredefKey(KeyHandle);
 
-  if (!NT_SUCCESS(Status))
+    if (!NT_SUCCESS(Status))
     {
-      WARN("NtQuerySecurityObject() failed (Status %lx)\n", Status);
-      return RtlNtStatusToDosError (Status);
+         WARN("NtQuerySecurityObject() failed (Status %lx)\n", Status);
+         return RtlNtStatusToDosError(Status);
     }
 
-  return ERROR_SUCCESS;
+    return ERROR_SUCCESS;
 }
 
 
@@ -2581,27 +3070,27 @@ RegGetKeySecurity(HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegLoadKeyA (HKEY hKey,
-            LPCSTR lpSubKey,
-            LPCSTR lpFile)
+RegLoadKeyA(HKEY hKey,
+            LPCSTR lpSubKey,
+            LPCSTR lpFile)
 {
-  UNICODE_STRING FileName;
-  UNICODE_STRING KeyName;
-  LONG ErrorCode;
+    UNICODE_STRING FileName;
+    UNICODE_STRING KeyName;
+    LONG ErrorCode;
 
-  RtlCreateUnicodeStringFromAsciiz (&KeyName,
-                                   (LPSTR)lpSubKey);
-  RtlCreateUnicodeStringFromAsciiz (&FileName,
-                                   (LPSTR)lpFile);
+    RtlCreateUnicodeStringFromAsciiz(&KeyName,
+                                     (LPSTR)lpSubKey);
+    RtlCreateUnicodeStringFromAsciiz(&FileName,
+                                     (LPSTR)lpFile);
 
-  ErrorCode = RegLoadKeyW (hKey,
-                          KeyName.Buffer,
-                          FileName.Buffer);
+    ErrorCode = RegLoadKeyW(hKey,
+                            KeyName.Buffer,
+                            FileName.Buffer);
 
-  RtlFreeUnicodeString (&FileName);
-  RtlFreeUnicodeString (&KeyName);
+    RtlFreeUnicodeString(&FileName);
+    RtlFreeUnicodeString(&KeyName);
 
-  return ErrorCode;
+    return ErrorCode;
 }
 
 
@@ -2611,71 +3100,71 @@ RegLoadKeyA (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegLoadKeyW (HKEY hKey,
-            LPCWSTR lpSubKey,
-            LPCWSTR lpFile)
+RegLoadKeyW(HKEY hKey,
+            LPCWSTR lpSubKey,
+            LPCWSTR lpFile)
 {
-  OBJECT_ATTRIBUTES FileObjectAttributes;
-  OBJECT_ATTRIBUTES KeyObjectAttributes;
-  UNICODE_STRING FileName;
-  UNICODE_STRING KeyName;
-  HANDLE KeyHandle;
-  NTSTATUS Status;
-  LONG ErrorCode = ERROR_SUCCESS;
+    OBJECT_ATTRIBUTES FileObjectAttributes;
+    OBJECT_ATTRIBUTES KeyObjectAttributes;
+    UNICODE_STRING FileName;
+    UNICODE_STRING KeyName;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
+    LONG ErrorCode = ERROR_SUCCESS;
 
-  if (hKey == HKEY_PERFORMANCE_DATA)
+    if (hKey == HKEY_PERFORMANCE_DATA)
     {
-      return ERROR_INVALID_HANDLE;
+        return ERROR_INVALID_HANDLE;
     }
 
-  Status = MapDefaultKey (&KeyHandle,
-                          hKey);
-  if (!NT_SUCCESS(Status))
+    Status = MapDefaultKey(&KeyHandle,
+                           hKey);
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  if (!RtlDosPathNameToNtPathName_U (lpFile,
-                                    &FileName,
-                                    NULL,
-                                    NULL))
+    if (!RtlDosPathNameToNtPathName_U(lpFile,
+                                      &FileName,
+                                      NULL,
+                                      NULL))
     {
       ErrorCode = ERROR_BAD_PATHNAME;
       goto Cleanup;
     }
 
-  InitializeObjectAttributes (&FileObjectAttributes,
-                             &FileName,
-                             OBJ_CASE_INSENSITIVE,
-                             NULL,
-                             NULL);
+    InitializeObjectAttributes(&FileObjectAttributes,
+                               &FileName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
 
-  RtlInitUnicodeString (&KeyName,
-                       (LPWSTR)lpSubKey);
+    RtlInitUnicodeString(&KeyName,
+                         (LPWSTR)lpSubKey);
 
-  InitializeObjectAttributes (&KeyObjectAttributes,
-                             &KeyName,
-                             OBJ_CASE_INSENSITIVE,
-                             KeyHandle,
-                             NULL);
+    InitializeObjectAttributes(&KeyObjectAttributes,
+                               &KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               KeyHandle,
+                               NULL);
 
-  Status = NtLoadKey (&KeyObjectAttributes,
-                     &FileObjectAttributes);
+    Status = NtLoadKey(&KeyObjectAttributes,
+                       &FileObjectAttributes);
 
-  RtlFreeHeap (RtlGetProcessHeap (),
-               0,
-               FileName.Buffer);
+    RtlFreeHeap(RtlGetProcessHeap(),
+                0,
+                FileName.Buffer);
 
-  if (!NT_SUCCESS(Status))
+    if (!NT_SUCCESS(Status))
     {
-      ErrorCode = RtlNtStatusToDosError (Status);
-      goto Cleanup;
+        ErrorCode = RtlNtStatusToDosError(Status);
+        goto Cleanup;
     }
 
 Cleanup:
-  ClosePredefKey(KeyHandle);
+    ClosePredefKey(KeyHandle);
 
-  return ErrorCode;
+    return ErrorCode;
 }
 
 
@@ -2685,54 +3174,54 @@ Cleanup:
  * @unimplemented
  */
 LONG STDCALL
-RegNotifyChangeKeyValue (HKEY hKey,
-                        BOOL bWatchSubtree,
-                        DWORD dwNotifyFilter,
-                        HANDLE hEvent,
-                        BOOL fAsynchronous)
+RegNotifyChangeKeyValue(HKEY hKey,
+                        BOOL bWatchSubtree,
+                        DWORD dwNotifyFilter,
+                        HANDLE hEvent,
+                        BOOL fAsynchronous)
 {
-  IO_STATUS_BLOCK IoStatusBlock;
-  HANDLE KeyHandle;
-  NTSTATUS Status;
-  LONG ErrorCode = ERROR_SUCCESS;
+    IO_STATUS_BLOCK IoStatusBlock;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
+    LONG ErrorCode = ERROR_SUCCESS;
 
-  if (hKey == HKEY_PERFORMANCE_DATA)
+    if (hKey == HKEY_PERFORMANCE_DATA)
     {
-      return ERROR_INVALID_HANDLE;
+        return ERROR_INVALID_HANDLE;
     }
 
-  if (fAsynchronous == TRUE && hEvent == NULL)
+    if (fAsynchronous == TRUE && hEvent == NULL)
     {
-      return ERROR_INVALID_PARAMETER;
+        return ERROR_INVALID_PARAMETER;
     }
 
-  Status = MapDefaultKey (&KeyHandle,
-                          hKey);
-  if (!NT_SUCCESS(Status))
+    Status = MapDefaultKey(&KeyHandle,
+                           hKey);
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  /* FIXME: Remote key handles must fail */
+    /* FIXME: Remote key handles must fail */
 
-  Status = NtNotifyChangeKey (KeyHandle,
-                             hEvent,
-                             0,
-                             0,
-                             &IoStatusBlock,
-                             dwNotifyFilter,
-                             bWatchSubtree,
-                             0,
-                             0,
-                             fAsynchronous);
-  if (!NT_SUCCESS(Status) && Status != STATUS_TIMEOUT)
+    Status = NtNotifyChangeKey(KeyHandle,
+                               hEvent,
+                               0,
+                               0,
+                               &IoStatusBlock,
+                               dwNotifyFilter,
+                               bWatchSubtree,
+                               0,
+                               0,
+                               fAsynchronous);
+    if (!NT_SUCCESS(Status) && Status != STATUS_TIMEOUT)
     {
-      ErrorCode = RtlNtStatusToDosError (Status);
+        ErrorCode = RtlNtStatusToDosError(Status);
     }
 
-  ClosePredefKey(KeyHandle);
+    ClosePredefKey(KeyHandle);
 
-  return ErrorCode;
+    return ErrorCode;
 }
 
 
@@ -2742,20 +3231,20 @@ RegNotifyChangeKeyValue (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegOpenCurrentUser (IN REGSAM samDesired,
-                    OUT PHKEY phkResult)
+RegOpenCurrentUser(IN REGSAM samDesired,
+                   OUT PHKEY phkResult)
 {
-  NTSTATUS Status;
+    NTSTATUS Status;
 
-  Status = RtlOpenCurrentUser((ACCESS_MASK)samDesired,
-                              (PHANDLE)phkResult);
-  if (!NT_SUCCESS(Status))
-  {
-    /* NOTE - don't set the last error code! just return the error! */
-    return RtlNtStatusToDosError(Status);
-  }
+    Status = RtlOpenCurrentUser((ACCESS_MASK)samDesired,
+                                (PHANDLE)phkResult);
+    if (!NT_SUCCESS(Status))
+    {
+        /* NOTE - don't set the last error code! just return the error! */
+        return RtlNtStatusToDosError(Status);
+    }
 
-  return ERROR_SUCCESS;
+    return ERROR_SUCCESS;
 }
 
 
@@ -2767,19 +3256,29 @@ RegOpenCurrentUser (IN REGSAM samDesired,
  * @implemented
  */
 LONG STDCALL
-RegOpenKeyA (HKEY hKey,
-            LPCSTR lpSubKey,
-            PHKEY phkResult)
+RegOpenKeyA(HKEY hKey,
+            LPCSTR lpSubKey,
+            PHKEY phkResult)
 {
-       TRACE("RegOpenKeyA hKey 0x%x lpSubKey %s phkResult %p\n", hKey, lpSubKey, phkResult);
+    TRACE("RegOpenKeyA hKey 0x%x lpSubKey %s phkResult %p\n",
+          hKey, lpSubKey, phkResult);
 
-       if (!lpSubKey || !*lpSubKey)
-       {
-               *phkResult = hKey;
-               return ERROR_SUCCESS;
-       }
+    if (!hKey && lpSubKey && phkResult)
+    {
+        return ERROR_INVALID_HANDLE;
+    }
 
-       return RegOpenKeyExA( hKey, lpSubKey, 0, MAXIMUM_ALLOWED, phkResult);
+    if (!lpSubKey || !*lpSubKey)
+    {
+        *phkResult = hKey;
+        return ERROR_SUCCESS;
+    }
+
+    return RegOpenKeyExA(hKey,
+                         lpSubKey,
+                         0,
+                         MAXIMUM_ALLOWED,
+                         phkResult);
 }
 
 
@@ -2793,18 +3292,29 @@ RegOpenKeyA (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegOpenKeyW (HKEY hKey,
-            LPCWSTR lpSubKey,
-            PHKEY phkResult)
+RegOpenKeyW(HKEY hKey,
+            LPCWSTR lpSubKey,
+            PHKEY phkResult)
 {
-       TRACE("RegOpenKeyW hKey 0x%x lpSubKey %S phkResult %p\n", hKey, lpSubKey, phkResult);
-
-       if (!lpSubKey || !*lpSubKey)
-       {
-               *phkResult = hKey;
-               return ERROR_SUCCESS;
-       }
-       return RegOpenKeyExW(hKey, lpSubKey, 0, MAXIMUM_ALLOWED, phkResult);
+    TRACE("RegOpenKeyW hKey 0x%x lpSubKey %S phkResult %p\n",
+          hKey, lpSubKey, phkResult);
+
+    if (!hKey && lpSubKey && phkResult)
+    {
+        return ERROR_INVALID_HANDLE;
+    }
+
+    if (!lpSubKey || !*lpSubKey)
+    {
+        *phkResult = hKey;
+        return ERROR_SUCCESS;
+    }
+
+    return RegOpenKeyExW(hKey,
+                         lpSubKey,
+                         0,
+                         MAXIMUM_ALLOWED,
+                         phkResult);
 }
 
 
@@ -2814,44 +3324,48 @@ RegOpenKeyW (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegOpenKeyExA (HKEY hKey,
-              LPCSTR lpSubKey,
-              DWORD ulOptions,
-              REGSAM samDesired,
-              PHKEY phkResult)
+RegOpenKeyExA(HKEY hKey,
+              LPCSTR lpSubKey,
+              DWORD ulOptions,
+              REGSAM samDesired,
+              PHKEY phkResult)
 {
-       OBJECT_ATTRIBUTES ObjectAttributes;
-       UNICODE_STRING SubKeyString;
-       HANDLE KeyHandle;
-       NTSTATUS Status;
-       LONG ErrorCode = ERROR_SUCCESS;
-
-       TRACE("RegOpenKeyExA hKey 0x%x lpSubKey %s ulOptions 0x%x samDesired 0x%x phkResult %p\n",
-               hKey, lpSubKey, ulOptions, samDesired, phkResult);
-
-       Status = MapDefaultKey (&KeyHandle, hKey);
-       if (!NT_SUCCESS(Status))
-       {
-               return RtlNtStatusToDosError (Status);
-       }
-
-       RtlCreateUnicodeStringFromAsciiz (&SubKeyString, (LPSTR)lpSubKey);
-       InitializeObjectAttributes (&ObjectAttributes,
-               &SubKeyString,
-               OBJ_CASE_INSENSITIVE,
-               KeyHandle,
-               NULL);
-
-       Status = NtOpenKey ((PHANDLE)phkResult, samDesired, &ObjectAttributes);
-       RtlFreeUnicodeString (&SubKeyString);
-       if (!NT_SUCCESS(Status))
-       {
-               ErrorCode = RtlNtStatusToDosError (Status);
-       }
-       
-       ClosePredefKey(KeyHandle);
-
-       return ErrorCode;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING SubKeyString;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
+    LONG ErrorCode = ERROR_SUCCESS;
+
+    TRACE("RegOpenKeyExA hKey 0x%x lpSubKey %s ulOptions 0x%x samDesired 0x%x phkResult %p\n",
+          hKey, lpSubKey, ulOptions, samDesired, phkResult);
+
+    Status = MapDefaultKey(&KeyHandle,
+                           hKey);
+    if (!NT_SUCCESS(Status))
+    {
+        return RtlNtStatusToDosError(Status);
+    }
+
+    RtlCreateUnicodeStringFromAsciiz(&SubKeyString,
+                                     (LPSTR)lpSubKey);
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &SubKeyString,
+                               OBJ_CASE_INSENSITIVE,
+                               KeyHandle,
+                               NULL);
+
+    Status = NtOpenKey((PHANDLE)phkResult,
+                       samDesired,
+                       &ObjectAttributes);
+    RtlFreeUnicodeString(&SubKeyString);
+    if (!NT_SUCCESS(Status))
+    {
+        ErrorCode = RtlNtStatusToDosError(Status);
+    }
+
+    ClosePredefKey(KeyHandle);
+
+    return ErrorCode;
 }
 
 
@@ -2861,48 +3375,49 @@ RegOpenKeyExA (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegOpenKeyExW (HKEY hKey,
-              LPCWSTR lpSubKey,
-              DWORD ulOptions,
-              REGSAM samDesired,
-              PHKEY phkResult)
+RegOpenKeyExW(HKEY hKey,
+              LPCWSTR lpSubKey,
+              DWORD ulOptions,
+              REGSAM samDesired,
+              PHKEY phkResult)
 {
-       OBJECT_ATTRIBUTES ObjectAttributes;
-       UNICODE_STRING SubKeyString;
-       HANDLE KeyHandle;
-       NTSTATUS Status;
-       LONG ErrorCode = ERROR_SUCCESS;
-
-       TRACE("RegOpenKeyExW hKey 0x%x lpSubKey %S ulOptions 0x%x samDesired 0x%x phkResult %p\n",
-               hKey, lpSubKey, ulOptions, samDesired, phkResult);
-
-       Status = MapDefaultKey (&KeyHandle, hKey);
-       if (!NT_SUCCESS(Status))
-       {
-               return RtlNtStatusToDosError (Status);
-       }
-
-       if (lpSubKey != NULL)
-               RtlInitUnicodeString (&SubKeyString, (LPWSTR)lpSubKey);
-       else
-               RtlInitUnicodeString (&SubKeyString, (LPWSTR)L"");
-
-       InitializeObjectAttributes (&ObjectAttributes,
-               &SubKeyString,
-               OBJ_CASE_INSENSITIVE,
-               KeyHandle,
-               NULL);
-
-       Status = NtOpenKey ((PHANDLE)phkResult, samDesired,     &ObjectAttributes);
-
-       if (!NT_SUCCESS(Status))
-       {
-               ErrorCode = RtlNtStatusToDosError (Status);
-       }
-       
-       ClosePredefKey(KeyHandle);
-
-       return ErrorCode;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING SubKeyString;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
+    LONG ErrorCode = ERROR_SUCCESS;
+
+    TRACE("RegOpenKeyExW hKey 0x%x lpSubKey %S ulOptions 0x%x samDesired 0x%x phkResult %p\n",
+          hKey, lpSubKey, ulOptions, samDesired, phkResult);
+
+    Status = MapDefaultKey(&KeyHandle, hKey);
+    if (!NT_SUCCESS(Status))
+    {
+        return RtlNtStatusToDosError(Status);
+    }
+
+    if (lpSubKey != NULL)
+        RtlInitUnicodeString(&SubKeyString, (LPWSTR)lpSubKey);
+    else
+        RtlInitUnicodeString(&SubKeyString, (LPWSTR)L"");
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &SubKeyString,
+                               OBJ_CASE_INSENSITIVE,
+                               KeyHandle,
+                               NULL);
+
+    Status = NtOpenKey((PHANDLE)phkResult,
+                       samDesired,
+                       &ObjectAttributes);
+    if (!NT_SUCCESS(Status))
+    {
+        ErrorCode = RtlNtStatusToDosError(Status);
+    }
+
+    ClosePredefKey(KeyHandle);
+
+    return ErrorCode;
 }
 
 
@@ -2912,140 +3427,139 @@ RegOpenKeyExW (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegOpenUserClassesRoot (IN HANDLE hToken,
-                        IN DWORD dwOptions,
-                        IN REGSAM samDesired,
-                        OUT PHKEY phkResult)
+RegOpenUserClassesRoot(IN HANDLE hToken,
+                       IN DWORD dwOptions,
+                       IN REGSAM samDesired,
+                       OUT PHKEY phkResult)
 {
-  const WCHAR UserClassesKeyPrefix[] = L"\\Registry\\User\\";
-  const WCHAR UserClassesKeySuffix[] = L"_Classes";
-  PTOKEN_USER TokenUserData;
-  ULONG RequiredLength;
-  UNICODE_STRING UserSidString, UserClassesKeyRoot;
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  NTSTATUS Status;
-
-  /* check parameters */
-  if (hToken == NULL || dwOptions != 0 || phkResult == NULL)
-  {
-    return ERROR_INVALID_PARAMETER;
-  }
-
-  /*
-   * Get the user sid from the token
-   */
+    const WCHAR UserClassesKeyPrefix[] = L"\\Registry\\User\\";
+    const WCHAR UserClassesKeySuffix[] = L"_Classes";
+    PTOKEN_USER TokenUserData;
+    ULONG RequiredLength;
+    UNICODE_STRING UserSidString, UserClassesKeyRoot;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    NTSTATUS Status;
+
+    /* check parameters */
+    if (hToken == NULL || dwOptions != 0 || phkResult == NULL)
+    {
+        return ERROR_INVALID_PARAMETER;
+    }
+
+    /*
+     * Get the user sid from the token
+     */
 
 ReadTokenSid:
-  /* determine how much memory we need */
-  Status = NtQueryInformationToken(hToken,
-                                   TokenUser,
-                                   NULL,
-                                   0,
-                                   &RequiredLength);
-  if (!NT_SUCCESS(Status) && (Status != STATUS_BUFFER_TOO_SMALL))
-  {
-    /* NOTE - as opposed to all other registry functions windows does indeed
-              change the last error code in case the caller supplied a invalid
-              handle for example! */
-    return RtlNtStatusToDosError (Status);
-  }
-
-  TokenUserData = RtlAllocateHeap(ProcessHeap,
-                                  0,
-                                  RequiredLength);
-  if (TokenUserData == NULL)
-  {
-    return ERROR_NOT_ENOUGH_MEMORY;
-  }
-
-  /* attempt to read the information */
-  Status = NtQueryInformationToken(hToken,
-                                   TokenUser,
-                                   TokenUserData,
-                                   RequiredLength,
-                                   &RequiredLength);
-  if (!NT_SUCCESS(Status))
-  {
+    /* determine how much memory we need */
+    Status = NtQueryInformationToken(hToken,
+                                     TokenUser,
+                                     NULL,
+                                     0,
+                                     &RequiredLength);
+    if (!NT_SUCCESS(Status) && (Status != STATUS_BUFFER_TOO_SMALL))
+    {
+        /* NOTE - as opposed to all other registry functions windows does indeed
+                  change the last error code in case the caller supplied a invalid
+                  handle for example! */
+        return RtlNtStatusToDosError(Status);
+    }
+
+    TokenUserData = RtlAllocateHeap(ProcessHeap,
+                                    0,
+                                    RequiredLength);
+    if (TokenUserData == NULL)
+    {
+        return ERROR_NOT_ENOUGH_MEMORY;
+    }
+
+    /* attempt to read the information */
+    Status = NtQueryInformationToken(hToken,
+                                     TokenUser,
+                                     TokenUserData,
+                                     RequiredLength,
+                                     &RequiredLength);
+    if (!NT_SUCCESS(Status))
+    {
+        RtlFreeHeap(ProcessHeap,
+                    0,
+                    TokenUserData);
+        if (Status == STATUS_BUFFER_TOO_SMALL)
+        {
+            /* the information appears to have changed?! try again */
+            goto ReadTokenSid;
+        }
+
+        /* NOTE - as opposed to all other registry functions windows does indeed
+                  change the last error code in case the caller supplied a invalid
+                  handle for example! */
+        return RtlNtStatusToDosError(Status);
+    }
+
+    /*
+     * Build the absolute path for the user's registry in the form
+     * "\Registry\User\<SID>_Classes"
+     */
+    Status = RtlConvertSidToUnicodeString(&UserSidString,
+                                          TokenUserData->User.Sid,
+                                          TRUE);
+
+    /* we don't need the user data anymore, free it */
     RtlFreeHeap(ProcessHeap,
                 0,
                 TokenUserData);
-    if (Status == STATUS_BUFFER_TOO_SMALL)
-    {
-      /* the information appears to have changed?! try again */
-      goto ReadTokenSid;
-    }
-
-    /* NOTE - as opposed to all other registry functions windows does indeed
-              change the last error code in case the caller supplied a invalid
-              handle for example! */
-    return RtlNtStatusToDosError (Status);
-  }
-
-  /*
-   * Build the absolute path for the user's registry in the form
-   * "\Registry\User\<SID>_Classes"
-   */
-  Status = RtlConvertSidToUnicodeString(&UserSidString,
-                                        TokenUserData->User.Sid,
-                                        TRUE);
-
-  /* we don't need the user data anymore, free it */
-  RtlFreeHeap(ProcessHeap,
-              0,
-              TokenUserData);
-
-  if (!NT_SUCCESS(Status))
-  {
-    return RtlNtStatusToDosError (Status);
-  }
-
-  /* allocate enough memory for the entire key string */
-  UserClassesKeyRoot.Length = 0;
-  UserClassesKeyRoot.MaximumLength = UserSidString.Length +
-                                     sizeof(UserClassesKeyPrefix) +
-                                     sizeof(UserClassesKeySuffix);
-  UserClassesKeyRoot.Buffer = RtlAllocateHeap(ProcessHeap,
-                                              0,
-                                              UserClassesKeyRoot.MaximumLength);
-  if (UserClassesKeyRoot.Buffer == NULL)
-  {
-    RtlFreeUnicodeString(&UserSidString);
-    return RtlNtStatusToDosError (Status);
-  }
 
-  /* build the string */
-  RtlAppendUnicodeToString(&UserClassesKeyRoot,
-                           UserClassesKeyPrefix);
-  RtlAppendUnicodeStringToString(&UserClassesKeyRoot,
-                                 &UserSidString);
-  RtlAppendUnicodeToString(&UserClassesKeyRoot,
-                           UserClassesKeySuffix);
+    if (!NT_SUCCESS(Status))
+    {
+        return RtlNtStatusToDosError(Status);
+    }
 
-  TRACE("RegOpenUserClassesRoot: Absolute path: %wZ\n", &UserClassesKeyRoot);
+    /* allocate enough memory for the entire key string */
+    UserClassesKeyRoot.Length = 0;
+    UserClassesKeyRoot.MaximumLength = UserSidString.Length +
+                                       sizeof(UserClassesKeyPrefix) +
+                                       sizeof(UserClassesKeySuffix);
+    UserClassesKeyRoot.Buffer = RtlAllocateHeap(ProcessHeap,
+                                                0,
+                                                UserClassesKeyRoot.MaximumLength);
+    if (UserClassesKeyRoot.Buffer == NULL)
+    {
+        RtlFreeUnicodeString(&UserSidString);
+        return RtlNtStatusToDosError(Status);
+    }
 
-  /*
-   * Open the key
-   */
+    /* build the string */
+    RtlAppendUnicodeToString(&UserClassesKeyRoot,
+                             UserClassesKeyPrefix);
+    RtlAppendUnicodeStringToString(&UserClassesKeyRoot,
+                                   &UserSidString);
+    RtlAppendUnicodeToString(&UserClassesKeyRoot,
+                             UserClassesKeySuffix);
 
-  InitializeObjectAttributes (&ObjectAttributes,
-                             &UserClassesKeyRoot,
-                             OBJ_CASE_INSENSITIVE,
-                             NULL,
-                             NULL);
+    TRACE("RegOpenUserClassesRoot: Absolute path: %wZ\n", &UserClassesKeyRoot);
 
-  Status = NtOpenKey((PHANDLE)phkResult,
-                     samDesired,
-                     &ObjectAttributes);
+    /*
+     * Open the key
+     */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &UserClassesKeyRoot,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
 
-  RtlFreeUnicodeString(&UserSidString);
-  RtlFreeUnicodeString(&UserClassesKeyRoot);
+    Status = NtOpenKey((PHANDLE)phkResult,
+                       samDesired,
+                       &ObjectAttributes);
 
-  if (!NT_SUCCESS(Status))
-  {
-    return RtlNtStatusToDosError (Status);
-  }
+    RtlFreeUnicodeString(&UserSidString);
+    RtlFreeUnicodeString(&UserClassesKeyRoot);
 
-  return ERROR_SUCCESS;
+    if (!NT_SUCCESS(Status))
+    {
+        return RtlNtStatusToDosError(Status);
+    }
+
+    return ERROR_SUCCESS;
 }
 
 
@@ -3055,58 +3569,58 @@ ReadTokenSid:
  * @implemented
  */
 LONG STDCALL
-RegQueryInfoKeyA (HKEY hKey,
-                 LPSTR lpClass,
-                 LPDWORD lpcbClass,
-                 LPDWORD lpReserved,
-                 LPDWORD lpcSubKeys,
-                 LPDWORD lpcbMaxSubKeyLen,
-                 LPDWORD lpcbMaxClassLen,
-                 LPDWORD lpcValues,
-                 LPDWORD lpcbMaxValueNameLen,
-                 LPDWORD lpcbMaxValueLen,
-                 LPDWORD lpcbSecurityDescriptor,
-                 PFILETIME lpftLastWriteTime)
+RegQueryInfoKeyA(HKEY hKey,
+                 LPSTR lpClass,
+                 LPDWORD lpcbClass,
+                 LPDWORD lpReserved,
+                 LPDWORD lpcSubKeys,
+                 LPDWORD lpcbMaxSubKeyLen,
+                 LPDWORD lpcbMaxClassLen,
+                 LPDWORD lpcValues,
+                 LPDWORD lpcbMaxValueNameLen,
+                 LPDWORD lpcbMaxValueLen,
+                 LPDWORD lpcbSecurityDescriptor,
+                 PFILETIME lpftLastWriteTime)
 {
-  WCHAR ClassName[MAX_PATH];
-  UNICODE_STRING UnicodeString;
-  ANSI_STRING AnsiString;
-  LONG ErrorCode;
-
-  RtlInitUnicodeString (&UnicodeString,
-                       NULL);
-  if (lpClass != NULL)
-    {
-      UnicodeString.Buffer = &ClassName[0];
-      UnicodeString.MaximumLength = sizeof(ClassName);
-      AnsiString.MaximumLength = *lpcbClass;
-    }
-
-  ErrorCode = RegQueryInfoKeyW (hKey,
-                               UnicodeString.Buffer,
-                               lpcbClass,
-                               lpReserved,
-                               lpcSubKeys,
-                               lpcbMaxSubKeyLen,
-                               lpcbMaxClassLen,
-                               lpcValues,
-                               lpcbMaxValueNameLen,
-                               lpcbMaxValueLen,
-                               lpcbSecurityDescriptor,
-                               lpftLastWriteTime);
-  if ((ErrorCode == ERROR_SUCCESS) && (lpClass != NULL))
-    {
-      AnsiString.Buffer = lpClass;
-      AnsiString.Length = 0;
-      UnicodeString.Length = *lpcbClass * sizeof(WCHAR);
-      RtlUnicodeStringToAnsiString (&AnsiString,
-                                   &UnicodeString,
-                                   FALSE);
-      *lpcbClass = AnsiString.Length;
-      lpClass[AnsiString.Length] = 0;
-    }
-
-  return ErrorCode;
+    WCHAR ClassName[MAX_PATH];
+    UNICODE_STRING UnicodeString;
+    ANSI_STRING AnsiString;
+    LONG ErrorCode;
+
+    RtlInitUnicodeString(&UnicodeString,
+                         NULL);
+    if (lpClass != NULL)
+    {
+        UnicodeString.Buffer = &ClassName[0];
+        UnicodeString.MaximumLength = sizeof(ClassName);
+        AnsiString.MaximumLength = *lpcbClass;
+    }
+
+    ErrorCode = RegQueryInfoKeyW(hKey,
+                                 UnicodeString.Buffer,
+                                 lpcbClass,
+                                 lpReserved,
+                                 lpcSubKeys,
+                                 lpcbMaxSubKeyLen,
+                                 lpcbMaxClassLen,
+                                 lpcValues,
+                                 lpcbMaxValueNameLen,
+                                 lpcbMaxValueLen,
+                                 lpcbSecurityDescriptor,
+                                 lpftLastWriteTime);
+    if ((ErrorCode == ERROR_SUCCESS) && (lpClass != NULL))
+    {
+        AnsiString.Buffer = lpClass;
+        AnsiString.Length = 0;
+        UnicodeString.Length = *lpcbClass * sizeof(WCHAR);
+        RtlUnicodeStringToAnsiString(&AnsiString,
+                                     &UnicodeString,
+                                     FALSE);
+        *lpcbClass = AnsiString.Length;
+        lpClass[AnsiString.Length] = 0;
+    }
+
+    return ErrorCode;
 }
 
 
@@ -3116,180 +3630,181 @@ RegQueryInfoKeyA (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegQueryInfoKeyW (HKEY hKey,
-                 LPWSTR lpClass,
-                 LPDWORD lpcbClass,
-                 LPDWORD lpReserved,
-                 LPDWORD lpcSubKeys,
-                 LPDWORD lpcbMaxSubKeyLen,
-                 LPDWORD lpcbMaxClassLen,
-                 LPDWORD lpcValues,
-                 LPDWORD lpcbMaxValueNameLen,
-                 LPDWORD lpcbMaxValueLen,
-                 LPDWORD lpcbSecurityDescriptor,
-                 PFILETIME lpftLastWriteTime)
+RegQueryInfoKeyW(HKEY hKey,
+                 LPWSTR lpClass,
+                 LPDWORD lpcbClass,
+                 LPDWORD lpReserved,
+                 LPDWORD lpcSubKeys,
+                 LPDWORD lpcbMaxSubKeyLen,
+                 LPDWORD lpcbMaxClassLen,
+                 LPDWORD lpcValues,
+                 LPDWORD lpcbMaxValueNameLen,
+                 LPDWORD lpcbMaxValueLen,
+                 LPDWORD lpcbSecurityDescriptor,
+                 PFILETIME lpftLastWriteTime)
 {
-  KEY_FULL_INFORMATION FullInfoBuffer;
-  PKEY_FULL_INFORMATION FullInfo;
-  ULONG FullInfoSize;
-  ULONG ClassLength = 0;
-  HANDLE KeyHandle;
-  NTSTATUS Status;
-  ULONG Length;
-  LONG ErrorCode = ERROR_SUCCESS;
-
-  if ((lpClass) && (!lpcbClass))
-    {
-      return ERROR_INVALID_PARAMETER;
-    }
-
-  Status = MapDefaultKey (&KeyHandle,
-                         hKey);
-  if (!NT_SUCCESS(Status))
-    {
-      return RtlNtStatusToDosError (Status);
-    }
-
-  if (lpClass != NULL)
-    {
-      if (*lpcbClass > 0)
-       {
-         ClassLength = min(*lpcbClass - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
-       }
-      else
-       {
-         ClassLength = 0;
-       }
-
-      FullInfoSize = sizeof(KEY_FULL_INFORMATION) + ((ClassLength + 3) & ~3);
-      FullInfo = RtlAllocateHeap (ProcessHeap,
-                                 0,
-                                 FullInfoSize);
-      if (FullInfo == NULL)
-       {
-         ErrorCode = ERROR_OUTOFMEMORY;
-         goto Cleanup;
-       }
-
-      FullInfo->ClassLength = ClassLength;
-    }
-  else
-    {
-      FullInfoSize = sizeof(KEY_FULL_INFORMATION);
-      FullInfo = &FullInfoBuffer;
-      FullInfo->ClassLength = 0;
-    }
-  FullInfo->ClassOffset = FIELD_OFFSET(KEY_FULL_INFORMATION, Class);
-
-  Status = NtQueryKey (KeyHandle,
-                      KeyFullInformation,
-                      FullInfo,
-                      FullInfoSize,
-                      &Length);
-  TRACE("NtQueryKey() returned status 0x%X\n", Status);
-  if (!NT_SUCCESS(Status))
-    {
-      if (lpClass != NULL)
-       {
-         RtlFreeHeap (ProcessHeap,
-                      0,
-                      FullInfo);
-       }
-
-      ErrorCode = RtlNtStatusToDosError (Status);
-      goto Cleanup;
+    KEY_FULL_INFORMATION FullInfoBuffer;
+    PKEY_FULL_INFORMATION FullInfo;
+    ULONG FullInfoSize;
+    ULONG ClassLength = 0;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
+    ULONG Length;
+    LONG ErrorCode = ERROR_SUCCESS;
+
+    if ((lpClass) && (!lpcbClass))
+    {
+        return ERROR_INVALID_PARAMETER;
+    }
+
+    Status = MapDefaultKey(&KeyHandle,
+                           hKey);
+    if (!NT_SUCCESS(Status))
+    {
+        return RtlNtStatusToDosError(Status);
+    }
+
+    if (lpClass != NULL)
+    {
+        if (*lpcbClass > 0)
+        {
+            ClassLength = min(*lpcbClass - 1, REG_MAX_NAME_SIZE) * sizeof(WCHAR);
+        }
+        else
+        {
+            ClassLength = 0;
+        }
+
+        FullInfoSize = sizeof(KEY_FULL_INFORMATION) + ((ClassLength + 3) & ~3);
+        FullInfo = RtlAllocateHeap(ProcessHeap,
+                                   0,
+                                   FullInfoSize);
+        if (FullInfo == NULL)
+        {
+            ErrorCode = ERROR_OUTOFMEMORY;
+            goto Cleanup;
+        }
+
+        FullInfo->ClassLength = ClassLength;
+    }
+    else
+    {
+        FullInfoSize = sizeof(KEY_FULL_INFORMATION);
+        FullInfo = &FullInfoBuffer;
+        FullInfo->ClassLength = 0;
     }
+    FullInfo->ClassOffset = FIELD_OFFSET(KEY_FULL_INFORMATION, Class);
 
-  TRACE("SubKeys %d\n", FullInfo->SubKeys);
-  if (lpcSubKeys != NULL)
+    Status = NtQueryKey(KeyHandle,
+                        KeyFullInformation,
+                        FullInfo,
+                        FullInfoSize,
+                        &Length);
+    TRACE("NtQueryKey() returned status 0x%X\n", Status);
+    if (!NT_SUCCESS(Status))
     {
-      *lpcSubKeys = FullInfo->SubKeys;
+        if (lpClass != NULL)
+        {
+            RtlFreeHeap(ProcessHeap,
+                        0,
+                        FullInfo);
+        }
+
+        ErrorCode = RtlNtStatusToDosError(Status);
+        goto Cleanup;
+    }
+
+    TRACE("SubKeys %d\n", FullInfo->SubKeys);
+    if (lpcSubKeys != NULL)
+    {
+        *lpcSubKeys = FullInfo->SubKeys;
     }
 
-  TRACE("MaxNameLen %lu\n", FullInfo->MaxNameLen);
-  if (lpcbMaxSubKeyLen != NULL)
+    TRACE("MaxNameLen %lu\n", FullInfo->MaxNameLen);
+    if (lpcbMaxSubKeyLen != NULL)
     {
-      *lpcbMaxSubKeyLen = FullInfo->MaxNameLen / sizeof(WCHAR) + 1;
+        *lpcbMaxSubKeyLen = FullInfo->MaxNameLen / sizeof(WCHAR) + 1;
     }
 
-  TRACE("MaxClassLen %lu\n", FullInfo->MaxClassLen);
-  if (lpcbMaxClassLen != NULL)
+    TRACE("MaxClassLen %lu\n", FullInfo->MaxClassLen);
+    if (lpcbMaxClassLen != NULL)
     {
-      *lpcbMaxClassLen = FullInfo->MaxClassLen / sizeof(WCHAR) + 1;
+        *lpcbMaxClassLen = FullInfo->MaxClassLen / sizeof(WCHAR) + 1;
     }
 
-  TRACE("Values %lu\n", FullInfo->Values);
-  if (lpcValues != NULL)
+    TRACE("Values %lu\n", FullInfo->Values);
+    if (lpcValues != NULL)
     {
-      *lpcValues = FullInfo->Values;
+        *lpcValues = FullInfo->Values;
     }
 
-  TRACE("MaxValueNameLen %lu\n", FullInfo->MaxValueNameLen);
-  if (lpcbMaxValueNameLen != NULL)
+    TRACE("MaxValueNameLen %lu\n", FullInfo->MaxValueNameLen);
+    if (lpcbMaxValueNameLen != NULL)
     {
-      *lpcbMaxValueNameLen = FullInfo->MaxValueNameLen / sizeof(WCHAR) + 1;
+        *lpcbMaxValueNameLen = FullInfo->MaxValueNameLen / sizeof(WCHAR) + 1;
     }
 
-  TRACE("MaxValueDataLen %lu\n", FullInfo->MaxValueDataLen);
-  if (lpcbMaxValueLen != NULL)
+    TRACE("MaxValueDataLen %lu\n", FullInfo->MaxValueDataLen);
+    if (lpcbMaxValueLen != NULL)
     {
-      *lpcbMaxValueLen = FullInfo->MaxValueDataLen;
+        *lpcbMaxValueLen = FullInfo->MaxValueDataLen;
     }
+
 #if 0
-  if (lpcbSecurityDescriptor != NULL)
-    {
-      Status = NtQuerySecurityObject(KeyHandle,
-                                    OWNER_SECURITY_INFORMATION |
-                                    GROUP_SECURITY_INFORMATION |
-                                    DACL_SECURITY_INFORMATION,
-                                    NULL,
-                                    0,
-                                    lpcbSecurityDescriptor);
-      if (!NT_SUCCESS(Status))
-       {
-         if (lpClass != NULL)
-           {
-             RtlFreeHeap(ProcessHeap,
-                         0,
-                         FullInfo);
-           }
-
-         ErrorCode = RtlNtStatusToDosError (Status);
-         goto Cleanup;
-       }
+    if (lpcbSecurityDescriptor != NULL)
+    {
+        Status = NtQuerySecurityObject(KeyHandle,
+                                       OWNER_SECURITY_INFORMATION |
+                                       GROUP_SECURITY_INFORMATION |
+                                       DACL_SECURITY_INFORMATION,
+                                       NULL,
+                                       0,
+                                       lpcbSecurityDescriptor);
+        if (!NT_SUCCESS(Status))
+        {
+            if (lpClass != NULL)
+            {
+                RtlFreeHeap(ProcessHeap,
+                            0,
+                            FullInfo);
+            }
+
+            ErrorCode = RtlNtStatusToDosError(Status);
+            goto Cleanup;
+        }
     }
 #endif
 
-  if (lpftLastWriteTime != NULL)
+    if (lpftLastWriteTime != NULL)
     {
-      lpftLastWriteTime->dwLowDateTime = FullInfo->LastWriteTime.u.LowPart;
-      lpftLastWriteTime->dwHighDateTime = FullInfo->LastWriteTime.u.HighPart;
+        lpftLastWriteTime->dwLowDateTime = FullInfo->LastWriteTime.u.LowPart;
+        lpftLastWriteTime->dwHighDateTime = FullInfo->LastWriteTime.u.HighPart;
     }
 
-  if (lpClass != NULL)
+    if (lpClass != NULL)
     {
-      if (FullInfo->ClassLength > ClassLength)
-       {
-             ErrorCode = ERROR_BUFFER_OVERFLOW;
-       }
-      else
-       {
-         RtlCopyMemory (lpClass,
-                        FullInfo->Class,
-                        FullInfo->ClassLength);
-         *lpcbClass = FullInfo->ClassLength / sizeof(WCHAR);
-         lpClass[*lpcbClass] = 0;
-       }
+        if (FullInfo->ClassLength > ClassLength)
+        {
+            ErrorCode = ERROR_BUFFER_OVERFLOW;
+        }
+        else
+        {
+            RtlCopyMemory(lpClass,
+                          FullInfo->Class,
+                          FullInfo->ClassLength);
+            *lpcbClass = FullInfo->ClassLength / sizeof(WCHAR);
+            lpClass[*lpcbClass] = 0;
+        }
 
-      RtlFreeHeap (ProcessHeap,
-                  0,
-                  FullInfo);
+        RtlFreeHeap(ProcessHeap,
+                    0,
+                    FullInfo);
     }
 
 Cleanup:
-  ClosePredefKey(KeyHandle);
-  
-  return ErrorCode;
+    ClosePredefKey(KeyHandle);
+
+    return ErrorCode;
 }
 
 
@@ -3299,61 +3814,61 @@ Cleanup:
  * @implemented
  */
 LONG STDCALL
-RegQueryMultipleValuesA (HKEY hKey,
-                        PVALENTA val_list,
-                        DWORD num_vals,
-                        LPSTR lpValueBuf,
-                        LPDWORD ldwTotsize)
+RegQueryMultipleValuesA(HKEY hKey,
+                        PVALENTA val_list,
+                        DWORD num_vals,
+                        LPSTR lpValueBuf,
+                        LPDWORD ldwTotsize)
 {
-  ULONG i;
-  DWORD maxBytes = *ldwTotsize;
-  LPSTR bufptr = (LPSTR)lpValueBuf;
-  LONG ErrorCode;
-
-  if (maxBytes >= (1024*1024))
-    return ERROR_TRANSFER_TOO_LONG;
-
-  *ldwTotsize = 0;
-
-  TRACE("RegQueryMultipleValuesA(%p,%p,%ld,%p,%p=%ld)\n",
-         hKey, val_list, num_vals, lpValueBuf, ldwTotsize, *ldwTotsize);
-
-  for (i = 0; i < num_vals; i++)
-    {
-      val_list[i].ve_valuelen = 0;
-      ErrorCode = RegQueryValueExA (hKey,
-                                   val_list[i].ve_valuename,
-                                   NULL,
-                                   NULL,
-                                   NULL,
-                                   &val_list[i].ve_valuelen);
-      if (ErrorCode != ERROR_SUCCESS)
-       {
-         return ErrorCode;
-       }
-
-      if (lpValueBuf != NULL && *ldwTotsize + val_list[i].ve_valuelen <= maxBytes)
-       {
-         ErrorCode = RegQueryValueExA (hKey,
-                                       val_list[i].ve_valuename,
-                                       NULL,
-                                       &val_list[i].ve_type,
-                                       (LPBYTE)bufptr,
-                                       &val_list[i].ve_valuelen);
-         if (ErrorCode != ERROR_SUCCESS)
-           {
-             return ErrorCode;
-           }
-
-         val_list[i].ve_valueptr = (DWORD_PTR)bufptr;
-
-         bufptr += val_list[i].ve_valuelen;
-       }
-
-      *ldwTotsize += val_list[i].ve_valuelen;
-    }
-
-  return (lpValueBuf != NULL && *ldwTotsize <= maxBytes) ? ERROR_SUCCESS : ERROR_MORE_DATA;
+    ULONG i;
+    DWORD maxBytes = *ldwTotsize;
+    LPSTR bufptr = (LPSTR)lpValueBuf;
+    LONG ErrorCode;
+
+    if (maxBytes >= (1024*1024))
+        return ERROR_TRANSFER_TOO_LONG;
+
+    *ldwTotsize = 0;
+
+    TRACE("RegQueryMultipleValuesA(%p,%p,%ld,%p,%p=%ld)\n",
+          hKey, val_list, num_vals, lpValueBuf, ldwTotsize, *ldwTotsize);
+
+    for (i = 0; i < num_vals; i++)
+    {
+        val_list[i].ve_valuelen = 0;
+        ErrorCode = RegQueryValueExA(hKey,
+                                     val_list[i].ve_valuename,
+                                     NULL,
+                                     NULL,
+                                     NULL,
+                                     &val_list[i].ve_valuelen);
+        if (ErrorCode != ERROR_SUCCESS)
+        {
+            return ErrorCode;
+        }
+
+        if (lpValueBuf != NULL && *ldwTotsize + val_list[i].ve_valuelen <= maxBytes)
+        {
+            ErrorCode = RegQueryValueExA(hKey,
+                                         val_list[i].ve_valuename,
+                                         NULL,
+                                         &val_list[i].ve_type,
+                                         (LPBYTE)bufptr,
+                                         &val_list[i].ve_valuelen);
+            if (ErrorCode != ERROR_SUCCESS)
+            {
+                return ErrorCode;
+            }
+
+            val_list[i].ve_valueptr = (DWORD_PTR)bufptr;
+
+            bufptr += val_list[i].ve_valuelen;
+        }
+
+        *ldwTotsize += val_list[i].ve_valuelen;
+    }
+
+    return (lpValueBuf != NULL && *ldwTotsize <= maxBytes) ? ERROR_SUCCESS : ERROR_MORE_DATA;
 }
 
 
@@ -3363,61 +3878,61 @@ RegQueryMultipleValuesA (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegQueryMultipleValuesW (HKEY hKey,
-                        PVALENTW val_list,
-                        DWORD num_vals,
-                        LPWSTR lpValueBuf,
-                        LPDWORD ldwTotsize)
+RegQueryMultipleValuesW(HKEY hKey,
+                        PVALENTW val_list,
+                        DWORD num_vals,
+                        LPWSTR lpValueBuf,
+                        LPDWORD ldwTotsize)
 {
-  ULONG i;
-  DWORD maxBytes = *ldwTotsize;
-  LPSTR bufptr = (LPSTR)lpValueBuf;
-  LONG ErrorCode;
-
-  if (maxBytes >= (1024*1024))
-    return ERROR_TRANSFER_TOO_LONG;
-
-  *ldwTotsize = 0;
-
-  TRACE ("RegQueryMultipleValuesW(%p,%p,%ld,%p,%p=%ld)\n",
-         hKey, val_list, num_vals, lpValueBuf, ldwTotsize, *ldwTotsize);
-
-  for (i = 0; i < num_vals; i++)
-    {
-      val_list[i].ve_valuelen = 0;
-      ErrorCode = RegQueryValueExW (hKey,
-                                   val_list[i].ve_valuename,
-                                   NULL,
-                                   NULL,
-                                   NULL,
-                                   &val_list[i].ve_valuelen);
-      if (ErrorCode != ERROR_SUCCESS)
-       {
-         return ErrorCode;
-       }
-
-      if (lpValueBuf != NULL && *ldwTotsize + val_list[i].ve_valuelen <= maxBytes)
-       {
-         ErrorCode = RegQueryValueExW (hKey,
-                                       val_list[i].ve_valuename,
-                                       NULL,
-                                       &val_list[i].ve_type,
-                                       (LPBYTE)bufptr,
-                                       &val_list[i].ve_valuelen);
-         if (ErrorCode != ERROR_SUCCESS)
-           {
-             return ErrorCode;
-           }
-
-         val_list[i].ve_valueptr = (DWORD_PTR)bufptr;
-
-         bufptr += val_list[i].ve_valuelen;
-       }
-
-      *ldwTotsize += val_list[i].ve_valuelen;
-    }
-
-  return (lpValueBuf != NULL && *ldwTotsize <= maxBytes) ? ERROR_SUCCESS : ERROR_MORE_DATA;
+    ULONG i;
+    DWORD maxBytes = *ldwTotsize;
+    LPSTR bufptr = (LPSTR)lpValueBuf;
+    LONG ErrorCode;
+
+    if (maxBytes >= (1024*1024))
+        return ERROR_TRANSFER_TOO_LONG;
+
+    *ldwTotsize = 0;
+
+    TRACE("RegQueryMultipleValuesW(%p,%p,%ld,%p,%p=%ld)\n",
+          hKey, val_list, num_vals, lpValueBuf, ldwTotsize, *ldwTotsize);
+
+    for (i = 0; i < num_vals; i++)
+    {
+        val_list[i].ve_valuelen = 0;
+        ErrorCode = RegQueryValueExW(hKey,
+                                     val_list[i].ve_valuename,
+                                     NULL,
+                                     NULL,
+                                     NULL,
+                                     &val_list[i].ve_valuelen);
+        if (ErrorCode != ERROR_SUCCESS)
+        {
+            return ErrorCode;
+         }
+
+        if (lpValueBuf != NULL && *ldwTotsize + val_list[i].ve_valuelen <= maxBytes)
+        {
+            ErrorCode = RegQueryValueExW(hKey,
+                                         val_list[i].ve_valuename,
+                                         NULL,
+                                         &val_list[i].ve_type,
+                                         (LPBYTE)bufptr,
+                                         &val_list[i].ve_valuelen);
+            if (ErrorCode != ERROR_SUCCESS)
+            {
+                return ErrorCode;
+            }
+
+            val_list[i].ve_valueptr = (DWORD_PTR)bufptr;
+
+            bufptr += val_list[i].ve_valuelen;
+        }
+
+        *ldwTotsize += val_list[i].ve_valuelen;
+    }
+
+    return (lpValueBuf != NULL && *ldwTotsize <= maxBytes) ? ERROR_SUCCESS : ERROR_MORE_DATA;
 }
 
 
@@ -3430,239 +3945,207 @@ LONG WINAPI
 RegQueryReflectionKey(IN HKEY hBase,
                       OUT BOOL* bIsReflectionDisabled)
 {
-    DPRINT1("RegQueryReflectionKey(0x%p, 0x%p) UNIMPLEMENTED!\n",
-            hBase, bIsReflectionDisabled);
+    FIXME("RegQueryReflectionKey(0x%p, 0x%p) UNIMPLEMENTED!\n",
+          hBase, bIsReflectionDisabled);
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
 
 /************************************************************************
- *  RegQueryValueExW
+ *  RegQueryValueExA
  *
  * @implemented
  */
 LONG STDCALL
-RegQueryValueEx(HKEY hKey,
-                 LPCWSTR lpValueName,
-                 LPDWORD lpReserved,
-                 LPDWORD lpType,
-                 LPBYTE lpData,
-                 LPDWORD lpcbData)
+RegQueryValueExA(HKEY hKey,
+                 LPCSTR 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;
+    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);
+    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))
+    if (lpData != NULL && lpcbData == NULL)
     {
-      return RtlNtStatusToDosError (Status);
+        return ERROR_INVALID_PARAMETER;
     }
 
-  if (lpData != NULL && lpcbData == NULL)
+    if (lpData)
     {
-      ErrorCode = ERROR_INVALID_PARAMETER;
-      goto Cleanup;
+        ValueData.Length = 0;
+        ValueData.MaximumLength = (*lpcbData + 1) * sizeof(WCHAR);
+        ValueData.Buffer = RtlAllocateHeap(ProcessHeap,
+                                           0,
+                                           ValueData.MaximumLength);
+        if (!ValueData.Buffer)
+        {
+            return ERROR_OUTOFMEMORY;
+        }
     }
-
-  RtlInitUnicodeString (&ValueName,
-                       lpValueName);
-  BufferSize = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]) + MaxCopy;
-  ValueInfo = RtlAllocateHeap (ProcessHeap,
-                              0,
-                              BufferSize);
-  if (ValueInfo == NULL)
+    else
     {
-      ErrorCode = ERROR_OUTOFMEMORY;
-      goto Cleanup;
-    }
+        ValueData.Buffer = NULL;
+        ValueData.Length = 0;
+        ValueData.MaximumLength = 0;
 
-  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 (lpcbData)
+            *lpcbData = 0;
     }
 
-  if (lpType != NULL)
+    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)
     {
-      *lpType = ValueInfo->Type;
+        if (lpType != NULL)
+        {
+            *lpType = Type;
+        }
+
+        if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ))
+        {
+            if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL)
+            {
+                RtlInitAnsiString(&AnsiString, NULL);
+                AnsiString.Buffer = (LPSTR)lpData;
+                AnsiString.MaximumLength = *lpcbData;
+                ValueData.Length = Length;
+                ValueData.MaximumLength = ValueData.Length + sizeof(WCHAR);
+                RtlUnicodeStringToAnsiString(&AnsiString, &ValueData, FALSE);
+            }
+
+            Length = Length / sizeof(WCHAR);
+        }
+        else if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL)
+        {
+            if (*lpcbData < Length)
+            {
+                ErrorCode = ERROR_MORE_DATA;
+            }
+            else
+            {
+                RtlMoveMemory(lpData, ValueData.Buffer, Length);
+            }
+        }
+
+        if (lpcbData != NULL)
+        {
+            *lpcbData = Length;
+        }
     }
 
-  if (NT_SUCCESS(Status) && lpData != NULL)
+    if (ValueData.Buffer != NULL)
     {
-      RtlMoveMemory (lpData,
-                    ValueInfo->Data,
-                    min(ValueInfo->DataLength, MaxCopy));
+        RtlFreeHeap(ProcessHeap, 0, ValueData.Buffer);
     }
 
-  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;
-       }
+    return ErrorCode;
+}
 
-      if (lpcbData != NULL)
-       {
-         *lpcbData = (ResultSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]));
-         TRACE("(string) Returning Size: %lu\n", *lpcbData);
-       }
-    }
-  else
+
+/************************************************************************
+ *  RegQueryValueExW
+ *
+ * @implemented
+ */
+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))
     {
-      if (lpcbData != NULL)
-       {
-         *lpcbData = ResultSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]);
-         TRACE("(other) Returning Size: %lu\n", *lpcbData);
-       }
+        return RtlNtStatusToDosError(status);
     }
 
-  TRACE("Type %d  Size %d\n", ValueInfo->Type, ValueInfo->DataLength);
-
-  RtlFreeHeap (ProcessHeap,
-              0,
-              ValueInfo);
+    RtlInitUnicodeString( &name_str, name );
 
-Cleanup:
-  ClosePredefKey(KeyHandle);
+    if (data) total_size = min( sizeof(buffer), *count + info_size );
+    else
+    {
+        total_size = info_size;
+        if (count) *count = 0;
+    }
 
-  return ErrorCode;
-}
+    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 );
+        }
 
-/************************************************************************
- *  RegQueryValueExA
- *
- * @implemented
- */
-LONG STDCALL
-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;
-    }
-
-  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)
-           {
-             RtlInitAnsiString(&AnsiString, NULL);
-             AnsiString.Buffer = (LPSTR)lpData;
-             AnsiString.MaximumLength = *lpcbData;
-             ValueData.Length = Length;
-             ValueData.MaximumLength = ValueData.Length + sizeof(WCHAR);
-             RtlUnicodeStringToAnsiString(&AnsiString, &ValueData, FALSE);
-           }
-         Length = Length / sizeof(WCHAR);
-       }
-      else if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL)
-       {
-          if (*lpcbData < Length)
-            {
-              ErrorCode = ERROR_MORE_DATA;
-            }
-          else
+        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))
             {
-              RtlMoveMemory(lpData, ValueData.Buffer, Length);
+                WCHAR *ptr = (WCHAR *)(data + total_size - info_size);
+                if (ptr > (WCHAR *)data && ptr[-1]) *ptr = 0;
             }
-       }
-
-      if (lpcbData != NULL)
-       {
-         *lpcbData = Length;
-       }
+        }
+        else if (status != STATUS_BUFFER_OVERFLOW) goto done;
     }
+    else status = STATUS_SUCCESS;
 
-  if (ValueData.Buffer != NULL)
-    {
-      RtlFreeHeap(ProcessHeap, 0, ValueData.Buffer);
-    }
+    if (type) *type = info->Type;
+    if (count) *count = total_size - info_size;
 
-  return ErrorCode;
+ done:
+    if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
+    ClosePredefKey(hkey);
+    return RtlNtStatusToDosError(status);
 }
 
 
@@ -3672,85 +4155,92 @@ RegQueryValueExA (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegQueryValueA (HKEY hKey,
-               LPCSTR lpSubKey,
-               LPSTR lpValue,
-               PLONG lpcbValue)
+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;
+    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);
+    TRACE("hKey 0x%X lpSubKey %s lpValue %p lpcbValue %d\n",
+          hKey, lpSubKey, lpValue, lpcbValue ? *lpcbValue : 0);
 
-  if (lpValue != NULL &&
-      lpcbValue == NULL)
+    if (lpValue != NULL &&
+        lpcbValue == NULL)
     {
-      return ERROR_INVALID_PARAMETER;
+        return ERROR_INVALID_PARAMETER;
     }
 
-  RtlInitUnicodeString (&SubKeyName,
-                       NULL);
-  RtlInitUnicodeString (&Value,
-                       NULL);
-  if (lpSubKey != NULL &&
-      strlen(lpSubKey) != 0)
+    RtlInitUnicodeString(&SubKeyName,
+                         NULL);
+    RtlInitUnicodeString(&Value,
+                         NULL);
+    if (lpSubKey != NULL &&
+        strlen(lpSubKey) != 0)
     {
-      RtlInitAnsiString (&AnsiString,
-                        (LPSTR)lpSubKey);
+        RtlInitAnsiString(&AnsiString,
+                          (LPSTR)lpSubKey);
       SubKeyName.Buffer = &SubKeyNameBuffer[0];
       SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer);
-      RtlAnsiStringToUnicodeString (&SubKeyName,
-                                   &AnsiString,
-                                   FALSE);
+      RtlAnsiStringToUnicodeString(&SubKeyName,
+                                   &AnsiString,
+                                   FALSE);
     }
 
-  if (lpValue != NULL)
+    if (lpValue != NULL)
     {
-      ValueSize = *lpcbValue * sizeof(WCHAR);
-      Value.MaximumLength = ValueSize;
-      Value.Buffer = RtlAllocateHeap (ProcessHeap,
-                                     0,
-                                     ValueSize);
-      if (Value.Buffer == NULL)
-       {
-         return ERROR_OUTOFMEMORY;
-       }
+        ValueSize = *lpcbValue * sizeof(WCHAR);
+        Value.MaximumLength = ValueSize;
+        Value.Buffer = RtlAllocateHeap(ProcessHeap,
+                                       0,
+                                       ValueSize);
+        if (Value.Buffer == NULL)
+        {
+            return ERROR_OUTOFMEMORY;
+        }
     }
-  else
+    else
     {
-      ValueSize = 0;
+        ValueSize = 0;
     }
 
-  ErrorCode = RegQueryValueW (hKey,
-                             (LPCWSTR)SubKeyName.Buffer,
-                             Value.Buffer,
-                             &ValueSize);
-  if (ErrorCode == ERROR_SUCCESS)
+    ErrorCode = RegQueryValueW(hKey,
+                               (LPCWSTR)SubKeyName.Buffer,
+                               Value.Buffer,
+                               &ValueSize);
+    if (ErrorCode == ERROR_SUCCESS)
     {
-      Value.Length = ValueSize;
-      RtlInitAnsiString (&AnsiString,
-                        NULL);
-      AnsiString.Buffer = lpValue;
-      AnsiString.MaximumLength = *lpcbValue;
-      RtlUnicodeStringToAnsiString (&AnsiString,
-                                   &Value,
-                                   FALSE);
+        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;
+        }
     }
 
-  *lpcbValue = ValueSize;
-  if (Value.Buffer != NULL)
+    if (Value.Buffer != NULL)
     {
-      RtlFreeHeap (ProcessHeap,
-                  0,
-                  Value.Buffer);
+        RtlFreeHeap(ProcessHeap,
+                    0,
+                    Value.Buffer);
     }
 
-  return ErrorCode;
+    return ErrorCode;
 }
 
 
@@ -3760,70 +4250,71 @@ RegQueryValueA (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegQueryValueW (HKEY hKey,
-               LPCWSTR lpSubKey,
-               LPWSTR lpValue,
-               PLONG lpcbValue)
+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;
+    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);
+    TRACE("hKey 0x%X lpSubKey %S lpValue %p lpcbValue %d\n",
+          hKey, lpSubKey, lpValue, lpcbValue ? *lpcbValue : 0);
 
-  Status = MapDefaultKey (&KeyHandle,
-                          hKey);
-  if (!NT_SUCCESS(Status))
+    Status = MapDefaultKey(&KeyHandle,
+                           hKey);
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  if (lpSubKey != NULL &&
-      wcslen(lpSubKey) != 0)
+    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;
+        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
+    else
     {
-      RealKey = hKey;
-      CloseRealKey = FALSE;
+        RealKey = hKey;
+        CloseRealKey = FALSE;
     }
 
-  ErrorCode = RegQueryValueExW (RealKey,
-                               NULL,
-                               NULL,
-                               NULL,
-                               (LPBYTE)lpValue,
-                               (LPDWORD)lpcbValue);
-  if (CloseRealKey)
+    ErrorCode = RegQueryValueExW(RealKey,
+                                 NULL,
+                                 NULL,
+                                 NULL,
+                                 (LPBYTE)lpValue,
+                                 (LPDWORD)lpcbValue);
+    if (CloseRealKey)
     {
-      NtClose (RealKey);
+        NtClose(RealKey);
     }
 
 Cleanup:
-  ClosePredefKey(KeyHandle);
+    ClosePredefKey(KeyHandle);
 
-  return ErrorCode;
+    return ErrorCode;
 }
 
 
@@ -3833,33 +4324,33 @@ Cleanup:
  * @implemented
  */
 LONG STDCALL
-RegReplaceKeyA (HKEY hKey,
-               LPCSTR lpSubKey,
-               LPCSTR lpNewFile,
-               LPCSTR lpOldFile)
+RegReplaceKeyA(HKEY hKey,
+               LPCSTR lpSubKey,
+               LPCSTR lpNewFile,
+               LPCSTR lpOldFile)
 {
-  UNICODE_STRING SubKey;
-  UNICODE_STRING NewFile;
-  UNICODE_STRING OldFile;
-  LONG ErrorCode;
-
-  RtlCreateUnicodeStringFromAsciiz (&SubKey,
-                                   (PCSZ)lpSubKey);
-  RtlCreateUnicodeStringFromAsciiz (&OldFile,
-                                   (PCSZ)lpOldFile);
-  RtlCreateUnicodeStringFromAsciiz (&NewFile,
-                                   (PCSZ)lpNewFile);
-
-  ErrorCode = RegReplaceKeyW (hKey,
-                             SubKey.Buffer,
-                             NewFile.Buffer,
-                             OldFile.Buffer);
-
-  RtlFreeUnicodeString (&OldFile);
-  RtlFreeUnicodeString (&NewFile);
-  RtlFreeUnicodeString (&SubKey);
-
-  return ErrorCode;
+    UNICODE_STRING SubKey;
+    UNICODE_STRING NewFile;
+    UNICODE_STRING OldFile;
+    LONG ErrorCode;
+
+    RtlCreateUnicodeStringFromAsciiz(&SubKey,
+                                     (PCSZ)lpSubKey);
+    RtlCreateUnicodeStringFromAsciiz(&OldFile,
+                                     (PCSZ)lpOldFile);
+    RtlCreateUnicodeStringFromAsciiz(&NewFile,
+                                     (PCSZ)lpNewFile);
+
+    ErrorCode = RegReplaceKeyW(hKey,
+                               SubKey.Buffer,
+                               NewFile.Buffer,
+                               OldFile.Buffer);
+
+    RtlFreeUnicodeString(&OldFile);
+    RtlFreeUnicodeString(&NewFile);
+    RtlFreeUnicodeString(&SubKey);
+
+    return ErrorCode;
 }
 
 
@@ -3869,129 +4360,132 @@ RegReplaceKeyA (HKEY hKey,
  * @unimplemented
  */
 LONG STDCALL
-RegReplaceKeyW (HKEY hKey,
-               LPCWSTR lpSubKey,
-               LPCWSTR lpNewFile,
-               LPCWSTR lpOldFile)
+RegReplaceKeyW(HKEY hKey,
+               LPCWSTR lpSubKey,
+               LPCWSTR lpNewFile,
+               LPCWSTR lpOldFile)
 {
-  OBJECT_ATTRIBUTES KeyObjectAttributes;
-  OBJECT_ATTRIBUTES NewObjectAttributes;
-  OBJECT_ATTRIBUTES OldObjectAttributes;
-  UNICODE_STRING SubKeyName;
-  UNICODE_STRING NewFileName;
-  UNICODE_STRING OldFileName;
-  BOOLEAN CloseRealKey;
-  HANDLE RealKeyHandle;
-  HANDLE KeyHandle;
-  NTSTATUS Status;
-  LONG ErrorCode = ERROR_SUCCESS;
-
-  if (hKey == HKEY_PERFORMANCE_DATA)
+    OBJECT_ATTRIBUTES KeyObjectAttributes;
+    OBJECT_ATTRIBUTES NewObjectAttributes;
+    OBJECT_ATTRIBUTES OldObjectAttributes;
+    UNICODE_STRING SubKeyName;
+    UNICODE_STRING NewFileName;
+    UNICODE_STRING OldFileName;
+    BOOLEAN CloseRealKey;
+    HANDLE RealKeyHandle;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
+    LONG ErrorCode = ERROR_SUCCESS;
+
+    if (hKey == HKEY_PERFORMANCE_DATA)
     {
-      return ERROR_INVALID_HANDLE;
+        return ERROR_INVALID_HANDLE;
     }
 
-  Status = MapDefaultKey (&KeyHandle,
-                          hKey);
-  if (!NT_SUCCESS(Status))
+    Status = MapDefaultKey(&KeyHandle,
+                           hKey);
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  /* Open the real key */
-  if (lpSubKey != NULL && *lpSubKey != (WCHAR)0)
+    /* Open the real key */
+    if (lpSubKey != NULL && *lpSubKey != (WCHAR)0)
     {
-      RtlInitUnicodeString (&SubKeyName,
-                           (PWSTR)lpSubKey);
-      InitializeObjectAttributes (&KeyObjectAttributes,
-                                 &SubKeyName,
-                                 OBJ_CASE_INSENSITIVE,
-                                 KeyHandle,
-                                 NULL);
-      Status = NtOpenKey (&RealKeyHandle,
-                         MAXIMUM_ALLOWED,
-                         &KeyObjectAttributes);
-      if (!NT_SUCCESS(Status))
-       {
-         ErrorCode = RtlNtStatusToDosError (Status);
-         goto Cleanup;
-       }
-      CloseRealKey = TRUE;
+        RtlInitUnicodeString(&SubKeyName,
+                             (PWSTR)lpSubKey);
+        InitializeObjectAttributes(&KeyObjectAttributes,
+                                   &SubKeyName,
+                                   OBJ_CASE_INSENSITIVE,
+                                   KeyHandle,
+                                   NULL);
+        Status = NtOpenKey(&RealKeyHandle,
+                           MAXIMUM_ALLOWED,
+                           &KeyObjectAttributes);
+        if (!NT_SUCCESS(Status))
+        {
+            ErrorCode = RtlNtStatusToDosError(Status);
+            goto Cleanup;
+        }
+
+        CloseRealKey = TRUE;
     }
-  else
+    else
     {
-      RealKeyHandle = KeyHandle;
-      CloseRealKey = FALSE;
+        RealKeyHandle = KeyHandle;
+        CloseRealKey = FALSE;
     }
 
-  /* Convert new file name */
-  if (!RtlDosPathNameToNtPathName_U (lpNewFile,
-                                    &NewFileName,
-                                    NULL,
-                                    NULL))
+    /* Convert new file name */
+    if (!RtlDosPathNameToNtPathName_U(lpNewFile,
+                                      &NewFileName,
+                                      NULL,
+                                      NULL))
     {
-      if (CloseRealKey)
-       {
-         NtClose (RealKeyHandle);
-       }
-      ErrorCode = ERROR_INVALID_PARAMETER;
-      goto Cleanup;
+        if (CloseRealKey)
+        {
+            NtClose(RealKeyHandle);
+        }
+
+        ErrorCode = ERROR_INVALID_PARAMETER;
+        goto Cleanup;
     }
 
-  InitializeObjectAttributes (&NewObjectAttributes,
-                             &NewFileName,
-                             OBJ_CASE_INSENSITIVE,
-                             NULL,
-                             NULL);
-
-  /* Convert old file name */
-  if (!RtlDosPathNameToNtPathName_U (lpOldFile,
-                                    &OldFileName,
-                                    NULL,
-                                    NULL))
-    {
-      RtlFreeHeap (RtlGetProcessHeap (),
-                   0,
-                   NewFileName.Buffer);
-      if (CloseRealKey)
-       {
-         NtClose (RealKeyHandle);
-       }
-      ErrorCode = ERROR_INVALID_PARAMETER;
-      goto Cleanup;
+    InitializeObjectAttributes(&NewObjectAttributes,
+                               &NewFileName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+
+    /* Convert old file name */
+    if (!RtlDosPathNameToNtPathName_U(lpOldFile,
+                                      &OldFileName,
+                                      NULL,
+                                      NULL))
+    {
+        RtlFreeHeap(RtlGetProcessHeap (),
+                    0,
+                    NewFileName.Buffer);
+        if (CloseRealKey)
+        {
+            NtClose(RealKeyHandle);
+        }
+
+        ErrorCode = ERROR_INVALID_PARAMETER;
+        goto Cleanup;
     }
 
-  InitializeObjectAttributes (&OldObjectAttributes,
-                             &OldFileName,
-                             OBJ_CASE_INSENSITIVE,
-                             NULL,
-                             NULL);
+    InitializeObjectAttributes(&OldObjectAttributes,
+                               &OldFileName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
 
-  Status = NtReplaceKey (&NewObjectAttributes,
-                        RealKeyHandle,
-                        &OldObjectAttributes);
+    Status = NtReplaceKey(&NewObjectAttributes,
+                          RealKeyHandle,
+                          &OldObjectAttributes);
 
-  RtlFreeHeap (RtlGetProcessHeap (),
-               0,
-               OldFileName.Buffer);
-  RtlFreeHeap (RtlGetProcessHeap (),
-               0,
-               NewFileName.Buffer);
+    RtlFreeHeap(RtlGetProcessHeap(),
+                0,
+                OldFileName.Buffer);
+    RtlFreeHeap(RtlGetProcessHeap(),
+                0,
+                NewFileName.Buffer);
 
-  if (CloseRealKey)
+    if (CloseRealKey)
     {
-      NtClose (RealKeyHandle);
+        NtClose(RealKeyHandle);
     }
 
-  if (!NT_SUCCESS(Status))
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
 Cleanup:
-  ClosePredefKey(KeyHandle);
+    ClosePredefKey(KeyHandle);
 
-  return ErrorCode;
+    return ErrorCode;
 }
 
 
@@ -4001,23 +4495,23 @@ Cleanup:
  * @implemented
  */
 LONG STDCALL
-RegRestoreKeyA (HKEY hKey,
-               LPCSTR lpFile,
-               DWORD dwFlags)
+RegRestoreKeyA(HKEY hKey,
+               LPCSTR lpFile,
+               DWORD dwFlags)
 {
-  UNICODE_STRING FileName;
-  LONG ErrorCode;
+    UNICODE_STRING FileName;
+    LONG ErrorCode;
 
-  RtlCreateUnicodeStringFromAsciiz (&FileName,
-                                   (PCSZ)lpFile);
+    RtlCreateUnicodeStringFromAsciiz(&FileName,
+                                     (PCSZ)lpFile);
 
-  ErrorCode = RegRestoreKeyW (hKey,
-                             FileName.Buffer,
-                             dwFlags);
+    ErrorCode = RegRestoreKeyW(hKey,
+                               FileName.Buffer,
+                               dwFlags);
 
-  RtlFreeUnicodeString (&FileName);
+    RtlFreeUnicodeString(&FileName);
 
-  return ErrorCode;
+    return ErrorCode;
 }
 
 
@@ -4027,72 +4521,72 @@ RegRestoreKeyA (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegRestoreKeyW (HKEY hKey,
-               LPCWSTR lpFile,
-               DWORD dwFlags)
+RegRestoreKeyW(HKEY hKey,
+               LPCWSTR lpFile,
+               DWORD dwFlags)
 {
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  IO_STATUS_BLOCK IoStatusBlock;
-  UNICODE_STRING FileName;
-  HANDLE FileHandle;
-  HANDLE KeyHandle;
-  NTSTATUS Status;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    IO_STATUS_BLOCK IoStatusBlock;
+    UNICODE_STRING FileName;
+    HANDLE FileHandle;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
 
-  if (hKey == HKEY_PERFORMANCE_DATA)
+    if (hKey == HKEY_PERFORMANCE_DATA)
     {
-      return ERROR_INVALID_HANDLE;
+        return ERROR_INVALID_HANDLE;
     }
 
-  Status = MapDefaultKey (&KeyHandle,
-                          hKey);
-  if (!NT_SUCCESS(Status))
+    Status = MapDefaultKey(&KeyHandle,
+                           hKey);
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  if (!RtlDosPathNameToNtPathName_U (lpFile,
-                                    &FileName,
-                                    NULL,
-                                    NULL))
+    if (!RtlDosPathNameToNtPathName_U(lpFile,
+                                      &FileName,
+                                      NULL,
+                                      NULL))
     {
-      Status = STATUS_INVALID_PARAMETER;
-      goto Cleanup;
+        Status = STATUS_INVALID_PARAMETER;
+        goto Cleanup;
     }
 
-  InitializeObjectAttributes (&ObjectAttributes,
-                             &FileName,
-                             OBJ_CASE_INSENSITIVE,
-                             NULL,
-                             NULL);
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &FileName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
 
-  Status = NtOpenFile (&FileHandle,
-                      FILE_GENERIC_READ,
-                      &ObjectAttributes,
-                      &IoStatusBlock,
-                      FILE_SHARE_READ,
-                      FILE_SYNCHRONOUS_IO_NONALERT);
-  RtlFreeHeap (RtlGetProcessHeap(),
-               0,
-               FileName.Buffer);
-  if (!NT_SUCCESS(Status))
+    Status = NtOpenFile(&FileHandle,
+                        FILE_GENERIC_READ,
+                        &ObjectAttributes,
+                        &IoStatusBlock,
+                        FILE_SHARE_READ,
+                        FILE_SYNCHRONOUS_IO_NONALERT);
+    RtlFreeHeap(RtlGetProcessHeap(),
+                0,
+                FileName.Buffer);
+    if (!NT_SUCCESS(Status))
     {
-      goto Cleanup;
+        goto Cleanup;
     }
 
-  Status = NtRestoreKey (KeyHandle,
-                        FileHandle,
-                        (ULONG)dwFlags);
-  NtClose (FileHandle);
-  
+    Status = NtRestoreKey(KeyHandle,
+                          FileHandle,
+                          (ULONG)dwFlags);
+    NtClose (FileHandle);
+
 Cleanup:
-  ClosePredefKey(KeyHandle);
+    ClosePredefKey(KeyHandle);
 
-  if (!NT_SUCCESS(Status))
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  return ERROR_SUCCESS;
+    return ERROR_SUCCESS;
 }
 
 
@@ -4102,21 +4596,21 @@ Cleanup:
  * @implemented
  */
 LONG STDCALL
-RegSaveKeyA (HKEY hKey,
-            LPCSTR lpFile,
-            LPSECURITY_ATTRIBUTES lpSecurityAttributes)
+RegSaveKeyA(HKEY hKey,
+            LPCSTR lpFile,
+            LPSECURITY_ATTRIBUTES lpSecurityAttributes)
 {
-  UNICODE_STRING FileName;
-  LONG ErrorCode;
+    UNICODE_STRING FileName;
+    LONG ErrorCode;
 
-  RtlCreateUnicodeStringFromAsciiz (&FileName,
-                                   (LPSTR)lpFile);
-  ErrorCode = RegSaveKeyW (hKey,
-                          FileName.Buffer,
-                          lpSecurityAttributes);
-  RtlFreeUnicodeString (&FileName);
+    RtlCreateUnicodeStringFromAsciiz(&FileName,
+                                     (LPSTR)lpFile);
+    ErrorCode = RegSaveKeyW(hKey,
+                            FileName.Buffer,
+                            lpSecurityAttributes);
+    RtlFreeUnicodeString(&FileName);
 
-  return ErrorCode;
+    return ErrorCode;
 }
 
 
@@ -4126,76 +4620,76 @@ RegSaveKeyA (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegSaveKeyW (HKEY hKey,
-            LPCWSTR lpFile,
-            LPSECURITY_ATTRIBUTES lpSecurityAttributes)
+RegSaveKeyW(HKEY hKey,
+            LPCWSTR lpFile,
+            LPSECURITY_ATTRIBUTES lpSecurityAttributes)
 {
-  PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  UNICODE_STRING FileName;
-  IO_STATUS_BLOCK IoStatusBlock;
-  HANDLE FileHandle;
-  HANDLE KeyHandle;
-  NTSTATUS Status;
+    PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING FileName;
+    IO_STATUS_BLOCK IoStatusBlock;
+    HANDLE FileHandle;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
 
-  Status = MapDefaultKey (&KeyHandle,
-                          hKey);
-  if (!NT_SUCCESS(Status))
+    Status = MapDefaultKey(&KeyHandle,
+                           hKey);
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  if (!RtlDosPathNameToNtPathName_U (lpFile,
-                                    &FileName,
-                                    NULL,
-                                    NULL))
+    if (!RtlDosPathNameToNtPathName_U(lpFile,
+                                      &FileName,
+                                      NULL,
+                                      NULL))
     {
-      Status = STATUS_INVALID_PARAMETER;
-      goto Cleanup;
+        Status = STATUS_INVALID_PARAMETER;
+        goto Cleanup;
     }
 
-  if (lpSecurityAttributes != NULL)
-    {
-      SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor;
-    }
-
-  InitializeObjectAttributes (&ObjectAttributes,
-                             &FileName,
-                             OBJ_CASE_INSENSITIVE,
-                             NULL,
-                             SecurityDescriptor);
-  Status = NtCreateFile (&FileHandle,
-                        GENERIC_WRITE | SYNCHRONIZE,
-                        &ObjectAttributes,
-                        &IoStatusBlock,
-                        NULL,
-                        FILE_ATTRIBUTE_NORMAL,
-                        FILE_SHARE_READ,
-                        FILE_CREATE,
-                        FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
-                        NULL,
-                        0);
-  RtlFreeHeap (RtlGetProcessHeap (),
-               0,
-               FileName.Buffer);
-  if (!NT_SUCCESS(Status))
+    if (lpSecurityAttributes != NULL)
     {
-      goto Cleanup;
+        SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor;
     }
 
-  Status = NtSaveKey (KeyHandle,
-                     FileHandle);
-  NtClose (FileHandle);
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &FileName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               SecurityDescriptor);
+    Status = NtCreateFile(&FileHandle,
+                          GENERIC_WRITE | SYNCHRONIZE,
+                          &ObjectAttributes,
+                          &IoStatusBlock,
+                          NULL,
+                          FILE_ATTRIBUTE_NORMAL,
+                          FILE_SHARE_READ,
+                          FILE_CREATE,
+                          FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
+                          NULL,
+                          0);
+    RtlFreeHeap(RtlGetProcessHeap(),
+                0,
+                FileName.Buffer);
+    if (!NT_SUCCESS(Status))
+    {
+        goto Cleanup;
+    }
+
+    Status = NtSaveKey(KeyHandle,
+                       FileHandle);
+    NtClose (FileHandle);
 
 Cleanup:
-  ClosePredefKey(KeyHandle);
+    ClosePredefKey(KeyHandle);
 
-  if (!NT_SUCCESS(Status))
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  return ERROR_SUCCESS;
+    return ERROR_SUCCESS;
 }
 
 
@@ -4205,37 +4699,37 @@ Cleanup:
  * @implemented
  */
 LONG STDCALL
-RegSetKeySecurity (HKEY hKey,
-                  SECURITY_INFORMATION SecurityInformation,
-                  PSECURITY_DESCRIPTOR pSecurityDescriptor)
+RegSetKeySecurity(HKEY hKey,
+                  SECURITY_INFORMATION SecurityInformation,
+                  PSECURITY_DESCRIPTOR pSecurityDescriptor)
 {
-  HANDLE KeyHandle;
-  NTSTATUS Status;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
 
-  if (hKey == HKEY_PERFORMANCE_DATA)
+    if (hKey == HKEY_PERFORMANCE_DATA)
     {
-      return ERROR_INVALID_HANDLE;
+        return ERROR_INVALID_HANDLE;
     }
 
-  Status = MapDefaultKey (&KeyHandle,
-                          hKey);
-  if (!NT_SUCCESS(Status))
+    Status = MapDefaultKey(&KeyHandle,
+                           hKey);
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  Status = NtSetSecurityObject (KeyHandle,
-                               SecurityInformation,
-                               pSecurityDescriptor);
+    Status = NtSetSecurityObject(KeyHandle,
+                                 SecurityInformation,
+                                 pSecurityDescriptor);
 
-  ClosePredefKey(KeyHandle);
-  
-  if (!NT_SUCCESS(Status))
+    ClosePredefKey(KeyHandle);
+
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  return ERROR_SUCCESS;
+    return ERROR_SUCCESS;
 }
 
 
@@ -4245,84 +4739,85 @@ RegSetKeySecurity (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegSetValueExA (HKEY hKey,
-               LPCSTR lpValueName,
-               DWORD Reserved,
-               DWORD dwType,
-               CONST BYTE* lpData,
-               DWORD cbData)
+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;
+    UNICODE_STRING ValueName;
+    LPWSTR pValueName;
+    ANSI_STRING AnsiString;
+    UNICODE_STRING Data;
+    LONG ErrorCode;
+    LPBYTE pData;
+    DWORD DataSize;
 
-  if (lpValueName != NULL &&
-      strlen(lpValueName) != 0)
+    if (lpValueName != NULL &&
+        strlen(lpValueName) != 0)
     {
-      RtlCreateUnicodeStringFromAsciiz (&ValueName,
-                                       (PSTR)lpValueName);
-      pValueName = (LPWSTR)ValueName.Buffer;
+        RtlCreateUnicodeStringFromAsciiz(&ValueName,
+                                         (PSTR)lpValueName);
     }
-  else
+    else
     {
-      pValueName = NULL;
+        ValueName.Buffer = NULL;
     }
 
-  if (((dwType == REG_SZ) ||
-       (dwType == REG_MULTI_SZ) ||
-       (dwType == REG_EXPAND_SZ)) &&
-      (cbData != 0))
+    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++;
-      }
+        /* 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);
+        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
+    else
     {
-      RtlInitUnicodeString (&Data,
-                           NULL);
-      pData = (LPBYTE)lpData;
-      DataSize = cbData;
+        RtlInitUnicodeString(&Data,
+                             NULL);
+        pData = (LPBYTE)lpData;
+        DataSize = cbData;
     }
 
-  ErrorCode = RegSetValueExW (hKey,
-                             pValueName,
-                             Reserved,
-                             dwType,
-                             pData,
-                             DataSize);
-  if (pValueName != NULL)
+    ErrorCode = RegSetValueExW(hKey,
+                               pValueName,
+                               Reserved,
+                               dwType,
+                               pData,
+                               DataSize);
+    if (pValueName != NULL)
     {
-      RtlFreeHeap (ProcessHeap,
-                  0,
-                  ValueName.Buffer);
+        RtlFreeHeap(ProcessHeap,
+                    0,
+                    ValueName.Buffer);
     }
 
-  if (Data.Buffer != NULL)
+    if (Data.Buffer != NULL)
     {
-      RtlFreeHeap (ProcessHeap,
-                  0,
-                  Data.Buffer);
+        RtlFreeHeap(ProcessHeap,
+                    0,
+                    Data.Buffer);
     }
 
-  return ErrorCode;
+    return ErrorCode;
 }
 
 
@@ -4332,60 +4827,60 @@ RegSetValueExA (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegSetValueExW (HKEY hKey,
-               LPCWSTR lpValueName,
-               DWORD Reserved,
-               DWORD dwType,
-               CONST BYTE* lpData,
-               DWORD cbData)
+RegSetValueExW(HKEY hKey,
+               LPCWSTR lpValueName,
+               DWORD Reserved,
+               DWORD dwType,
+               CONST BYTE* lpData,
+               DWORD cbData)
 {
-  UNICODE_STRING ValueName;
-  PUNICODE_STRING pValueName;
-  HANDLE KeyHandle;
-  NTSTATUS Status;
+    UNICODE_STRING ValueName;
+    PUNICODE_STRING pValueName;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
 
-  Status = MapDefaultKey (&KeyHandle,
-                          hKey);
-  if (!NT_SUCCESS(Status))
+    Status = MapDefaultKey(&KeyHandle,
+                           hKey);
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  if (lpValueName != NULL)
+    if (lpValueName != NULL)
     {
-      RtlInitUnicodeString (&ValueName,
-                           lpValueName);
+        RtlInitUnicodeString(&ValueName,
+                             lpValueName);
     }
-  else
+    else
     {
-      RtlInitUnicodeString (&ValueName, L"");
+        RtlInitUnicodeString(&ValueName, L"");
     }
-  pValueName = &ValueName;
+    pValueName = &ValueName;
 
-  if (((dwType == REG_SZ) ||
-       (dwType == REG_MULTI_SZ) ||
-       (dwType == REG_EXPAND_SZ)) &&
-      (cbData != 0) && (*(((PWCHAR)lpData) + (cbData / sizeof(WCHAR)) - 1) != L'\0'))
+    if (((dwType == REG_SZ) ||
+         (dwType == REG_MULTI_SZ) ||
+         (dwType == REG_EXPAND_SZ)) &&
+        (cbData != 0) && (*(((PWCHAR)lpData) + (cbData / sizeof(WCHAR)) - 1) != L'\0'))
     {
-      /* NT adds one if the caller forgot the NULL-termination character */
-      cbData += sizeof(WCHAR);
+        /* NT adds one if the caller forgot the NULL-termination character */
+        cbData += sizeof(WCHAR);
     }
 
-  Status = NtSetValueKey (KeyHandle,
-                         pValueName,
-                         0,
-                         dwType,
-                         (PVOID)lpData,
-                         (ULONG)cbData);
+    Status = NtSetValueKey(KeyHandle,
+                           pValueName,
+                           0,
+                           dwType,
+                           (PVOID)lpData,
+                           (ULONG)cbData);
 
-  ClosePredefKey(KeyHandle);
+    ClosePredefKey(KeyHandle);
 
-  if (!NT_SUCCESS(Status))
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  return ERROR_SUCCESS;
+    return ERROR_SUCCESS;
 }
 
 
@@ -4395,47 +4890,43 @@ RegSetValueExW (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegSetValueA (HKEY hKey,
-             LPCSTR lpSubKey,
-             DWORD dwType,
-             LPCSTR lpData,
-             DWORD cbData)
+RegSetValueA(HKEY hKeyOriginal,
+             LPCSTR lpSubKey,
+             DWORD dwType,
+             LPCSTR lpData,
+             DWORD cbData)
 {
-  LONG ret;
-  HKEY hSubKey;
+    HKEY subkey;
+    HANDLE hKey;
+    DWORD ret;
+    NTSTATUS Status;
 
-  if (dwType != REG_SZ)
-  {
-     return ERROR_INVALID_PARAMETER;
-  }
+    TRACE("(%p,%s,%d,%s,%d)\n", hKey, debugstr_a(lpSubKey), dwType, debugstr_a(lpData), cbData );
 
-  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;
+    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 */
+    {
+        ret = RegCreateKeyA(hKey, lpSubKey, &subkey);
+        if (ret != 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;
 }
 
 
@@ -4445,67 +4936,46 @@ RegSetValueA (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegSetValueW (HKEY hKey,
-             LPCWSTR lpSubKey,
-             DWORD dwType,
-             LPCWSTR lpData,
-             DWORD cbData)
+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;
+    HKEY subkey;
+    HANDLE hKey;
+    DWORD ret;
+    NTSTATUS Status;
 
-  Status = MapDefaultKey (&KeyHandle,
-                          hKey);
-  if (!NT_SUCCESS(Status))
-    {
-      return RtlNtStatusToDosError (Status);
-    }
+    TRACE("(%p,%s,%d,%s,%d)\n", hKeyOriginal, debugstr_w(lpSubKey), dwType, debugstr_w(lpData), cbData );
 
-  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
+    if (dwType != REG_SZ || !lpData)
+        return ERROR_INVALID_PARAMETER;
+
+    Status = MapDefaultKey(&hKey,
+                           hKeyOriginal);
+    if (!NT_SUCCESS(Status))
     {
-      RealKey = hKey;
-      CloseRealKey = FALSE;
+        return RtlNtStatusToDosError(Status);
     }
+    subkey = hKey;
 
-  ErrorCode = RegSetValueExW (RealKey,
-                             NULL,
-                             0,
-                             dwType,
-                             (LPBYTE)lpData,
-                             cbData);
-  if (CloseRealKey == TRUE)
+    if (lpSubKey && lpSubKey[0])  /* need to create the subkey */
     {
-      NtClose (RealKey);
+        ret = RegCreateKeyW(hKey, lpSubKey, &subkey);
+        if (ret != 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);
+    ClosePredefKey(hKey);
 
-  return ErrorCode;
+    return ret;
 }
 
 
@@ -4515,21 +4985,21 @@ Cleanup:
  * @implemented
  */
 LONG STDCALL
-RegUnLoadKeyA (HKEY hKey,
-              LPCSTR lpSubKey)
+RegUnLoadKeyA(HKEY hKey,
+              LPCSTR lpSubKey)
 {
-  UNICODE_STRING KeyName;
-  DWORD ErrorCode;
+    UNICODE_STRING KeyName;
+    DWORD ErrorCode;
 
-  RtlCreateUnicodeStringFromAsciiz (&KeyName,
-                                   (LPSTR)lpSubKey);
+    RtlCreateUnicodeStringFromAsciiz(&KeyName,
+                                     (LPSTR)lpSubKey);
 
-  ErrorCode = RegUnLoadKeyW (hKey,
-                            KeyName.Buffer);
+    ErrorCode = RegUnLoadKeyW(hKey,
+                              KeyName.Buffer);
 
-  RtlFreeUnicodeString (&KeyName);
+    RtlFreeUnicodeString (&KeyName);
 
-  return ErrorCode;
+    return ErrorCode;
 }
 
 
@@ -4539,83 +5009,235 @@ RegUnLoadKeyA (HKEY hKey,
  * @implemented
  */
 LONG STDCALL
-RegUnLoadKeyW (HKEY hKey,
-              LPCWSTR lpSubKey)
+RegUnLoadKeyW(HKEY hKey,
+              LPCWSTR lpSubKey)
 {
-  OBJECT_ATTRIBUTES ObjectAttributes;
-  UNICODE_STRING KeyName;
-  HANDLE KeyHandle;
-  NTSTATUS Status;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    UNICODE_STRING KeyName;
+    HANDLE KeyHandle;
+    NTSTATUS Status;
 
-  if (hKey == HKEY_PERFORMANCE_DATA)
+    if (hKey == HKEY_PERFORMANCE_DATA)
     {
       return ERROR_INVALID_HANDLE;
     }
 
-  Status = MapDefaultKey (&KeyHandle, hKey);
-  if (!NT_SUCCESS(Status))
+    Status = MapDefaultKey(&KeyHandle, hKey);
+    if (!NT_SUCCESS(Status))
+    {
+        return RtlNtStatusToDosError(Status);
+    }
+
+    RtlInitUnicodeString(&KeyName,
+                         (LPWSTR)lpSubKey);
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &KeyName,
+                               OBJ_CASE_INSENSITIVE,
+                               KeyHandle,
+                               NULL);
+
+    Status = NtUnloadKey(&ObjectAttributes);
+
+    ClosePredefKey(KeyHandle);
+
+    if (!NT_SUCCESS(Status))
     {
-      return RtlNtStatusToDosError (Status);
+        return RtlNtStatusToDosError(Status);
     }
 
-  RtlInitUnicodeString (&KeyName,
-                       (LPWSTR)lpSubKey);
+    return ERROR_SUCCESS;
+}
+
+
+/******************************************************************************
+ * load_string [Internal]
+ *
+ * This is basically a copy of user32/resource.c's LoadStringW. Necessary to
+ * avoid importing user32, which is higher level than advapi32. Helper for
+ * RegLoadMUIString.
+ */
+static int load_string(HINSTANCE hModule, UINT resId, LPWSTR pwszBuffer, INT cMaxChars)
+{
+    HGLOBAL hMemory;
+    HRSRC hResource;
+    WCHAR *pString;
+    int idxString;
+
+    /* Negative values have to be inverted. */
+    if (HIWORD(resId) == 0xffff)
+        resId = (UINT)(-((INT)resId));
+
+    /* Load the resource into memory and get a pointer to it. */
+    hResource = FindResourceW(hModule, MAKEINTRESOURCEW(LOWORD(resId >> 4) + 1), (LPWSTR)RT_STRING);
+    if (!hResource) return 0;
+    hMemory = LoadResource(hModule, hResource);
+    if (!hMemory) return 0;
+    pString = LockResource(hMemory);
 
-  InitializeObjectAttributes (&ObjectAttributes,
-                             &KeyName,
-                             OBJ_CASE_INSENSITIVE,
-                             KeyHandle,
-                             NULL);
+    /* Strings are length-prefixed. Lowest nibble of resId is an index. */
+    idxString = resId & 0xf;
+    while (idxString--) pString += *pString + 1;
 
-  Status = NtUnloadKey (&ObjectAttributes);
-  
-  ClosePredefKey(KeyHandle);
+    /* If no buffer is given, return length of the string. */
+    if (!pwszBuffer) return *pString;
 
-  if (!NT_SUCCESS(Status))
+    /* Else copy over the string, respecting the buffer size. */
+    cMaxChars = (*pString < cMaxChars) ? *pString : (cMaxChars - 1);
+    if (cMaxChars >= 0)
     {
-      return RtlNtStatusToDosError (Status);
+        memcpy(pwszBuffer, pString+1, cMaxChars * sizeof(WCHAR));
+        pwszBuffer[cMaxChars] = L'\0';
     }
 
-  return ERROR_SUCCESS;
+    return cMaxChars;
 }
 
 
 /************************************************************************
  *  RegLoadMUIStringW
  *
- * @unimplemented
+ * @implemented
  */
 LONG STDCALL
 RegLoadMUIStringW(IN HKEY hKey,
                   IN LPCWSTR pszValue  OPTIONAL,
                   OUT LPWSTR pszOutBuf,
-                  IN ULONG cbOutBuf,
-                  IN ULONG Reserved,
+                  IN DWORD cbOutBuf,
+                  OUT LPDWORD pcbData OPTIONAL,
+                  IN DWORD Flags,
                   IN LPCWSTR pszDirectory  OPTIONAL)
 {
-    DPRINT1("RegLoadMUIStringW(0x%p, 0x%p, 0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
-            hKey, pszValue, pszOutBuf, cbOutBuf, Reserved, pszDirectory);
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    DWORD dwValueType, cbData;
+    LPWSTR pwszTempBuffer = NULL, pwszExpandedBuffer = NULL;
+    LONG result;
+
+    /* Parameter sanity checks. */
+    if (!hKey || !pszOutBuf)
+        return ERROR_INVALID_PARAMETER;
+
+    if (pszDirectory && *pszDirectory)
+    {
+        FIXME("BaseDir parameter not yet supported!\n");
+        return ERROR_INVALID_PARAMETER;
+    }
+
+    /* Check for value existence and correctness of it's type, allocate a buffer and load it. */
+    result = RegQueryValueExW(hKey, pszValue, NULL, &dwValueType, NULL, &cbData);
+    if (result != ERROR_SUCCESS) goto cleanup;
+    if (!(dwValueType == REG_SZ || dwValueType == REG_EXPAND_SZ) || !cbData)
+    {
+        result = ERROR_FILE_NOT_FOUND;
+        goto cleanup;
+    }
+    pwszTempBuffer = HeapAlloc(GetProcessHeap(), 0, cbData);
+    if (!pwszTempBuffer)
+    {
+        result = ERROR_NOT_ENOUGH_MEMORY;
+        goto cleanup;
+    }
+    result = RegQueryValueExW(hKey, pszValue, NULL, &dwValueType, (LPBYTE)pwszTempBuffer, &cbData);
+    if (result != ERROR_SUCCESS) goto cleanup;
+
+    /* Expand environment variables, if appropriate, or copy the original string over. */
+    if (dwValueType == REG_EXPAND_SZ)
+    {
+        cbData = ExpandEnvironmentStringsW(pwszTempBuffer, NULL, 0) * sizeof(WCHAR);
+        if (!cbData) goto cleanup;
+        pwszExpandedBuffer = HeapAlloc(GetProcessHeap(), 0, cbData);
+        if (!pwszExpandedBuffer)
+        {
+            result = ERROR_NOT_ENOUGH_MEMORY;
+            goto cleanup;
+        }
+        ExpandEnvironmentStringsW(pwszTempBuffer, pwszExpandedBuffer, cbData);
+    }
+    else
+    {
+        pwszExpandedBuffer = HeapAlloc(GetProcessHeap(), 0, cbData);
+        memcpy(pwszExpandedBuffer, pwszTempBuffer, cbData);
+    }
+
+    /* If the value references a resource based string, parse the value and load the string.
+     * Else just copy over the original value. */
+    result = ERROR_SUCCESS;
+    if (*pwszExpandedBuffer != L'@') /* '@' is the prefix for resource based string entries. */
+    {
+        lstrcpynW(pszOutBuf, pwszExpandedBuffer, cbOutBuf / sizeof(WCHAR));
+    }
+    else
+    {
+        WCHAR *pComma = wcsrchr(pwszExpandedBuffer, L',');
+        UINT uiStringId;
+        HMODULE hModule;
+
+        /* Format of the expanded value is 'path_to_dll,-resId' */
+        if (!pComma || pComma[1] != L'-')
+        {
+            result = ERROR_BADKEY;
+            goto cleanup;
+        }
+
+        uiStringId = _wtoi(pComma+2);
+        *pComma = L'\0';
+
+        hModule = LoadLibraryExW(pwszExpandedBuffer + 1, NULL, LOAD_LIBRARY_AS_DATAFILE);
+        if (!hModule || !load_string(hModule, uiStringId, pszOutBuf, cbOutBuf / sizeof(WCHAR)))
+            result = ERROR_BADKEY;
+        FreeLibrary(hModule);
+    }
+
+cleanup:
+    HeapFree(GetProcessHeap(), 0, pwszTempBuffer);
+    HeapFree(GetProcessHeap(), 0, pwszExpandedBuffer);
+    return result;
 }
 
 
 /************************************************************************
  *  RegLoadMUIStringA
  *
- * @unimplemented
+ * @implemented
  */
 LONG STDCALL
 RegLoadMUIStringA(IN HKEY hKey,
                   IN LPCSTR pszValue  OPTIONAL,
                   OUT LPSTR pszOutBuf,
-                  IN ULONG cbOutBuf,
-                  IN ULONG Reserved,
+                  IN DWORD cbOutBuf,
+                  OUT LPDWORD pcbData OPTIONAL,
+                  IN DWORD Flags,
                   IN LPCSTR pszDirectory  OPTIONAL)
 {
-    DPRINT1("RegLoadMUIStringA(0x%p, 0x%p, 0x%p, 0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n",
-            hKey, pszValue, pszOutBuf, cbOutBuf, Reserved, pszDirectory);
-    return ERROR_CALL_NOT_IMPLEMENTED;
-}
+    UNICODE_STRING valueW, baseDirW;
+    WCHAR *pwszBuffer;
+    DWORD cbData = cbOutBuf * sizeof(WCHAR);
+    LONG result;
+
+    valueW.Buffer = baseDirW.Buffer = pwszBuffer = NULL;
+    if (!RtlCreateUnicodeStringFromAsciiz(&valueW, pszValue) ||
+        !RtlCreateUnicodeStringFromAsciiz(&baseDirW, pszDirectory) ||
+        !(pwszBuffer = HeapAlloc(GetProcessHeap(), 0, cbData)))
+    {
+        result = ERROR_NOT_ENOUGH_MEMORY;
+        goto cleanup;
+    }
+
+    result = RegLoadMUIStringW(hKey, valueW.Buffer, pwszBuffer, cbData, NULL, Flags,
+                               baseDirW.Buffer);
+
+    if (result == ERROR_SUCCESS)
+    {
+        cbData = WideCharToMultiByte(CP_ACP, 0, pwszBuffer, -1, pszOutBuf, cbOutBuf, NULL, NULL);
+        if (pcbData)
+            *pcbData = cbData;
+    }
 
+cleanup:
+    HeapFree(GetProcessHeap(), 0, pwszBuffer);
+    RtlFreeUnicodeString(&baseDirW);
+    RtlFreeUnicodeString(&valueW);
+
+    return result;
+}
 
 /* EOF */