2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/userenv/profile.c
5 * PURPOSE: User profile code
6 * PROGRAMMERS: Eric Kohl
17 /* FUNCTIONS ***************************************************************/
20 AppendSystemPostfix(LPWSTR lpName
,
23 WCHAR szSystemRoot
[MAX_PATH
];
27 /* Build profile name postfix */
28 if (!ExpandEnvironmentStringsW(L
"%SystemRoot%",
30 ARRAYSIZE(szSystemRoot
)))
32 DPRINT1("Error: %lu\n", GetLastError());
36 _wcsupr(szSystemRoot
);
38 /* Get name postfix */
39 szSystemRoot
[2] = L
'.';
40 lpszPostfix
= &szSystemRoot
[2];
41 lpszPtr
= lpszPostfix
;
42 while (*lpszPtr
!= (WCHAR
)0)
44 if (*lpszPtr
== L
'\\')
49 if (wcslen(lpName
) + wcslen(lpszPostfix
) + 1 >= dwMaxLength
)
51 DPRINT1("Error: buffer overflow\n");
52 SetLastError(ERROR_BUFFER_OVERFLOW
);
56 wcscat(lpName
, lpszPostfix
);
64 AcquireRemoveRestorePrivilege(IN BOOL bAcquire
)
68 TOKEN_PRIVILEGES TokenPriv
;
70 DPRINT("AcquireRemoveRestorePrivilege(%d)\n", bAcquire
);
72 if (OpenProcessToken(GetCurrentProcess(),
73 TOKEN_ADJUST_PRIVILEGES
,
76 TokenPriv
.PrivilegeCount
= 1;
77 TokenPriv
.Privileges
[0].Attributes
= (bAcquire
? SE_PRIVILEGE_ENABLED
: 0);
79 if (LookupPrivilegeValue(NULL
, SE_RESTORE_NAME
, &TokenPriv
.Privileges
[0].Luid
))
81 bRet
= AdjustTokenPrivileges(Token
, FALSE
, &TokenPriv
, 0, NULL
, NULL
);
85 DPRINT1("AdjustTokenPrivileges() failed with error %lu\n", GetLastError());
87 else if (GetLastError() == ERROR_NOT_ALL_ASSIGNED
)
89 DPRINT1("AdjustTokenPrivileges() succeeded, but with not all privileges assigned\n");
95 DPRINT1("LookupPrivilegeValue() failed with error %lu\n", GetLastError());
102 DPRINT1("OpenProcessToken() failed with error %lu\n", GetLastError());
113 _In_ LPCSTR lpUserName
)
115 LPWSTR pUserNameW
= NULL
;
119 DPRINT("CreateUserProfileA(%p %s)\n", pSid
, lpUserName
);
121 /* Convert lpUserName to Unicode */
122 nLength
= MultiByteToWideChar(CP_ACP
, 0, lpUserName
, -1, NULL
, 0);
123 pUserNameW
= HeapAlloc(GetProcessHeap(), 0, nLength
* sizeof(WCHAR
));
124 if (pUserNameW
== NULL
)
126 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
129 MultiByteToWideChar(CP_ACP
, 0, lpUserName
, -1, pUserNameW
, nLength
);
131 /* Call the Ex function */
132 bResult
= CreateUserProfileExW(pSid
,
139 HeapFree(GetProcessHeap(), 0, pUserNameW
);
149 _In_ LPCWSTR lpUserName
)
151 DPRINT("CreateUserProfileW(%p %S)\n", pSid
, lpUserName
);
153 /* Call the Ex function */
154 return CreateUserProfileExW(pSid
,
165 CreateUserProfileExA(
167 _In_ LPCSTR lpUserName
,
168 _In_opt_ LPCSTR lpUserHive
,
169 _Out_opt_ LPSTR lpProfileDir
,
170 _In_ DWORD dwDirSize
,
173 LPWSTR pUserNameW
= NULL
;
174 LPWSTR pUserHiveW
= NULL
;
175 LPWSTR pProfileDirW
= NULL
;
177 BOOL bResult
= FALSE
;
179 DPRINT("CreateUserProfileExA(%p %s %s %p %lu %d)\n",
180 pSid
, lpUserName
, lpUserHive
, lpProfileDir
, dwDirSize
, bWin9xUpg
);
182 /* Check the parameters */
183 if (lpProfileDir
!= NULL
&& dwDirSize
== 0)
185 SetLastError(ERROR_INVALID_PARAMETER
);
189 /* Convert lpUserName to Unicode */
190 nLength
= MultiByteToWideChar(CP_ACP
, 0, lpUserName
, -1, NULL
, 0);
191 pUserNameW
= HeapAlloc(GetProcessHeap(), 0, nLength
* sizeof(WCHAR
));
192 if (pUserNameW
== NULL
)
194 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
197 MultiByteToWideChar(CP_ACP
, 0, lpUserName
, -1, pUserNameW
, nLength
);
199 /* Convert lpUserHive to Unicode */
200 if (lpUserHive
!= NULL
)
202 nLength
= MultiByteToWideChar(CP_ACP
, 0, lpUserHive
, -1, NULL
, 0);
203 pUserHiveW
= HeapAlloc(GetProcessHeap(), 0, nLength
* sizeof(WCHAR
));
204 if (pUserHiveW
== NULL
)
206 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
209 MultiByteToWideChar(CP_ACP
, 0, lpUserHive
, -1, pUserHiveW
, nLength
);
212 /* Allocate a Unicode buffer for lpProfileDir */
213 if (lpProfileDir
!= NULL
)
215 pProfileDirW
= HeapAlloc(GetProcessHeap(), 0, dwDirSize
* sizeof(WCHAR
));
216 if (pProfileDirW
== NULL
)
218 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
223 /* Call the Unicode function */
224 bResult
= CreateUserProfileExW(pSid
,
231 /* Convert the profile path to ANSI */
232 if (bResult
&& lpProfileDir
!= NULL
)
234 WideCharToMultiByte(CP_ACP
, 0, pProfileDirW
, -1, lpProfileDir
, dwDirSize
, NULL
, NULL
);
238 /* Free the buffers */
239 if (pProfileDirW
!= NULL
)
240 HeapFree(GetProcessHeap(), 0, pProfileDirW
);
242 if (pUserHiveW
!= NULL
)
243 HeapFree(GetProcessHeap(), 0, pUserHiveW
);
245 if (pUserNameW
!= NULL
)
246 HeapFree(GetProcessHeap(), 0, pUserNameW
);
254 CreateUserProfileExW(
256 _In_ LPCWSTR lpUserName
,
257 _In_opt_ LPCWSTR lpUserHive
,
258 _Out_opt_ LPWSTR lpProfileDir
,
259 _In_ DWORD dwDirSize
,
262 WCHAR szRawProfilesPath
[MAX_PATH
];
263 WCHAR szProfilesPath
[MAX_PATH
];
264 WCHAR szUserProfilePath
[MAX_PATH
];
265 WCHAR szDefaultUserPath
[MAX_PATH
];
266 WCHAR szUserProfileName
[MAX_PATH
];
267 WCHAR szBuffer
[MAX_PATH
];
276 DPRINT("CreateUserProfileExW(%p %S %S %p %lu %d)\n",
277 pSid
, lpUserName
, lpUserHive
, lpProfileDir
, dwDirSize
, bWin9xUpg
);
281 * - Add support for lpUserHive, lpProfileDir.
282 * - bWin9xUpg is obsolete. Don't waste your time implementing this.
285 Error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
286 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
290 if (Error
!= ERROR_SUCCESS
)
292 DPRINT1("Error: %lu\n", Error
);
293 SetLastError((DWORD
)Error
);
297 /* Get profiles path */
298 dwLength
= sizeof(szRawProfilesPath
);
299 Error
= RegQueryValueExW(hKey
,
300 L
"ProfilesDirectory",
303 (LPBYTE
)szRawProfilesPath
,
305 if (Error
!= ERROR_SUCCESS
)
307 DPRINT1("Error: %lu\n", Error
);
309 SetLastError((DWORD
)Error
);
314 if (!ExpandEnvironmentStringsW(szRawProfilesPath
,
316 ARRAYSIZE(szProfilesPath
)))
318 DPRINT1("Error: %lu\n", GetLastError());
323 /* create the profiles directory if it does not yet exist */
324 if (!CreateDirectoryW(szProfilesPath
, NULL
))
326 if (GetLastError() != ERROR_ALREADY_EXISTS
)
328 DPRINT1("Error: %lu\n", GetLastError());
333 /* Get default user path */
334 dwLength
= sizeof(szBuffer
);
335 Error
= RegQueryValueExW(hKey
,
336 L
"DefaultUserProfile",
341 if (Error
!= ERROR_SUCCESS
)
343 DPRINT1("Error: %lu\n", Error
);
345 SetLastError((DWORD
)Error
);
351 wcscpy(szUserProfileName
, lpUserName
);
353 wcscpy(szUserProfilePath
, szProfilesPath
);
354 wcscat(szUserProfilePath
, L
"\\");
355 wcscat(szUserProfilePath
, szUserProfileName
);
357 wcscpy(szDefaultUserPath
, szProfilesPath
);
358 wcscat(szDefaultUserPath
, L
"\\");
359 wcscat(szDefaultUserPath
, szBuffer
);
361 /* Create user profile directory */
362 if (!CreateDirectoryW(szUserProfilePath
, NULL
))
364 if (GetLastError() != ERROR_ALREADY_EXISTS
)
366 DPRINT1("Error: %lu\n", GetLastError());
370 for (i
= 0; i
< 1000; i
++)
372 swprintf(szUserProfileName
, L
"%s.%03u", lpUserName
, i
);
374 wcscpy(szUserProfilePath
, szProfilesPath
);
375 wcscat(szUserProfilePath
, L
"\\");
376 wcscat(szUserProfilePath
, szUserProfileName
);
378 if (CreateDirectoryW(szUserProfilePath
, NULL
))
381 if (GetLastError() != ERROR_ALREADY_EXISTS
)
383 DPRINT1("Error: %lu\n", GetLastError());
389 /* Copy default user directory */
390 if (!CopyDirectory(szUserProfilePath
, szDefaultUserPath
))
392 DPRINT1("Error: %lu\n", GetLastError());
396 /* Add profile to profile list */
397 if (!ConvertSidToStringSidW(pSid
,
400 DPRINT1("Error: %lu\n", GetLastError());
405 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
406 wcscat(szBuffer
, SidString
);
408 /* Create user profile key */
409 Error
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
413 REG_OPTION_NON_VOLATILE
,
418 if (Error
!= ERROR_SUCCESS
)
420 DPRINT1("Error: %lu\n", Error
);
425 /* Create non-expanded user profile path */
426 wcscpy(szBuffer
, szRawProfilesPath
);
427 wcscat(szBuffer
, L
"\\");
428 wcscat(szBuffer
, szUserProfileName
);
430 /* Set 'ProfileImagePath' value (non-expanded) */
431 Error
= RegSetValueExW(hKey
,
436 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
437 if (Error
!= ERROR_SUCCESS
)
439 DPRINT1("Error: %lu\n", Error
);
445 /* Set 'Sid' value */
446 Error
= RegSetValueExW(hKey
,
452 if (Error
!= ERROR_SUCCESS
)
454 DPRINT1("Error: %lu\n", Error
);
462 /* Create user hive name */
463 wcscpy(szBuffer
, szUserProfilePath
);
464 wcscat(szBuffer
, L
"\\ntuser.dat");
466 /* Acquire restore privilege */
467 if (!AcquireRemoveRestorePrivilege(TRUE
))
469 Error
= GetLastError();
470 DPRINT1("Error: %lu\n", Error
);
475 /* Create new user hive */
476 Error
= RegLoadKeyW(HKEY_USERS
,
479 AcquireRemoveRestorePrivilege(FALSE
);
480 if (Error
!= ERROR_SUCCESS
)
482 DPRINT1("Error: %lu\n", Error
);
487 /* Initialize user hive */
488 if (!CreateUserHive(SidString
, szUserProfilePath
))
490 Error
= GetLastError();
491 DPRINT1("Error: %lu\n", Error
);
495 /* Unload the hive */
496 AcquireRemoveRestorePrivilege(TRUE
);
497 RegUnLoadKeyW(HKEY_USERS
, SidString
);
498 AcquireRemoveRestorePrivilege(FALSE
);
501 LocalFree((HLOCAL
)SidString
);
502 SetLastError((DWORD
)Error
);
504 DPRINT("CreateUserProfileExW() done\n");
512 GetAllUsersProfileDirectoryA(
513 _Out_opt_ LPSTR lpProfileDir
,
514 _Inout_ LPDWORD lpcchSize
)
519 lpBuffer
= GlobalAlloc(GMEM_FIXED
,
520 *lpcchSize
* sizeof(WCHAR
));
521 if (lpBuffer
== NULL
)
524 bResult
= GetAllUsersProfileDirectoryW(lpBuffer
,
528 WideCharToMultiByte(CP_ACP
,
538 GlobalFree(lpBuffer
);
546 GetAllUsersProfileDirectoryW(
547 _Out_opt_ LPWSTR lpProfileDir
,
548 _Inout_ LPDWORD lpcchSize
)
550 WCHAR szProfilePath
[MAX_PATH
];
551 WCHAR szBuffer
[MAX_PATH
];
558 SetLastError(ERROR_INVALID_PARAMETER
);
562 Error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
563 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
567 if (Error
!= ERROR_SUCCESS
)
569 DPRINT1("Error: %lu\n", Error
);
570 SetLastError((DWORD
)Error
);
574 /* Get profiles path */
575 dwLength
= sizeof(szBuffer
);
576 Error
= RegQueryValueExW(hKey
,
577 L
"ProfilesDirectory",
582 if (Error
!= ERROR_SUCCESS
)
584 DPRINT1("Error: %lu\n", Error
);
586 SetLastError((DWORD
)Error
);
591 if (!ExpandEnvironmentStringsW(szBuffer
,
595 DPRINT1("Error: %lu\n", GetLastError());
600 /* Get 'AllUsersProfile' name */
601 dwLength
= sizeof(szBuffer
);
602 Error
= RegQueryValueExW(hKey
,
608 if (Error
!= ERROR_SUCCESS
)
610 DPRINT1("Error: %lu\n", Error
);
612 SetLastError((DWORD
)Error
);
618 wcscat(szProfilePath
, L
"\\");
619 wcscat(szProfilePath
, szBuffer
);
621 dwLength
= wcslen(szProfilePath
) + 1;
622 if (lpProfileDir
!= NULL
)
624 if (*lpcchSize
< dwLength
)
626 *lpcchSize
= dwLength
;
627 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
631 wcscpy(lpProfileDir
, szProfilePath
);
634 *lpcchSize
= dwLength
;
642 GetDefaultUserProfileDirectoryA(
643 _Out_opt_ LPSTR lpProfileDir
,
644 _Inout_ LPDWORD lpcchSize
)
649 lpBuffer
= GlobalAlloc(GMEM_FIXED
,
650 *lpcchSize
* sizeof(WCHAR
));
651 if (lpBuffer
== NULL
)
654 bResult
= GetDefaultUserProfileDirectoryW(lpBuffer
,
658 WideCharToMultiByte(CP_ACP
,
668 GlobalFree(lpBuffer
);
676 GetDefaultUserProfileDirectoryW(
677 _Out_opt_ LPWSTR lpProfileDir
,
678 _Inout_ LPDWORD lpcchSize
)
680 WCHAR szProfilePath
[MAX_PATH
];
681 WCHAR szBuffer
[MAX_PATH
];
688 SetLastError(ERROR_INVALID_PARAMETER
);
692 Error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
693 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
697 if (Error
!= ERROR_SUCCESS
)
699 DPRINT1("Error: %lu\n", Error
);
700 SetLastError((DWORD
)Error
);
704 /* Get profiles path */
705 dwLength
= sizeof(szBuffer
);
706 Error
= RegQueryValueExW(hKey
,
707 L
"ProfilesDirectory",
712 if (Error
!= ERROR_SUCCESS
)
714 DPRINT1("Error: %lu\n", Error
);
716 SetLastError((DWORD
)Error
);
721 if (!ExpandEnvironmentStringsW(szBuffer
,
725 DPRINT1("Error: %lu\n", GetLastError());
730 /* Get 'DefaultUserProfile' name */
731 dwLength
= sizeof(szBuffer
);
732 Error
= RegQueryValueExW(hKey
,
733 L
"DefaultUserProfile",
738 if (Error
!= ERROR_SUCCESS
)
740 DPRINT1("Error: %lu\n", Error
);
742 SetLastError((DWORD
)Error
);
748 wcscat(szProfilePath
, L
"\\");
749 wcscat(szProfilePath
, szBuffer
);
751 dwLength
= wcslen(szProfilePath
) + 1;
752 if (lpProfileDir
!= NULL
)
754 if (*lpcchSize
< dwLength
)
756 *lpcchSize
= dwLength
;
757 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
761 wcscpy(lpProfileDir
, szProfilePath
);
764 *lpcchSize
= dwLength
;
772 GetProfilesDirectoryA(
773 _Out_ LPSTR lpProfileDir
, // _Out_opt_
774 _Inout_ LPDWORD lpcchSize
)
779 if (!lpProfileDir
|| !lpcchSize
)
781 SetLastError(ERROR_INVALID_PARAMETER
);
785 lpBuffer
= GlobalAlloc(GMEM_FIXED
,
786 *lpcchSize
* sizeof(WCHAR
));
787 if (lpBuffer
== NULL
)
790 bResult
= GetProfilesDirectoryW(lpBuffer
,
794 bResult
= WideCharToMultiByte(CP_ACP
,
804 GlobalFree(lpBuffer
);
812 GetProfilesDirectoryW(
813 _Out_ LPWSTR lpProfilesDir
, // _Out_opt_
814 _Inout_ LPDWORD lpcchSize
)
816 WCHAR szProfilesPath
[MAX_PATH
];
817 WCHAR szBuffer
[MAX_PATH
];
825 SetLastError(ERROR_INVALID_PARAMETER
);
829 Error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
830 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
834 if (Error
!= ERROR_SUCCESS
)
836 DPRINT1("Error: %lu\n", Error
);
837 SetLastError((DWORD
)Error
);
841 /* Get profiles path */
842 dwLength
= sizeof(szBuffer
);
843 Error
= RegQueryValueExW(hKey
,
844 L
"ProfilesDirectory",
849 if (Error
!= ERROR_SUCCESS
)
851 DPRINT1("Error: %lu\n", Error
);
853 SetLastError((DWORD
)Error
);
860 if (!ExpandEnvironmentStringsW(szBuffer
,
862 ARRAYSIZE(szProfilesPath
)))
864 DPRINT1("Error: %lu\n", GetLastError());
868 dwLength
= wcslen(szProfilesPath
) + 1;
869 if (lpProfilesDir
!= NULL
)
871 if (*lpcchSize
< dwLength
)
873 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
877 wcscpy(lpProfilesDir
, szProfilesPath
);
883 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
886 *lpcchSize
= dwLength
;
894 GetUserProfileDirectoryA(
896 _Out_opt_ LPSTR lpProfileDir
,
897 _Inout_ LPDWORD lpcchSize
)
902 if (!lpProfileDir
|| !lpcchSize
)
904 SetLastError( ERROR_INVALID_PARAMETER
);
908 lpBuffer
= GlobalAlloc(GMEM_FIXED
,
909 *lpcchSize
* sizeof(WCHAR
));
910 if (lpBuffer
== NULL
)
913 bResult
= GetUserProfileDirectoryW(hToken
,
918 WideCharToMultiByte(CP_ACP
,
928 GlobalFree(lpBuffer
);
936 GetUserProfileDirectoryW(
938 _Out_opt_ LPWSTR lpProfileDir
,
939 _Inout_ LPDWORD lpcchSize
)
941 UNICODE_STRING SidString
;
942 WCHAR szKeyName
[MAX_PATH
];
943 WCHAR szRawImagePath
[MAX_PATH
];
944 WCHAR szImagePath
[MAX_PATH
];
951 SetLastError(ERROR_INVALID_HANDLE
);
957 SetLastError(ERROR_INVALID_PARAMETER
);
961 if (!GetUserSidStringFromToken(hToken
,
964 DPRINT1("GetUserSidFromToken() failed\n");
968 DPRINT("SidString: '%wZ'\n", &SidString
);
971 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
975 RtlFreeUnicodeString(&SidString
);
977 DPRINT("KeyName: '%S'\n", szKeyName
);
979 Error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
984 if (Error
!= ERROR_SUCCESS
)
986 DPRINT1("Error: %lu\n", Error
);
987 SetLastError((DWORD
)Error
);
991 dwLength
= sizeof(szRawImagePath
);
992 Error
= RegQueryValueExW(hKey
,
996 (LPBYTE
)szRawImagePath
,
998 if (Error
!= ERROR_SUCCESS
)
1000 DPRINT1("Error: %lu\n", Error
);
1002 SetLastError((DWORD
)Error
);
1008 DPRINT("RawImagePath: '%S'\n", szRawImagePath
);
1011 if (!ExpandEnvironmentStringsW(szRawImagePath
,
1013 ARRAYSIZE(szImagePath
)))
1015 DPRINT1 ("Error: %lu\n", GetLastError());
1019 DPRINT("ImagePath: '%S'\n", szImagePath
);
1021 dwLength
= wcslen (szImagePath
) + 1;
1022 if (*lpcchSize
< dwLength
)
1024 *lpcchSize
= dwLength
;
1025 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1029 *lpcchSize
= dwLength
;
1030 wcscpy(lpProfileDir
, szImagePath
);
1038 CheckForLoadedProfile(HANDLE hToken
)
1040 UNICODE_STRING SidString
;
1043 DPRINT("CheckForLoadedProfile() called\n");
1045 if (!GetUserSidStringFromToken(hToken
,
1048 DPRINT1("GetUserSidFromToken() failed\n");
1052 if (RegOpenKeyExW(HKEY_USERS
,
1058 DPRINT("Profile not loaded\n");
1059 RtlFreeUnicodeString(&SidString
);
1065 RtlFreeUnicodeString(&SidString
);
1067 DPRINT("Profile already loaded\n");
1077 _Inout_ LPPROFILEINFOA lpProfileInfo
)
1079 BOOL bResult
= FALSE
;
1080 PROFILEINFOW ProfileInfoW
= {0};
1083 DPRINT("LoadUserProfileA() called\n");
1085 /* Check profile info */
1086 if (!lpProfileInfo
|| (lpProfileInfo
->dwSize
!= sizeof(PROFILEINFOA
)) ||
1087 (lpProfileInfo
->lpUserName
== NULL
) || (lpProfileInfo
->lpUserName
[0] == 0))
1089 SetLastError(ERROR_INVALID_PARAMETER
);
1093 /* Convert the structure to UNICODE... */
1094 ProfileInfoW
.dwSize
= sizeof(ProfileInfoW
);
1095 ProfileInfoW
.dwFlags
= lpProfileInfo
->dwFlags
;
1097 if (lpProfileInfo
->lpUserName
)
1099 len
= MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpUserName
, -1, NULL
, 0);
1100 ProfileInfoW
.lpUserName
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1101 if (!ProfileInfoW
.lpUserName
)
1103 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1106 MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpUserName
, -1, ProfileInfoW
.lpUserName
, len
);
1109 if (lpProfileInfo
->lpProfilePath
)
1111 len
= MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpProfilePath
, -1, NULL
, 0);
1112 ProfileInfoW
.lpProfilePath
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1113 if (!ProfileInfoW
.lpProfilePath
)
1115 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1118 MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpProfilePath
, -1, ProfileInfoW
.lpProfilePath
, len
);
1121 if (lpProfileInfo
->lpDefaultPath
)
1123 len
= MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpDefaultPath
, -1, NULL
, 0);
1124 ProfileInfoW
.lpDefaultPath
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1125 if (!ProfileInfoW
.lpDefaultPath
)
1127 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1130 MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpDefaultPath
, -1, ProfileInfoW
.lpDefaultPath
, len
);
1133 if (lpProfileInfo
->lpServerName
)
1135 len
= MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpServerName
, -1, NULL
, 0);
1136 ProfileInfoW
.lpServerName
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1137 if (!ProfileInfoW
.lpServerName
)
1139 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1142 MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpServerName
, -1, ProfileInfoW
.lpServerName
, len
);
1145 if ((ProfileInfoW
.dwFlags
& PI_APPLYPOLICY
) != 0 && lpProfileInfo
->lpPolicyPath
)
1147 len
= MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpPolicyPath
, -1, NULL
, 0);
1148 ProfileInfoW
.lpPolicyPath
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1149 if (!ProfileInfoW
.lpPolicyPath
)
1151 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1154 MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpPolicyPath
, -1, ProfileInfoW
.lpPolicyPath
, len
);
1157 /* ... and call the UNICODE function */
1158 bResult
= LoadUserProfileW(hToken
, &ProfileInfoW
);
1160 /* Save the returned value */
1161 lpProfileInfo
->hProfile
= ProfileInfoW
.hProfile
;
1164 /* Memory cleanup */
1165 if (ProfileInfoW
.lpUserName
)
1166 HeapFree(GetProcessHeap(), 0, ProfileInfoW
.lpUserName
);
1168 if (ProfileInfoW
.lpProfilePath
)
1169 HeapFree(GetProcessHeap(), 0, ProfileInfoW
.lpProfilePath
);
1171 if (ProfileInfoW
.lpDefaultPath
)
1172 HeapFree(GetProcessHeap(), 0, ProfileInfoW
.lpDefaultPath
);
1174 if (ProfileInfoW
.lpServerName
)
1175 HeapFree(GetProcessHeap(), 0, ProfileInfoW
.lpServerName
);
1177 if ((ProfileInfoW
.dwFlags
& PI_APPLYPOLICY
) != 0 && ProfileInfoW
.lpPolicyPath
)
1178 HeapFree(GetProcessHeap(), 0, ProfileInfoW
.lpPolicyPath
);
1188 _Inout_ LPPROFILEINFOW lpProfileInfo
)
1190 WCHAR szUserHivePath
[MAX_PATH
];
1191 LPWSTR UserName
= NULL
, Domain
= NULL
;
1192 DWORD UserNameLength
= 0, DomainLength
= 0;
1193 PTOKEN_USER UserSid
= NULL
;
1194 SID_NAME_USE AccountType
;
1195 UNICODE_STRING SidString
= { 0, 0, NULL
};
1198 DWORD dwLength
= sizeof(szUserHivePath
) / sizeof(szUserHivePath
[0]);
1200 DPRINT("LoadUserProfileW() called\n");
1202 /* Check profile info */
1203 if (!lpProfileInfo
|| (lpProfileInfo
->dwSize
!= sizeof(PROFILEINFOW
)) ||
1204 (lpProfileInfo
->lpUserName
== NULL
) || (lpProfileInfo
->lpUserName
[0] == 0))
1206 SetLastError(ERROR_INVALID_PARAMETER
);
1210 /* Don't load a profile twice */
1211 if (CheckForLoadedProfile(hToken
))
1213 DPRINT ("Profile already loaded\n");
1214 lpProfileInfo
->hProfile
= NULL
;
1218 if (lpProfileInfo
->lpProfilePath
)
1220 wcscpy(szUserHivePath
, lpProfileInfo
->lpProfilePath
);
1224 /* FIXME: check if MS Windows allows lpProfileInfo->lpProfilePath to be NULL */
1225 if (!GetProfilesDirectoryW(szUserHivePath
, &dwLength
))
1227 DPRINT1("GetProfilesDirectoryW() failed (error %ld)\n", GetLastError());
1232 /* Create user hive name */
1233 wcscat(szUserHivePath
, L
"\\");
1234 wcscat(szUserHivePath
, lpProfileInfo
->lpUserName
);
1235 wcscat(szUserHivePath
, L
"\\ntuser.dat");
1236 DPRINT("szUserHivePath: %S\n", szUserHivePath
);
1238 /* Create user profile directory if needed */
1239 if (GetFileAttributesW(szUserHivePath
) == INVALID_FILE_ATTRIBUTES
)
1242 if (GetTokenInformation(hToken
, TokenUser
, NULL
, 0, &dwLength
) ||
1243 GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
1245 DPRINT1 ("GetTokenInformation() failed\n");
1249 UserSid
= (PTOKEN_USER
)HeapAlloc(GetProcessHeap(), 0, dwLength
);
1252 DPRINT1("HeapAlloc() failed\n");
1253 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1257 if (!GetTokenInformation(hToken
, TokenUser
, UserSid
, dwLength
, &dwLength
))
1259 DPRINT1("GetTokenInformation() failed\n");
1266 if (UserNameLength
> 0)
1268 HeapFree(GetProcessHeap(), 0, UserName
);
1269 UserName
= (LPWSTR
)HeapAlloc(GetProcessHeap(), 0, UserNameLength
* sizeof(WCHAR
));
1272 DPRINT1("HeapAlloc() failed\n");
1273 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1277 if (DomainLength
> 0)
1279 HeapFree(GetProcessHeap(), 0, Domain
);
1280 Domain
= (LPWSTR
)HeapAlloc(GetProcessHeap(), 0, DomainLength
* sizeof(WCHAR
));
1283 DPRINT1("HeapAlloc() failed\n");
1284 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1288 ret
= LookupAccountSidW(NULL
,
1295 } while (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
);
1299 DPRINT1("LookupAccountSidW() failed\n");
1303 /* Create profile */
1304 /* FIXME: ignore Domain? */
1305 DPRINT("UserName %S, Domain %S\n", UserName
, Domain
);
1306 ret
= CreateUserProfileW(UserSid
->User
.Sid
, UserName
);
1309 DPRINT1("CreateUserProfileW() failed\n");
1314 /* Get user SID string */
1315 ret
= GetUserSidStringFromToken(hToken
, &SidString
);
1318 DPRINT1("GetUserSidFromToken() failed\n");
1323 /* Acquire restore privilege */
1324 if (!AcquireRemoveRestorePrivilege(TRUE
))
1326 DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
1330 /* Load user registry hive */
1331 Error
= RegLoadKeyW(HKEY_USERS
,
1334 AcquireRemoveRestorePrivilege(FALSE
);
1336 /* HACK: Do not fail if the profile has already been loaded! */
1337 if (Error
== ERROR_SHARING_VIOLATION
)
1338 Error
= ERROR_SUCCESS
;
1340 if (Error
!= ERROR_SUCCESS
)
1342 DPRINT1("RegLoadKeyW() failed (Error %ld)\n", Error
);
1343 SetLastError((DWORD
)Error
);
1347 /* Open future HKEY_CURRENT_USER */
1348 Error
= RegOpenKeyExW(HKEY_USERS
,
1352 (PHKEY
)&lpProfileInfo
->hProfile
);
1353 if (Error
!= ERROR_SUCCESS
)
1355 DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error
);
1356 SetLastError((DWORD
)Error
);
1363 HeapFree(GetProcessHeap(), 0, UserSid
);
1364 HeapFree(GetProcessHeap(), 0, UserName
);
1365 HeapFree(GetProcessHeap(), 0, Domain
);
1366 RtlFreeUnicodeString(&SidString
);
1368 DPRINT("LoadUserProfileW() done\n");
1377 _In_ HANDLE hProfile
)
1379 UNICODE_STRING SidString
;
1382 DPRINT("UnloadUserProfile() called\n");
1384 if (hProfile
== NULL
)
1386 DPRINT1("Invalid profile handle\n");
1387 SetLastError(ERROR_INVALID_PARAMETER
);
1391 RegCloseKey(hProfile
);
1393 if (!GetUserSidStringFromToken(hToken
,
1396 DPRINT1("GetUserSidFromToken() failed\n");
1400 DPRINT("SidString: '%wZ'\n", &SidString
);
1402 /* Acquire restore privilege */
1403 if (!AcquireRemoveRestorePrivilege(TRUE
))
1405 DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
1406 RtlFreeUnicodeString(&SidString
);
1414 Error
= RegOpenKeyExW(HKEY_USERS
,
1419 if (Error
== ERROR_SUCCESS
)
1421 RegDeleteKeyW(hUserKey
,
1422 L
"Volatile Environment");
1424 RegCloseKey(hUserKey
);
1429 /* Unload the hive */
1430 Error
= RegUnLoadKeyW(HKEY_USERS
,
1433 /* Remove restore privilege */
1434 AcquireRemoveRestorePrivilege(FALSE
);
1436 if (Error
!= ERROR_SUCCESS
)
1438 DPRINT1("RegUnLoadKeyW() failed (Error %ld)\n", Error
);
1439 RtlFreeUnicodeString(&SidString
);
1440 SetLastError((DWORD
)Error
);
1444 RtlFreeUnicodeString(&SidString
);
1446 DPRINT("UnloadUserProfile() done\n");
1455 _In_ LPCWSTR lpSidString
,
1456 _In_opt_ LPCWSTR lpProfilePath
,
1457 _In_opt_ LPCWSTR lpComputerName
)
1459 DPRINT1("DeleteProfileW() not implemented!\n");
1467 _In_ LPCSTR lpSidString
,
1468 _In_opt_ LPCSTR lpProfilePath
,
1469 _In_opt_ LPCSTR lpComputerName
)
1472 UNICODE_STRING SidString
, ProfilePath
, ComputerName
;
1474 DPRINT("DeleteProfileA() called\n");
1476 /* Conversion to UNICODE */
1478 RtlCreateUnicodeStringFromAsciiz(&SidString
,
1479 (LPSTR
)lpSidString
);
1482 RtlCreateUnicodeStringFromAsciiz(&ProfilePath
,
1483 (LPSTR
)lpProfilePath
);
1486 RtlCreateUnicodeStringFromAsciiz(&ComputerName
,
1487 (LPSTR
)lpComputerName
);
1489 /* Call the UNICODE function */
1490 bResult
= DeleteProfileW(SidString
.Buffer
,
1492 ComputerName
.Buffer
);
1494 /* Memory cleanup */
1496 RtlFreeUnicodeString(&SidString
);
1499 RtlFreeUnicodeString(&ProfilePath
);
1502 RtlFreeUnicodeString(&ComputerName
);
1510 GetProfileType(_Out_ PDWORD pdwFlags
)
1512 DPRINT1("GetProfileType() not implemented!\n");