added a whole bunch of hacks #ifdef'd into the header section to support private...
[reactos.git] / reactos / lib / advapi32 / reg / reg.c
index c0dd6b1..5b2c685 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: reg.c,v 1.17 2002/09/08 10:22:36 chorns Exp $
+/* $Id: reg.c,v 1.19 2002/11/10 13:44:48 robd Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -9,6 +9,81 @@
  *                  Created 01/11/98
  *                  19990309 EA Stubs
  */
+
+#ifdef WIN32_REGDBG
+#include "cm_win32.h"
+
+#ifdef __GNUC__
+#define WINAPI __stdcall
+#define WINAPIV __cdecl
+#define APIENTRY __stdcall
+#define DECLSPEC_IMPORT __declspec(dllimport)
+#define DECLSPEC_EXPORT __declspec(dllexport)
+#define DECLARE_HANDLE(n) typedef HANDLE n
+#define HKEY_PERFORMANCE_DATA  ((HKEY)0x80000004)
+
+#define ERROR_SUCCESS 0L
+#define ERROR_INVALID_HANDLE 6L
+#define ERROR_OUTOFMEMORY 14L
+#define ERROR_INVALID_PARAMETER 87L
+#define ERROR_CALL_NOT_IMPLEMENTED 120L
+#define ERROR_MORE_DATA 234L
+
+void WINAPI SetLastError(DWORD);
+
+BOOLEAN
+STDCALL
+RtlDosPathNameToNtPathName_U (
+       PWSTR           dosname,
+       PUNICODE_STRING ntname,
+       PWSTR           *shortname,
+       PCURDIR         nah);
+
+NTSTATUS
+STDCALL
+RtlInitializeCriticalSection(LPCRITICAL_SECTION lpcs);
+
+NTSTATUS
+STDCALL
+RtlDeleteCriticalSection(LPCRITICAL_SECTION lpcs);
+
+NTSTATUS
+STDCALL
+RtlLeaveCriticalSection(LPCRITICAL_SECTION lpcs);
+
+NTSTATUS
+STDCALL
+RtlEnterCriticalSection(LPCRITICAL_SECTION lpcs);
+
+DECLARE_HANDLE(HKEY);
+typedef HKEY *PHKEY;
+typedef ACCESS_MASK REGSAM;
+
+typedef struct value_entA {
+       LPSTR ve_valuename;
+       DWORD ve_valuelen;
+       DWORD ve_valueptr;
+       DWORD ve_type;
+} VALENTA,*PVALENTA;
+typedef struct value_entW {
+       LPWSTR ve_valuename;
+       DWORD ve_valuelen;
+       DWORD ve_valueptr;
+       DWORD ve_type;
+} VALENTW,*PVALENTW;
+#endif
+
+#undef STDCALL
+#define STDCALL _stdcall
+#undef RegSetValueEx
+#undef RegCreateKeyEx
+#undef RegQueryInfoKey
+#undef RegDeleteKey
+#undef RegOpenKey
+#undef RegOpenKeyEx
+#undef RegEnumKeyEx
+#undef RegEnumValue
+#else
 #include <ddk/ntddk.h>
 #include <ntdll/rtl.h>
 #include <windows.h>
@@ -16,6 +91,7 @@
 
 #define NDEBUG
 #include <debug.h>
