1 /* $Id: profile.c,v 1.11 2004/05/03 12:05:44 ekohl Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/userenv/profile.c
6 * PURPOSE: User profile code
7 * PROGRAMMER: Eric Kohl
19 /* FUNCTIONS ***************************************************************/
22 AppendSystemPostfix (LPWSTR lpName
,
25 WCHAR szSystemRoot
[MAX_PATH
];
26 WCHAR szDrivePostfix
[3];
29 DWORD dwPostfixLength
;
31 /* Build profile name postfix */
32 if (!ExpandEnvironmentStringsW (L
"%SystemRoot%",
36 DPRINT1("Error: %lu\n", GetLastError());
40 _wcsupr (szSystemRoot
);
42 /* Get name postfix */
43 szSystemRoot
[2] = L
'.';
44 lpszPostfix
= &szSystemRoot
[2];
45 lpszPtr
= lpszPostfix
;
46 while (*lpszPtr
!= (WCHAR
)0)
48 if (*lpszPtr
== L
'\\')
53 dwPostfixLength
= wcslen (lpszPostfix
);
54 if (szSystemRoot
[0] != L
'C')
57 szDrivePostfix
[0] = L
'_';
58 szDrivePostfix
[1] = szSystemRoot
[0];
59 szDrivePostfix
[2] = (WCHAR
)0;
62 if (wcslen (lpName
) + dwPostfixLength
>= dwMaxLength
)
64 DPRINT1("Error: buffer overflow\n");
68 wcscat (lpName
, lpszPostfix
);
69 if (szSystemRoot
[0] != L
'C')
71 wcscat (lpName
, szDrivePostfix
);
79 CreateUserProfileA (PSID Sid
,
82 UNICODE_STRING UserName
;
86 Status
= RtlCreateUnicodeStringFromAsciiz (&UserName
,
88 if (!NT_SUCCESS(Status
))
90 SetLastError (RtlNtStatusToDosError (Status
));
94 bResult
= CreateUserProfileW (Sid
,
97 RtlFreeUnicodeString (&UserName
);
104 CreateUserProfileW (PSID Sid
,
107 WCHAR szRawProfilesPath
[MAX_PATH
];
108 WCHAR szProfilesPath
[MAX_PATH
];
109 WCHAR szUserProfilePath
[MAX_PATH
];
110 WCHAR szDefaultUserPath
[MAX_PATH
];
111 WCHAR szBuffer
[MAX_PATH
];
112 UNICODE_STRING SidString
;
118 DPRINT ("CreateUserProfileW() called\n");
120 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
121 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
126 DPRINT1("Error: %lu\n", GetLastError());
130 /* Get profiles path */
131 dwLength
= MAX_PATH
* sizeof(WCHAR
);
132 if (RegQueryValueExW (hKey
,
133 L
"ProfilesDirectory",
136 (LPBYTE
)szRawProfilesPath
,
139 DPRINT1("Error: %lu\n", GetLastError());
145 if (!ExpandEnvironmentStringsW (szRawProfilesPath
,
149 DPRINT1("Error: %lu\n", GetLastError());
154 /* Get default user path */
155 dwLength
= MAX_PATH
* sizeof(WCHAR
);
156 if (RegQueryValueExW (hKey
,
157 L
"DefaultUserProfile",
163 DPRINT1("Error: %lu\n", GetLastError());
170 wcscpy (szUserProfilePath
, szProfilesPath
);
171 wcscat (szUserProfilePath
, L
"\\");
172 wcscat (szUserProfilePath
, lpUserName
);
173 if (!AppendSystemPostfix (szUserProfilePath
, MAX_PATH
))
175 DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
176 RtlFreeUnicodeString (&SidString
);
181 wcscpy (szDefaultUserPath
, szProfilesPath
);
182 wcscat (szDefaultUserPath
, L
"\\");
183 wcscat (szDefaultUserPath
, szBuffer
);
185 /* Create user profile directory */
186 if (!CreateDirectoryW (szUserProfilePath
, NULL
))
188 if (GetLastError () != ERROR_ALREADY_EXISTS
)
190 DPRINT1("Error: %lu\n", GetLastError());
195 /* Copy default user directory */
196 if (!CopyDirectory (szUserProfilePath
, szDefaultUserPath
))
198 DPRINT1("Error: %lu\n", GetLastError());
202 /* Add profile to profile list */
203 Status
= RtlConvertSidToUnicodeString (&SidString
, Sid
, TRUE
);
204 if (!NT_SUCCESS(Status
))
206 DPRINT1("Status: %lx\n", Status
);
211 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
212 wcscat (szBuffer
, SidString
.Buffer
);
214 /* Create user profile key */
215 if (RegCreateKeyExW (HKEY_LOCAL_MACHINE
,
219 REG_OPTION_NON_VOLATILE
,
225 DPRINT1("Error: %lu\n", GetLastError());
226 RtlFreeUnicodeString (&SidString
);
230 /* Create non-expanded user profile path */
231 wcscpy (szBuffer
, szRawProfilesPath
);
232 wcscat (szBuffer
, L
"\\");
233 wcscat (szBuffer
, lpUserName
);
234 if (!AppendSystemPostfix (szBuffer
, MAX_PATH
))
236 DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
237 RtlFreeUnicodeString (&SidString
);
242 /* Set 'ProfileImagePath' value (non-expanded) */
243 if (RegSetValueExW (hKey
,
248 (wcslen (szBuffer
) + 1) * sizeof(WCHAR
)))
250 DPRINT1("Error: %lu\n", GetLastError());
251 RtlFreeUnicodeString (&SidString
);
256 /* Set 'Sid' value */
257 if (RegSetValueExW (hKey
,
264 DPRINT1("Error: %lu\n", GetLastError());
265 RtlFreeUnicodeString (&SidString
);
272 /* Create user hive name */
273 wcscat (szUserProfilePath
, L
"\\ntuser.dat");
275 /* Create new user hive */
276 if (RegLoadKeyW (HKEY_USERS
,
280 DPRINT1("Error: %lu\n", GetLastError());
281 RtlFreeUnicodeString (&SidString
);
285 /* Initialize user hive */
286 if (!CreateUserHive (SidString
.Buffer
))
288 DPRINT1("Error: %lu\n", GetLastError());
289 RtlFreeUnicodeString (&SidString
);
293 RegUnLoadKeyW (HKEY_USERS
,
296 RtlFreeUnicodeString (&SidString
);
298 DPRINT ("CreateUserProfileW() done\n");
305 GetAllUsersProfileDirectoryA (LPSTR lpProfileDir
,
311 lpBuffer
= GlobalAlloc (GMEM_FIXED
,
312 *lpcchSize
* sizeof(WCHAR
));
313 if (lpBuffer
== NULL
)
316 bResult
= GetAllUsersProfileDirectoryW (lpBuffer
,
320 WideCharToMultiByte (CP_ACP
,
330 GlobalFree (lpBuffer
);
337 GetAllUsersProfileDirectoryW (LPWSTR lpProfileDir
,
340 WCHAR szProfilePath
[MAX_PATH
];
341 WCHAR szBuffer
[MAX_PATH
];
345 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
346 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
351 DPRINT1("Error: %lu\n", GetLastError());
355 /* Get profiles path */
356 dwLength
= MAX_PATH
* sizeof(WCHAR
);
357 if (RegQueryValueExW (hKey
,
358 L
"ProfilesDirectory",
364 DPRINT1("Error: %lu\n", GetLastError());
370 if (!ExpandEnvironmentStringsW (szBuffer
,
374 DPRINT1("Error: %lu\n", GetLastError());
379 /* Get 'AllUsersProfile' name */
380 dwLength
= MAX_PATH
* sizeof(WCHAR
);
381 if (RegQueryValueExW (hKey
,
388 DPRINT1("Error: %lu\n", GetLastError());
395 wcscat (szProfilePath
, L
"\\");
396 wcscat (szProfilePath
, szBuffer
);
398 dwLength
= wcslen (szProfilePath
);
399 if (lpProfileDir
!= NULL
)
401 if (*lpcchSize
< dwLength
)
403 *lpcchSize
= dwLength
;
404 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
408 wcscpy (lpProfileDir
, szProfilePath
);
411 *lpcchSize
= dwLength
;
418 GetDefaultUserProfileDirectoryA (LPSTR lpProfileDir
,
424 lpBuffer
= GlobalAlloc (GMEM_FIXED
,
425 *lpcchSize
* sizeof(WCHAR
));
426 if (lpBuffer
== NULL
)
429 bResult
= GetDefaultUserProfileDirectoryW (lpBuffer
,
433 WideCharToMultiByte (CP_ACP
,
443 GlobalFree (lpBuffer
);
450 GetDefaultUserProfileDirectoryW (LPWSTR lpProfileDir
,
453 WCHAR szProfilePath
[MAX_PATH
];
454 WCHAR szBuffer
[MAX_PATH
];
458 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
459 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
464 DPRINT1("Error: %lu\n", GetLastError());
468 /* Get profiles path */
469 dwLength
= MAX_PATH
* sizeof(WCHAR
);
470 if (RegQueryValueExW (hKey
,
471 L
"ProfilesDirectory",
477 DPRINT1("Error: %lu\n", GetLastError());
483 if (!ExpandEnvironmentStringsW (szBuffer
,
487 DPRINT1("Error: %lu\n", GetLastError());
492 /* Get 'DefaultUserProfile' name */
493 dwLength
= MAX_PATH
* sizeof(WCHAR
);
494 if (RegQueryValueExW (hKey
,
495 L
"DefaultUserProfile",
501 DPRINT1("Error: %lu\n", GetLastError());
508 wcscat (szProfilePath
, L
"\\");
509 wcscat (szProfilePath
, szBuffer
);
511 dwLength
= wcslen (szProfilePath
);
512 if (lpProfileDir
!= NULL
)
514 if (*lpcchSize
< dwLength
)
516 *lpcchSize
= dwLength
;
517 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
521 wcscpy (lpProfileDir
, szProfilePath
);
524 *lpcchSize
= dwLength
;
531 GetProfilesDirectoryA (LPSTR lpProfileDir
,
537 lpBuffer
= GlobalAlloc (GMEM_FIXED
,
538 *lpcchSize
* sizeof(WCHAR
));
539 if (lpBuffer
== NULL
)
542 bResult
= GetProfilesDirectoryW (lpBuffer
,
546 WideCharToMultiByte (CP_ACP
,
556 GlobalFree (lpBuffer
);
563 GetProfilesDirectoryW (LPWSTR lpProfilesDir
,
566 WCHAR szProfilesPath
[MAX_PATH
];
567 WCHAR szBuffer
[MAX_PATH
];
571 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
572 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
577 DPRINT1("Error: %lu\n", GetLastError());
581 /* Get profiles path */
582 dwLength
= MAX_PATH
* sizeof(WCHAR
);
583 if (RegQueryValueExW (hKey
,
584 L
"ProfilesDirectory",
590 DPRINT1("Error: %lu\n", GetLastError());
598 if (!ExpandEnvironmentStringsW (szBuffer
,
602 DPRINT1("Error: %lu\n", GetLastError());
606 dwLength
= wcslen (szProfilesPath
);
607 if (lpProfilesDir
!= NULL
)
609 if (*lpcchSize
< dwLength
)
611 *lpcchSize
= dwLength
;
612 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
616 wcscpy (lpProfilesDir
, szProfilesPath
);
619 *lpcchSize
= dwLength
;
626 GetUserProfileDirectoryA (HANDLE hToken
,
633 lpBuffer
= GlobalAlloc (GMEM_FIXED
,
634 *lpcchSize
* sizeof(WCHAR
));
635 if (lpBuffer
== NULL
)
638 bResult
= GetUserProfileDirectoryW (hToken
,
643 WideCharToMultiByte (CP_ACP
,
653 GlobalFree (lpBuffer
);
660 GetUserProfileDirectoryW (HANDLE hToken
,
664 UNICODE_STRING SidString
;
665 WCHAR szKeyName
[MAX_PATH
];
666 WCHAR szRawImagePath
[MAX_PATH
];
667 WCHAR szImagePath
[MAX_PATH
];
671 if (!GetUserSidFromToken (hToken
,
674 DPRINT1 ("GetUserSidFromToken() failed\n");
678 DPRINT ("SidString: '%wZ'\n", &SidString
);
681 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
685 RtlFreeUnicodeString (&SidString
);
687 DPRINT ("KeyName: '%S'\n", szKeyName
);
689 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
695 DPRINT1 ("Error: %lu\n", GetLastError());
699 dwLength
= MAX_PATH
* sizeof(WCHAR
);
700 if (RegQueryValueExW (hKey
,
704 (LPBYTE
)szRawImagePath
,
707 DPRINT1 ("Error: %lu\n", GetLastError());
714 DPRINT ("RawImagePath: '%S'\n", szRawImagePath
);
717 if (!ExpandEnvironmentStringsW (szRawImagePath
,
721 DPRINT1 ("Error: %lu\n", GetLastError());
725 DPRINT ("ImagePath: '%S'\n", szImagePath
);
727 dwLength
= wcslen (szImagePath
);
728 if (dwLength
> *lpcchSize
)
730 DPRINT1 ("Buffer too small\n");
731 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
735 *lpcchSize
= dwLength
;
736 wcscpy (lpProfileDir
,
744 CheckForLoadedProfile (HANDLE hToken
)
746 UNICODE_STRING SidString
;
749 DPRINT ("CheckForLoadedProfile() called \n");
751 if (!GetUserSidFromToken (hToken
,
754 DPRINT1 ("GetUserSidFromToken() failed\n");
758 if (RegOpenKeyExW (HKEY_USERS
,
764 DPRINT ("Profile not loaded\n");
765 RtlFreeUnicodeString (&SidString
);
771 RtlFreeUnicodeString (&SidString
);
773 DPRINT ("Profile already loaded\n");
780 LoadUserProfileA (HANDLE hToken
,
781 LPPROFILEINFOA lpProfileInfo
)
783 DPRINT ("LoadUserProfileA() not implemented\n");
789 LoadUserProfileW (HANDLE hToken
,
790 LPPROFILEINFOW lpProfileInfo
)
792 WCHAR szUserHivePath
[MAX_PATH
];
793 UNICODE_STRING SidString
;
796 DPRINT ("LoadUserProfileW() called\n");
798 /* Check profile info */
799 if (lpProfileInfo
->dwSize
!= sizeof(PROFILEINFOW
) ||
800 lpProfileInfo
->lpUserName
== NULL
||
801 lpProfileInfo
->lpUserName
[0] == 0)
803 SetLastError (ERROR_INVALID_PARAMETER
);
807 /* Don't load a profile twice */
808 if (CheckForLoadedProfile (hToken
))
810 DPRINT ("Profile already loaded\n");
811 lpProfileInfo
->hProfile
= NULL
;
815 if (!GetProfilesDirectoryW (szUserHivePath
,
818 DPRINT1("GetProfilesDirectoryW() failed\n", GetLastError());
822 wcscat (szUserHivePath
, L
"\\");
823 wcscat (szUserHivePath
, lpProfileInfo
->lpUserName
);
824 if (!AppendSystemPostfix (szUserHivePath
, MAX_PATH
))
826 DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
830 /* Create user hive name */
831 wcscat (szUserHivePath
, L
"\\ntuser.dat");
833 DPRINT ("szUserHivePath: %S\n", szUserHivePath
);
835 if (!GetUserSidFromToken (hToken
,
838 DPRINT1 ("GetUserSidFromToken() failed\n");
842 DPRINT ("SidString: '%wZ'\n", &SidString
);
844 if (RegLoadKeyW (HKEY_USERS
,
848 DPRINT1 ("RegLoadKeyW() failed (Error %ld)\n", GetLastError());
849 RtlFreeUnicodeString (&SidString
);
853 if (RegOpenKeyExW (HKEY_USERS
,
857 (PHKEY
)&lpProfileInfo
->hProfile
))
859 DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", GetLastError());
860 RtlFreeUnicodeString (&SidString
);
864 RtlFreeUnicodeString (&SidString
);
866 DPRINT ("LoadUserProfileW() done\n");
873 UnloadUserProfile (HANDLE hToken
,
876 UNICODE_STRING SidString
;
878 DPRINT ("UnloadUserProfile() called\n");
880 if (hProfile
== NULL
)
882 DPRINT1 ("Invalide profile handle\n");
883 SetLastError (ERROR_INVALID_PARAMETER
);
887 RegCloseKey (hProfile
);
889 if (!GetUserSidFromToken (hToken
,
892 DPRINT1 ("GetUserSidFromToken() failed\n");
896 DPRINT ("SidString: '%wZ'\n", &SidString
);
898 if (RegUnLoadKeyW (HKEY_USERS
,
901 DPRINT1 ("RegUnLoadKeyW() failed (Error %ld)\n", GetLastError());
902 RtlFreeUnicodeString (&SidString
);
906 RtlFreeUnicodeString (&SidString
);
908 DPRINT ("UnloadUserProfile() done\n");