From 51e6829b672e4a8f69a42f4b980b63fe5414ce6f Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Wed, 5 May 2010 22:30:14 +0000 Subject: [PATCH] [USERENV] - 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 | 60 +++++++----- reactos/dll/win32/userenv/setup.c | 146 ++++++++++++++++++---------- 2 files changed, 131 insertions(+), 75 deletions(-) diff --git a/reactos/dll/win32/userenv/profile.c b/reactos/dll/win32/userenv/profile.c index c2de4087c02..9e3f2b19114 100644 --- a/reactos/dll/win32/userenv/profile.c +++ b/reactos/dll/win32/userenv/profile.c @@ -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); diff --git a/reactos/dll/win32/userenv/setup.c b/reactos/dll/win32/userenv/setup.c index ca422dd5e9f..783d35621c9 100644 --- a/reactos/dll/win32/userenv/setup.c +++ b/reactos/dll/win32/userenv/setup.c @@ -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,15 +161,66 @@ InitializeProfiles(VOID) } } - /* Set 'DefaultUserProfile' value */ - wcscpy(szBuffer, L"Default User"); - if (!AppendSystemPostfix(szBuffer, MAX_PATH)) + /* Store the profiles directory path in the registry */ + dwLength = (wcslen (szBuffer) + 1) * sizeof(WCHAR); + Error = RegSetValueExW(hKey, + L"ProfilesDirectory", + 0, + REG_EXPAND_SZ, + (LPBYTE)szBuffer, + dwLength); + if (Error != ERROR_SUCCESS) { - DPRINT1("AppendSystemPostfix() failed\n", GetLastError()); + DPRINT1("Error: %lu\n", Error); RegCloseKey(hKey); + SetLastError((DWORD)Error); return FALSE; } + /* Set 'DefaultUserProfile' value */ + wcscpy(szBuffer, L"Default User"); + + /* 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", @@ -203,19 +238,6 @@ InitializeProfiles(VOID) RegCloseKey(hKey); - /* Create 'Default User' 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 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,27 +460,14 @@ InitializeProfiles(VOID) REG_SZ, (LPBYTE)szBuffer, dwLength); - 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 (Error != ERROR_SUCCESS) { - if (GetLastError() != ERROR_ALREADY_EXISTS) - { - DPRINT1("Error: %lu\n", GetLastError()); - return FALSE; - } + DPRINT1("Error: %lu\n", Error); + SetLastError((DWORD)Error); + return FALSE; } /* Set 'All Users' profile */