Author: hpoussin Date: Wed Aug 8 12:26:44 2007 New Revision: 28241
URL: http://svn.reactos.org/svn/reactos?rev=28241&view=rev Log: Improve LoadUserProfileW, by creating the profile if it doesn't exist
Modified: trunk/reactos/dll/win32/userenv/profile.c
Modified: trunk/reactos/dll/win32/userenv/profile.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/userenv/profile.c... ============================================================================== --- trunk/reactos/dll/win32/userenv/profile.c (original) +++ trunk/reactos/dll/win32/userenv/profile.c Wed Aug 8 12:26:44 2007 @@ -63,7 +63,7 @@ lpszPtr++; }
- if (wcslen(lpName) + wcslen(lpszPostfix) >= dwMaxLength) + if (wcslen(lpName) + wcslen(lpszPostfix) + 1 >= dwMaxLength) { DPRINT1("Error: buffer overflow\n"); SetLastError(ERROR_BUFFER_OVERFLOW); @@ -825,52 +825,194 @@
BOOL WINAPI -LoadUserProfileW (HANDLE hToken, - LPPROFILEINFOW lpProfileInfo) -{ - WCHAR szUserHivePath[MAX_PATH]; +LoadUserProfileW( + IN HANDLE hToken, + IN OUT LPPROFILEINFOW lpProfileInfo) +{ + WCHAR szUserHivePath[MAX_PATH]; + 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 + || lpProfileInfo->dwSize != sizeof(PROFILEINFOW) + || lpProfileInfo->lpUserName == NULL + || lpProfileInfo->lpUserName[0] == 0) + { + SetLastError(ERROR_INVALID_PARAMETER); + return TRUE; + } + + /* Don't load a profile twice */ + if (CheckForLoadedProfile(hToken)) + { + DPRINT ("Profile already loaded\n"); + lpProfileInfo->hProfile = NULL; + return TRUE; + } + + if (!GetProfilesDirectoryW(szUserHivePath, &dwLength)) + { + DPRINT1("GetProfilesDirectoryW() failed (error %ld)\n", GetLastError()); + return FALSE; + } + + 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); + + /* 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; + } + + /* 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); + SetLastError((DWORD)Error); + goto cleanup; + } + + /* Open future HKEY_CURRENT_USER */ + Error = RegOpenKeyExW(HKEY_USERS, + SidString.Buffer, + 0, + MAXIMUM_ALLOWED, + (PHKEY)&lpProfileInfo->hProfile); + if (Error != ERROR_SUCCESS) + { + DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error); + SetLastError((DWORD)Error); + goto cleanup; + } + + ret = TRUE; + +cleanup: + HeapFree(GetProcessHeap(), 0, UserSid); + HeapFree(GetProcessHeap(), 0, UserName); + HeapFree(GetProcessHeap(), 0, Domain); + RtlFreeUnicodeString(&SidString); + + DPRINT("LoadUserProfileW() done\n"); + return ret; +} + + +BOOL WINAPI +UnloadUserProfile (HANDLE hToken, + HANDLE hProfile) +{ UNICODE_STRING SidString; LONG Error; - 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) - { + + DPRINT ("UnloadUserProfile() called\n"); + + if (hProfile == NULL) + { + DPRINT1 ("Invalide profile handle\n"); SetLastError (ERROR_INVALID_PARAMETER); return FALSE; }
- /* Don't load a profile twice */ - if (CheckForLoadedProfile (hToken)) - { - DPRINT ("Profile already loaded\n"); - lpProfileInfo->hProfile = NULL; - return TRUE; - } - - if (!GetProfilesDirectoryW (szUserHivePath, - &dwLength)) - { - DPRINT1("GetProfilesDirectoryW() failed\n", GetLastError()); - return FALSE; - } - - wcscat (szUserHivePath, L"\"); - wcscat (szUserHivePath, lpProfileInfo->lpUserName); - if (!AppendSystemPostfix (szUserHivePath, MAX_PATH)) - { - DPRINT1("AppendSystemPostfix() failed\n", GetLastError()); - return FALSE; - } - - /* Create user hive name */ - wcscat (szUserHivePath, L"\ntuser.dat"); - - DPRINT ("szUserHivePath: %S\n", szUserHivePath); + RegCloseKey (hProfile);
if (!GetUserSidFromToken (hToken, &SidString)) @@ -881,65 +1023,6 @@
DPRINT ("SidString: '%wZ'\n", &SidString);
- 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; - } - - Error = RegOpenKeyExW (HKEY_USERS, - SidString.Buffer, - 0, - MAXIMUM_ALLOWED, - (PHKEY)&lpProfileInfo->hProfile); - if (Error != ERROR_SUCCESS) - { - DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", Error); - RtlFreeUnicodeString (&SidString); - SetLastError((DWORD)Error); - return FALSE; - } - - RtlFreeUnicodeString (&SidString); - - DPRINT ("LoadUserProfileW() done\n"); - - return TRUE; -} - - -BOOL WINAPI -UnloadUserProfile (HANDLE hToken, - HANDLE hProfile) -{ - UNICODE_STRING SidString; - LONG Error; - - DPRINT ("UnloadUserProfile() called\n"); - - if (hProfile == NULL) - { - DPRINT1 ("Invalide profile handle\n"); - SetLastError (ERROR_INVALID_PARAMETER); - return FALSE; - } - - RegCloseKey (hProfile); - - if (!GetUserSidFromToken (hToken, - &SidString)) - { - DPRINT1 ("GetUserSidFromToken() failed\n"); - return FALSE; - } - - DPRINT ("SidString: '%wZ'\n", &SidString); - Error = RegUnLoadKeyW (HKEY_USERS, SidString.Buffer); if (Error != ERROR_SUCCESS)