static HKEY GetCurrentUserKey(HANDLE hToken) { LONG Error; UNICODE_STRING SidString; HKEY hKey; if (!GetUserSidStringFromToken(hToken, &SidString)) { DPRINT1("GetUserSidFromToken() failed\n"); return NULL; } Error = RegOpenKeyExW(HKEY_USERS, SidString.Buffer, 0, MAXIMUM_ALLOWED, &hKey); if (Error != ERROR_SUCCESS) { DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error); RtlFreeUnicodeString(&SidString); SetLastError((DWORD)Error); return NULL; } RtlFreeUnicodeString(&SidString); return hKey; }
static BOOL CheckForLoadedProfile(HANDLE hToken) { UNICODE_STRING SidString; HKEY hKey; DPRINT("CheckForLoadedProfile() called\n"); if (!GetUserSidStringFromToken(hToken, &SidString)) { DPRINT1("GetUserSidFromToken() failed\n"); return FALSE; } if (RegOpenKeyExW(HKEY_USERS, SidString.Buffer, 0, MAXIMUM_ALLOWED, &hKey)) { DPRINT("Profile not loaded\n"); RtlFreeUnicodeString(&SidString); return FALSE; } RegCloseKey(hKey); RtlFreeUnicodeString(&SidString); DPRINT("Profile already loaded\n"); return TRUE; }
BOOL WINAPI UnloadUserProfile(HANDLE hToken, HANDLE hProfile) { UNICODE_STRING SidString; LONG Error; DPRINT("UnloadUserProfile() called\n"); if (hProfile == NULL) { DPRINT1("Invalid profile handle\n"); SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } RegCloseKey(hProfile); if (!GetUserSidStringFromToken(hToken, &SidString)) { DPRINT1("GetUserSidFromToken() failed\n"); return FALSE; } DPRINT("SidString: '%wZ'\n", &SidString); /* Acquire restore privilege */ if (!AcquireRemoveRestorePrivilege(TRUE)) { DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError()); RtlFreeUnicodeString(&SidString); return FALSE; } /* Unload the hive */ Error = RegUnLoadKeyW(HKEY_USERS, SidString.Buffer); /* Remove restore privilege */ AcquireRemoveRestorePrivilege(FALSE); if (Error != ERROR_SUCCESS) { DPRINT1("RegUnLoadKeyW() failed (Error %ld)\n", Error); RtlFreeUnicodeString(&SidString); SetLastError((DWORD)Error); return FALSE; } RtlFreeUnicodeString(&SidString); DPRINT("UnloadUserProfile() done\n"); return TRUE; }
BOOL WINAPI GetUserProfileDirectoryW(HANDLE hToken, LPWSTR lpProfileDir, LPDWORD lpcchSize) { UNICODE_STRING SidString; WCHAR szKeyName[MAX_PATH]; WCHAR szRawImagePath[MAX_PATH]; WCHAR szImagePath[MAX_PATH]; DWORD dwLength; HKEY hKey; LONG Error; if (!GetUserSidStringFromToken(hToken, &SidString)) { DPRINT1("GetUserSidFromToken() failed\n"); return FALSE; } DPRINT("SidString: '%wZ'\n", &SidString); wcscpy(szKeyName, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\"); wcscat(szKeyName, SidString.Buffer); RtlFreeUnicodeString(&SidString); DPRINT("KeyName: '%S'\n", szKeyName); Error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey); if (Error != ERROR_SUCCESS) { DPRINT1("Error: %lu\n", Error); SetLastError((DWORD)Error); return FALSE; } dwLength = sizeof(szRawImagePath); Error = RegQueryValueExW(hKey, L"ProfileImagePath", NULL, NULL, (LPBYTE)szRawImagePath, &dwLength); if (Error != ERROR_SUCCESS) { DPRINT1("Error: %lu\n", Error); RegCloseKey(hKey); SetLastError((DWORD)Error); return FALSE; } RegCloseKey(hKey); DPRINT("RawImagePath: '%S'\n", szRawImagePath); /* Expand it */ if (!ExpandEnvironmentStringsW(szRawImagePath, szImagePath, MAX_PATH)) { DPRINT1 ("Error: %lu\n", GetLastError()); return FALSE; } DPRINT("ImagePath: '%S'\n", szImagePath); dwLength = wcslen (szImagePath) + 1; if (*lpcchSize < dwLength) { *lpcchSize = dwLength; SetLastError(ERROR_INSUFFICIENT_BUFFER); return FALSE; } *lpcchSize = dwLength; wcscpy(lpProfileDir, szImagePath); return TRUE; }
BOOL WINAPI 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, 0, NULL }; 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 FALSE; } /* Don't load a profile twice */ if (CheckForLoadedProfile(hToken)) { DPRINT ("Profile already loaded\n"); lpProfileInfo->hProfile = NULL; return TRUE; } if (lpProfileInfo->lpProfilePath) { wcscpy(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 */ wcscat(szUserHivePath, L"\\"); wcscat(szUserHivePath, lpProfileInfo->lpUserName); 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 = GetUserSidStringFromToken(hToken, &SidString); if (!ret) { DPRINT1("GetUserSidFromToken() failed\n"); goto cleanup; } ret = FALSE; /* 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 */ 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; }