Fix code assuming that the Reg* functions set the last error code
[reactos.git] / reactos / lib / userenv / profile.c
index 664e24d..4491f79 100644 (file)
@@ -1,4 +1,22 @@
-/* $Id: profile.c,v 1.9 2004/04/19 10:51:17 ekohl Exp $
+/*
+ *  ReactOS kernel
+ *  Copyright (C) 2004 ReactOS Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id$
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
  * PROGRAMMER:      Eric Kohl
  */
 
-#include <ntos.h>
-#include <windows.h>
-#include <string.h>
-
-#include <userenv.h>
+#include <precomp.h>
 
-#include "internal.h"
+#define NDEBUG
+#include <debug.h>
 
 
 /* FUNCTIONS ***************************************************************/
@@ -23,10 +38,8 @@ AppendSystemPostfix (LPWSTR lpName,
                     DWORD dwMaxLength)
 {
   WCHAR szSystemRoot[MAX_PATH];
-  WCHAR szDrivePostfix[3];
   LPWSTR lpszPostfix;
   LPWSTR lpszPtr;
-  DWORD dwPostfixLength;
 
   /* Build profile name postfix */
   if (!ExpandEnvironmentStringsW (L"%SystemRoot%",
@@ -50,26 +63,14 @@ AppendSystemPostfix (LPWSTR lpName,
       lpszPtr++;
     }
 
-  dwPostfixLength = wcslen (lpszPostfix);
-  if (szSystemRoot[0] != L'C')
-    {
-      dwPostfixLength += 2;
-      szDrivePostfix[0] = L'_';
-      szDrivePostfix[1] = szSystemRoot[0];
-      szDrivePostfix[2] = (WCHAR)0;
-    }
-
-  if (wcslen (lpName) + dwPostfixLength >= dwMaxLength)
+  if (wcslen(lpName) + wcslen(lpszPostfix) >= dwMaxLength)
     {
       DPRINT1("Error: buffer overflow\n");
+      SetLastError(ERROR_BUFFER_OVERFLOW);
       return FALSE;
     }
 
-  wcscat (lpName, lpszPostfix);
-  if (szSystemRoot[0] != L'C')
-    {
-      wcscat (lpName, szDrivePostfix);
-    }
+  wcscat(lpName, lpszPostfix);
 
   return TRUE;
 }
@@ -109,35 +110,39 @@ CreateUserProfileW (PSID Sid,
   WCHAR szUserProfilePath[MAX_PATH];
   WCHAR szDefaultUserPath[MAX_PATH];
   WCHAR szBuffer[MAX_PATH];
-  UNICODE_STRING SidString;
+  LPWSTR SidString;
   DWORD dwLength;
   DWORD dwDisposition;
   HKEY hKey;
-  NTSTATUS Status;
+  LONG Error;
 
-  DPRINT ("CreateUserProfileW() called\n");
+  DPRINT("CreateUserProfileW() called\n");
 
-  if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
-                    L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
-                    0,
-                    KEY_ALL_ACCESS,
-                    &hKey))
+  Error = RegOpenKeyExW (HKEY_LOCAL_MACHINE,
+                        L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
+                        0,
+                        KEY_ALL_ACCESS,
+                        &hKey);
+  if (Error != ERROR_SUCCESS)
     {
-      DPRINT1("Error: %lu\n", GetLastError());
+      DPRINT1("Error: %lu\n", Error);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
   /* Get profiles path */
   dwLength = MAX_PATH * sizeof(WCHAR);
-  if (RegQueryValueExW (hKey,
-                       L"ProfilesDirectory",
-                       NULL,
-                       NULL,
-                       (LPBYTE)szRawProfilesPath,
-                       &dwLength))
-    {
-      DPRINT1("Error: %lu\n", GetLastError());
+  Error = RegQueryValueExW (hKey,
+                           L"ProfilesDirectory",
+                           NULL,
+                           NULL,
+                           (LPBYTE)szRawProfilesPath,
+                           &dwLength);
+  if (Error != ERROR_SUCCESS)
+    {
+      DPRINT1("Error: %lu\n", Error);
       RegCloseKey (hKey);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
@@ -153,15 +158,17 @@ CreateUserProfileW (PSID Sid,
 
   /* Get default user path */
   dwLength = MAX_PATH * sizeof(WCHAR);
-  if (RegQueryValueExW (hKey,
-                       L"DefaultUserProfile",
-                       NULL,
-                       NULL,
-                       (LPBYTE)szBuffer,
-                       &dwLength))
-    {
-      DPRINT1("Error: %lu\n", GetLastError());
+  Error = RegQueryValueExW (hKey,
+                           L"DefaultUserProfile",
+                           NULL,
+                           NULL,
+                           (LPBYTE)szBuffer,
+                           &dwLength);
+  if (Error != ERROR_SUCCESS)
+    {
+      DPRINT1("Error: %lu\n", Error);
       RegCloseKey (hKey);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
@@ -173,7 +180,7 @@ CreateUserProfileW (PSID Sid,
   if (!AppendSystemPostfix (szUserProfilePath, MAX_PATH))
     {
       DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
-      RtlFreeUnicodeString (&SidString);
+      LocalFree ((HLOCAL)SidString);
       RegCloseKey (hKey);
       return FALSE;
     }
@@ -200,30 +207,32 @@ CreateUserProfileW (PSID Sid,
     }
 
   /* Add profile to profile list */
-  Status = RtlConvertSidToUnicodeString (&SidString, Sid, TRUE);
-  if (!NT_SUCCESS(Status))
+  if (!ConvertSidToStringSidW (Sid,
+                               &SidString))
     {
-      DPRINT1("Status: %lx\n", Status);
+      DPRINT1("Error: %lu\n", GetLastError());
       return FALSE;
     }
 
   wcscpy (szBuffer,
          L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
-  wcscat (szBuffer, SidString.Buffer);
+  wcscat (szBuffer, SidString);
 
   /* Create user profile key */
-  if (RegCreateKeyExW (HKEY_LOCAL_MACHINE,
-                      szBuffer,
-                      0,
-                      NULL,
-                      REG_OPTION_NON_VOLATILE,
-                      KEY_ALL_ACCESS,
-                      NULL,
-                      &hKey,
-                      &dwDisposition))
+  Error = RegCreateKeyExW (HKEY_LOCAL_MACHINE,
+                          szBuffer,
+                          0,
+                          NULL,
+                          REG_OPTION_NON_VOLATILE,
+                          KEY_ALL_ACCESS,
+                          NULL,
+                          &hKey,
+                          &dwDisposition);
+  if (Error != ERROR_SUCCESS)
     {
-      DPRINT1("Error: %lu\n", GetLastError());
-      RtlFreeUnicodeString (&SidString);
+      DPRINT1("Error: %lu\n", Error);
+      LocalFree ((HLOCAL)SidString);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
@@ -234,73 +243,112 @@ CreateUserProfileW (PSID Sid,
   if (!AppendSystemPostfix (szBuffer, MAX_PATH))
     {
       DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
-      RtlFreeUnicodeString (&SidString);
+      LocalFree ((HLOCAL)SidString);
       RegCloseKey (hKey);
       return FALSE;
     }
 
   /* Set 'ProfileImagePath' value (non-expanded) */
-  if (RegSetValueExW (hKey,
-                     L"ProfileImagePath",
-                     0,
-                     REG_EXPAND_SZ,
-                     (LPBYTE)szBuffer,
-                     (wcslen (szBuffer) + 1) * sizeof(WCHAR)))
-    {
-      DPRINT1("Error: %lu\n", GetLastError());
-      RtlFreeUnicodeString (&SidString);
+  Error = RegSetValueExW (hKey,
+                         L"ProfileImagePath",
+                         0,
+                         REG_EXPAND_SZ,
+                         (LPBYTE)szBuffer,
+                         (wcslen (szBuffer) + 1) * sizeof(WCHAR));
+  if (Error != ERROR_SUCCESS)
+    {
+      DPRINT1("Error: %lu\n", Error);
+      LocalFree ((HLOCAL)SidString);
       RegCloseKey (hKey);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
   /* Set 'Sid' value */
-  if (RegSetValueExW (hKey,
-                     L"Sid",
-                     0,
-                     REG_BINARY,
-                     Sid,
-                     RtlLengthSid (Sid)))
-    {
-      DPRINT1("Error: %lu\n", GetLastError());
-      RtlFreeUnicodeString (&SidString);
+  Error = RegSetValueExW (hKey,
+                         L"Sid",
+                         0,
+                         REG_BINARY,
+                         Sid,
+                         GetLengthSid (Sid));
+  if (Error != ERROR_SUCCESS)
+    {
+      DPRINT1("Error: %lu\n", Error);
+      LocalFree ((HLOCAL)SidString);
       RegCloseKey (hKey);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
   RegCloseKey (hKey);
 
   /* Create user hive name */
-  wcscat (szUserProfilePath, L"\\ntuser.dat");
+  wcscpy (szBuffer, szUserProfilePath);
+  wcscat (szBuffer, L"\\ntuser.dat");
 
   /* Create new user hive */
-  if (RegLoadKeyW (HKEY_USERS,
-                  SidString.Buffer,
-                  szUserProfilePath))
+  Error = RegLoadKeyW (HKEY_USERS,
+                      SidString,
+                      szBuffer);
+  if (Error != ERROR_SUCCESS)
     {
-      DPRINT1("Error: %lu\n", GetLastError());
-      RtlFreeUnicodeString (&SidString);
+      DPRINT1("Error: %lu\n", Error);
+      LocalFree ((HLOCAL)SidString);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
   /* Initialize user hive */
-  if (!CreateUserHive (SidString.Buffer))
+  if (!CreateUserHive (SidString, szUserProfilePath))
     {
       DPRINT1("Error: %lu\n", GetLastError());
-      RtlFreeUnicodeString (&SidString);
+      LocalFree ((HLOCAL)SidString);
       return FALSE;
     }
 
   RegUnLoadKeyW (HKEY_USERS,
-                SidString.Buffer);
+                SidString);
 
-  RtlFreeUnicodeString (&SidString);
+  LocalFree ((HLOCAL)SidString);
 
-  DPRINT ("CreateUserProfileW() done\n");
+  DPRINT("CreateUserProfileW() done\n");
 
   return TRUE;
 }
 
 
+BOOL WINAPI
+GetAllUsersProfileDirectoryA (LPSTR lpProfileDir,
+                             LPDWORD lpcchSize)
+{
+  LPWSTR lpBuffer;
+  BOOL bResult;
+
+  lpBuffer = GlobalAlloc (GMEM_FIXED,
+                         *lpcchSize * sizeof(WCHAR));
+  if (lpBuffer == NULL)
+    return FALSE;
+
+  bResult = GetAllUsersProfileDirectoryW (lpBuffer,
+                                         lpcchSize);
+  if (bResult)
+    {
+      WideCharToMultiByte (CP_ACP,
+                          0,
+                          lpBuffer,
+                          -1,
+                          lpProfileDir,
+                          *lpcchSize,
+                          NULL,
+                          NULL);
+    }
+
+  GlobalFree (lpBuffer);
+
+  return bResult;
+}
+
+
 BOOL WINAPI
 GetAllUsersProfileDirectoryW (LPWSTR lpProfileDir,
                              LPDWORD lpcchSize)
@@ -309,28 +357,33 @@ GetAllUsersProfileDirectoryW (LPWSTR lpProfileDir,
   WCHAR szBuffer[MAX_PATH];
   DWORD dwLength;
   HKEY hKey;
+  LONG Error;
 
-  if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
-                    L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
-                    0,
-                    KEY_READ,
-                    &hKey))
+  Error = RegOpenKeyExW (HKEY_LOCAL_MACHINE,
+                        L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
+                        0,
+                        KEY_READ,
+                        &hKey);
+  if (Error != ERROR_SUCCESS)
     {
-      DPRINT1("Error: %lu\n", GetLastError());
+      DPRINT1("Error: %lu\n", Error);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
   /* Get profiles path */
-  dwLength = MAX_PATH * sizeof(WCHAR);
-  if (RegQueryValueExW (hKey,
-                       L"ProfilesDirectory",
-                       NULL,
-                       NULL,
-                       (LPBYTE)szBuffer,
-                       &dwLength))
-    {
-      DPRINT1("Error: %lu\n", GetLastError());
+  dwLength = sizeof(szBuffer);
+  Error = RegQueryValueExW (hKey,
+                           L"ProfilesDirectory",
+                           NULL,
+                           NULL,
+                           (LPBYTE)szBuffer,
+                           &dwLength);
+  if (Error != ERROR_SUCCESS)
+    {
+      DPRINT1("Error: %lu\n", Error);
       RegCloseKey (hKey);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
@@ -345,16 +398,18 @@ GetAllUsersProfileDirectoryW (LPWSTR lpProfileDir,
     }
 
   /* Get 'AllUsersProfile' name */
-  dwLength = MAX_PATH * sizeof(WCHAR);
-  if (RegQueryValueExW (hKey,
-                       L"AllUsersProfile",
-                       NULL,
-                       NULL,
-                       (LPBYTE)szBuffer,
-                       &dwLength))
-    {
-      DPRINT1("Error: %lu\n", GetLastError());
+  dwLength = sizeof(szBuffer);
+  Error = RegQueryValueExW (hKey,
+                           L"AllUsersProfile",
+                           NULL,
+                           NULL,
+                           (LPBYTE)szBuffer,
+                           &dwLength);
+  if (Error != ERROR_SUCCESS)
+    {
+      DPRINT1("Error: %lu\n", Error);
       RegCloseKey (hKey);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
@@ -363,7 +418,7 @@ GetAllUsersProfileDirectoryW (LPWSTR lpProfileDir,
   wcscat (szProfilePath, L"\\");
   wcscat (szProfilePath, szBuffer);
 
-  dwLength = wcslen (szProfilePath);
+  dwLength = wcslen (szProfilePath) + 1;
   if (lpProfileDir != NULL)
     {
       if (*lpcchSize < dwLength)
@@ -382,6 +437,38 @@ GetAllUsersProfileDirectoryW (LPWSTR lpProfileDir,
 }
 
 
+BOOL WINAPI
+GetDefaultUserProfileDirectoryA (LPSTR lpProfileDir,
+                                LPDWORD lpcchSize)
+{
+  LPWSTR lpBuffer;
+  BOOL bResult;
+
+  lpBuffer = GlobalAlloc (GMEM_FIXED,
+                         *lpcchSize * sizeof(WCHAR));
+  if (lpBuffer == NULL)
+    return FALSE;
+
+  bResult = GetDefaultUserProfileDirectoryW (lpBuffer,
+                                            lpcchSize);
+  if (bResult)
+    {
+      WideCharToMultiByte (CP_ACP,
+                          0,
+                          lpBuffer,
+                          -1,
+                          lpProfileDir,
+                          *lpcchSize,
+                          NULL,
+                          NULL);
+    }
+
+  GlobalFree (lpBuffer);
+
+  return bResult;
+}
+
+
 BOOL WINAPI
 GetDefaultUserProfileDirectoryW (LPWSTR lpProfileDir,
                                 LPDWORD lpcchSize)
@@ -390,28 +477,33 @@ GetDefaultUserProfileDirectoryW (LPWSTR lpProfileDir,
   WCHAR szBuffer[MAX_PATH];
   DWORD dwLength;
   HKEY hKey;
+  LONG Error;
 
-  if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
-                    L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
-                    0,
-                    KEY_READ,
-                    &hKey))
+  Error = RegOpenKeyExW (HKEY_LOCAL_MACHINE,
+                        L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
+                        0,
+                        KEY_READ,
+                        &hKey);
+  if (Error != ERROR_SUCCESS)
     {
-      DPRINT1("Error: %lu\n", GetLastError());
+      DPRINT1("Error: %lu\n", Error);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
   /* Get profiles path */
-  dwLength = MAX_PATH * sizeof(WCHAR);
-  if (RegQueryValueExW (hKey,
-                       L"ProfilesDirectory",
-                       NULL,
-                       NULL,
-                       (LPBYTE)szBuffer,
-                       &dwLength))
-    {
-      DPRINT1("Error: %lu\n", GetLastError());
+  dwLength = sizeof(szBuffer);
+  Error = RegQueryValueExW (hKey,
+                           L"ProfilesDirectory",
+                           NULL,
+                           NULL,
+                           (LPBYTE)szBuffer,
+                           &dwLength);
+  if (Error != ERROR_SUCCESS)
+    {
+      DPRINT1("Error: %lu\n", Error);
       RegCloseKey (hKey);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
@@ -426,16 +518,18 @@ GetDefaultUserProfileDirectoryW (LPWSTR lpProfileDir,
     }
 
   /* Get 'DefaultUserProfile' name */
-  dwLength = MAX_PATH * sizeof(WCHAR);
-  if (RegQueryValueExW (hKey,
-                       L"DefaultUserProfile",
-                       NULL,
-                       NULL,
-                       (LPBYTE)szBuffer,
-                       &dwLength))
-    {
-      DPRINT1("Error: %lu\n", GetLastError());
+  dwLength = sizeof(szBuffer);
+  Error = RegQueryValueExW (hKey,
+                           L"DefaultUserProfile",
+                           NULL,
+                           NULL,
+                          (LPBYTE)szBuffer,
+                          &dwLength);
+  if (Error != ERROR_SUCCESS)
+    {
+      DPRINT1("Error: %lu\n", Error);
       RegCloseKey (hKey);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
@@ -444,7 +538,7 @@ GetDefaultUserProfileDirectoryW (LPWSTR lpProfileDir,
   wcscat (szProfilePath, L"\\");
   wcscat (szProfilePath, szBuffer);
 
-  dwLength = wcslen (szProfilePath);
+  dwLength = wcslen (szProfilePath) + 1;
   if (lpProfileDir != NULL)
     {
       if (*lpcchSize < dwLength)
@@ -463,6 +557,38 @@ GetDefaultUserProfileDirectoryW (LPWSTR lpProfileDir,
 }
 
 
+BOOL WINAPI
+GetProfilesDirectoryA (LPSTR lpProfileDir,
+                      LPDWORD lpcchSize)
+{
+  LPWSTR lpBuffer;
+  BOOL bResult;
+
+  lpBuffer = GlobalAlloc (GMEM_FIXED,
+                         *lpcchSize * sizeof(WCHAR));
+  if (lpBuffer == NULL)
+    return FALSE;
+
+  bResult = GetProfilesDirectoryW (lpBuffer,
+                                  lpcchSize);
+  if (bResult)
+    {
+      WideCharToMultiByte (CP_ACP,
+                          0,
+                          lpBuffer,
+                          -1,
+                          lpProfileDir,
+                          *lpcchSize,
+                          NULL,
+                          NULL);
+    }
+
+  GlobalFree (lpBuffer);
+
+  return bResult;
+}
+
+
 BOOL WINAPI
 GetProfilesDirectoryW (LPWSTR lpProfilesDir,
                       LPDWORD lpcchSize)
@@ -471,28 +597,33 @@ GetProfilesDirectoryW (LPWSTR lpProfilesDir,
   WCHAR szBuffer[MAX_PATH];
   DWORD dwLength;
   HKEY hKey;
+  LONG Error;
 
-  if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
-                    L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
-                    0,
-                    KEY_READ,
-                    &hKey))
+  Error = RegOpenKeyExW (HKEY_LOCAL_MACHINE,
+                        L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
+                        0,
+                        KEY_READ,
+                       &hKey);
+  if (Error != ERROR_SUCCESS)
     {
-      DPRINT1("Error: %lu\n", GetLastError());
+      DPRINT1("Error: %lu\n", Error);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
   /* Get profiles path */
-  dwLength = MAX_PATH * sizeof(WCHAR);
-  if (RegQueryValueExW (hKey,
-                       L"ProfilesDirectory",
-                       NULL,
-                       NULL,
-                       (LPBYTE)szBuffer,
-                       &dwLength))
-    {
-      DPRINT1("Error: %lu\n", GetLastError());
+  dwLength = sizeof(szBuffer);
+  Error = RegQueryValueExW (hKey,
+                           L"ProfilesDirectory",
+                           NULL,
+                           NULL,
+                           (LPBYTE)szBuffer,
+                           &dwLength);
+  if (Error != ERROR_SUCCESS)
+    {
+      DPRINT1("Error: %lu\n", Error);
       RegCloseKey (hKey);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
@@ -507,7 +638,7 @@ GetProfilesDirectoryW (LPWSTR lpProfilesDir,
       return FALSE;
     }
 
-  dwLength = wcslen (szProfilesPath);
+  dwLength = wcslen (szProfilesPath) + 1;
   if (lpProfilesDir != NULL)
     {
       if (*lpcchSize < dwLength)
@@ -526,6 +657,40 @@ GetProfilesDirectoryW (LPWSTR lpProfilesDir,
 }
 
 
+BOOL WINAPI
+GetUserProfileDirectoryA (HANDLE hToken,
+                         LPSTR lpProfileDir,
+                         LPDWORD lpcchSize)
+{
+  LPWSTR lpBuffer;
+  BOOL bResult;
+
+  lpBuffer = GlobalAlloc (GMEM_FIXED,
+                         *lpcchSize * sizeof(WCHAR));
+  if (lpBuffer == NULL)
+    return FALSE;
+
+  bResult = GetUserProfileDirectoryW (hToken,
+                                     lpBuffer,
+                                     lpcchSize);
+  if (bResult)
+    {
+      WideCharToMultiByte (CP_ACP,
+                          0,
+                          lpBuffer,
+                          -1,
+                          lpProfileDir,
+                          *lpcchSize,
+                          NULL,
+                          NULL);
+    }
+
+  GlobalFree (lpBuffer);
+
+  return bResult;
+}
+
+
 BOOL WINAPI
 GetUserProfileDirectoryW (HANDLE hToken,
                          LPWSTR lpProfileDir,
@@ -537,6 +702,7 @@ GetUserProfileDirectoryW (HANDLE hToken,
   WCHAR szImagePath[MAX_PATH];
   DWORD dwLength;
   HKEY hKey;
+  LONG Error;
 
   if (!GetUserSidFromToken (hToken,
                            &SidString))
@@ -556,26 +722,30 @@ GetUserProfileDirectoryW (HANDLE hToken,
 
   DPRINT ("KeyName: '%S'\n", szKeyName);
 
-  if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
-                    szKeyName,
-                    0,
-                    KEY_ALL_ACCESS,
-                    &hKey))
+  Error = RegOpenKeyExW (HKEY_LOCAL_MACHINE,
+                        szKeyName,
+                        0,
+                        KEY_ALL_ACCESS,
+                        &hKey);
+  if (Error != ERROR_SUCCESS)
     {
-      DPRINT1 ("Error: %lu\n", GetLastError());
+      DPRINT1 ("Error: %lu\n", Error);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
-  dwLength = MAX_PATH * sizeof(WCHAR);
-  if (RegQueryValueExW (hKey,
-                       L"ProfileImagePath",
-                       NULL,
-                       NULL,
-                       (LPBYTE)szRawImagePath,
-                       &dwLength))
+  dwLength = sizeof(szRawImagePath);
+  Error = RegQueryValueExW (hKey,
+                           L"ProfileImagePath",
+                           NULL,
+                           NULL,
+                           (LPBYTE)szRawImagePath,
+                           &dwLength);
+  if (Error != ERROR_SUCCESS)
     {
-      DPRINT1 ("Error: %lu\n", GetLastError());
+      DPRINT1 ("Error: %lu\n", Error);
       RegCloseKey (hKey);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
@@ -594,8 +764,8 @@ GetUserProfileDirectoryW (HANDLE hToken,
 
   DPRINT ("ImagePath: '%S'\n", szImagePath);
 
-  dwLength = wcslen (szImagePath);
-  if (dwLength > *lpcchSize)
+  dwLength = wcslen (szImagePath) + 1;
+  if (*lpcchSize < dwLength)
     {
       DPRINT1 ("Buffer too small\n");
       SetLastError (ERROR_INSUFFICIENT_BUFFER);
@@ -646,13 +816,23 @@ CheckForLoadedProfile (HANDLE hToken)
 }
 
 
+BOOL WINAPI
+LoadUserProfileA (HANDLE hToken,
+                 LPPROFILEINFOA lpProfileInfo)
+{
+  DPRINT ("LoadUserProfileA() not implemented\n");
+  return FALSE;
+}
+
+
 BOOL WINAPI
 LoadUserProfileW (HANDLE hToken,
                  LPPROFILEINFOW lpProfileInfo)
 {
   WCHAR szUserHivePath[MAX_PATH];
   UNICODE_STRING SidString;
-  DWORD dwLength;
+  LONG Error;
+  DWORD dwLength = sizeof(szUserHivePath) / sizeof(szUserHivePath[0]);
 
   DPRINT ("LoadUserProfileW() called\n");
 
@@ -702,23 +882,27 @@ LoadUserProfileW (HANDLE hToken,
 
   DPRINT ("SidString: '%wZ'\n", &SidString);
 
-  if (RegLoadKeyW (HKEY_USERS,
-                  SidString.Buffer,
-                  szUserHivePath))
+  Error = RegLoadKeyW (HKEY_USERS,
+                      SidString.Buffer,
+                      szUserHivePath);
+  if (Error != ERROR_SUCCESS)
     {
-      DPRINT1 ("RegLoadKeyW() failed (Error %ld)\n", GetLastError());
+      DPRINT1 ("RegLoadKeyW() failed (Error %ld)\n", Error);
       RtlFreeUnicodeString (&SidString);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
-  if (RegOpenKeyExW (HKEY_USERS,
-                    SidString.Buffer,
-                    0,
-                    KEY_ALL_ACCESS,
-                    (PHKEY)&lpProfileInfo->hProfile))
+  Error = RegOpenKeyExW (HKEY_USERS,
+                        SidString.Buffer,
+                        0,
+                        KEY_ALL_ACCESS,
+                        (PHKEY)&lpProfileInfo->hProfile);
+  if (Error != ERROR_SUCCESS)
     {
-      DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", GetLastError());
+      DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", Error);
       RtlFreeUnicodeString (&SidString);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
@@ -735,6 +919,7 @@ UnloadUserProfile (HANDLE hToken,
                   HANDLE hProfile)
 {
   UNICODE_STRING SidString;
+  LONG Error;
 
   DPRINT ("UnloadUserProfile() called\n");
 
@@ -756,11 +941,13 @@ UnloadUserProfile (HANDLE hToken,
 
   DPRINT ("SidString: '%wZ'\n", &SidString);
 
-  if (RegUnLoadKeyW (HKEY_USERS,
-                    SidString.Buffer))
+  Error = RegUnLoadKeyW (HKEY_USERS,
+                        SidString.Buffer);
+  if (Error != ERROR_SUCCESS)
     {
-      DPRINT1 ("RegUnLoadKeyW() failed (Error %ld)\n", GetLastError());
+      DPRINT1 ("RegUnLoadKeyW() failed (Error %ld)\n", Error);
       RtlFreeUnicodeString (&SidString);
+      SetLastError((DWORD)Error);
       return FALSE;
     }