[ros-diffs] [hpoussin] 28241: Improve LoadUserProfileW, by creating the profile if it doesn't exist

hpoussin at svn.reactos.org hpoussin at svn.reactos.org
Wed Aug 8 10:26:44 CEST 2007


Author: hpoussin
Date: Wed Aug  8 12:26:44 2007
New Revision: 28241

URL: http://svn.reactos.org/svn/reactos?rev=28241&view=rev
Log:
Improve LoadUserProfileW, by creating the profile if it doesn't exist

Modified:
    trunk/reactos/dll/win32/userenv/profile.c

Modified: trunk/reactos/dll/win32/userenv/profile.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/userenv/profile.c?rev=28241&r1=28240&r2=28241&view=diff
==============================================================================
--- trunk/reactos/dll/win32/userenv/profile.c (original)
+++ trunk/reactos/dll/win32/userenv/profile.c Wed Aug  8 12:26:44 2007
@@ -63,7 +63,7 @@
       lpszPtr++;
     }
 
-  if (wcslen(lpName) + wcslen(lpszPostfix) >= dwMaxLength)
+  if (wcslen(lpName) + wcslen(lpszPostfix) + 1 >= dwMaxLength)
     {
       DPRINT1("Error: buffer overflow\n");
       SetLastError(ERROR_BUFFER_OVERFLOW);
@@ -825,52 +825,194 @@
 
 
 BOOL WINAPI
-LoadUserProfileW (HANDLE hToken,
-		  LPPROFILEINFOW lpProfileInfo)
-{
-  WCHAR szUserHivePath[MAX_PATH];
+LoadUserProfileW(
+    IN HANDLE hToken,
+    IN OUT LPPROFILEINFOW lpProfileInfo)
+{
+    WCHAR szUserHivePath[MAX_PATH];
+    LPWSTR UserName = NULL, Domain = NULL;
+    DWORD UserNameLength = 0, DomainLength = 0;
+    PTOKEN_USER UserSid = NULL;
+    SID_NAME_USE AccountType;
+    UNICODE_STRING SidString = { 0, };
+    LONG Error;
+    BOOL ret = FALSE;
+    DWORD dwLength = sizeof(szUserHivePath) / sizeof(szUserHivePath[0]);
+
+    DPRINT("LoadUserProfileW() called\n");
+
+    /* Check profile info */
+    if (!lpProfileInfo
+     || lpProfileInfo->dwSize != sizeof(PROFILEINFOW)
+     || lpProfileInfo->lpUserName == NULL
+     || lpProfileInfo->lpUserName[0] == 0)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return TRUE;
+    }
+
+    /* Don't load a profile twice */
+    if (CheckForLoadedProfile(hToken))
+    {
+        DPRINT ("Profile already loaded\n");
+        lpProfileInfo->hProfile = NULL;
+        return TRUE;
+    }
+
+    if (!GetProfilesDirectoryW(szUserHivePath, &dwLength))
+    {
+        DPRINT1("GetProfilesDirectoryW() failed (error %ld)\n", GetLastError());
+        return FALSE;
+    }
+
+    wcscat(szUserHivePath, L"\\");
+    wcscat(szUserHivePath, lpProfileInfo->lpUserName);
+    dwLength = sizeof(szUserHivePath) / sizeof(szUserHivePath[0]);
+    if (!AppendSystemPostfix(szUserHivePath, dwLength))
+    {
+        DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
+        return FALSE;
+    }
+
+    /* Create user hive name */
+    wcscat(szUserHivePath, L"\\ntuser.dat");
+    DPRINT("szUserHivePath: %S\n", szUserHivePath);
+
+    /* Create user profile directory if needed */
+    if (GetFileAttributesW(szUserHivePath) == INVALID_FILE_ATTRIBUTES)
+    {
+        /* Get user sid */
+        if (GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLength)
+         || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+        {
+            DPRINT1 ("GetTokenInformation() failed\n");
+            return FALSE;
+        }
+        UserSid = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), 0, dwLength);
+        if (!UserSid)
+        {
+            DPRINT1 ("HeapAlloc() failed\n");
+            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+            goto cleanup;
+        }
+        if (!GetTokenInformation(hToken, TokenUser, UserSid, dwLength, &dwLength))
+        {
+            DPRINT1 ("GetTokenInformation() failed\n");
+            goto cleanup;
+        }
+
+        /* Get user name */
+        do
+        {
+            if (UserNameLength > 0)
+            {
+                HeapFree(GetProcessHeap(), 0, UserName);
+                UserName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, UserNameLength * sizeof(WCHAR));
+                if (!UserName)
+                {
+                    DPRINT1("HeapAlloc() failed\n");
+                    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+                    goto cleanup;
+                }
+            }
+            if (DomainLength > 0)
+            {
+                HeapFree(GetProcessHeap(), 0, Domain);
+                Domain = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, DomainLength * sizeof(WCHAR));
+                if (!Domain)
+                {
+                    DPRINT1("HeapAlloc() failed\n");
+                    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+                    goto cleanup;
+                }
+            }
+            ret = LookupAccountSidW(
+                NULL, UserSid->User.Sid,
+                UserName, &UserNameLength,
+                Domain, &DomainLength,
+               &AccountType);
+        } while (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER);
+
+        if (!ret)
+        {
+            DPRINT1("LookupAccountSidW() failed\n");
+            goto cleanup;
+        }
+
+        /* Create profile */
+        /* FIXME: ignore Domain? */
+        DPRINT("UserName %S, Domain %S\n", UserName, Domain);
+        ret = CreateUserProfileW(UserSid->User.Sid, UserName);
+        if (!ret)
+        {
+            DPRINT1("CreateUserProfileW() failed\n");
+            goto cleanup;
+        }
+    }
+
+    /* Get user SID string */
+    ret = GetUserSidFromToken(hToken, &SidString);
+    if (!ret)
+    {
+        DPRINT1("GetUserSidFromToken() failed\n");
+        goto cleanup;
+    }
+    ret = FALSE;
+
+    /* Load user registry hive */
+    Error = RegLoadKeyW(HKEY_USERS,
+                        SidString.Buffer,
+                        szUserHivePath);
+    if (Error != ERROR_SUCCESS)
+    {
+        DPRINT1("RegLoadKeyW() failed (Error %ld)\n", Error);
+        SetLastError((DWORD)Error);
+        goto cleanup;
+    }
+
+    /* Open future HKEY_CURRENT_USER */
+    Error = RegOpenKeyExW(HKEY_USERS,
+                          SidString.Buffer,
+                          0,
+                          MAXIMUM_ALLOWED,
+                          (PHKEY)&lpProfileInfo->hProfile);
+    if (Error != ERROR_SUCCESS)
+    {
+        DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error);
+        SetLastError((DWORD)Error);
+        goto cleanup;
+    }
+
+    ret = TRUE;
+
+cleanup:
+    HeapFree(GetProcessHeap(), 0, UserSid);
+    HeapFree(GetProcessHeap(), 0, UserName);
+    HeapFree(GetProcessHeap(), 0, Domain);
+    RtlFreeUnicodeString(&SidString);
+
+    DPRINT("LoadUserProfileW() done\n");
+    return ret;
+}
+
+
+BOOL WINAPI
+UnloadUserProfile (HANDLE hToken,
+		   HANDLE hProfile)
+{
   UNICODE_STRING SidString;
   LONG Error;
-  DWORD dwLength = sizeof(szUserHivePath) / sizeof(szUserHivePath[0]);
-
-  DPRINT ("LoadUserProfileW() called\n");
-
-  /* Check profile info */
-  if (lpProfileInfo->dwSize != sizeof(PROFILEINFOW) ||
-      lpProfileInfo->lpUserName == NULL ||
-      lpProfileInfo->lpUserName[0] == 0)
-    {
+
+  DPRINT ("UnloadUserProfile() called\n");
+
+  if (hProfile == NULL)
+    {
+      DPRINT1 ("Invalide profile handle\n");
       SetLastError (ERROR_INVALID_PARAMETER);
       return FALSE;
     }
 
-  /* Don't load a profile twice */
-  if (CheckForLoadedProfile (hToken))
-    {
-      DPRINT ("Profile already loaded\n");
-      lpProfileInfo->hProfile = NULL;
-      return TRUE;
-    }
-
-  if (!GetProfilesDirectoryW (szUserHivePath,
-			      &dwLength))
-    {
-      DPRINT1("GetProfilesDirectoryW() failed\n", GetLastError());
-      return FALSE;
-    }
-
-  wcscat (szUserHivePath, L"\\");
-  wcscat (szUserHivePath, lpProfileInfo->lpUserName);
-  if (!AppendSystemPostfix (szUserHivePath, MAX_PATH))
-    {
-      DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
-      return FALSE;
-    }
-
-  /* Create user hive name */
-  wcscat (szUserHivePath, L"\\ntuser.dat");
-
-  DPRINT ("szUserHivePath: %S\n", szUserHivePath);
+  RegCloseKey (hProfile);
 
   if (!GetUserSidFromToken (hToken,
 			    &SidString))
@@ -881,65 +1023,6 @@
 
   DPRINT ("SidString: '%wZ'\n", &SidString);
 
-  Error = RegLoadKeyW (HKEY_USERS,
-		       SidString.Buffer,
-		       szUserHivePath);
-  if (Error != ERROR_SUCCESS)
-    {
-      DPRINT1 ("RegLoadKeyW() failed (Error %ld)\n", Error);
-      RtlFreeUnicodeString (&SidString);
-      SetLastError((DWORD)Error);
-      return FALSE;
-    }
-
-  Error = RegOpenKeyExW (HKEY_USERS,
-		         SidString.Buffer,
-		         0,
-		         MAXIMUM_ALLOWED,
-		         (PHKEY)&lpProfileInfo->hProfile);
-  if (Error != ERROR_SUCCESS)
-    {
-      DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", Error);
-      RtlFreeUnicodeString (&SidString);
-      SetLastError((DWORD)Error);
-      return FALSE;
-    }
-
-  RtlFreeUnicodeString (&SidString);
-
-  DPRINT ("LoadUserProfileW() done\n");
-
-  return TRUE;
-}
-
-
-BOOL WINAPI
-UnloadUserProfile (HANDLE hToken,
-		   HANDLE hProfile)
-{
-  UNICODE_STRING SidString;
-  LONG Error;
-
-  DPRINT ("UnloadUserProfile() called\n");
-
-  if (hProfile == NULL)
-    {
-      DPRINT1 ("Invalide profile handle\n");
-      SetLastError (ERROR_INVALID_PARAMETER);
-      return FALSE;
-    }
-
-  RegCloseKey (hProfile);
-
-  if (!GetUserSidFromToken (hToken,
-			    &SidString))
-    {
-      DPRINT1 ("GetUserSidFromToken() failed\n");
-      return FALSE;
-    }
-
-  DPRINT ("SidString: '%wZ'\n", &SidString);
-
   Error = RegUnLoadKeyW (HKEY_USERS,
 		         SidString.Buffer);
   if (Error != ERROR_SUCCESS)




More information about the Ros-diffs mailing list