4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 * COPYRIGHT: See COPYING in the top level directory
20 * PROJECT: ReactOS system libraries
21 * FILE: dll/win32/userenv/profile.c
22 * PURPOSE: User profile code
23 * PROGRAMMERS: Eric Kohl
34 /* FUNCTIONS ***************************************************************/
37 AppendSystemPostfix(LPWSTR lpName
,
40 WCHAR szSystemRoot
[MAX_PATH
];
44 /* Build profile name postfix */
45 if (!ExpandEnvironmentStringsW(L
"%SystemRoot%",
49 DPRINT1("Error: %lu\n", GetLastError());
53 _wcsupr(szSystemRoot
);
55 /* Get name postfix */
56 szSystemRoot
[2] = L
'.';
57 lpszPostfix
= &szSystemRoot
[2];
58 lpszPtr
= lpszPostfix
;
59 while (*lpszPtr
!= (WCHAR
)0)
61 if (*lpszPtr
== L
'\\')
66 if (wcslen(lpName
) + wcslen(lpszPostfix
) + 1 >= dwMaxLength
)
68 DPRINT1("Error: buffer overflow\n");
69 SetLastError(ERROR_BUFFER_OVERFLOW
);
73 wcscat(lpName
, lpszPostfix
);
81 AcquireRemoveRestorePrivilege(IN BOOL bAcquire
)
85 TOKEN_PRIVILEGES TokenPriv
;
87 DPRINT("AcquireRemoveRestorePrivilege(%d)\n", bAcquire
);
89 if (OpenProcessToken(GetCurrentProcess(),
90 TOKEN_ADJUST_PRIVILEGES
,
93 TokenPriv
.PrivilegeCount
= 1;
94 TokenPriv
.Privileges
[0].Attributes
= (bAcquire
? SE_PRIVILEGE_ENABLED
: 0);
96 if (LookupPrivilegeValue(NULL
, SE_RESTORE_NAME
, &TokenPriv
.Privileges
[0].Luid
))
98 bRet
= AdjustTokenPrivileges(Token
, FALSE
, &TokenPriv
, 0, NULL
, NULL
);
102 DPRINT1("AdjustTokenPrivileges() failed with error %lu\n", GetLastError());
104 else if (GetLastError() == ERROR_NOT_ALL_ASSIGNED
)
106 DPRINT1("AdjustTokenPrivileges() succeeded, but with not all privileges assigned\n");
112 DPRINT1("LookupPrivilegeValue() failed with error %lu\n", GetLastError());
119 DPRINT1("OpenProcessToken() failed with error %lu\n", GetLastError());
128 CreateUserProfileA(PSID Sid
,
131 UNICODE_STRING UserName
;
134 if (!RtlCreateUnicodeStringFromAsciiz(&UserName
,
137 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
141 bResult
= CreateUserProfileW(Sid
, UserName
.Buffer
);
143 RtlFreeUnicodeString(&UserName
);
151 CreateUserProfileW(PSID Sid
,
154 WCHAR szRawProfilesPath
[MAX_PATH
];
155 WCHAR szProfilesPath
[MAX_PATH
];
156 WCHAR szUserProfilePath
[MAX_PATH
];
157 WCHAR szDefaultUserPath
[MAX_PATH
];
158 WCHAR szUserProfileName
[MAX_PATH
];
159 WCHAR szBuffer
[MAX_PATH
];
168 DPRINT("CreateUserProfileW() called\n");
170 Error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
171 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
175 if (Error
!= ERROR_SUCCESS
)
177 DPRINT1("Error: %lu\n", Error
);
178 SetLastError((DWORD
)Error
);
182 /* Get profiles path */
183 dwLength
= MAX_PATH
* sizeof(WCHAR
);
184 Error
= RegQueryValueExW(hKey
,
185 L
"ProfilesDirectory",
188 (LPBYTE
)szRawProfilesPath
,
190 if (Error
!= ERROR_SUCCESS
)
192 DPRINT1("Error: %lu\n", Error
);
194 SetLastError((DWORD
)Error
);
199 if (!ExpandEnvironmentStringsW(szRawProfilesPath
,
203 DPRINT1("Error: %lu\n", GetLastError());
208 /* create the profiles directory if it does not yet exist */
209 if (!CreateDirectoryW(szProfilesPath
, NULL
))
211 if (GetLastError() != ERROR_ALREADY_EXISTS
)
213 DPRINT1("Error: %lu\n", GetLastError());
218 /* Get default user path */
219 dwLength
= MAX_PATH
* sizeof(WCHAR
);
220 Error
= RegQueryValueExW(hKey
,
221 L
"DefaultUserProfile",
226 if (Error
!= ERROR_SUCCESS
)
228 DPRINT1("Error: %lu\n", Error
);
230 SetLastError((DWORD
)Error
);
236 wcscpy(szUserProfileName
, lpUserName
);
238 wcscpy(szUserProfilePath
, szProfilesPath
);
239 wcscat(szUserProfilePath
, L
"\\");
240 wcscat(szUserProfilePath
, szUserProfileName
);
242 wcscpy(szDefaultUserPath
, szProfilesPath
);
243 wcscat(szDefaultUserPath
, L
"\\");
244 wcscat(szDefaultUserPath
, szBuffer
);
246 /* Create user profile directory */
247 if (!CreateDirectoryW(szUserProfilePath
, NULL
))
249 if (GetLastError() != ERROR_ALREADY_EXISTS
)
251 DPRINT1("Error: %lu\n", GetLastError());
255 for (i
= 0; i
< 1000; i
++)
257 swprintf(szUserProfileName
, L
"%s.%03u", lpUserName
, i
);
259 wcscpy(szUserProfilePath
, szProfilesPath
);
260 wcscat(szUserProfilePath
, L
"\\");
261 wcscat(szUserProfilePath
, szUserProfileName
);
263 if (CreateDirectoryW(szUserProfilePath
, NULL
))
266 if (GetLastError() != ERROR_ALREADY_EXISTS
)
268 DPRINT1("Error: %lu\n", GetLastError());
274 /* Copy default user directory */
275 if (!CopyDirectory(szUserProfilePath
, szDefaultUserPath
))
277 DPRINT1("Error: %lu\n", GetLastError());
281 /* Add profile to profile list */
282 if (!ConvertSidToStringSidW(Sid
,
285 DPRINT1("Error: %lu\n", GetLastError());
290 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
291 wcscat(szBuffer
, SidString
);
293 /* Create user profile key */
294 Error
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
298 REG_OPTION_NON_VOLATILE
,
303 if (Error
!= ERROR_SUCCESS
)
305 DPRINT1("Error: %lu\n", Error
);
310 /* Create non-expanded user profile path */
311 wcscpy(szBuffer
, szRawProfilesPath
);
312 wcscat(szBuffer
, L
"\\");
313 wcscat(szBuffer
, szUserProfileName
);
315 /* Set 'ProfileImagePath' value (non-expanded) */
316 Error
= RegSetValueExW(hKey
,
321 (wcslen (szBuffer
) + 1) * sizeof(WCHAR
));
322 if (Error
!= ERROR_SUCCESS
)
324 DPRINT1("Error: %lu\n", Error
);
330 /* Set 'Sid' value */
331 Error
= RegSetValueExW(hKey
,
337 if (Error
!= ERROR_SUCCESS
)
339 DPRINT1("Error: %lu\n", Error
);
347 /* Create user hive name */
348 wcscpy(szBuffer
, szUserProfilePath
);
349 wcscat(szBuffer
, L
"\\ntuser.dat");
351 /* Acquire restore privilege */
352 if (!AcquireRemoveRestorePrivilege(TRUE
))
354 Error
= GetLastError();
355 DPRINT1("Error: %lu\n", Error
);
360 /* Create new user hive */
361 Error
= RegLoadKeyW(HKEY_USERS
,
364 AcquireRemoveRestorePrivilege(FALSE
);
365 if (Error
!= ERROR_SUCCESS
)
367 DPRINT1("Error: %lu\n", Error
);
372 /* Initialize user hive */
373 if (!CreateUserHive(SidString
, szUserProfilePath
))
375 Error
= GetLastError();
376 DPRINT1("Error: %lu\n", Error
);
380 /* Unload the hive */
381 AcquireRemoveRestorePrivilege(TRUE
);
382 RegUnLoadKeyW(HKEY_USERS
, SidString
);
383 AcquireRemoveRestorePrivilege(FALSE
);
386 LocalFree((HLOCAL
)SidString
);
387 SetLastError((DWORD
)Error
);
389 DPRINT("CreateUserProfileW() done\n");
397 CreateUserProfileExA(IN PSID pSid
,
398 IN LPCSTR lpUserName
,
399 IN LPCSTR lpUserHive OPTIONAL
,
400 OUT LPSTR lpProfileDir OPTIONAL
,
404 DPRINT1("CreateUserProfileExA() not implemented!\n");
411 CreateUserProfileExW(IN PSID pSid
,
412 IN LPCWSTR lpUserName
,
413 IN LPCWSTR lpUserHive OPTIONAL
,
414 OUT LPWSTR lpProfileDir OPTIONAL
,
418 DPRINT1("CreateUserProfileExW() not implemented!\n");
425 GetAllUsersProfileDirectoryA(LPSTR lpProfileDir
,
431 lpBuffer
= GlobalAlloc(GMEM_FIXED
,
432 *lpcchSize
* sizeof(WCHAR
));
433 if (lpBuffer
== NULL
)
436 bResult
= GetAllUsersProfileDirectoryW(lpBuffer
,
440 WideCharToMultiByte(CP_ACP
,
450 GlobalFree(lpBuffer
);
458 GetAllUsersProfileDirectoryW(LPWSTR lpProfileDir
,
461 WCHAR szProfilePath
[MAX_PATH
];
462 WCHAR szBuffer
[MAX_PATH
];
469 SetLastError(ERROR_INVALID_PARAMETER
);
473 Error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
474 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
478 if (Error
!= ERROR_SUCCESS
)
480 DPRINT1("Error: %lu\n", Error
);
481 SetLastError((DWORD
)Error
);
485 /* Get profiles path */
486 dwLength
= sizeof(szBuffer
);
487 Error
= RegQueryValueExW(hKey
,
488 L
"ProfilesDirectory",
493 if (Error
!= ERROR_SUCCESS
)
495 DPRINT1("Error: %lu\n", Error
);
497 SetLastError((DWORD
)Error
);
502 if (!ExpandEnvironmentStringsW(szBuffer
,
506 DPRINT1("Error: %lu\n", GetLastError());
511 /* Get 'AllUsersProfile' name */
512 dwLength
= sizeof(szBuffer
);
513 Error
= RegQueryValueExW(hKey
,
519 if (Error
!= ERROR_SUCCESS
)
521 DPRINT1("Error: %lu\n", Error
);
523 SetLastError((DWORD
)Error
);
529 wcscat(szProfilePath
, L
"\\");
530 wcscat(szProfilePath
, szBuffer
);
532 dwLength
= wcslen(szProfilePath
) + 1;
533 if (lpProfileDir
!= NULL
)
535 if (*lpcchSize
< dwLength
)
537 *lpcchSize
= dwLength
;
538 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
542 wcscpy(lpProfileDir
, szProfilePath
);
545 *lpcchSize
= dwLength
;
553 GetDefaultUserProfileDirectoryA(LPSTR lpProfileDir
,
559 lpBuffer
= GlobalAlloc(GMEM_FIXED
,
560 *lpcchSize
* sizeof(WCHAR
));
561 if (lpBuffer
== NULL
)
564 bResult
= GetDefaultUserProfileDirectoryW(lpBuffer
,
568 WideCharToMultiByte(CP_ACP
,
578 GlobalFree(lpBuffer
);
586 GetDefaultUserProfileDirectoryW(LPWSTR lpProfileDir
,
589 WCHAR szProfilePath
[MAX_PATH
];
590 WCHAR szBuffer
[MAX_PATH
];
597 SetLastError(ERROR_INVALID_PARAMETER
);
601 Error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
602 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
606 if (Error
!= ERROR_SUCCESS
)
608 DPRINT1("Error: %lu\n", Error
);
609 SetLastError((DWORD
)Error
);
613 /* Get profiles path */
614 dwLength
= sizeof(szBuffer
);
615 Error
= RegQueryValueExW(hKey
,
616 L
"ProfilesDirectory",
621 if (Error
!= ERROR_SUCCESS
)
623 DPRINT1("Error: %lu\n", Error
);
625 SetLastError((DWORD
)Error
);
630 if (!ExpandEnvironmentStringsW(szBuffer
,
634 DPRINT1("Error: %lu\n", GetLastError());
639 /* Get 'DefaultUserProfile' name */
640 dwLength
= sizeof(szBuffer
);
641 Error
= RegQueryValueExW(hKey
,
642 L
"DefaultUserProfile",
647 if (Error
!= ERROR_SUCCESS
)
649 DPRINT1("Error: %lu\n", Error
);
651 SetLastError((DWORD
)Error
);
657 wcscat(szProfilePath
, L
"\\");
658 wcscat(szProfilePath
, szBuffer
);
660 dwLength
= wcslen(szProfilePath
) + 1;
661 if (lpProfileDir
!= NULL
)
663 if (*lpcchSize
< dwLength
)
665 *lpcchSize
= dwLength
;
666 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
670 wcscpy(lpProfileDir
, szProfilePath
);
673 *lpcchSize
= dwLength
;
681 GetProfilesDirectoryA(LPSTR lpProfileDir
,
687 if (!lpProfileDir
|| !lpcchSize
)
689 SetLastError(ERROR_INVALID_PARAMETER
);
693 lpBuffer
= GlobalAlloc(GMEM_FIXED
,
694 *lpcchSize
* sizeof(WCHAR
));
695 if (lpBuffer
== NULL
)
698 bResult
= GetProfilesDirectoryW(lpBuffer
,
702 bResult
= WideCharToMultiByte(CP_ACP
,
712 GlobalFree(lpBuffer
);
720 GetProfilesDirectoryW(LPWSTR lpProfilesDir
,
723 WCHAR szProfilesPath
[MAX_PATH
];
724 WCHAR szBuffer
[MAX_PATH
];
732 SetLastError(ERROR_INVALID_PARAMETER
);
736 Error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
737 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
741 if (Error
!= ERROR_SUCCESS
)
743 DPRINT1("Error: %lu\n", Error
);
744 SetLastError((DWORD
)Error
);
748 /* Get profiles path */
749 dwLength
= sizeof(szBuffer
);
750 Error
= RegQueryValueExW(hKey
,
751 L
"ProfilesDirectory",
756 if (Error
!= ERROR_SUCCESS
)
758 DPRINT1("Error: %lu\n", Error
);
760 SetLastError((DWORD
)Error
);
767 if (!ExpandEnvironmentStringsW(szBuffer
,
771 DPRINT1("Error: %lu\n", GetLastError());
775 dwLength
= wcslen (szProfilesPath
) + 1;
776 if (lpProfilesDir
!= NULL
)
778 if (*lpcchSize
< dwLength
)
780 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
784 wcscpy(lpProfilesDir
, szProfilesPath
);
790 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
793 *lpcchSize
= dwLength
;
801 GetUserProfileDirectoryA(HANDLE hToken
,
808 if (!lpProfileDir
|| !lpcchSize
)
810 SetLastError( ERROR_INVALID_PARAMETER
);
814 lpBuffer
= GlobalAlloc(GMEM_FIXED
,
815 *lpcchSize
* sizeof(WCHAR
));
816 if (lpBuffer
== NULL
)
819 bResult
= GetUserProfileDirectoryW(hToken
,
824 WideCharToMultiByte(CP_ACP
,
834 GlobalFree(lpBuffer
);
842 GetUserProfileDirectoryW(HANDLE hToken
,
846 UNICODE_STRING SidString
;
847 WCHAR szKeyName
[MAX_PATH
];
848 WCHAR szRawImagePath
[MAX_PATH
];
849 WCHAR szImagePath
[MAX_PATH
];
856 SetLastError(ERROR_INVALID_HANDLE
);
862 SetLastError(ERROR_INVALID_PARAMETER
);
866 if (!GetUserSidStringFromToken(hToken
,
869 DPRINT1("GetUserSidFromToken() failed\n");
873 DPRINT("SidString: '%wZ'\n", &SidString
);
876 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
880 RtlFreeUnicodeString(&SidString
);
882 DPRINT("KeyName: '%S'\n", szKeyName
);
884 Error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
889 if (Error
!= ERROR_SUCCESS
)
891 DPRINT1("Error: %lu\n", Error
);
892 SetLastError((DWORD
)Error
);
896 dwLength
= sizeof(szRawImagePath
);
897 Error
= RegQueryValueExW(hKey
,
901 (LPBYTE
)szRawImagePath
,
903 if (Error
!= ERROR_SUCCESS
)
905 DPRINT1("Error: %lu\n", Error
);
907 SetLastError((DWORD
)Error
);
913 DPRINT("RawImagePath: '%S'\n", szRawImagePath
);
916 if (!ExpandEnvironmentStringsW(szRawImagePath
,
920 DPRINT1 ("Error: %lu\n", GetLastError());
924 DPRINT("ImagePath: '%S'\n", szImagePath
);
926 dwLength
= wcslen (szImagePath
) + 1;
927 if (*lpcchSize
< dwLength
)
929 *lpcchSize
= dwLength
;
930 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
934 *lpcchSize
= dwLength
;
935 wcscpy(lpProfileDir
, szImagePath
);
943 CheckForLoadedProfile(HANDLE hToken
)
945 UNICODE_STRING SidString
;
948 DPRINT("CheckForLoadedProfile() called\n");
950 if (!GetUserSidStringFromToken(hToken
,
953 DPRINT1("GetUserSidFromToken() failed\n");
957 if (RegOpenKeyExW(HKEY_USERS
,
963 DPRINT("Profile not loaded\n");
964 RtlFreeUnicodeString(&SidString
);
970 RtlFreeUnicodeString(&SidString
);
972 DPRINT("Profile already loaded\n");
980 LoadUserProfileA(IN HANDLE hToken
,
981 IN OUT LPPROFILEINFOA lpProfileInfo
)
983 BOOL bResult
= FALSE
;
984 PROFILEINFOW ProfileInfoW
= {0};
987 DPRINT("LoadUserProfileA() called\n");
989 /* Check profile info */
990 if (!lpProfileInfo
|| (lpProfileInfo
->dwSize
!= sizeof(PROFILEINFOA
)) ||
991 (lpProfileInfo
->lpUserName
== NULL
) || (lpProfileInfo
->lpUserName
[0] == 0))
993 SetLastError(ERROR_INVALID_PARAMETER
);
997 /* Convert the structure to UNICODE... */
998 ProfileInfoW
.dwSize
= sizeof(PROFILEINFOW
);
999 ProfileInfoW
.dwFlags
= lpProfileInfo
->dwFlags
;
1001 if (lpProfileInfo
->lpUserName
)
1003 len
= MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpUserName
, -1, NULL
, 0);
1004 ProfileInfoW
.lpUserName
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1005 if (!ProfileInfoW
.lpUserName
)
1007 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1010 MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpUserName
, -1, ProfileInfoW
.lpUserName
, len
);
1013 if (lpProfileInfo
->lpProfilePath
)
1015 len
= MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpProfilePath
, -1, NULL
, 0);
1016 ProfileInfoW
.lpProfilePath
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1017 if (!ProfileInfoW
.lpProfilePath
)
1019 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1022 MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpProfilePath
, -1, ProfileInfoW
.lpProfilePath
, len
);
1025 if (lpProfileInfo
->lpDefaultPath
)
1027 len
= MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpDefaultPath
, -1, NULL
, 0);
1028 ProfileInfoW
.lpDefaultPath
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1029 if (!ProfileInfoW
.lpDefaultPath
)
1031 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1034 MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpDefaultPath
, -1, ProfileInfoW
.lpDefaultPath
, len
);
1037 if (lpProfileInfo
->lpServerName
)
1039 len
= MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpServerName
, -1, NULL
, 0);
1040 ProfileInfoW
.lpServerName
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1041 if (!ProfileInfoW
.lpServerName
)
1043 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1046 MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpServerName
, -1, ProfileInfoW
.lpServerName
, len
);
1049 if ((ProfileInfoW
.dwFlags
& PI_APPLYPOLICY
) != 0 && lpProfileInfo
->lpPolicyPath
)
1051 len
= MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpPolicyPath
, -1, NULL
, 0);
1052 ProfileInfoW
.lpPolicyPath
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1053 if (!ProfileInfoW
.lpPolicyPath
)
1055 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1058 MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpPolicyPath
, -1, ProfileInfoW
.lpPolicyPath
, len
);
1061 /* ... and call the UNICODE function */
1062 bResult
= LoadUserProfileW(hToken
, &ProfileInfoW
);
1064 /* Save the returned value */
1065 lpProfileInfo
->hProfile
= ProfileInfoW
.hProfile
;
1068 /* Memory cleanup */
1069 if (ProfileInfoW
.lpUserName
)
1070 HeapFree(GetProcessHeap(), 0, ProfileInfoW
.lpUserName
);
1072 if (ProfileInfoW
.lpProfilePath
)
1073 HeapFree(GetProcessHeap(), 0, ProfileInfoW
.lpProfilePath
);
1075 if (ProfileInfoW
.lpDefaultPath
)
1076 HeapFree(GetProcessHeap(), 0, ProfileInfoW
.lpDefaultPath
);
1078 if (ProfileInfoW
.lpServerName
)
1079 HeapFree(GetProcessHeap(), 0, ProfileInfoW
.lpServerName
);
1081 if ((ProfileInfoW
.dwFlags
& PI_APPLYPOLICY
) != 0 && ProfileInfoW
.lpPolicyPath
)
1082 HeapFree(GetProcessHeap(), 0, ProfileInfoW
.lpPolicyPath
);
1090 LoadUserProfileW(IN HANDLE hToken
,
1091 IN OUT LPPROFILEINFOW lpProfileInfo
)
1093 WCHAR szUserHivePath
[MAX_PATH
];
1094 LPWSTR UserName
= NULL
, Domain
= NULL
;
1095 DWORD UserNameLength
= 0, DomainLength
= 0;
1096 PTOKEN_USER UserSid
= NULL
;
1097 SID_NAME_USE AccountType
;
1098 UNICODE_STRING SidString
= { 0, 0, NULL
};
1101 DWORD dwLength
= sizeof(szUserHivePath
) / sizeof(szUserHivePath
[0]);
1103 DPRINT("LoadUserProfileW() called\n");
1105 /* Check profile info */
1106 if (!lpProfileInfo
|| (lpProfileInfo
->dwSize
!= sizeof(PROFILEINFOW
)) ||
1107 (lpProfileInfo
->lpUserName
== NULL
) || (lpProfileInfo
->lpUserName
[0] == 0))
1109 SetLastError(ERROR_INVALID_PARAMETER
);
1113 /* Don't load a profile twice */
1114 if (CheckForLoadedProfile(hToken
))
1116 DPRINT ("Profile already loaded\n");
1117 lpProfileInfo
->hProfile
= NULL
;
1121 if (lpProfileInfo
->lpProfilePath
)
1123 wcscpy(szUserHivePath
, lpProfileInfo
->lpProfilePath
);
1127 /* FIXME: check if MS Windows allows lpProfileInfo->lpProfilePath to be NULL */
1128 if (!GetProfilesDirectoryW(szUserHivePath
, &dwLength
))
1130 DPRINT1("GetProfilesDirectoryW() failed (error %ld)\n", GetLastError());
1135 /* Create user hive name */
1136 wcscat(szUserHivePath
, L
"\\");
1137 wcscat(szUserHivePath
, lpProfileInfo
->lpUserName
);
1138 wcscat(szUserHivePath
, L
"\\ntuser.dat");
1139 DPRINT("szUserHivePath: %S\n", szUserHivePath
);
1141 /* Create user profile directory if needed */
1142 if (GetFileAttributesW(szUserHivePath
) == INVALID_FILE_ATTRIBUTES
)
1145 if (GetTokenInformation(hToken
, TokenUser
, NULL
, 0, &dwLength
) ||
1146 GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
1148 DPRINT1 ("GetTokenInformation() failed\n");
1152 UserSid
= (PTOKEN_USER
)HeapAlloc(GetProcessHeap(), 0, dwLength
);
1155 DPRINT1("HeapAlloc() failed\n");
1156 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1160 if (!GetTokenInformation(hToken
, TokenUser
, UserSid
, dwLength
, &dwLength
))
1162 DPRINT1("GetTokenInformation() failed\n");
1169 if (UserNameLength
> 0)
1171 HeapFree(GetProcessHeap(), 0, UserName
);
1172 UserName
= (LPWSTR
)HeapAlloc(GetProcessHeap(), 0, UserNameLength
* sizeof(WCHAR
));
1175 DPRINT1("HeapAlloc() failed\n");
1176 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1180 if (DomainLength
> 0)
1182 HeapFree(GetProcessHeap(), 0, Domain
);
1183 Domain
= (LPWSTR
)HeapAlloc(GetProcessHeap(), 0, DomainLength
* sizeof(WCHAR
));
1186 DPRINT1("HeapAlloc() failed\n");
1187 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1191 ret
= LookupAccountSidW(NULL
,
1198 } while (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
);
1202 DPRINT1("LookupAccountSidW() failed\n");
1206 /* Create profile */
1207 /* FIXME: ignore Domain? */
1208 DPRINT("UserName %S, Domain %S\n", UserName
, Domain
);
1209 ret
= CreateUserProfileW(UserSid
->User
.Sid
, UserName
);
1212 DPRINT1("CreateUserProfileW() failed\n");
1217 /* Get user SID string */
1218 ret
= GetUserSidStringFromToken(hToken
, &SidString
);
1221 DPRINT1("GetUserSidFromToken() failed\n");
1226 /* Acquire restore privilege */
1227 if (!AcquireRemoveRestorePrivilege(TRUE
))
1229 DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
1233 /* Load user registry hive */
1234 Error
= RegLoadKeyW(HKEY_USERS
,
1237 AcquireRemoveRestorePrivilege(FALSE
);
1239 /* HACK: Do not fail if the profile has already been loaded! */
1240 if (Error
== ERROR_SHARING_VIOLATION
)
1241 Error
= ERROR_SUCCESS
;
1243 if (Error
!= ERROR_SUCCESS
)
1245 DPRINT1("RegLoadKeyW() failed (Error %ld)\n", Error
);
1246 SetLastError((DWORD
)Error
);
1250 /* Open future HKEY_CURRENT_USER */
1251 Error
= RegOpenKeyExW(HKEY_USERS
,
1255 (PHKEY
)&lpProfileInfo
->hProfile
);
1256 if (Error
!= ERROR_SUCCESS
)
1258 DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error
);
1259 SetLastError((DWORD
)Error
);
1266 HeapFree(GetProcessHeap(), 0, UserSid
);
1267 HeapFree(GetProcessHeap(), 0, UserName
);
1268 HeapFree(GetProcessHeap(), 0, Domain
);
1269 RtlFreeUnicodeString(&SidString
);
1271 DPRINT("LoadUserProfileW() done\n");
1278 UnloadUserProfile(HANDLE hToken
,
1281 UNICODE_STRING SidString
;
1284 DPRINT("UnloadUserProfile() called\n");
1286 if (hProfile
== NULL
)
1288 DPRINT1("Invalid profile handle\n");
1289 SetLastError(ERROR_INVALID_PARAMETER
);
1293 RegCloseKey(hProfile
);
1295 if (!GetUserSidStringFromToken(hToken
,
1298 DPRINT1("GetUserSidFromToken() failed\n");
1302 DPRINT("SidString: '%wZ'\n", &SidString
);
1304 /* Acquire restore privilege */
1305 if (!AcquireRemoveRestorePrivilege(TRUE
))
1307 DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
1308 RtlFreeUnicodeString(&SidString
);
1316 Error
= RegOpenKeyExW(HKEY_USERS
,
1321 if (Error
== ERROR_SUCCESS
)
1323 RegDeleteKeyW(hUserKey
,
1324 L
"Volatile Environment");
1326 RegCloseKey(hUserKey
);
1331 /* Unload the hive */
1332 Error
= RegUnLoadKeyW(HKEY_USERS
,
1335 /* Remove restore privilege */
1336 AcquireRemoveRestorePrivilege(FALSE
);
1338 if (Error
!= ERROR_SUCCESS
)
1340 DPRINT1("RegUnLoadKeyW() failed (Error %ld)\n", Error
);
1341 RtlFreeUnicodeString(&SidString
);
1342 SetLastError((DWORD
)Error
);
1346 RtlFreeUnicodeString(&SidString
);
1348 DPRINT("UnloadUserProfile() done\n");
1356 DeleteProfileW(LPCWSTR lpSidString
,
1357 LPCWSTR lpProfilePath
,
1358 LPCWSTR lpComputerName
)
1360 DPRINT1("DeleteProfileW() not implemented!\n");
1367 DeleteProfileA(LPCSTR lpSidString
,
1368 LPCSTR lpProfilePath
,
1369 LPCSTR lpComputerName
)
1372 UNICODE_STRING SidString
, ProfilePath
, ComputerName
;
1374 DPRINT("DeleteProfileA() called\n");
1376 /* Conversion to UNICODE */
1378 RtlCreateUnicodeStringFromAsciiz(&SidString
,
1379 (LPSTR
)lpSidString
);
1382 RtlCreateUnicodeStringFromAsciiz(&ProfilePath
,
1383 (LPSTR
)lpProfilePath
);
1386 RtlCreateUnicodeStringFromAsciiz(&ComputerName
,
1387 (LPSTR
)lpComputerName
);
1389 /* Call the UNICODE function */
1390 bResult
= DeleteProfileW(SidString
.Buffer
,
1392 ComputerName
.Buffer
);
1394 /* Memory cleanup */
1396 RtlFreeUnicodeString(&SidString
);
1399 RtlFreeUnicodeString(&ProfilePath
);
1402 RtlFreeUnicodeString(&ComputerName
);
1410 GetProfileType(OUT PDWORD pdwFlags
)
1412 DPRINT1("GetProfileType() not implemented!\n");