mirror of
https://github.com/reactos/reactos.git
synced 2025-04-27 17:10:22 +00:00
[USERENV] LoadUserProfileW: If a user profile has already been loaded, just open and return the profile key.
This commit is contained in:
parent
ee62837ec0
commit
30c501fc9f
1 changed files with 86 additions and 83 deletions
|
@ -1436,69 +1436,6 @@ LoadUserProfileW(
|
||||||
|
|
||||||
DPRINT("UserName: %S\n", lpProfileInfo->lpUserName);
|
DPRINT("UserName: %S\n", lpProfileInfo->lpUserName);
|
||||||
|
|
||||||
/* Don't load a profile twice */
|
|
||||||
if (CheckForLoadedProfile(hToken))
|
|
||||||
{
|
|
||||||
DPRINT ("Profile already loaded\n");
|
|
||||||
lpProfileInfo->hProfile = NULL;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lpProfileInfo->lpProfilePath)
|
|
||||||
{
|
|
||||||
/* Use the caller's specified roaming user profile path */
|
|
||||||
StringCbCopyW(szUserHivePath, sizeof(szUserHivePath), lpProfileInfo->lpProfilePath);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* FIXME: check if MS Windows allows lpProfileInfo->lpProfilePath to be NULL */
|
|
||||||
if (!GetProfilesDirectoryW(szUserHivePath, &dwLength))
|
|
||||||
{
|
|
||||||
DPRINT1("GetProfilesDirectoryW() failed (error %ld)\n", GetLastError());
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create user hive name */
|
|
||||||
StringCbCatW(szUserHivePath, sizeof(szUserHivePath), L"\\");
|
|
||||||
StringCbCatW(szUserHivePath, sizeof(szUserHivePath), lpProfileInfo->lpUserName);
|
|
||||||
StringCbCatW(szUserHivePath, sizeof(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create profile */
|
|
||||||
ret = CreateUserProfileW(UserSid->User.Sid, lpProfileInfo->lpUserName);
|
|
||||||
if (!ret)
|
|
||||||
{
|
|
||||||
DPRINT1("CreateUserProfileW() failed\n");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the user SID string */
|
/* Get the user SID string */
|
||||||
ret = GetUserSidStringFromToken(hToken, &SidString);
|
ret = GetUserSidStringFromToken(hToken, &SidString);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
|
@ -1508,28 +1445,93 @@ LoadUserProfileW(
|
||||||
}
|
}
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
|
|
||||||
/* Acquire restore privilege */
|
/* Don't load a profile twice */
|
||||||
if (!AcquireRemoveRestorePrivilege(TRUE))
|
if (CheckForLoadedProfile(hToken))
|
||||||
{
|
{
|
||||||
DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
|
DPRINT1("Profile %S already loaded\n", SidString.Buffer);
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* Load user registry hive */
|
|
||||||
Error = RegLoadKeyW(HKEY_USERS,
|
|
||||||
SidString.Buffer,
|
|
||||||
szUserHivePath);
|
|
||||||
AcquireRemoveRestorePrivilege(FALSE);
|
|
||||||
|
|
||||||
/* HACK: Do not fail if the profile has already been loaded! */
|
|
||||||
if (Error == ERROR_SHARING_VIOLATION)
|
|
||||||
Error = ERROR_SUCCESS;
|
|
||||||
|
|
||||||
if (Error != ERROR_SUCCESS)
|
|
||||||
{
|
{
|
||||||
DPRINT1("RegLoadKeyW() failed (Error %ld)\n", Error);
|
DPRINT1("Loading profile %S\n", SidString.Buffer);
|
||||||
SetLastError((DWORD)Error);
|
|
||||||
goto cleanup;
|
if (lpProfileInfo->lpProfilePath)
|
||||||
|
{
|
||||||
|
/* Use the caller's specified roaming user profile path */
|
||||||
|
StringCbCopyW(szUserHivePath, sizeof(szUserHivePath), lpProfileInfo->lpProfilePath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* FIXME: check if MS Windows allows lpProfileInfo->lpProfilePath to be NULL */
|
||||||
|
if (!GetProfilesDirectoryW(szUserHivePath, &dwLength))
|
||||||
|
{
|
||||||
|
DPRINT1("GetProfilesDirectoryW() failed (error %ld)\n", GetLastError());
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create user hive name */
|
||||||
|
StringCbCatW(szUserHivePath, sizeof(szUserHivePath), L"\\");
|
||||||
|
StringCbCatW(szUserHivePath, sizeof(szUserHivePath), lpProfileInfo->lpUserName);
|
||||||
|
StringCbCatW(szUserHivePath, sizeof(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");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create profile */
|
||||||
|
ret = CreateUserProfileW(UserSid->User.Sid, lpProfileInfo->lpUserName);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
DPRINT1("CreateUserProfileW() failed\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Acquire restore privilege */
|
||||||
|
if (!AcquireRemoveRestorePrivilege(TRUE))
|
||||||
|
{
|
||||||
|
DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load user registry hive */
|
||||||
|
Error = RegLoadKeyW(HKEY_USERS,
|
||||||
|
SidString.Buffer,
|
||||||
|
szUserHivePath);
|
||||||
|
AcquireRemoveRestorePrivilege(FALSE);
|
||||||
|
|
||||||
|
/* HACK: Do not fail if the profile has already been loaded! */
|
||||||
|
if (Error == ERROR_SHARING_VIOLATION)
|
||||||
|
Error = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
if (Error != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
DPRINT1("RegLoadKeyW() failed (Error %ld)\n", Error);
|
||||||
|
SetLastError((DWORD)Error);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open future HKEY_CURRENT_USER */
|
/* Open future HKEY_CURRENT_USER */
|
||||||
|
@ -1548,7 +1550,8 @@ LoadUserProfileW(
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
HeapFree(GetProcessHeap(), 0, UserSid);
|
if (UserSid != NULL)
|
||||||
|
HeapFree(GetProcessHeap(), 0, UserSid);
|
||||||
RtlFreeUnicodeString(&SidString);
|
RtlFreeUnicodeString(&SidString);
|
||||||
|
|
||||||
DPRINT("LoadUserProfileW() done\n");
|
DPRINT("LoadUserProfileW() done\n");
|
||||||
|
|
Loading…
Reference in a new issue