[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
This commit is contained in:
Eric Kohl 2010-05-05 22:30:14 +00:00
parent 751c365e6e
commit 51e6829b67
2 changed files with 131 additions and 75 deletions

View 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);

View 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,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 */