[USERENV]
authorEric Kohl <eric.kohl@reactos.org>
Wed, 5 May 2010 22:30:14 +0000 (22:30 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Wed, 5 May 2010 22:30:14 +0000 (22:30 +0000)
- Create 'Default User' and 'All Users' directories without postfix and append a postfix only if they already exist.
- Create the user account directory without a prefix and append a prefix if the directory already exists.
- Acquire the restore privilege before unloading a hive and remove it after unloading the hive.

Patch is based on Gabriel Ilardi's patch. Fixes bug #2972.

svn path=/trunk/; revision=47106

reactos/dll/win32/userenv/profile.c
reactos/dll/win32/userenv/setup.c

index c2de408..9e3f2b1 100644 (file)
@@ -170,10 +170,12 @@ CreateUserProfileW(PSID Sid,
     WCHAR szProfilesPath[MAX_PATH];
     WCHAR szUserProfilePath[MAX_PATH];
     WCHAR szDefaultUserPath[MAX_PATH];
+    WCHAR szUserProfileName[MAX_PATH];
     WCHAR szBuffer[MAX_PATH];
     LPWSTR SidString;
     DWORD dwLength;
     DWORD dwDisposition;
+    UINT i;
     HKEY hKey;
     LONG Error;
 
@@ -245,14 +247,11 @@ CreateUserProfileW(PSID Sid,
 
     RegCloseKey (hKey);
 
+    wcscpy(szUserProfileName, lpUserName);
+
     wcscpy(szUserProfilePath, szProfilesPath);
     wcscat(szUserProfilePath, L"\\");
-    wcscat(szUserProfilePath, lpUserName);
-    if (!AppendSystemPostfix(szUserProfilePath, MAX_PATH))
-    {
-        DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
-        return FALSE;
-    }
+    wcscat(szUserProfilePath, szUserProfileName);
 
     wcscpy(szDefaultUserPath, szProfilesPath);
     wcscat(szDefaultUserPath, L"\\");
@@ -266,6 +265,24 @@ CreateUserProfileW(PSID Sid,
             DPRINT1("Error: %lu\n", GetLastError());
             return FALSE;
         }
+
+        for (i = 0; i < 1000; i++)
+        {
+            swprintf(szUserProfileName, L"%s.%03u", lpUserName, i);
+
+            wcscpy(szUserProfilePath, szProfilesPath);
+            wcscat(szUserProfilePath, L"\\");
+            wcscat(szUserProfilePath, szUserProfileName);
+
+            if (CreateDirectoryW(szUserProfilePath, NULL))
+                break;
+
+            if (GetLastError() != ERROR_ALREADY_EXISTS)
+            {
+                DPRINT1("Error: %lu\n", GetLastError());
+                return FALSE;
+            }
+        }
     }
 
     /* Copy default user directory */
@@ -308,14 +325,7 @@ CreateUserProfileW(PSID Sid,
     /* Create non-expanded user profile path */
     wcscpy(szBuffer, szRawProfilesPath);
     wcscat(szBuffer, L"\\");
-    wcscat(szBuffer, lpUserName);
-    if (!AppendSystemPostfix(szBuffer, MAX_PATH))
-    {
-        DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
-        LocalFree((HLOCAL)SidString);
-        RegCloseKey (hKey);
-        return FALSE;
-    }
+    wcscat(szBuffer, szUserProfileName);
 
     /* Set 'ProfileImagePath' value (non-expanded) */
     Error = RegSetValueExW(hKey,
@@ -958,16 +968,9 @@ LoadUserProfileW(IN HANDLE hToken,
         }
     }
 
+    /* Create user hive name */
     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);
 
@@ -1129,8 +1132,21 @@ UnloadUserProfile(HANDLE hToken,
 
     DPRINT("SidString: '%wZ'\n", &SidString);
 
+    /* Acquire restore privilege */
+    if (!AcquireRemoveRestorePrivilege(TRUE))
+    {
+        DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
+        RtlFreeUnicodeString(&SidString);
+        return FALSE;
+    }
+
+    /* Unload the hive */
     Error = RegUnLoadKeyW(HKEY_USERS,
                           SidString.Buffer);
+
+    /* Remove restore privilege */
+    AcquireRemoveRestorePrivilege(FALSE);
+
     if (Error != ERROR_SUCCESS)
     {
         DPRINT1("RegUnLoadKeyW() failed (Error %ld)\n", Error);
index ca422dd..783d356 100644 (file)
@@ -140,22 +140,6 @@ InitializeProfiles(VOID)
         return FALSE;
     }
 
-    /* Store profiles directory path */
-    dwLength = (wcslen (szBuffer) + 1) * sizeof(WCHAR);
-    Error = RegSetValueExW(hKey,
-                           L"ProfilesDirectory",
-                           0,
-                           REG_EXPAND_SZ,
-                           (LPBYTE)szBuffer,
-                           dwLength);
-    if (Error != ERROR_SUCCESS)
-    {
-        DPRINT1("Error: %lu\n", Error);
-        RegCloseKey(hKey);
-        SetLastError((DWORD)Error);
-        return FALSE;
-    }
-
     /* Expand it */
     if (!ExpandEnvironmentStringsW(szBuffer,
                                    szProfilesPath,
@@ -177,20 +161,12 @@ InitializeProfiles(VOID)
         }
     }
 
-    /* Set 'DefaultUserProfile' value */
-    wcscpy(szBuffer, L"Default User");
-    if (!AppendSystemPostfix(szBuffer, MAX_PATH))
-    {
-        DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
-        RegCloseKey(hKey);
-        return FALSE;
-    }
-
+    /* Store the profiles directory path in the registry */
     dwLength = (wcslen (szBuffer) + 1) * sizeof(WCHAR);
     Error = RegSetValueExW(hKey,
-                           L"DefaultUserProfile",
+                           L"ProfilesDirectory",
                            0,
-                           REG_SZ,
+                           REG_EXPAND_SZ,
                            (LPBYTE)szBuffer,
                            dwLength);
     if (Error != ERROR_SUCCESS)
@@ -201,21 +177,67 @@ InitializeProfiles(VOID)
         return FALSE;
     }
 
-    RegCloseKey(hKey);
+    /* Set 'DefaultUserProfile' value */
+    wcscpy(szBuffer, L"Default User");
 
-    /* Create 'Default User' profile directory */
+    /* Create Default User profile directory path */
     wcscpy(szProfilePath, szProfilesPath);
     wcscat(szProfilePath, L"\\");
     wcscat(szProfilePath, szBuffer);
+
+    /* Attempt default user directory creation */
     if (!CreateDirectoryW (szProfilePath, NULL))
     {
         if (GetLastError() != ERROR_ALREADY_EXISTS)
         {
             DPRINT1("Error: %lu\n", GetLastError());
+            RegCloseKey(hKey);
             return FALSE;
         }
+
+        /* Directory existed, let's try to append the postfix */
+        if (!AppendSystemPostfix(szBuffer, MAX_PATH))
+        {
+            DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
+            RegCloseKey(hKey);
+            return FALSE;
+        }
+
+        /* Create Default User profile directory path again */
+        wcscpy(szProfilePath, szProfilesPath);
+        wcscat(szProfilePath, L"\\");
+        wcscat(szProfilePath, szBuffer);
+
+        /* Attempt creation again with appended postfix */
+        if (!CreateDirectoryW(szProfilePath, NULL))
+        {
+            if (GetLastError() != ERROR_ALREADY_EXISTS)
+            {
+                DPRINT1("Error: %lu\n", GetLastError());
+                RegCloseKey(hKey);
+                return FALSE;
+            }
+        }
     }
 
+    /* Store the default user profile path in the registry */
+    dwLength = (wcslen (szBuffer) + 1) * sizeof(WCHAR);
+    Error = RegSetValueExW(hKey,
+                           L"DefaultUserProfile",
+                           0,
+                           REG_SZ,
+                           (LPBYTE)szBuffer,
+                           dwLength);
+    if (Error != ERROR_SUCCESS)
+    {
+        DPRINT1("Error: %lu\n", Error);
+        RegCloseKey(hKey);
+        SetLastError((DWORD)Error);
+        return FALSE;
+    }
+
+    RegCloseKey(hKey);
+
     /* Set current user profile */
     SetEnvironmentVariableW(L"USERPROFILE", szProfilePath);
 
@@ -382,10 +404,41 @@ InitializeProfiles(VOID)
 
     /* Set 'AllUsersProfile' value */
     wcscpy(szBuffer, L"All Users");
-    if (!AppendSystemPostfix(szBuffer, MAX_PATH))
+
+    /* Create 'All Users' profile directory path */
+    wcscpy(szProfilePath, szProfilesPath);
+    wcscat(szProfilePath, L"\\");
+    wcscat(szProfilePath, szBuffer);
+
+    /* Attempt 'All Users' directory creation */
+    if (!CreateDirectoryW (szProfilePath, NULL))
     {
-        DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
-        return FALSE;
+        if (GetLastError() != ERROR_ALREADY_EXISTS)
+        {
+            DPRINT1("Error: %lu\n", GetLastError());
+            return FALSE;
+        }
+
+        /* Directory existed, let's try to append the postfix */
+        if (!AppendSystemPostfix(szBuffer, MAX_PATH))
+        {
+            DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
+            return FALSE;
+        }
+
+        /* Attempt again creation with appended postfix */
+        wcscpy(szProfilePath, szProfilesPath);
+        wcscat(szProfilePath, L"\\");
+        wcscat(szProfilePath, szBuffer);
+
+        if (!CreateDirectoryW(szProfilePath, NULL))
+        {
+            if (GetLastError() != ERROR_ALREADY_EXISTS)
+            {
+                DPRINT1("Error: %lu\n", GetLastError());
+                return FALSE;
+            }
+        }
     }
 
     Error = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
@@ -407,29 +460,16 @@ InitializeProfiles(VOID)
                            REG_SZ,
                            (LPBYTE)szBuffer,
                            dwLength);
+
+    RegCloseKey(hKey);
+
     if (Error != ERROR_SUCCESS)
     {
         DPRINT1("Error: %lu\n", Error);
-        RegCloseKey(hKey);
         SetLastError((DWORD)Error);
         return FALSE;
     }
 
-    RegCloseKey(hKey);
-
-    /* Create 'All Users' profile directory */
-    wcscpy(szProfilePath, szProfilesPath);
-    wcscat(szProfilePath, L"\\");
-    wcscat(szProfilePath, szBuffer);
-    if (!CreateDirectoryW(szProfilePath, NULL))
-    {
-        if (GetLastError() != ERROR_ALREADY_EXISTS)
-        {
-            DPRINT1("Error: %lu\n", GetLastError());
-            return FALSE;
-        }
-    }
-
     /* Set 'All Users' profile */
     SetEnvironmentVariableW(L"ALLUSERSPROFILE", szProfilePath);