+#endif
 
 #define CHECK_STATUS \
 { \
@@ -286,7 +362,7 @@ RegCloseKey(HKEY hKey)
  *     RegConnectRegistryA
  */
 LONG STDCALL
-RegConnectRegistryA(LPSTR lpMachineName,
+RegConnectRegistryA(LPCSTR lpMachineName,
                    HKEY hKey,
                    PHKEY phkResult)
 {
@@ -299,7 +375,7 @@ RegConnectRegistryA(LPSTR lpMachineName,
  *     RegConnectRegistryW
  */
 LONG STDCALL
-RegConnectRegistryW(LPWSTR lpMachineName,
+RegConnectRegistryW(LPCWSTR lpMachineName,
                    HKEY hKey,
                    PHKEY phkResult)
 {
@@ -308,46 +384,6 @@ RegConnectRegistryW(LPWSTR lpMachineName,
 }
 
 
-/************************************************************************
- *     RegCreateKeyA
- */
-LONG STDCALL
-RegCreateKeyA(HKEY hKey,
-             LPCSTR lpSubKey,
-             PHKEY phkResult)
-{
-  return(RegCreateKeyExA(hKey,
-                        lpSubKey,
-                        0,
-                        NULL,
-                        0,
-                        KEY_ALL_ACCESS,
-                        NULL,
-                        phkResult,
-                        NULL));
-}
-
-
-/************************************************************************
- *     RegCreateKeyW
- */
-LONG STDCALL
-RegCreateKeyW(HKEY hKey,
-             LPCWSTR lpSubKey,
-             PHKEY phkResult)
-{
-  return(RegCreateKeyExW(hKey,
-                        lpSubKey,
-                        0,
-                        NULL,
-                        0,
-                        KEY_ALL_ACCESS,
-                        NULL,
-                        phkResult,
-                        NULL));
-}
-
-
 /************************************************************************
  *     RegCreateKeyExA
  */
@@ -482,6 +518,46 @@ RegCreateKeyExW(HKEY                       hKey,
 }
 
 
+/************************************************************************
+ *     RegCreateKeyA
+ */
+LONG STDCALL
+RegCreateKeyA(HKEY hKey,
+             LPCSTR lpSubKey,
+             PHKEY phkResult)
+{
+  return(RegCreateKeyExA(hKey,
+                        lpSubKey,
+                        0,
+                        NULL,
+                        0,
+                        KEY_ALL_ACCESS,
+                        NULL,
+                        phkResult,
+                        NULL));
+}
+
+
+/************************************************************************
+ *     RegCreateKeyW
+ */
+LONG STDCALL
+RegCreateKeyW(HKEY hKey,
+             LPCWSTR lpSubKey,
+             PHKEY phkResult)
+{
+  return(RegCreateKeyExW(hKey,
+                        lpSubKey,
+                        0,
+                        NULL,
+                        0,
+                        KEY_ALL_ACCESS,
+                        NULL,
+                        phkResult,
+                        NULL));
+}
+
+
 /************************************************************************
  *     RegDeleteKeyA
  */
@@ -495,7 +571,8 @@ RegDeleteKeyA(
        OBJECT_ATTRIBUTES ObjectAttributes;
        UNICODE_STRING SubKeyStringW;
        ANSI_STRING SubKeyStringA;
-       HANDLE ParentKey;
+//     HANDLE ParentKey;
+       HKEY ParentKey;
        HANDLE TargetKey;
        NTSTATUS Status;
        LONG ErrorCode;
@@ -563,7 +640,7 @@ RegDeleteKeyW(
 {
        OBJECT_ATTRIBUTES ObjectAttributes;
        UNICODE_STRING SubKeyString;
-       HANDLE ParentKey;
+       HKEY ParentKey;
        HANDLE TargetKey;
        NTSTATUS Status;
        LONG ErrorCode;
@@ -627,7 +704,7 @@ RegDeleteValueA(
        ANSI_STRING ValueNameA;
        NTSTATUS Status;
        LONG ErrorCode;
-       HANDLE KeyHandle;
+       HKEY KeyHandle;
 
        Status = MapDefaultKey(&KeyHandle,
                               hKey);
@@ -675,7 +752,7 @@ RegDeleteValueW(
        UNICODE_STRING ValueName;
        NTSTATUS Status;
        LONG ErrorCode;
-       HANDLE KeyHandle;
+       HKEY KeyHandle;
 
        Status = MapDefaultKey(&KeyHandle,
                               hKey);
@@ -704,124 +781,6 @@ RegDeleteValueW(
 }
 
 
-/************************************************************************
- *     RegEnumKeyA
- */
-LONG
-STDCALL
-RegEnumKeyA(
-       HKEY    hKey,
-       DWORD   dwIndex,
-       LPSTR   lpName,
-       DWORD   cbName
-       )
-{
-       DWORD dwLength = cbName;
-
-       return RegEnumKeyExA(hKey,
-                            dwIndex,
-                            lpName,
-                            &dwLength,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL);
-}
-
-
-/************************************************************************
- *     RegEnumKeyExA
- */
-LONG
-STDCALL
-RegEnumKeyExA(
-       HKEY            hKey,
-       DWORD           dwIndex,
-       LPSTR           lpName,
-       LPDWORD         lpcbName,
-       LPDWORD         lpReserved,
-       LPSTR           lpClass,
-       LPDWORD         lpcbClass,
-       PFILETIME       lpftLastWriteTime
-       )
-{
-  WCHAR Name[MAX_PATH+1];
-  UNICODE_STRING UnicodeStringName;
-  WCHAR Class[MAX_PATH+1];
-  UNICODE_STRING UnicodeStringClass;
-  ANSI_STRING AnsiString;
-  LONG ErrorCode;
-  DWORD NameLength;
-  DWORD ClassLength;
-
-  DPRINT("hKey 0x%x  dwIndex %d  lpName 0x%x  *lpcbName %d  lpClass 0x%x  lpcbClass %d\n",
-    hKey, dwIndex, lpName, *lpcbName, lpClass, lpcbClass);
-
-  if ((lpClass) && (!lpcbClass))
-  {
-    SetLastError(ERROR_INVALID_PARAMETER);
-    return ERROR_INVALID_PARAMETER;
-  }
-
-  RtlInitUnicodeString(&UnicodeStringName, NULL);
-  UnicodeStringName.Buffer = &Name[0];
-  UnicodeStringName.MaximumLength = sizeof(Name);
-
-  RtlInitUnicodeString(&UnicodeStringClass, NULL);
-
-  if (lpClass)
-  {
-    UnicodeStringClass.Buffer = &Class[0];
-    UnicodeStringClass.MaximumLength = sizeof(Class);
-    ClassLength = *lpcbClass;
-  }
-  else
-  {
-    ClassLength = 0;
-  }
-
-  NameLength = *lpcbName;
-
-  ErrorCode = RegEnumKeyExW(
-         hKey,
-         dwIndex,
-         UnicodeStringName.Buffer,
-         &NameLength,
-    lpReserved,
-         UnicodeStringClass.Buffer,
-         &ClassLength,
-         lpftLastWriteTime);
-
-  if (ErrorCode != ERROR_SUCCESS)
-    return ErrorCode;
-
-  UnicodeStringName.Length = NameLength * sizeof(WCHAR);
-  UnicodeStringClass.Length = ClassLength * sizeof(WCHAR);
-
-  RtlInitAnsiString(&AnsiString, NULL);
-  AnsiString.Buffer = lpName;
-  AnsiString.MaximumLength = *lpcbName;
-  RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeStringName, FALSE);
-  *lpcbName = AnsiString.Length;
-
-  DPRINT("Key Namea0 Length %d\n", UnicodeStringName.Length);
-  DPRINT("Key Namea1 Length %d\n", NameLength);
-  DPRINT("Key Namea Length %d\n", *lpcbName);
-  DPRINT("Key Namea %s\n", lpName);
-
-  if (lpClass)
-  {
-    RtlInitAnsiString(&AnsiString, NULL);
-    AnsiString.Buffer = lpClass;
-    AnsiString.MaximumLength = *lpcbClass;
-    RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeStringClass, FALSE);
-    *lpcbClass = AnsiString.Length;
-  }
-
-  return ERROR_SUCCESS;
-}
-
-
 /************************************************************************
  *     RegEnumKeyExW
  */
@@ -838,12 +797,12 @@ RegEnumKeyExW(
        PFILETIME       lpftLastWriteTime
        )
 {
-  PKEY_NODE_INFORMATION KeyInfo;
+    PKEY_NODE_INFORMATION KeyInfo;
        NTSTATUS Status;
        DWORD dwError = ERROR_SUCCESS;
        ULONG BufferSize;
        ULONG ResultSize;
-  HANDLE KeyHandle;
+    HKEY KeyHandle;
 
   Status = MapDefaultKey(&KeyHandle, hKey);
        if (!NT_SUCCESS(Status))
@@ -856,7 +815,12 @@ RegEnumKeyExW(
        BufferSize = sizeof (KEY_NODE_INFORMATION) + *lpcbName * sizeof(WCHAR);
        if (lpClass)
                BufferSize += *lpcbClass;
-       KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize);
+
+    //
+    // I think this is a memory leak, always allocated again below ???
+    //
+    // KeyInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize);
+    //
 
   /* We don't know the exact size of the data returned, so call
      NtEnumerateKey() with a buffer size determined from parameters
@@ -958,58 +922,123 @@ RegEnumKeyW(
 
 
 /************************************************************************
- *     RegEnumValueA
+ *     RegEnumKeyExA
  */
 LONG
 STDCALL
-RegEnumValueA(
-       HKEY    hKey,
-       DWORD   dwIndex,
-       LPSTR   lpValueName,
-       LPDWORD lpcbValueName,
-       LPDWORD lpReserved,
-       LPDWORD lpType,
-       LPBYTE  lpData,
-       LPDWORD lpcbData
+RegEnumKeyExA(
+       HKEY            hKey,
+       DWORD           dwIndex,
+       LPSTR           lpName,
+       LPDWORD         lpcbName,
+       LPDWORD         lpReserved,
+       LPSTR           lpClass,
+       LPDWORD         lpcbClass,
+       PFILETIME       lpftLastWriteTime
        )
 {
-  WCHAR ValueName[MAX_PATH+1];
-  UNICODE_STRING UnicodeString;
+  WCHAR Name[MAX_PATH+1];
+  UNICODE_STRING UnicodeStringName;
+  WCHAR Class[MAX_PATH+1];
+  UNICODE_STRING UnicodeStringClass;
   ANSI_STRING AnsiString;
   LONG ErrorCode;
-  DWORD ValueNameLength;
-
-  RtlInitUnicodeString(&UnicodeString, NULL);
-  UnicodeString.Buffer = &ValueName[0];
-  UnicodeString.MaximumLength = sizeof(ValueName);
+  DWORD NameLength;
+  DWORD ClassLength;
 
-  ValueNameLength = *lpcbValueName;
+  DPRINT("hKey 0x%x  dwIndex %d  lpName 0x%x  *lpcbName %d  lpClass 0x%x  lpcbClass %d\n",
+    hKey, dwIndex, lpName, *lpcbName, lpClass, lpcbClass);
 
-  ErrorCode = RegEnumValueW(
-         hKey,
+  if ((lpClass) && (!lpcbClass))
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return ERROR_INVALID_PARAMETER;
+  }
+
+  RtlInitUnicodeString(&UnicodeStringName, NULL);
+  UnicodeStringName.Buffer = &Name[0];
+  UnicodeStringName.MaximumLength = sizeof(Name);
+
+  RtlInitUnicodeString(&UnicodeStringClass, NULL);
+
+  if (lpClass)
+  {
+    UnicodeStringClass.Buffer = &Class[0];
+    UnicodeStringClass.MaximumLength = sizeof(Class);
+    ClassLength = *lpcbClass;
+  }
+  else
+  {
+    ClassLength = 0;
+  }
+
+  NameLength = *lpcbName;
+
+  ErrorCode = RegEnumKeyExW(
+         hKey,
          dwIndex,
-         UnicodeString.Buffer,
-         &ValueNameLength,
-         lpReserved,
-         lpType,
-         lpData,
-         lpcbData);
+         UnicodeStringName.Buffer,
+         &NameLength,
+    lpReserved,
+         UnicodeStringClass.Buffer,
+         &ClassLength,
+         lpftLastWriteTime);
 
   if (ErrorCode != ERROR_SUCCESS)
     return ErrorCode;
 
-  UnicodeString.Length = ValueNameLength * sizeof(WCHAR);
+  UnicodeStringName.Length = NameLength * sizeof(WCHAR);
+  UnicodeStringClass.Length = ClassLength * sizeof(WCHAR);
 
   RtlInitAnsiString(&AnsiString, NULL);
-  AnsiString.Buffer = lpValueName;
-  AnsiString.MaximumLength = *lpcbValueName;
-  RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE);
-  *lpcbValueName = AnsiString.Length;
+  AnsiString.Buffer = lpName;
+  AnsiString.MaximumLength = *lpcbName;
+  RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeStringName, FALSE);
+  *lpcbName = AnsiString.Length;
+
+  DPRINT("Key Namea0 Length %d\n", UnicodeStringName.Length);
+  DPRINT("Key Namea1 Length %d\n", NameLength);
+  DPRINT("Key Namea Length %d\n", *lpcbName);
+  DPRINT("Key Namea %s\n", lpName);
+
+  if (lpClass)
+  {
+    RtlInitAnsiString(&AnsiString, NULL);
+    AnsiString.Buffer = lpClass;
+    AnsiString.MaximumLength = *lpcbClass;
+    RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeStringClass, FALSE);
+    *lpcbClass = AnsiString.Length;
+  }
 
   return ERROR_SUCCESS;
 }
 
 
+/************************************************************************
+ *     RegEnumKeyA
+ */
+LONG
+STDCALL
+RegEnumKeyA(
+       HKEY    hKey,
+       DWORD   dwIndex,
+       LPSTR   lpName,
+       DWORD   cbName
+       )
+{
+       DWORD dwLength = cbName;
+
+       return RegEnumKeyExA(hKey,
+                            dwIndex,
+                            lpName,
+                            &dwLength,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL);
+}
+
+
 /************************************************************************
  *     RegEnumValueW
  */
@@ -1031,10 +1060,10 @@ RegEnumValueW(
        DWORD dwError = ERROR_SUCCESS;
        ULONG BufferSize;
        ULONG ResultSize;
-  HANDLE KeyHandle;
+    HKEY KeyHandle;
 
-  Status = MapDefaultKey(&KeyHandle, hKey);
-  if (!NT_SUCCESS(Status))
+    Status = MapDefaultKey(&KeyHandle, hKey);
+    if (!NT_SUCCESS(Status))
     {
       dwError = RtlNtStatusToDosError(Status);
       SetLastError(dwError);
@@ -1103,10 +1132,16 @@ RegEnumValueW(
                if (lpData)
                {
                        memcpy(lpData,
-                               (PVOID)((ULONG_PTR)ValueInfo->Name + ValueInfo->DataOffset),
+                               //(PVOID)((ULONG_PTR)ValueInfo->Name + ValueInfo->DataOffset),
+                               (PVOID)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset),
                                ValueInfo->DataLength);
                        *lpcbData = (DWORD)ValueInfo->DataLength;
-               }
+/*
+                       RtlCopyMemory((PCHAR) ValueFullInformation + ValueFullInformation->DataOffset,
+                         DataCell->Data,
+                         ValueCell->DataSize & LONG_MAX);
+ */
+        }
 
       break;
        }
@@ -1118,13 +1153,102 @@ RegEnumValueW(
 }
 
 
+/************************************************************************
+ *     RegEnumValueA
+ */
+LONG
+STDCALL
+RegEnumValueA(
+       HKEY    hKey,
+       DWORD   dwIndex,
+       LPSTR   lpValueName,
+       LPDWORD lpcbValueName,
+       LPDWORD lpReserved,
+       LPDWORD lpType,
+       LPBYTE  lpData,
+       LPDWORD lpcbData
+       )
+{
+  WCHAR ValueName[MAX_PATH+1];
+  UNICODE_STRING UnicodeString;
+  ANSI_STRING AnsiString;
+  LONG ErrorCode;
+  DWORD ValueNameLength;
+  BYTE* lpDataBuffer = NULL;
+  DWORD        cbData = 0;
+  DWORD        Type;
+  ANSI_STRING AnsiDataString;
+  UNICODE_STRING UnicodeDataString;
+
+  if (lpData != NULL /*&& lpcbData != NULL*/) {
+    cbData = *lpcbData; // this should always be valid if lpData is valid
+    lpDataBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, (*lpcbData) * sizeof(WCHAR));
+    if (lpDataBuffer == NULL) {
+      SetLastError(ERROR_OUTOFMEMORY);
+      return ERROR_OUTOFMEMORY;
+    }
+  }
+
+  RtlInitUnicodeString(&UnicodeString, NULL);
+  UnicodeString.Buffer = &ValueName[0];
+  UnicodeString.MaximumLength = sizeof(ValueName);
+
+  ValueNameLength = *lpcbValueName;
+
+  ErrorCode = RegEnumValueW(
+         hKey,
+         dwIndex,
+         UnicodeString.Buffer,
+         &ValueNameLength,
+         lpReserved,
+         &Type,
+         lpDataBuffer,
+         &cbData);
+
+  if (ErrorCode != ERROR_SUCCESS)
+    return ErrorCode;
+
+  UnicodeString.Length = ValueNameLength * sizeof(WCHAR);
+
+  RtlInitAnsiString(&AnsiString, NULL);
+  AnsiString.Buffer = lpValueName;
+  AnsiString.MaximumLength = *lpcbValueName;
+  RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE);
+  *lpcbValueName = AnsiString.Length;
+
+//  if (lpData != lpDataBuffer) { // did we use a temp buffer
+  if (lpDataBuffer) { // did we use a temp buffer
+      if ((Type == REG_SZ) || (Type == REG_MULTI_SZ) || (Type == REG_EXPAND_SZ)) {
+          RtlInitUnicodeString(&UnicodeDataString, NULL);
+          UnicodeDataString.Buffer = lpDataBuffer;
+          UnicodeDataString.MaximumLength = (*lpcbData) * sizeof(WCHAR);
+          UnicodeDataString.Length = cbData /* * sizeof(WCHAR)*/;
+          RtlInitAnsiString(&AnsiDataString, NULL);
+          AnsiDataString.Buffer = lpData;
+          AnsiDataString.MaximumLength = *lpcbData;
+          RtlUnicodeStringToAnsiString(&AnsiDataString, &UnicodeDataString, FALSE);
+          *lpcbData = AnsiDataString.Length;
+//      else if (Type == REG_EXPAND_SZ) {
+      } else {
+          memcpy(lpData, lpDataBuffer, min(*lpcbData, cbData));
+          *lpcbData = cbData;
+      }
+      RtlFreeHeap(RtlGetProcessHeap(), 0, lpDataBuffer);
+  }
+  if (lpType != NULL) {
+    *lpType = Type;
+  }
+  return ERROR_SUCCESS;
+}
+
+
 /************************************************************************
  *     RegFlushKey
  */
 LONG STDCALL
 RegFlushKey(HKEY hKey)
 {
-  HANDLE KeyHandle;
+  HKEY KeyHandle;
   NTSTATUS Status;
   LONG ErrorCode;
   
@@ -1177,7 +1301,7 @@ RegGetKeySecurity (
  */
 LONG
 STDCALL
-RegLoadKey(
+RegLoadKeyA(
        HKEY    hKey,
        LPCSTR  lpSubKey,
        LPCSTR  lpFile
@@ -1235,7 +1359,7 @@ RegOpenKeyA(HKEY hKey,
 {
   OBJECT_ATTRIBUTES ObjectAttributes;
   UNICODE_STRING SubKeyString;
-  HANDLE KeyHandle;
+  HKEY KeyHandle;
   LONG ErrorCode;
   NTSTATUS Status;
 
@@ -1292,7 +1416,7 @@ RegOpenKeyW (
        NTSTATUS                errCode;
        UNICODE_STRING          SubKeyString;
        OBJECT_ATTRIBUTES       ObjectAttributes;
-       HANDLE                  KeyHandle;
+       HKEY                    KeyHandle;
        LONG                    ErrorCode;
 
        errCode = MapDefaultKey(&KeyHandle,
@@ -1342,7 +1466,7 @@ RegOpenKeyExA(HKEY hKey,
 {
   OBJECT_ATTRIBUTES ObjectAttributes;
   UNICODE_STRING SubKeyString;
-  HANDLE KeyHandle;
+  HKEY KeyHandle;
   LONG ErrorCode;
   NTSTATUS Status;
 
@@ -1395,7 +1519,7 @@ RegOpenKeyExW(HKEY hKey,
 {
   OBJECT_ATTRIBUTES ObjectAttributes;
   UNICODE_STRING SubKeyString;
-  HANDLE KeyHandle;
+  HKEY KeyHandle;
   LONG ErrorCode;
   NTSTATUS Status;
 
@@ -1409,8 +1533,13 @@ RegOpenKeyExW(HKEY hKey,
       return(ErrorCode);
     }
 
-  RtlInitUnicodeString(&SubKeyString,
+  if (lpSubKey != NULL) {
+      RtlInitUnicodeString(&SubKeyString,
                       (LPWSTR)lpSubKey);
+  } else {
+      RtlInitUnicodeString(&SubKeyString,
+                      (LPWSTR)L"");
+  }
 
   InitializeObjectAttributes(&ObjectAttributes,
                             &SubKeyString,
@@ -1432,66 +1561,6 @@ RegOpenKeyExW(HKEY hKey,
 }
 
 
-/************************************************************************
- *     RegQueryInfoKeyA
- */
-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
-       )
-{
-  WCHAR ClassName[MAX_PATH];
-  UNICODE_STRING UnicodeString;
-  ANSI_STRING AnsiString;
-  LONG ErrorCode;
-
-  RtlInitUnicodeString(&UnicodeString, NULL);
-
-  if (lpClass)
-  {
-    UnicodeString.Buffer = &ClassName[0];
-    UnicodeString.MaximumLength = sizeof(ClassName);
-  }
-
-  ErrorCode = RegQueryInfoKeyW(
-         hKey,
-         UnicodeString.Buffer,
-         lpcbClass,
-         lpReserved,
-         lpcSubKeys,
-         lpcbMaxSubKeyLen,
-         lpcbMaxClassLen,
-         lpcValues,
-         lpcbMaxValueNameLen,
-         lpcbMaxValueLen,
-         lpcbSecurityDescriptor,
-         lpftLastWriteTime);
-
-  if ((ErrorCode == ERROR_SUCCESS) && (lpClass))
-  {
-    RtlInitAnsiString(&AnsiString, NULL);
-    AnsiString.Buffer = lpClass;
-    AnsiString.MaximumLength = *lpcbClass;
-    RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE);
-    *lpcbClass = AnsiString.Length;
-  }
-
-  return ErrorCode;
-}
-
-
 /************************************************************************
  *     RegQueryInfoKeyW
  */
@@ -1515,7 +1584,7 @@ RegQueryInfoKeyW(
   KEY_FULL_INFORMATION FullInfoBuffer;
   PKEY_FULL_INFORMATION FullInfo;
   ULONG FullInfoSize;
-  HANDLE KeyHandle;
+  HKEY KeyHandle;
   NTSTATUS Status;
   LONG ErrorCode;
   ULONG Length;
@@ -1623,118 +1692,197 @@ RegQueryInfoKeyW(
 
 
 /************************************************************************
- *     RegQueryMultipleValuesA
+ *     RegQueryInfoKeyA
  */
 LONG
 STDCALL
-RegQueryMultipleValuesA(
-       HKEY    hKey,
-       PVALENT val_list,
-       DWORD   num_vals,
-       LPSTR   lpValueBuf,
-       LPDWORD ldwTotsize
+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
        )
 {
-  UNIMPLEMENTED;
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return ERROR_CALL_NOT_IMPLEMENTED;
-}
-
+  WCHAR ClassName[MAX_PATH];
+  UNICODE_STRING UnicodeString;
+  ANSI_STRING AnsiString;
+  LONG ErrorCode;
 
-/************************************************************************
- *     RegQueryMultipleValuesW
- */
-LONG
-STDCALL
-RegQueryMultipleValuesW(
-       HKEY    hKey,
-       PVALENT val_list,
-       DWORD   num_vals,
-       LPWSTR  lpValueBuf,
-       LPDWORD ldwTotsize
-       )
-{
-  UNIMPLEMENTED;
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return ERROR_CALL_NOT_IMPLEMENTED;
-}
+  RtlInitUnicodeString(&UnicodeString, NULL);
+
+  if (lpClass)
+  {
+    UnicodeString.Buffer = &ClassName[0];
+    UnicodeString.MaximumLength = sizeof(ClassName);
+  }
+
+  ErrorCode = RegQueryInfoKeyW(
+         hKey,
+         UnicodeString.Buffer,
+         lpcbClass,
+         lpReserved,
+         lpcSubKeys,
+         lpcbMaxSubKeyLen,
+         lpcbMaxClassLen,
+         lpcValues,
+         lpcbMaxValueNameLen,
+         lpcbMaxValueLen,
+         lpcbSecurityDescriptor,
+         lpftLastWriteTime);
+
+  if ((ErrorCode == ERROR_SUCCESS) && (lpClass))
+  {
+    RtlInitAnsiString(&AnsiString, NULL);
+    AnsiString.Buffer = lpClass;
+    AnsiString.MaximumLength = *lpcbClass;
+    RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, FALSE);
+    *lpcbClass = AnsiString.Length;
+  }
+
+  return ErrorCode;
+}
 
 
 /************************************************************************
- *     RegQueryValueA
+ *     RegQueryMultipleValuesA
  */
 LONG
 STDCALL
-RegQueryValueA(
+RegQueryMultipleValuesA(
+       HKEY     hKey,
+       PVALENTA val_list,
+       DWORD    num_vals,
+       LPSTR    lpValueBuf,
+       LPDWORD  ldwTotsize
+       )
+{
+  UNIMPLEMENTED;
+       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+       return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/************************************************************************
+ *     RegQueryMultipleValuesW
+ */
+LONG
+STDCALL
+RegQueryMultipleValuesW(
+       HKEY     hKey,
+       PVALENTW val_list,
+       DWORD    num_vals,
+       LPWSTR   lpValueBuf,
+       LPDWORD  ldwTotsize
+       )
+{
+  UNIMPLEMENTED;
+       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+       return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/************************************************************************
+ *     RegQueryValueExW
+ */
+LONG
+STDCALL
+RegQueryValueExW(
        HKEY    hKey,
-       LPCSTR  lpSubKey,
-       LPSTR   lpValue,
-       PLONG   lpcbValue
+       LPCWSTR lpValueName,
+       LPDWORD lpReserved,
+       LPDWORD lpType,
+       LPBYTE  lpData,
+       LPDWORD lpcbData
        )
 {
-  WCHAR SubKeyNameBuffer[MAX_PATH+1];
-  UNICODE_STRING SubKeyName;
-  UNICODE_STRING Value;
-  ANSI_STRING AnsiString;
-  LONG ValueSize;
-  LONG ErrorCode;
+       PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
+       UNICODE_STRING ValueName;
+       NTSTATUS Status;
+       DWORD dwError = ERROR_SUCCESS;
+       ULONG BufferSize;
+       ULONG ResultSize;
+    HKEY KeyHandle;
 
-  if ((lpValue) && (!lpcbValue))
+  DPRINT("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))
+    {
+      dwError = RtlNtStatusToDosError(Status);
+      SetLastError(dwError);
+      return(dwError);
+    }
+
+  if ((lpData) && (!lpcbData))
   {
        SetLastError(ERROR_INVALID_PARAMETER);
          return ERROR_INVALID_PARAMETER;
   }
 
-  RtlInitUnicodeString(&SubKeyName, NULL);
-  RtlInitUnicodeString(&Value, NULL);
+       RtlInitUnicodeString (&ValueName,
+                             lpValueName);
 
-  if ((lpSubKey) && (strlen(lpSubKey) != 0))
+       BufferSize = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + *lpcbData;
+       ValueInfo = RtlAllocateHeap (RtlGetProcessHeap(),
+                                    0,
+                                    BufferSize);
+       if (ValueInfo == NULL)
   {
-    RtlInitAnsiString(&AnsiString, (LPSTR)lpSubKey);
-    SubKeyName.Buffer = &SubKeyNameBuffer[0];
-    SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer);
-    RtlAnsiStringToUnicodeString(&SubKeyName, &AnsiString, FALSE);
+    SetLastError(ERROR_OUTOFMEMORY);
+               return ERROR_OUTOFMEMORY;
   }
 
-  if (lpValue)
+       Status = NtQueryValueKey (hKey,
+                                 &ValueName,
+                                 KeyValuePartialInformation,
+                                 ValueInfo,
+                                 BufferSize,
+                                 &ResultSize);
+
+  DPRINT("Status 0x%X\n", Status);
+
+  if (Status == STATUS_BUFFER_TOO_SMALL)
   {
-    ValueSize = *lpcbValue * sizeof(WCHAR);
-    Value.MaximumLength = ValueSize;
-    Value.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueSize);
-    if (!Value.Buffer)
+    /* Return ERROR_SUCCESS and the buffer space needed for a successful call */
+    dwError = ERROR_SUCCESS;
+  }
+  else if (!NT_SUCCESS(Status))
+       {
+               dwError = RtlNtStatusToDosError(Status);
+               SetLastError(dwError);
+       }
+       else
+       {
+    if (lpType)
     {
-           SetLastError(ERROR_OUTOFMEMORY);
-           return ERROR_OUTOFMEMORY;
+           *lpType = ValueInfo->Type;
     }
-  }
-  else
-  {
-    ValueSize = 0;
-  }
 
-  ErrorCode = RegQueryValueW(
-       hKey,
-       (LPCWSTR)SubKeyName.Buffer,
-       Value.Buffer,
-       &ValueSize);
+               RtlMoveMemory(lpData, ValueInfo->Data, ValueInfo->DataLength);
+    if ((ValueInfo->Type == REG_SZ) ||
+      (ValueInfo->Type == REG_MULTI_SZ) ||
+      (ValueInfo->Type == REG_EXPAND_SZ))
+    {
+                       ((PWSTR)lpData)[ValueInfo->DataLength / sizeof(WCHAR)] = 0;
+    }
+       }
 
-  if (ErrorCode == ERROR_SUCCESS)
-  {
-    Value.Length = ValueSize;
-    RtlInitAnsiString(&AnsiString, NULL);
-    AnsiString.Buffer = lpValue;
-    AnsiString.MaximumLength = *lpcbValue;
-    RtlUnicodeStringToAnsiString(&AnsiString, &Value, FALSE);
-  }
+  DPRINT("Type %d  ResultSize %d\n", ValueInfo->Type, ResultSize);
 
-  *lpcbValue = ValueSize; 
+       *lpcbData = (DWORD)ResultSize;
 
-  if (Value.Buffer)
-  {
-    RtlFreeHeap(RtlGetProcessHeap(), 0, Value.Buffer);
-  }
+       RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
 
-  return ErrorCode;
+       return dwError;
 }
 
 
@@ -1745,7 +1893,7 @@ LONG
 STDCALL
 RegQueryValueExA(
        HKEY    hKey,
-       LPSTR   lpValueName,
+       LPCSTR  lpValueName,
        LPDWORD lpReserved,
        LPDWORD lpType,
        LPBYTE  lpData,
@@ -1842,103 +1990,6 @@ RegQueryValueExA(
 }
 
 
-/************************************************************************
- *     RegQueryValueExW
- */
-LONG
-STDCALL
-RegQueryValueExW(
-       HKEY    hKey,
-       LPWSTR  lpValueName,
-       LPDWORD lpReserved,
-       LPDWORD lpType,
-       LPBYTE  lpData,
-       LPDWORD lpcbData
-       )
-{
-       PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
-       UNICODE_STRING ValueName;
-       NTSTATUS Status;
-       DWORD dwError = ERROR_SUCCESS;
-       ULONG BufferSize;
-       ULONG ResultSize;
-  HANDLE KeyHandle;
-
-  DPRINT("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))
-    {
-      dwError = RtlNtStatusToDosError(Status);
-      SetLastError(dwError);
-      return(dwError);
-    }
-
-  if ((lpData) && (!lpcbData))
-  {
-       SetLastError(ERROR_INVALID_PARAMETER);
-         return ERROR_INVALID_PARAMETER;
-  }
-
-       RtlInitUnicodeString (&ValueName,
-                             lpValueName);
-
-       BufferSize = sizeof (KEY_VALUE_PARTIAL_INFORMATION) + *lpcbData;
-       ValueInfo = RtlAllocateHeap (RtlGetProcessHeap(),
-                                    0,
-                                    BufferSize);
-       if (ValueInfo == NULL)
-  {
-    SetLastError(ERROR_OUTOFMEMORY);
-               return ERROR_OUTOFMEMORY;
-  }
-
-       Status = NtQueryValueKey (hKey,
-                                 &ValueName,
-                                 KeyValuePartialInformation,
-                                 ValueInfo,
-                                 BufferSize,
-                                 &ResultSize);
-
-  DPRINT("Status 0x%X\n", Status);
-
-  if (Status == STATUS_BUFFER_TOO_SMALL)
-  {
-    /* Return ERROR_SUCCESS and the buffer space needed for a successful call */
-    dwError = ERROR_SUCCESS;
-  }
-  else if (!NT_SUCCESS(Status))
-       {
-               dwError = RtlNtStatusToDosError(Status);
-               SetLastError(dwError);
-       }
-       else
-       {
-    if (lpType)
-    {
-           *lpType = ValueInfo->Type;
-    }
-
-               RtlMoveMemory(lpData, ValueInfo->Data, ValueInfo->DataLength);
-    if ((ValueInfo->Type == REG_SZ) ||
-      (ValueInfo->Type == REG_MULTI_SZ) ||
-      (ValueInfo->Type == REG_EXPAND_SZ))
-    {
-                       ((PWSTR)lpData)[ValueInfo->DataLength / sizeof(WCHAR)] = 0;
-    }
-       }
-
-  DPRINT("Type %d  ResultSize %d\n", ValueInfo->Type, ResultSize);
-
-       *lpcbData = (DWORD)ResultSize;
-
-       RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
-
-       return dwError;
-}
-
-
 /************************************************************************
  *     RegQueryValueW
  */
@@ -1954,10 +2005,10 @@ RegQueryValueW(
        NTSTATUS                errCode;
        UNICODE_STRING          SubKeyString;
        OBJECT_ATTRIBUTES       ObjectAttributes;
-       HANDLE                  KeyHandle;
-  HANDLE                       RealKey;
+       HKEY                    KeyHandle;
+    HANDLE                     RealKey;
        LONG                      ErrorCode;
-  BOOL        CloseRealKey;
+    BOOL        CloseRealKey;
 
        errCode = MapDefaultKey(&KeyHandle, hKey);
        if (!NT_SUCCESS(errCode))
@@ -1994,21 +2045,99 @@ RegQueryValueW(
   }
   else
   {
-    RealKey = hKey;
-    CloseRealKey = FALSE;
+    RealKey = hKey;
+    CloseRealKey = FALSE;
+  }
+
+  ErrorCode = RegQueryValueExW(
+         RealKey,
+         NULL,
+         NULL,
+         NULL,
+         (LPBYTE)lpValue,
+         (LPDWORD)lpcbValue);
+
+  if (CloseRealKey)
+  {
+    NtClose(RealKey);
+  }
+
+  return ErrorCode;
+}
+
+
+/************************************************************************
+ *     RegQueryValueA
+ */
+LONG
+STDCALL
+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;
+
+  if ((lpValue) && (!lpcbValue))
+  {
+       SetLastError(ERROR_INVALID_PARAMETER);
+         return ERROR_INVALID_PARAMETER;
+  }
+
+  RtlInitUnicodeString(&SubKeyName, NULL);
+  RtlInitUnicodeString(&Value, NULL);
+
+  if ((lpSubKey) && (strlen(lpSubKey) != 0))
+  {
+    RtlInitAnsiString(&AnsiString, (LPSTR)lpSubKey);
+    SubKeyName.Buffer = &SubKeyNameBuffer[0];
+    SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer);
+    RtlAnsiStringToUnicodeString(&SubKeyName, &AnsiString, FALSE);
+  }
+
+  if (lpValue)
+  {
+    ValueSize = *lpcbValue * sizeof(WCHAR);
+    Value.MaximumLength = ValueSize;
+    Value.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, ValueSize);
+    if (!Value.Buffer)
+    {
+           SetLastError(ERROR_OUTOFMEMORY);
+           return ERROR_OUTOFMEMORY;
+    }
+  }
+  else
+  {
+    ValueSize = 0;
+  }
+
+  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);
   }
 
-  ErrorCode = RegQueryValueExW(
-         RealKey,
-         NULL,
-         NULL,
-         NULL,
-         (LPBYTE)lpValue,
-         (LPDWORD)lpcbValue);
+  *lpcbValue = ValueSize; 
 
-  if (CloseRealKey)
+  if (Value.Buffer)
   {
-    NtClose(RealKey);
+    RtlFreeHeap(RtlGetProcessHeap(), 0, Value.Buffer);
   }
 
   return ErrorCode;
@@ -2085,28 +2214,6 @@ RegRestoreKeyW(
 }
 
 
-/************************************************************************
- *     RegSaveKeyA
- */
-LONG STDCALL
-RegSaveKeyA(HKEY hKey,
-           LPCSTR lpFile,
-           LPSECURITY_ATTRIBUTES lpSecurityAttributes)
-{
-  UNICODE_STRING FileName;
-  LONG ErrorCode;
-
-  RtlCreateUnicodeStringFromAsciiz(&FileName,
-                                  (LPSTR)lpFile);
-  ErrorCode = RegSaveKeyW(hKey,
-                         FileName.Buffer,
-                         lpSecurityAttributes);
-  RtlFreeUnicodeString(&FileName);
-
-  return(ErrorCode);
-}
-
-
 /************************************************************************
  *     RegSaveKeyW
  */
@@ -2120,7 +2227,7 @@ RegSaveKeyW(HKEY hKey,
   UNICODE_STRING NtName;
   IO_STATUS_BLOCK IoStatusBlock;
   HANDLE FileHandle;
-  HANDLE KeyHandle;
+  HKEY KeyHandle;
   NTSTATUS Status;
   LONG ErrorCode;
 
@@ -2184,6 +2291,28 @@ RegSaveKeyW(HKEY hKey,
 }
 
 
+/************************************************************************
+ *     RegSaveKeyA
+ */
+LONG STDCALL
+RegSaveKeyA(HKEY hKey,
+           LPCSTR lpFile,
+           LPSECURITY_ATTRIBUTES lpSecurityAttributes)
+{
+  UNICODE_STRING FileName;
+  LONG ErrorCode;
+
+  RtlCreateUnicodeStringFromAsciiz(&FileName,
+                                  (LPSTR)lpFile);
+  ErrorCode = RegSaveKeyW(hKey,
+                         FileName.Buffer,
+                         lpSecurityAttributes);
+  RtlFreeUnicodeString(&FileName);
+
+  return(ErrorCode);
+}
+
+
 /************************************************************************
  *     RegSetKeySecurity
  */
@@ -2202,61 +2331,58 @@ RegSetKeySecurity(
 
 
 /************************************************************************
- *     RegSetValueA
+ *     RegSetValueExW
  */
 LONG
 STDCALL
-RegSetValueA(
-       HKEY    hKey,
-       LPCSTR  lpSubKey,
-       DWORD   dwType,
-       LPCSTR  lpData,
-       DWORD   cbData
+RegSetValueExW(
+       HKEY            hKey,
+       LPCWSTR         lpValueName,
+       DWORD           Reserved,
+       DWORD           dwType,
+       CONST BYTE      *lpData,
+       DWORD           cbData
        )
 {
-  WCHAR SubKeyNameBuffer[MAX_PATH+1];
-  UNICODE_STRING SubKeyName;
-  UNICODE_STRING Data;
-  ANSI_STRING AnsiString;
-  LONG DataSize;
-  LONG ErrorCode;
-
-  if (!lpData)
-  {
-       SetLastError(ERROR_INVALID_PARAMETER);
-         return ERROR_INVALID_PARAMETER;
-  }
+       UNICODE_STRING ValueName;
+    PUNICODE_STRING pValueName;
+    HKEY KeyHandle;
+       NTSTATUS Status;
+    LONG ErrorCode;
 
-  RtlInitUnicodeString(&SubKeyName, NULL);
-  RtlInitUnicodeString(&Data, NULL);
+    Status = MapDefaultKey(&KeyHandle, hKey);
+       if (!NT_SUCCESS(Status))
+       {
+               ErrorCode = RtlNtStatusToDosError(Status);
+               SetLastError(ErrorCode);
+               return ErrorCode;
+       }
 
-  if ((lpSubKey) && (strlen(lpSubKey) != 0))
+  if (lpValueName)
   {
-    RtlInitAnsiString(&AnsiString, (LPSTR)lpSubKey);
-    SubKeyName.Buffer = &SubKeyNameBuffer[0];
-    SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer);
-    RtlAnsiStringToUnicodeString(&SubKeyName, &AnsiString, FALSE);
+         RtlInitUnicodeString(&ValueName, lpValueName);
+    pValueName = &ValueName;
   }
-
-  DataSize = cbData * sizeof(WCHAR);
-  Data.MaximumLength = DataSize;
-  Data.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, DataSize);
-  if (!Data.Buffer)
+  else
   {
-         SetLastError(ERROR_OUTOFMEMORY);
-         return ERROR_OUTOFMEMORY;
+    pValueName = NULL;
   }
 
-  ErrorCode = RegSetValueW(
-         hKey,
-         (LPCWSTR)SubKeyName.Buffer,
-         dwType,
-         Data.Buffer,
-         DataSize);
-
-  RtlFreeHeap(RtlGetProcessHeap(), 0, Data.Buffer);
+       Status = NtSetValueKey(
+    KeyHandle,
+         pValueName,
+               0,
+               dwType,
+               (PVOID)lpData,
+               (ULONG)cbData);
+       if (!NT_SUCCESS(Status))
+       {
+               LONG ErrorCode = RtlNtStatusToDosError(Status);
+               SetLastError (ErrorCode);
+               return ErrorCode;
+       }
 
-  return ErrorCode;
+       return ERROR_SUCCESS;
 }
 
 
@@ -2337,62 +2463,6 @@ RegSetValueExA(
 }
 
 
-/************************************************************************
- *     RegSetValueExW
- */
-LONG
-STDCALL
-RegSetValueExW(
-       HKEY            hKey,
-       LPCWSTR         lpValueName,
-       DWORD           Reserved,
-       DWORD           dwType,
-       CONST BYTE      *lpData,
-       DWORD           cbData
-       )
-{
-       UNICODE_STRING ValueName;
-  PUNICODE_STRING pValueName;
-  HANDLE KeyHandle;
-       NTSTATUS Status;
-  LONG ErrorCode;
-
-  Status = MapDefaultKey(&KeyHandle, hKey);
-       if (!NT_SUCCESS(Status))
-       {
-               ErrorCode = RtlNtStatusToDosError(Status);
-               SetLastError(ErrorCode);
-               return ErrorCode;
-       }
-
-  if (lpValueName)
-  {
-         RtlInitUnicodeString(&ValueName, lpValueName);
-    pValueName = &ValueName;
-  }
-  else
-  {
-    pValueName = NULL;
-  }
-
-       Status = NtSetValueKey(
-    KeyHandle,
-         pValueName,
-               0,
-               dwType,
-               (PVOID)lpData,
-               (ULONG)cbData);
-       if (!NT_SUCCESS(Status))
-       {
-               LONG ErrorCode = RtlNtStatusToDosError(Status);
-               SetLastError (ErrorCode);
-               return ErrorCode;
-       }
-
-       return ERROR_SUCCESS;
-}
-
-
 /************************************************************************
  *     RegSetValueW
  */
@@ -2409,10 +2479,10 @@ RegSetValueW(
        NTSTATUS                errCode;
        UNICODE_STRING          SubKeyString;
        OBJECT_ATTRIBUTES       ObjectAttributes;
-       HANDLE                  KeyHandle;
-  HANDLE                       RealKey;
+       HKEY                    KeyHandle;
+    HANDLE                     RealKey;
        LONG                      ErrorCode;
-  BOOL        CloseRealKey;
+    BOOL        CloseRealKey;
 
        errCode = MapDefaultKey(&KeyHandle, hKey);
        if (!NT_SUCCESS(errCode))
@@ -2470,6 +2540,65 @@ RegSetValueW(
 }
 
 
+/************************************************************************
+ *     RegSetValueA
+ */
+LONG
+STDCALL
+RegSetValueA(
+       HKEY    hKey,
+       LPCSTR  lpSubKey,
+       DWORD   dwType,
+       LPCSTR  lpData,
+       DWORD   cbData
+       )
+{
+  WCHAR SubKeyNameBuffer[MAX_PATH+1];
+  UNICODE_STRING SubKeyName;
+  UNICODE_STRING Data;
+  ANSI_STRING AnsiString;
+  LONG DataSize;
+  LONG ErrorCode;
+
+  if (!lpData)
+  {
+       SetLastError(ERROR_INVALID_PARAMETER);
+         return ERROR_INVALID_PARAMETER;
+  }
+
+  RtlInitUnicodeString(&SubKeyName, NULL);
+  RtlInitUnicodeString(&Data, NULL);
+
+  if ((lpSubKey) && (strlen(lpSubKey) != 0))
+  {
+    RtlInitAnsiString(&AnsiString, (LPSTR)lpSubKey);
+    SubKeyName.Buffer = &SubKeyNameBuffer[0];
+    SubKeyName.MaximumLength = sizeof(SubKeyNameBuffer);
+    RtlAnsiStringToUnicodeString(&SubKeyName, &AnsiString, FALSE);
+  }
+
+  DataSize = cbData * sizeof(WCHAR);
+  Data.MaximumLength = DataSize;
+  Data.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, DataSize);
+  if (!Data.Buffer)
+  {
+         SetLastError(ERROR_OUTOFMEMORY);
+         return ERROR_OUTOFMEMORY;
+  }
+
+  ErrorCode = RegSetValueW(
+         hKey,
+         (LPCWSTR)SubKeyName.Buffer,
+         dwType,
+         Data.Buffer,
+         DataSize);
+
+  RtlFreeHeap(RtlGetProcessHeap(), 0, Data.Buffer);
+
+  return ErrorCode;
+}
+
+
 /************************************************************************
  *     RegUnLoadKeyA
  */