mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 08:55:19 +00:00
[USERENV] Use a mutex to serialize profile loading and unloading.
This commit is contained in:
parent
332ca5f572
commit
05886b83e9
1 changed files with 102 additions and 8 deletions
|
@ -143,6 +143,60 @@ CheckForLoadedProfile(HANDLE hToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
HANDLE
|
||||||
|
CreateProfileMutex(
|
||||||
|
_In_ PWSTR pszSidString)
|
||||||
|
{
|
||||||
|
SECURITY_DESCRIPTOR SecurityDescriptor;
|
||||||
|
SECURITY_ATTRIBUTES SecurityAttributes;
|
||||||
|
PWSTR pszMutexName = NULL;
|
||||||
|
HANDLE hMutex = NULL;
|
||||||
|
|
||||||
|
pszMutexName = HeapAlloc(GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
(wcslen(L"Global\\userenv: User Profile Mutex for ") + wcslen(pszSidString) + 1) * sizeof(WCHAR));
|
||||||
|
if (pszMutexName == NULL)
|
||||||
|
{
|
||||||
|
DPRINT("Failed to allocate the mutex name buffer!\n");
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build the profile mutex name */
|
||||||
|
wcscpy(pszMutexName, L"Global\\userenv: User Profile Mutex for ");
|
||||||
|
wcscat(pszMutexName, pszSidString);
|
||||||
|
|
||||||
|
/* Initialize the security descriptor */
|
||||||
|
InitializeSecurityDescriptor(&SecurityDescriptor,
|
||||||
|
SECURITY_DESCRIPTOR_REVISION);
|
||||||
|
|
||||||
|
/* Set a NULL-DACL (everyone has access) */
|
||||||
|
SetSecurityDescriptorDacl(&SecurityDescriptor,
|
||||||
|
TRUE,
|
||||||
|
NULL,
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
/* Initialize the security attributes */
|
||||||
|
SecurityAttributes.nLength = sizeof(SecurityAttributes);
|
||||||
|
SecurityAttributes.lpSecurityDescriptor = &SecurityDescriptor;
|
||||||
|
SecurityAttributes.bInheritHandle = FALSE;
|
||||||
|
|
||||||
|
/* Create the profile mutex */
|
||||||
|
hMutex = CreateMutexW(&SecurityAttributes,
|
||||||
|
FALSE,
|
||||||
|
pszMutexName);
|
||||||
|
if (hMutex == NULL)
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to create the profile mutex (Error %lu)\n", GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, pszMutexName);
|
||||||
|
|
||||||
|
return hMutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS ********************************************************/
|
/* PUBLIC FUNCTIONS ********************************************************/
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -1420,6 +1474,7 @@ LoadUserProfileW(
|
||||||
WCHAR szUserHivePath[MAX_PATH];
|
WCHAR szUserHivePath[MAX_PATH];
|
||||||
PTOKEN_USER UserSid = NULL;
|
PTOKEN_USER UserSid = NULL;
|
||||||
UNICODE_STRING SidString = { 0, 0, NULL };
|
UNICODE_STRING SidString = { 0, 0, NULL };
|
||||||
|
HANDLE hProfileMutex = NULL;
|
||||||
LONG Error;
|
LONG Error;
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
DWORD dwLength = sizeof(szUserHivePath) / sizeof(szUserHivePath[0]);
|
DWORD dwLength = sizeof(szUserHivePath) / sizeof(szUserHivePath[0]);
|
||||||
|
@ -1445,6 +1500,17 @@ LoadUserProfileW(
|
||||||
}
|
}
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
|
|
||||||
|
/* Create the profile mutex */
|
||||||
|
hProfileMutex = CreateProfileMutex(SidString.Buffer);
|
||||||
|
if (hProfileMutex == NULL)
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to create the profile mutex\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for the profile mutex */
|
||||||
|
WaitForSingleObject(hProfileMutex, INFINITE);
|
||||||
|
|
||||||
/* Don't load a profile twice */
|
/* Don't load a profile twice */
|
||||||
if (CheckForLoadedProfile(hToken))
|
if (CheckForLoadedProfile(hToken))
|
||||||
{
|
{
|
||||||
|
@ -1552,6 +1618,13 @@ LoadUserProfileW(
|
||||||
cleanup:
|
cleanup:
|
||||||
if (UserSid != NULL)
|
if (UserSid != NULL)
|
||||||
HeapFree(GetProcessHeap(), 0, UserSid);
|
HeapFree(GetProcessHeap(), 0, UserSid);
|
||||||
|
|
||||||
|
if (hProfileMutex != NULL)
|
||||||
|
{
|
||||||
|
ReleaseMutex(hProfileMutex);
|
||||||
|
CloseHandle(hProfileMutex);
|
||||||
|
}
|
||||||
|
|
||||||
RtlFreeUnicodeString(&SidString);
|
RtlFreeUnicodeString(&SidString);
|
||||||
|
|
||||||
DPRINT("LoadUserProfileW() done\n");
|
DPRINT("LoadUserProfileW() done\n");
|
||||||
|
@ -1565,8 +1638,10 @@ UnloadUserProfile(
|
||||||
_In_ HANDLE hToken,
|
_In_ HANDLE hToken,
|
||||||
_In_ HANDLE hProfile)
|
_In_ HANDLE hProfile)
|
||||||
{
|
{
|
||||||
UNICODE_STRING SidString;
|
UNICODE_STRING SidString = {0, 0, NULL};
|
||||||
|
HANDLE hProfileMutex = NULL;
|
||||||
LONG Error;
|
LONG Error;
|
||||||
|
BOOL bRet = FALSE;
|
||||||
|
|
||||||
DPRINT("UnloadUserProfile() called\n");
|
DPRINT("UnloadUserProfile() called\n");
|
||||||
|
|
||||||
|
@ -1577,8 +1652,6 @@ UnloadUserProfile(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
RegCloseKey(hProfile);
|
|
||||||
|
|
||||||
/* Get the user SID string */
|
/* Get the user SID string */
|
||||||
if (!GetUserSidStringFromToken(hToken, &SidString))
|
if (!GetUserSidStringFromToken(hToken, &SidString))
|
||||||
{
|
{
|
||||||
|
@ -1588,12 +1661,25 @@ UnloadUserProfile(
|
||||||
|
|
||||||
DPRINT("SidString: '%wZ'\n", &SidString);
|
DPRINT("SidString: '%wZ'\n", &SidString);
|
||||||
|
|
||||||
|
/* Create the profile mutex */
|
||||||
|
hProfileMutex = CreateProfileMutex(SidString.Buffer);
|
||||||
|
if (hProfileMutex == NULL)
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to create the profile mutex\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for the profile mutex */
|
||||||
|
WaitForSingleObject(hProfileMutex, INFINITE);
|
||||||
|
|
||||||
|
/* Close the profile handle */
|
||||||
|
RegCloseKey(hProfile);
|
||||||
|
|
||||||
/* Acquire restore privilege */
|
/* Acquire restore privilege */
|
||||||
if (!AcquireRemoveRestorePrivilege(TRUE))
|
if (!AcquireRemoveRestorePrivilege(TRUE))
|
||||||
{
|
{
|
||||||
DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
|
DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
|
||||||
RtlFreeUnicodeString(&SidString);
|
goto cleanup;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* HACK */
|
/* HACK */
|
||||||
|
@ -1625,16 +1711,24 @@ UnloadUserProfile(
|
||||||
if (Error != ERROR_SUCCESS)
|
if (Error != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
DPRINT1("RegUnLoadKeyW() failed (Error %ld)\n", Error);
|
DPRINT1("RegUnLoadKeyW() failed (Error %ld)\n", Error);
|
||||||
RtlFreeUnicodeString(&SidString);
|
|
||||||
SetLastError((DWORD)Error);
|
SetLastError((DWORD)Error);
|
||||||
return FALSE;
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
bRet = TRUE;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (hProfileMutex != NULL)
|
||||||
|
{
|
||||||
|
ReleaseMutex(hProfileMutex);
|
||||||
|
CloseHandle(hProfileMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlFreeUnicodeString(&SidString);
|
RtlFreeUnicodeString(&SidString);
|
||||||
|
|
||||||
DPRINT("UnloadUserProfile() done\n");
|
DPRINT("UnloadUserProfile() done\n");
|
||||||
|
|
||||||
return TRUE;
|
return bRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue