mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
Improve LoadUserProfileW, by creating the profile if it doesn't exist
svn path=/trunk/; revision=28241
This commit is contained in:
parent
32789f3a9e
commit
6d37743cf2
1 changed files with 142 additions and 59 deletions
|
@ -63,7 +63,7 @@ AppendSystemPostfix (LPWSTR lpName,
|
||||||
lpszPtr++;
|
lpszPtr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wcslen(lpName) + wcslen(lpszPostfix) >= dwMaxLength)
|
if (wcslen(lpName) + wcslen(lpszPostfix) + 1 >= dwMaxLength)
|
||||||
{
|
{
|
||||||
DPRINT1("Error: buffer overflow\n");
|
DPRINT1("Error: buffer overflow\n");
|
||||||
SetLastError(ERROR_BUFFER_OVERFLOW);
|
SetLastError(ERROR_BUFFER_OVERFLOW);
|
||||||
|
@ -825,91 +825,174 @@ LoadUserProfileA (HANDLE hToken,
|
||||||
|
|
||||||
|
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
LoadUserProfileW (HANDLE hToken,
|
LoadUserProfileW(
|
||||||
LPPROFILEINFOW lpProfileInfo)
|
IN HANDLE hToken,
|
||||||
|
IN OUT LPPROFILEINFOW lpProfileInfo)
|
||||||
{
|
{
|
||||||
WCHAR szUserHivePath[MAX_PATH];
|
WCHAR szUserHivePath[MAX_PATH];
|
||||||
UNICODE_STRING SidString;
|
LPWSTR UserName = NULL, Domain = NULL;
|
||||||
LONG Error;
|
DWORD UserNameLength = 0, DomainLength = 0;
|
||||||
DWORD dwLength = sizeof(szUserHivePath) / sizeof(szUserHivePath[0]);
|
PTOKEN_USER UserSid = NULL;
|
||||||
|
SID_NAME_USE AccountType;
|
||||||
|
UNICODE_STRING SidString = { 0, };
|
||||||
|
LONG Error;
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
DWORD dwLength = sizeof(szUserHivePath) / sizeof(szUserHivePath[0]);
|
||||||
|
|
||||||
DPRINT ("LoadUserProfileW() called\n");
|
DPRINT("LoadUserProfileW() called\n");
|
||||||
|
|
||||||
/* Check profile info */
|
/* Check profile info */
|
||||||
if (lpProfileInfo->dwSize != sizeof(PROFILEINFOW) ||
|
if (!lpProfileInfo
|
||||||
lpProfileInfo->lpUserName == NULL ||
|
|| lpProfileInfo->dwSize != sizeof(PROFILEINFOW)
|
||||||
lpProfileInfo->lpUserName[0] == 0)
|
|| lpProfileInfo->lpUserName == NULL
|
||||||
|
|| lpProfileInfo->lpUserName[0] == 0)
|
||||||
{
|
{
|
||||||
SetLastError (ERROR_INVALID_PARAMETER);
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't load a profile twice */
|
/* Don't load a profile twice */
|
||||||
if (CheckForLoadedProfile (hToken))
|
if (CheckForLoadedProfile(hToken))
|
||||||
{
|
{
|
||||||
DPRINT ("Profile already loaded\n");
|
DPRINT ("Profile already loaded\n");
|
||||||
lpProfileInfo->hProfile = NULL;
|
lpProfileInfo->hProfile = NULL;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GetProfilesDirectoryW (szUserHivePath,
|
if (!GetProfilesDirectoryW(szUserHivePath, &dwLength))
|
||||||
&dwLength))
|
|
||||||
{
|
{
|
||||||
DPRINT1("GetProfilesDirectoryW() failed\n", GetLastError());
|
DPRINT1("GetProfilesDirectoryW() failed (error %ld)\n", GetLastError());
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
wcscat (szUserHivePath, L"\\");
|
wcscat(szUserHivePath, L"\\");
|
||||||
wcscat (szUserHivePath, lpProfileInfo->lpUserName);
|
wcscat(szUserHivePath, lpProfileInfo->lpUserName);
|
||||||
if (!AppendSystemPostfix (szUserHivePath, MAX_PATH))
|
dwLength = sizeof(szUserHivePath) / sizeof(szUserHivePath[0]);
|
||||||
|
if (!AppendSystemPostfix(szUserHivePath, dwLength))
|
||||||
{
|
{
|
||||||
DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
|
DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create user hive name */
|
/* Create user hive name */
|
||||||
wcscat (szUserHivePath, L"\\ntuser.dat");
|
wcscat(szUserHivePath, L"\\ntuser.dat");
|
||||||
|
DPRINT("szUserHivePath: %S\n", szUserHivePath);
|
||||||
|
|
||||||
DPRINT ("szUserHivePath: %S\n", szUserHivePath);
|
/* Create user profile directory if needed */
|
||||||
|
if (GetFileAttributesW(szUserHivePath) == INVALID_FILE_ATTRIBUTES)
|
||||||
if (!GetUserSidFromToken (hToken,
|
|
||||||
&SidString))
|
|
||||||
{
|
{
|
||||||
DPRINT1 ("GetUserSidFromToken() failed\n");
|
/* Get user sid */
|
||||||
return FALSE;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get user name */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (UserNameLength > 0)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, UserName);
|
||||||
|
UserName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, UserNameLength * sizeof(WCHAR));
|
||||||
|
if (!UserName)
|
||||||
|
{
|
||||||
|
DPRINT1("HeapAlloc() failed\n");
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (DomainLength > 0)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, Domain);
|
||||||
|
Domain = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, DomainLength * sizeof(WCHAR));
|
||||||
|
if (!Domain)
|
||||||
|
{
|
||||||
|
DPRINT1("HeapAlloc() failed\n");
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = LookupAccountSidW(
|
||||||
|
NULL, UserSid->User.Sid,
|
||||||
|
UserName, &UserNameLength,
|
||||||
|
Domain, &DomainLength,
|
||||||
|
&AccountType);
|
||||||
|
} while (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
DPRINT1("LookupAccountSidW() failed\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create profile */
|
||||||
|
/* FIXME: ignore Domain? */
|
||||||
|
DPRINT("UserName %S, Domain %S\n", UserName, Domain);
|
||||||
|
ret = CreateUserProfileW(UserSid->User.Sid, UserName);
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
DPRINT1("CreateUserProfileW() failed\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT ("SidString: '%wZ'\n", &SidString);
|
/* Get user SID string */
|
||||||
|
ret = GetUserSidFromToken(hToken, &SidString);
|
||||||
Error = RegLoadKeyW (HKEY_USERS,
|
if (!ret)
|
||||||
SidString.Buffer,
|
|
||||||
szUserHivePath);
|
|
||||||
if (Error != ERROR_SUCCESS)
|
|
||||||
{
|
{
|
||||||
DPRINT1 ("RegLoadKeyW() failed (Error %ld)\n", Error);
|
DPRINT1("GetUserSidFromToken() failed\n");
|
||||||
RtlFreeUnicodeString (&SidString);
|
goto cleanup;
|
||||||
SetLastError((DWORD)Error);
|
}
|
||||||
return FALSE;
|
ret = FALSE;
|
||||||
|
|
||||||
|
/* Load user registry hive */
|
||||||
|
Error = RegLoadKeyW(HKEY_USERS,
|
||||||
|
SidString.Buffer,
|
||||||
|
szUserHivePath);
|
||||||
|
if (Error != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
DPRINT1("RegLoadKeyW() failed (Error %ld)\n", Error);
|
||||||
|
SetLastError((DWORD)Error);
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error = RegOpenKeyExW (HKEY_USERS,
|
/* Open future HKEY_CURRENT_USER */
|
||||||
SidString.Buffer,
|
Error = RegOpenKeyExW(HKEY_USERS,
|
||||||
0,
|
SidString.Buffer,
|
||||||
MAXIMUM_ALLOWED,
|
0,
|
||||||
(PHKEY)&lpProfileInfo->hProfile);
|
MAXIMUM_ALLOWED,
|
||||||
if (Error != ERROR_SUCCESS)
|
(PHKEY)&lpProfileInfo->hProfile);
|
||||||
|
if (Error != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", Error);
|
DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error);
|
||||||
RtlFreeUnicodeString (&SidString);
|
SetLastError((DWORD)Error);
|
||||||
SetLastError((DWORD)Error);
|
goto cleanup;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlFreeUnicodeString (&SidString);
|
ret = TRUE;
|
||||||
|
|
||||||
DPRINT ("LoadUserProfileW() done\n");
|
cleanup:
|
||||||
|
HeapFree(GetProcessHeap(), 0, UserSid);
|
||||||
|
HeapFree(GetProcessHeap(), 0, UserName);
|
||||||
|
HeapFree(GetProcessHeap(), 0, Domain);
|
||||||
|
RtlFreeUnicodeString(&SidString);
|
||||||
|
|
||||||
return TRUE;
|
DPRINT("LoadUserProfileW() done\n");
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue