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: lib/userenv/profile.c
22 * PURPOSE: User profile code
23 * PROGRAMMERS: Eric Kohl
33 /* FUNCTIONS ***************************************************************/
36 AppendSystemPostfix(LPWSTR lpName
,
39 WCHAR szSystemRoot
[MAX_PATH
];
43 /* Build profile name postfix */
44 if (!ExpandEnvironmentStringsW(L
"%SystemRoot%",
48 DPRINT1("Error: %lu\n", GetLastError());
52 _wcsupr(szSystemRoot
);
54 /* Get name postfix */
55 szSystemRoot
[2] = L
'.';
56 lpszPostfix
= &szSystemRoot
[2];
57 lpszPtr
= lpszPostfix
;
58 while (*lpszPtr
!= (WCHAR
)0)
60 if (*lpszPtr
== L
'\\')
65 if (wcslen(lpName
) + wcslen(lpszPostfix
) + 1 >= dwMaxLength
)
67 DPRINT1("Error: buffer overflow\n");
68 SetLastError(ERROR_BUFFER_OVERFLOW
);
72 wcscat(lpName
, lpszPostfix
);
80 AcquireRemoveRestorePrivilege(IN BOOL bAcquire
)
84 TOKEN_PRIVILEGES TokenPriv
;
86 DPRINT("AcquireRemoveRestorePrivilege(%d)\n", bAcquire
);
88 if (OpenProcessToken(GetCurrentProcess(),
89 TOKEN_ADJUST_PRIVILEGES
,
92 TokenPriv
.PrivilegeCount
= 1;
93 TokenPriv
.Privileges
[0].Attributes
= (bAcquire
? SE_PRIVILEGE_ENABLED
: 0);
95 if (LookupPrivilegeValue(NULL
, SE_RESTORE_NAME
, &TokenPriv
.Privileges
[0].Luid
))
97 bRet
= AdjustTokenPrivileges(Token
, FALSE
, &TokenPriv
, 0, NULL
, NULL
);
101 DPRINT1("AdjustTokenPrivileges() failed with error %lu\n", GetLastError());
103 else if (GetLastError() == ERROR_NOT_ALL_ASSIGNED
)
105 DPRINT1("AdjustTokenPrivileges() succeeded, but with not all privileges assigned\n");
111 DPRINT1("LookupPrivilegeValue() failed with error %lu\n", GetLastError());
118 DPRINT1("OpenProcessToken() failed with error %lu\n", GetLastError());
127 CreateUserProfileA(PSID Sid
,
130 UNICODE_STRING UserName
;
133 if (!RtlCreateUnicodeStringFromAsciiz(&UserName
,
136 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
140 bResult
= CreateUserProfileW(Sid
, UserName
.Buffer
);
142 RtlFreeUnicodeString(&UserName
);
150 CreateUserProfileW(PSID Sid
,
153 WCHAR szRawProfilesPath
[MAX_PATH
];
154 WCHAR szProfilesPath
[MAX_PATH
];
155 WCHAR szUserProfilePath
[MAX_PATH
];
156 WCHAR szDefaultUserPath
[MAX_PATH
];
157 WCHAR szUserProfileName
[MAX_PATH
];
158 WCHAR szBuffer
[MAX_PATH
];
167 DPRINT("CreateUserProfileW() called\n");
169 Error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
170 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
174 if (Error
!= ERROR_SUCCESS
)
176 DPRINT1("Error: %lu\n", Error
);
177 SetLastError((DWORD
)Error
);
181 /* Get profiles path */
182 dwLength
= MAX_PATH
* sizeof(WCHAR
);
183 Error
= RegQueryValueExW(hKey
,
184 L
"ProfilesDirectory",
187 (LPBYTE
)szRawProfilesPath
,
189 if (Error
!= ERROR_SUCCESS
)
191 DPRINT1("Error: %lu\n", Error
);
193 SetLastError((DWORD
)Error
);
198 if (!ExpandEnvironmentStringsW(szRawProfilesPath
,
202 DPRINT1("Error: %lu\n", GetLastError());
207 /* create the profiles directory if it does not yet exist */
208 if (!CreateDirectoryW(szProfilesPath
, NULL
))
210 if (GetLastError() != ERROR_ALREADY_EXISTS
)
212 DPRINT1("Error: %lu\n", GetLastError());
217 /* Get default user path */
218 dwLength
= MAX_PATH
* sizeof(WCHAR
);
219 Error
= RegQueryValueExW(hKey
,
220 L
"DefaultUserProfile",
225 if (Error
!= ERROR_SUCCESS
)
227 DPRINT1("Error: %lu\n", Error
);
229 SetLastError((DWORD
)Error
);
235 wcscpy(szUserProfileName
, lpUserName
);
237 wcscpy(szUserProfilePath
, szProfilesPath
);
238 wcscat(szUserProfilePath
, L
"\\");
239 wcscat(szUserProfilePath
, szUserProfileName
);
241 wcscpy(szDefaultUserPath
, szProfilesPath
);
242 wcscat(szDefaultUserPath
, L
"\\");
243 wcscat(szDefaultUserPath
, szBuffer
);
245 /* Create user profile directory */
246 if (!CreateDirectoryW(szUserProfilePath
, NULL
))
248 if (GetLastError() != ERROR_ALREADY_EXISTS
)
250 DPRINT1("Error: %lu\n", GetLastError());
254 for (i
= 0; i
< 1000; i
++)
256 swprintf(szUserProfileName
, L
"%s.%03u", lpUserName
, i
);
258 wcscpy(szUserProfilePath
, szProfilesPath
);
259 wcscat(szUserProfilePath
, L
"\\");
260 wcscat(szUserProfilePath
, szUserProfileName
);
262 if (CreateDirectoryW(szUserProfilePath
, NULL
))
265 if (GetLastError() != ERROR_ALREADY_EXISTS
)
267 DPRINT1("Error: %lu\n", GetLastError());
273 /* Copy default user directory */
274 if (!CopyDirectory(szUserProfilePath
, szDefaultUserPath
))
276 DPRINT1("Error: %lu\n", GetLastError());
280 /* Add profile to profile list */
281 if (!ConvertSidToStringSidW(Sid
,
284 DPRINT1("Error: %lu\n", GetLastError());
289 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
290 wcscat(szBuffer
, SidString
);
292 /* Create user profile key */
293 Error
= RegCreateKeyExW(HKEY_LOCAL_MACHINE
,
297 REG_OPTION_NON_VOLATILE
,
302 if (Error
!= ERROR_SUCCESS
)
304 DPRINT1("Error: %lu\n", Error
);
309 /* Create non-expanded user profile path */
310 wcscpy(szBuffer
, szRawProfilesPath
);
311 wcscat(szBuffer
, L
"\\");
312 wcscat(szBuffer
, szUserProfileName
);
314 /* Set 'ProfileImagePath' value (non-expanded) */
315 Error
= RegSetValueExW(hKey
,
320 (wcslen (szBuffer
) + 1) * sizeof(WCHAR
));
321 if (Error
!= ERROR_SUCCESS
)
323 DPRINT1("Error: %lu\n", Error
);
329 /* Set 'Sid' value */
330 Error
= RegSetValueExW(hKey
,
336 if (Error
!= ERROR_SUCCESS
)
338 DPRINT1("Error: %lu\n", Error
);
346 /* Create user hive name */
347 wcscpy(szBuffer
, szUserProfilePath
);
348 wcscat(szBuffer
, L
"\\ntuser.dat");
350 /* Acquire restore privilege */
351 if (!AcquireRemoveRestorePrivilege(TRUE
))
353 Error
= GetLastError();
354 DPRINT1("Error: %lu\n", Error
);
359 /* Create new user hive */
360 Error
= RegLoadKeyW(HKEY_USERS
,
363 AcquireRemoveRestorePrivilege(FALSE
);
364 if (Error
!= ERROR_SUCCESS
)
366 DPRINT1("Error: %lu\n", Error
);
371 /* Initialize user hive */
372 if (!CreateUserHive(SidString
, szUserProfilePath
))
374 Error
= GetLastError();
375 DPRINT1("Error: %lu\n", Error
);
379 /* Unload the hive */
380 AcquireRemoveRestorePrivilege(TRUE
);
381 RegUnLoadKeyW(HKEY_USERS
, SidString
);
382 AcquireRemoveRestorePrivilege(FALSE
);
385 LocalFree((HLOCAL
)SidString
);
386 SetLastError((DWORD
)Error
);
388 DPRINT("CreateUserProfileW() done\n");
396 CreateUserProfileExA(IN PSID pSid
,
397 IN LPCSTR lpUserName
,
398 IN LPCSTR lpUserHive OPTIONAL
,
399 OUT LPSTR lpProfileDir OPTIONAL
,
403 DPRINT1("CreateUserProfileExA() not implemented!\n");
410 CreateUserProfileExW(IN PSID pSid
,
411 IN LPCWSTR lpUserName
,
412 IN LPCWSTR lpUserHive OPTIONAL
,
413 OUT LPWSTR lpProfileDir OPTIONAL
,
417 DPRINT1("CreateUserProfileExW() not implemented!\n");
424 GetAllUsersProfileDirectoryA(LPSTR lpProfileDir
,
430 lpBuffer
= GlobalAlloc(GMEM_FIXED
,
431 *lpcchSize
* sizeof(WCHAR
));
432 if (lpBuffer
== NULL
)
435 bResult
= GetAllUsersProfileDirectoryW(lpBuffer
,
439 WideCharToMultiByte(CP_ACP
,
449 GlobalFree(lpBuffer
);
457 GetAllUsersProfileDirectoryW(LPWSTR lpProfileDir
,
460 WCHAR szProfilePath
[MAX_PATH
];
461 WCHAR szBuffer
[MAX_PATH
];
466 Error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
467 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
471 if (Error
!= ERROR_SUCCESS
)
473 DPRINT1("Error: %lu\n", Error
);
474 SetLastError((DWORD
)Error
);
478 /* Get profiles path */
479 dwLength
= sizeof(szBuffer
);
480 Error
= RegQueryValueExW(hKey
,
481 L
"ProfilesDirectory",
486 if (Error
!= ERROR_SUCCESS
)
488 DPRINT1("Error: %lu\n", Error
);
490 SetLastError((DWORD
)Error
);
495 if (!ExpandEnvironmentStringsW(szBuffer
,
499 DPRINT1("Error: %lu\n", GetLastError());
504 /* Get 'AllUsersProfile' name */
505 dwLength
= sizeof(szBuffer
);
506 Error
= RegQueryValueExW(hKey
,
512 if (Error
!= ERROR_SUCCESS
)
514 DPRINT1("Error: %lu\n", Error
);
516 SetLastError((DWORD
)Error
);
522 wcscat(szProfilePath
, L
"\\");
523 wcscat(szProfilePath
, szBuffer
);
525 dwLength
= wcslen(szProfilePath
) + 1;
526 if (lpProfileDir
!= NULL
)
528 if (*lpcchSize
< dwLength
)
530 *lpcchSize
= dwLength
;
531 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
535 wcscpy(lpProfileDir
, szProfilePath
);
538 *lpcchSize
= dwLength
;
546 GetDefaultUserProfileDirectoryA(LPSTR lpProfileDir
,
552 lpBuffer
= GlobalAlloc(GMEM_FIXED
,
553 *lpcchSize
* sizeof(WCHAR
));
554 if (lpBuffer
== NULL
)
557 bResult
= GetDefaultUserProfileDirectoryW(lpBuffer
,
561 WideCharToMultiByte(CP_ACP
,
571 GlobalFree(lpBuffer
);
579 GetDefaultUserProfileDirectoryW(LPWSTR lpProfileDir
,
582 WCHAR szProfilePath
[MAX_PATH
];
583 WCHAR szBuffer
[MAX_PATH
];
588 Error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
589 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
593 if (Error
!= ERROR_SUCCESS
)
595 DPRINT1("Error: %lu\n", Error
);
596 SetLastError((DWORD
)Error
);
600 /* Get profiles path */
601 dwLength
= sizeof(szBuffer
);
602 Error
= RegQueryValueExW(hKey
,
603 L
"ProfilesDirectory",
608 if (Error
!= ERROR_SUCCESS
)
610 DPRINT1("Error: %lu\n", Error
);
612 SetLastError((DWORD
)Error
);
617 if (!ExpandEnvironmentStringsW(szBuffer
,
621 DPRINT1("Error: %lu\n", GetLastError());
626 /* Get 'DefaultUserProfile' name */
627 dwLength
= sizeof(szBuffer
);
628 Error
= RegQueryValueExW(hKey
,
629 L
"DefaultUserProfile",
634 if (Error
!= ERROR_SUCCESS
)
636 DPRINT1("Error: %lu\n", Error
);
638 SetLastError((DWORD
)Error
);
644 wcscat(szProfilePath
, L
"\\");
645 wcscat(szProfilePath
, szBuffer
);
647 dwLength
= wcslen(szProfilePath
) + 1;
648 if (lpProfileDir
!= NULL
)
650 if (*lpcchSize
< dwLength
)
652 *lpcchSize
= dwLength
;
653 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
657 wcscpy(lpProfileDir
, szProfilePath
);
660 *lpcchSize
= dwLength
;
668 GetProfilesDirectoryA(LPSTR lpProfileDir
,
674 lpBuffer
= GlobalAlloc(GMEM_FIXED
,
675 *lpcchSize
* sizeof(WCHAR
));
676 if (lpBuffer
== NULL
)
679 bResult
= GetProfilesDirectoryW(lpBuffer
,
683 WideCharToMultiByte(CP_ACP
,
693 GlobalFree(lpBuffer
);
701 GetProfilesDirectoryW(LPWSTR lpProfilesDir
,
704 WCHAR szProfilesPath
[MAX_PATH
];
705 WCHAR szBuffer
[MAX_PATH
];
710 Error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
711 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
715 if (Error
!= ERROR_SUCCESS
)
717 DPRINT1("Error: %lu\n", Error
);
718 SetLastError((DWORD
)Error
);
722 /* Get profiles path */
723 dwLength
= sizeof(szBuffer
);
724 Error
= RegQueryValueExW(hKey
,
725 L
"ProfilesDirectory",
730 if (Error
!= ERROR_SUCCESS
)
732 DPRINT1("Error: %lu\n", Error
);
734 SetLastError((DWORD
)Error
);
741 if (!ExpandEnvironmentStringsW(szBuffer
,
745 DPRINT1("Error: %lu\n", GetLastError());
749 dwLength
= wcslen (szProfilesPath
) + 1;
750 if (lpProfilesDir
!= NULL
)
752 if (*lpcchSize
< dwLength
)
754 *lpcchSize
= dwLength
;
755 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
759 wcscpy(lpProfilesDir
, szProfilesPath
);
762 *lpcchSize
= dwLength
;
770 GetUserProfileDirectoryA(HANDLE hToken
,
777 lpBuffer
= GlobalAlloc(GMEM_FIXED
,
778 *lpcchSize
* sizeof(WCHAR
));
779 if (lpBuffer
== NULL
)
782 bResult
= GetUserProfileDirectoryW(hToken
,
787 WideCharToMultiByte(CP_ACP
,
797 GlobalFree(lpBuffer
);
805 GetUserProfileDirectoryW(HANDLE hToken
,
809 UNICODE_STRING SidString
;
810 WCHAR szKeyName
[MAX_PATH
];
811 WCHAR szRawImagePath
[MAX_PATH
];
812 WCHAR szImagePath
[MAX_PATH
];
817 if (!GetUserSidFromToken(hToken
,
820 DPRINT1("GetUserSidFromToken() failed\n");
824 DPRINT("SidString: '%wZ'\n", &SidString
);
827 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
831 RtlFreeUnicodeString(&SidString
);
833 DPRINT("KeyName: '%S'\n", szKeyName
);
835 Error
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
,
840 if (Error
!= ERROR_SUCCESS
)
842 DPRINT1("Error: %lu\n", Error
);
843 SetLastError((DWORD
)Error
);
847 dwLength
= sizeof(szRawImagePath
);
848 Error
= RegQueryValueExW(hKey
,
852 (LPBYTE
)szRawImagePath
,
854 if (Error
!= ERROR_SUCCESS
)
856 DPRINT1("Error: %lu\n", Error
);
858 SetLastError((DWORD
)Error
);
864 DPRINT("RawImagePath: '%S'\n", szRawImagePath
);
867 if (!ExpandEnvironmentStringsW(szRawImagePath
,
871 DPRINT1 ("Error: %lu\n", GetLastError());
875 DPRINT("ImagePath: '%S'\n", szImagePath
);
877 dwLength
= wcslen (szImagePath
) + 1;
878 if (*lpcchSize
< dwLength
)
880 *lpcchSize
= dwLength
;
881 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
885 *lpcchSize
= dwLength
;
886 wcscpy(lpProfileDir
, szImagePath
);
894 CheckForLoadedProfile(HANDLE hToken
)
896 UNICODE_STRING SidString
;
899 DPRINT("CheckForLoadedProfile() called\n");
901 if (!GetUserSidFromToken(hToken
,
904 DPRINT1("GetUserSidFromToken() failed\n");
908 if (RegOpenKeyExW(HKEY_USERS
,
914 DPRINT("Profile not loaded\n");
915 RtlFreeUnicodeString(&SidString
);
921 RtlFreeUnicodeString(&SidString
);
923 DPRINT("Profile already loaded\n");
931 LoadUserProfileA(IN HANDLE hToken
,
932 IN OUT LPPROFILEINFOA lpProfileInfo
)
934 BOOL bResult
= FALSE
;
935 PROFILEINFOW ProfileInfoW
= {0};
938 DPRINT("LoadUserProfileA() called\n");
940 /* Check profile info */
941 if (!lpProfileInfo
|| (lpProfileInfo
->dwSize
!= sizeof(PROFILEINFOA
)) ||
942 (lpProfileInfo
->lpUserName
== NULL
) || (lpProfileInfo
->lpUserName
[0] == 0))
944 SetLastError(ERROR_INVALID_PARAMETER
);
948 /* Convert the structure to UNICODE... */
949 ProfileInfoW
.dwSize
= sizeof(PROFILEINFOW
);
950 ProfileInfoW
.dwFlags
= lpProfileInfo
->dwFlags
;
952 if (lpProfileInfo
->lpUserName
)
954 len
= MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpUserName
, -1, NULL
, 0);
955 ProfileInfoW
.lpUserName
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
956 if (!ProfileInfoW
.lpUserName
)
958 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
961 MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpUserName
, -1, ProfileInfoW
.lpUserName
, len
);
964 if (lpProfileInfo
->lpProfilePath
)
966 len
= MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpProfilePath
, -1, NULL
, 0);
967 ProfileInfoW
.lpProfilePath
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
968 if (!ProfileInfoW
.lpProfilePath
)
970 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
973 MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpProfilePath
, -1, ProfileInfoW
.lpProfilePath
, len
);
976 if (lpProfileInfo
->lpDefaultPath
)
978 len
= MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpDefaultPath
, -1, NULL
, 0);
979 ProfileInfoW
.lpDefaultPath
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
980 if (!ProfileInfoW
.lpDefaultPath
)
982 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
985 MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpDefaultPath
, -1, ProfileInfoW
.lpDefaultPath
, len
);
988 if (lpProfileInfo
->lpServerName
)
990 len
= MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpServerName
, -1, NULL
, 0);
991 ProfileInfoW
.lpServerName
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
992 if (!ProfileInfoW
.lpServerName
)
994 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
997 MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpServerName
, -1, ProfileInfoW
.lpServerName
, len
);
1000 if ((ProfileInfoW
.dwFlags
& PI_APPLYPOLICY
) != 0 && lpProfileInfo
->lpPolicyPath
)
1002 len
= MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpPolicyPath
, -1, NULL
, 0);
1003 ProfileInfoW
.lpPolicyPath
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1004 if (!ProfileInfoW
.lpPolicyPath
)
1006 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1009 MultiByteToWideChar(CP_ACP
, 0, lpProfileInfo
->lpPolicyPath
, -1, ProfileInfoW
.lpPolicyPath
, len
);
1012 /* ... and call the UNICODE function */
1013 bResult
= LoadUserProfileW(hToken
, &ProfileInfoW
);
1015 /* Save the returned value */
1016 lpProfileInfo
->hProfile
= ProfileInfoW
.hProfile
;
1019 /* Memory cleanup */
1020 if (ProfileInfoW
.lpUserName
)
1021 HeapFree(GetProcessHeap(), 0, ProfileInfoW
.lpUserName
);
1023 if (ProfileInfoW
.lpProfilePath
)
1024 HeapFree(GetProcessHeap(), 0, ProfileInfoW
.lpProfilePath
);
1026 if (ProfileInfoW
.lpDefaultPath
)
1027 HeapFree(GetProcessHeap(), 0, ProfileInfoW
.lpDefaultPath
);
1029 if (ProfileInfoW
.lpServerName
)
1030 HeapFree(GetProcessHeap(), 0, ProfileInfoW
.lpServerName
);
1032 if ((ProfileInfoW
.dwFlags
& PI_APPLYPOLICY
) != 0 && ProfileInfoW
.lpPolicyPath
)
1033 HeapFree(GetProcessHeap(), 0, ProfileInfoW
.lpPolicyPath
);
1041 LoadUserProfileW(IN HANDLE hToken
,
1042 IN OUT LPPROFILEINFOW lpProfileInfo
)
1044 WCHAR szUserHivePath
[MAX_PATH
];
1045 LPWSTR UserName
= NULL
, Domain
= NULL
;
1046 DWORD UserNameLength
= 0, DomainLength
= 0;
1047 PTOKEN_USER UserSid
= NULL
;
1048 SID_NAME_USE AccountType
;
1049 UNICODE_STRING SidString
= { 0, 0, NULL
};
1052 DWORD dwLength
= sizeof(szUserHivePath
) / sizeof(szUserHivePath
[0]);
1054 DPRINT("LoadUserProfileW() called\n");
1056 /* Check profile info */
1057 if (!lpProfileInfo
|| (lpProfileInfo
->dwSize
!= sizeof(PROFILEINFOW
)) ||
1058 (lpProfileInfo
->lpUserName
== NULL
) || (lpProfileInfo
->lpUserName
[0] == 0))
1060 SetLastError(ERROR_INVALID_PARAMETER
);
1064 /* Don't load a profile twice */
1065 if (CheckForLoadedProfile(hToken
))
1067 DPRINT ("Profile already loaded\n");
1068 lpProfileInfo
->hProfile
= NULL
;
1072 if (lpProfileInfo
->lpProfilePath
)
1074 wcscpy(szUserHivePath
, lpProfileInfo
->lpProfilePath
);
1078 /* FIXME: check if MS Windows allows lpProfileInfo->lpProfilePath to be NULL */
1079 if (!GetProfilesDirectoryW(szUserHivePath
, &dwLength
))
1081 DPRINT1("GetProfilesDirectoryW() failed (error %ld)\n", GetLastError());
1086 /* Create user hive name */
1087 wcscat(szUserHivePath
, L
"\\");
1088 wcscat(szUserHivePath
, lpProfileInfo
->lpUserName
);
1089 wcscat(szUserHivePath
, L
"\\ntuser.dat");
1090 DPRINT("szUserHivePath: %S\n", szUserHivePath
);
1092 /* Create user profile directory if needed */
1093 if (GetFileAttributesW(szUserHivePath
) == INVALID_FILE_ATTRIBUTES
)
1096 if (GetTokenInformation(hToken
, TokenUser
, NULL
, 0, &dwLength
) ||
1097 GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
1099 DPRINT1 ("GetTokenInformation() failed\n");
1103 UserSid
= (PTOKEN_USER
)HeapAlloc(GetProcessHeap(), 0, dwLength
);
1106 DPRINT1("HeapAlloc() failed\n");
1107 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1111 if (!GetTokenInformation(hToken
, TokenUser
, UserSid
, dwLength
, &dwLength
))
1113 DPRINT1("GetTokenInformation() failed\n");
1120 if (UserNameLength
> 0)
1122 HeapFree(GetProcessHeap(), 0, UserName
);
1123 UserName
= (LPWSTR
)HeapAlloc(GetProcessHeap(), 0, UserNameLength
* sizeof(WCHAR
));
1126 DPRINT1("HeapAlloc() failed\n");
1127 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1131 if (DomainLength
> 0)
1133 HeapFree(GetProcessHeap(), 0, Domain
);
1134 Domain
= (LPWSTR
)HeapAlloc(GetProcessHeap(), 0, DomainLength
* sizeof(WCHAR
));
1137 DPRINT1("HeapAlloc() failed\n");
1138 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1142 ret
= LookupAccountSidW(NULL
,
1149 } while (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
);
1153 DPRINT1("LookupAccountSidW() failed\n");
1157 /* Create profile */
1158 /* FIXME: ignore Domain? */
1159 DPRINT("UserName %S, Domain %S\n", UserName
, Domain
);
1160 ret
= CreateUserProfileW(UserSid
->User
.Sid
, UserName
);
1163 DPRINT1("CreateUserProfileW() failed\n");
1168 /* Get user SID string */
1169 ret
= GetUserSidFromToken(hToken
, &SidString
);
1172 DPRINT1("GetUserSidFromToken() failed\n");
1177 /* Acquire restore privilege */
1178 if (!AcquireRemoveRestorePrivilege(TRUE
))
1180 DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
1184 /* Load user registry hive */
1185 Error
= RegLoadKeyW(HKEY_USERS
,
1188 AcquireRemoveRestorePrivilege(FALSE
);
1189 if (Error
!= ERROR_SUCCESS
)
1191 DPRINT1("RegLoadKeyW() failed (Error %ld)\n", Error
);
1192 SetLastError((DWORD
)Error
);
1196 /* Open future HKEY_CURRENT_USER */
1197 Error
= RegOpenKeyExW(HKEY_USERS
,
1201 (PHKEY
)&lpProfileInfo
->hProfile
);
1202 if (Error
!= ERROR_SUCCESS
)
1204 DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error
);
1205 SetLastError((DWORD
)Error
);
1212 HeapFree(GetProcessHeap(), 0, UserSid
);
1213 HeapFree(GetProcessHeap(), 0, UserName
);
1214 HeapFree(GetProcessHeap(), 0, Domain
);
1215 RtlFreeUnicodeString(&SidString
);
1217 DPRINT("LoadUserProfileW() done\n");
1224 UnloadUserProfile(HANDLE hToken
,
1227 UNICODE_STRING SidString
;
1230 DPRINT("UnloadUserProfile() called\n");
1232 if (hProfile
== NULL
)
1234 DPRINT1("Invalid profile handle\n");
1235 SetLastError(ERROR_INVALID_PARAMETER
);
1239 RegCloseKey(hProfile
);
1241 if (!GetUserSidFromToken(hToken
,
1244 DPRINT1("GetUserSidFromToken() failed\n");
1248 DPRINT("SidString: '%wZ'\n", &SidString
);
1250 /* Acquire restore privilege */
1251 if (!AcquireRemoveRestorePrivilege(TRUE
))
1253 DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
1254 RtlFreeUnicodeString(&SidString
);
1258 /* Unload the hive */
1259 Error
= RegUnLoadKeyW(HKEY_USERS
,
1262 /* Remove restore privilege */
1263 AcquireRemoveRestorePrivilege(FALSE
);
1265 if (Error
!= ERROR_SUCCESS
)
1267 DPRINT1("RegUnLoadKeyW() failed (Error %ld)\n", Error
);
1268 RtlFreeUnicodeString(&SidString
);
1269 SetLastError((DWORD
)Error
);
1273 RtlFreeUnicodeString(&SidString
);
1275 DPRINT("UnloadUserProfile() done\n");
1283 DeleteProfileW(LPCWSTR lpSidString
,
1284 LPCWSTR lpProfilePath
,
1285 LPCWSTR lpComputerName
)
1287 DPRINT1("DeleteProfileW() not implemented!\n");
1294 DeleteProfileA(LPCSTR lpSidString
,
1295 LPCSTR lpProfilePath
,
1296 LPCSTR lpComputerName
)
1299 UNICODE_STRING SidString
, ProfilePath
, ComputerName
;
1301 DPRINT("DeleteProfileA() called\n");
1303 /* Conversion to UNICODE */
1305 RtlCreateUnicodeStringFromAsciiz(&SidString
,
1306 (LPSTR
)lpSidString
);
1309 RtlCreateUnicodeStringFromAsciiz(&ProfilePath
,
1310 (LPSTR
)lpProfilePath
);
1313 RtlCreateUnicodeStringFromAsciiz(&ComputerName
,
1314 (LPSTR
)lpComputerName
);
1316 /* Call the UNICODE function */
1317 bResult
= DeleteProfileW(SidString
.Buffer
,
1319 ComputerName
.Buffer
);
1321 /* Memory cleanup */
1323 RtlFreeUnicodeString(&SidString
);
1326 RtlFreeUnicodeString(&ProfilePath
);
1329 RtlFreeUnicodeString(&ComputerName
);
1337 GetProfileType(OUT PDWORD pdwFlags
)
1339 DPRINT1("GetProfileType() not implemented!\n");