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.…
==============================================================================
--- 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)