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++;
|
||||
}
|
||||
|
||||
if (wcslen(lpName) + wcslen(lpszPostfix) >= dwMaxLength)
|
||||
if (wcslen(lpName) + wcslen(lpszPostfix) + 1 >= dwMaxLength)
|
||||
{
|
||||
DPRINT1("Error: buffer overflow\n");
|
||||
SetLastError(ERROR_BUFFER_OVERFLOW);
|
||||
|
@ -825,23 +825,30 @@ LoadUserProfileA (HANDLE hToken,
|
|||
|
||||
|
||||
BOOL WINAPI
|
||||
LoadUserProfileW (HANDLE hToken,
|
||||
LPPROFILEINFOW lpProfileInfo)
|
||||
LoadUserProfileW(
|
||||
IN HANDLE hToken,
|
||||
IN OUT LPPROFILEINFOW lpProfileInfo)
|
||||
{
|
||||
WCHAR szUserHivePath[MAX_PATH];
|
||||
UNICODE_STRING SidString;
|
||||
LPWSTR UserName = NULL, Domain = NULL;
|
||||
DWORD UserNameLength = 0, DomainLength = 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");
|
||||
|
||||
/* Check profile info */
|
||||
if (lpProfileInfo->dwSize != sizeof(PROFILEINFOW) ||
|
||||
lpProfileInfo->lpUserName == NULL ||
|
||||
lpProfileInfo->lpUserName[0] == 0)
|
||||
if (!lpProfileInfo
|
||||
|| lpProfileInfo->dwSize != sizeof(PROFILEINFOW)
|
||||
|| lpProfileInfo->lpUserName == NULL
|
||||
|| lpProfileInfo->lpUserName[0] == 0)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Don't load a profile twice */
|
||||
|
@ -852,16 +859,16 @@ LoadUserProfileW (HANDLE hToken,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
if (!GetProfilesDirectoryW (szUserHivePath,
|
||||
&dwLength))
|
||||
if (!GetProfilesDirectoryW(szUserHivePath, &dwLength))
|
||||
{
|
||||
DPRINT1("GetProfilesDirectoryW() failed\n", GetLastError());
|
||||
DPRINT1("GetProfilesDirectoryW() failed (error %ld)\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
wcscat(szUserHivePath, L"\\");
|
||||
wcscat(szUserHivePath, lpProfileInfo->lpUserName);
|
||||
if (!AppendSystemPostfix (szUserHivePath, MAX_PATH))
|
||||
dwLength = sizeof(szUserHivePath) / sizeof(szUserHivePath[0]);
|
||||
if (!AppendSystemPostfix(szUserHivePath, dwLength))
|
||||
{
|
||||
DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
|
||||
return FALSE;
|
||||
|
@ -869,29 +876,101 @@ LoadUserProfileW (HANDLE hToken,
|
|||
|
||||
/* Create user hive name */
|
||||
wcscat(szUserHivePath, L"\\ntuser.dat");
|
||||
|
||||
DPRINT("szUserHivePath: %S\n", szUserHivePath);
|
||||
|
||||
if (!GetUserSidFromToken (hToken,
|
||||
&SidString))
|
||||
/* Create user profile directory if needed */
|
||||
if (GetFileAttributesW(szUserHivePath) == INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
DPRINT1 ("GetUserSidFromToken() failed\n");
|
||||
/* 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;
|
||||
}
|
||||
|
||||
DPRINT ("SidString: '%wZ'\n", &SidString);
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get user SID string */
|
||||
ret = GetUserSidFromToken(hToken, &SidString);
|
||||
if (!ret)
|
||||
{
|
||||
DPRINT1("GetUserSidFromToken() failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
ret = FALSE;
|
||||
|
||||
/* Load user registry hive */
|
||||
Error = RegLoadKeyW(HKEY_USERS,
|
||||
SidString.Buffer,
|
||||
szUserHivePath);
|
||||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("RegLoadKeyW() failed (Error %ld)\n", Error);
|
||||
RtlFreeUnicodeString (&SidString);
|
||||
SetLastError((DWORD)Error);
|
||||
return FALSE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Open future HKEY_CURRENT_USER */
|
||||
Error = RegOpenKeyExW(HKEY_USERS,
|
||||
SidString.Buffer,
|
||||
0,
|
||||
|
@ -900,16 +979,20 @@ LoadUserProfileW (HANDLE hToken,
|
|||
if (Error != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error);
|
||||
RtlFreeUnicodeString (&SidString);
|
||||
SetLastError((DWORD)Error);
|
||||
return FALSE;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
cleanup:
|
||||
HeapFree(GetProcessHeap(), 0, UserSid);
|
||||
HeapFree(GetProcessHeap(), 0, UserName);
|
||||
HeapFree(GetProcessHeap(), 0, Domain);
|
||||
RtlFreeUnicodeString(&SidString);
|
||||
|
||||
DPRINT("LoadUserProfileW() done\n");
|
||||
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue