1 /* $Id: profile.c,v 1.12 2004/08/15 19:02:40 chorns 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
13 /* FUNCTIONS ***************************************************************/
16 AppendSystemPostfix (LPWSTR lpName
,
19 WCHAR szSystemRoot
[MAX_PATH
];
20 WCHAR szDrivePostfix
[3];
23 DWORD dwPostfixLength
;
25 /* Build profile name postfix */
26 if (!ExpandEnvironmentStringsW (L
"%SystemRoot%",
30 DPRINT1("Error: %lu\n", GetLastError());
34 _wcsupr (szSystemRoot
);
36 /* Get name postfix */
37 szSystemRoot
[2] = L
'.';
38 lpszPostfix
= &szSystemRoot
[2];
39 lpszPtr
= lpszPostfix
;
40 while (*lpszPtr
!= (WCHAR
)0)
42 if (*lpszPtr
== L
'\\')
47 dwPostfixLength
= wcslen (lpszPostfix
);
48 if (szSystemRoot
[0] != L
'C')
51 szDrivePostfix
[0] = L
'_';
52 szDrivePostfix
[1] = szSystemRoot
[0];
53 szDrivePostfix
[2] = (WCHAR
)0;
56 if (wcslen (lpName
) + dwPostfixLength
>= dwMaxLength
)
58 DPRINT1("Error: buffer overflow\n");
62 wcscat (lpName
, lpszPostfix
);
63 if (szSystemRoot
[0] != L
'C')
65 wcscat (lpName
, szDrivePostfix
);
73 CreateUserProfileA (PSID Sid
,
76 UNICODE_STRING UserName
;
80 Status
= RtlCreateUnicodeStringFromAsciiz (&UserName
,
82 if (!NT_SUCCESS(Status
))
84 SetLastError (RtlNtStatusToDosError (Status
));
88 bResult
= CreateUserProfileW (Sid
,
91 RtlFreeUnicodeString (&UserName
);
98 CreateUserProfileW (PSID Sid
,
101 WCHAR szRawProfilesPath
[MAX_PATH
];
102 WCHAR szProfilesPath
[MAX_PATH
];
103 WCHAR szUserProfilePath
[MAX_PATH
];
104 WCHAR szDefaultUserPath
[MAX_PATH
];
105 WCHAR szBuffer
[MAX_PATH
];
106 UNICODE_STRING SidString
;
112 DPRINT ("CreateUserProfileW() called\n");
114 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
115 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
120 DPRINT1("Error: %lu\n", GetLastError());
124 /* Get profiles path */
125 dwLength
= MAX_PATH
* sizeof(WCHAR
);
126 if (RegQueryValueExW (hKey
,
127 L
"ProfilesDirectory",
130 (LPBYTE
)szRawProfilesPath
,
133 DPRINT1("Error: %lu\n", GetLastError());
139 if (!ExpandEnvironmentStringsW (szRawProfilesPath
,
143 DPRINT1("Error: %lu\n", GetLastError());
148 /* Get default user path */
149 dwLength
= MAX_PATH
* sizeof(WCHAR
);
150 if (RegQueryValueExW (hKey
,
151 L
"DefaultUserProfile",
157 DPRINT1("Error: %lu\n", GetLastError());
164 wcscpy (szUserProfilePath
, szProfilesPath
);
165 wcscat (szUserProfilePath
, L
"\\");
166 wcscat (szUserProfilePath
, lpUserName
);
167 if (!AppendSystemPostfix (szUserProfilePath
, MAX_PATH
))
169 DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
170 RtlFreeUnicodeString (&SidString
);
175 wcscpy (szDefaultUserPath
, szProfilesPath
);
176 wcscat (szDefaultUserPath
, L
"\\");
177 wcscat (szDefaultUserPath
, szBuffer
);
179 /* Create user profile directory */
180 if (!CreateDirectoryW (szUserProfilePath
, NULL
))
182 if (GetLastError () != ERROR_ALREADY_EXISTS
)
184 DPRINT1("Error: %lu\n", GetLastError());
189 /* Copy default user directory */
190 if (!CopyDirectory (szUserProfilePath
, szDefaultUserPath
))
192 DPRINT1("Error: %lu\n", GetLastError());
196 /* Add profile to profile list */
197 Status
= RtlConvertSidToUnicodeString (&SidString
, Sid
, TRUE
);
198 if (!NT_SUCCESS(Status
))
200 DPRINT1("Status: %lx\n", Status
);
205 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
206 wcscat (szBuffer
, SidString
.Buffer
);
208 /* Create user profile key */
209 if (RegCreateKeyExW (HKEY_LOCAL_MACHINE
,
213 REG_OPTION_NON_VOLATILE
,
219 DPRINT1("Error: %lu\n", GetLastError());
220 RtlFreeUnicodeString (&SidString
);
224 /* Create non-expanded user profile path */
225 wcscpy (szBuffer
, szRawProfilesPath
);
226 wcscat (szBuffer
, L
"\\");
227 wcscat (szBuffer
, lpUserName
);
228 if (!AppendSystemPostfix (szBuffer
, MAX_PATH
))
230 DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
231 RtlFreeUnicodeString (&SidString
);
236 /* Set 'ProfileImagePath' value (non-expanded) */
237 if (RegSetValueExW (hKey
,
242 (wcslen (szBuffer
) + 1) * sizeof(WCHAR
)))
244 DPRINT1("Error: %lu\n", GetLastError());
245 RtlFreeUnicodeString (&SidString
);
250 /* Set 'Sid' value */
251 if (RegSetValueExW (hKey
,
258 DPRINT1("Error: %lu\n", GetLastError());
259 RtlFreeUnicodeString (&SidString
);
266 /* Create user hive name */
267 wcscat (szUserProfilePath
, L
"\\ntuser.dat");
269 /* Create new user hive */
270 if (RegLoadKeyW (HKEY_USERS
,
274 DPRINT1("Error: %lu\n", GetLastError());
275 RtlFreeUnicodeString (&SidString
);
279 /* Initialize user hive */
280 if (!CreateUserHive (SidString
.Buffer
))
282 DPRINT1("Error: %lu\n", GetLastError());
283 RtlFreeUnicodeString (&SidString
);
287 RegUnLoadKeyW (HKEY_USERS
,
290 RtlFreeUnicodeString (&SidString
);
292 DPRINT ("CreateUserProfileW() done\n");
299 GetAllUsersProfileDirectoryA (LPSTR lpProfileDir
,
305 lpBuffer
= GlobalAlloc (GMEM_FIXED
,
306 *lpcchSize
* sizeof(WCHAR
));
307 if (lpBuffer
== NULL
)
310 bResult
= GetAllUsersProfileDirectoryW (lpBuffer
,
314 WideCharToMultiByte (CP_ACP
,
324 GlobalFree (lpBuffer
);
331 GetAllUsersProfileDirectoryW (LPWSTR lpProfileDir
,
334 WCHAR szProfilePath
[MAX_PATH
];
335 WCHAR szBuffer
[MAX_PATH
];
339 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
340 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
345 DPRINT1("Error: %lu\n", GetLastError());
349 /* Get profiles path */
350 dwLength
= MAX_PATH
* sizeof(WCHAR
);
351 if (RegQueryValueExW (hKey
,
352 L
"ProfilesDirectory",
358 DPRINT1("Error: %lu\n", GetLastError());
364 if (!ExpandEnvironmentStringsW (szBuffer
,
368 DPRINT1("Error: %lu\n", GetLastError());
373 /* Get 'AllUsersProfile' name */
374 dwLength
= MAX_PATH
* sizeof(WCHAR
);
375 if (RegQueryValueExW (hKey
,
382 DPRINT1("Error: %lu\n", GetLastError());
389 wcscat (szProfilePath
, L
"\\");
390 wcscat (szProfilePath
, szBuffer
);
392 dwLength
= wcslen (szProfilePath
);
393 if (lpProfileDir
!= NULL
)
395 if (*lpcchSize
< dwLength
)
397 *lpcchSize
= dwLength
;
398 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
402 wcscpy (lpProfileDir
, szProfilePath
);
405 *lpcchSize
= dwLength
;
412 GetDefaultUserProfileDirectoryA (LPSTR lpProfileDir
,
418 lpBuffer
= GlobalAlloc (GMEM_FIXED
,
419 *lpcchSize
* sizeof(WCHAR
));
420 if (lpBuffer
== NULL
)
423 bResult
= GetDefaultUserProfileDirectoryW (lpBuffer
,
427 WideCharToMultiByte (CP_ACP
,
437 GlobalFree (lpBuffer
);
444 GetDefaultUserProfileDirectoryW (LPWSTR lpProfileDir
,
447 WCHAR szProfilePath
[MAX_PATH
];
448 WCHAR szBuffer
[MAX_PATH
];
452 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
453 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
458 DPRINT1("Error: %lu\n", GetLastError());
462 /* Get profiles path */
463 dwLength
= MAX_PATH
* sizeof(WCHAR
);
464 if (RegQueryValueExW (hKey
,
465 L
"ProfilesDirectory",
471 DPRINT1("Error: %lu\n", GetLastError());
477 if (!ExpandEnvironmentStringsW (szBuffer
,
481 DPRINT1("Error: %lu\n", GetLastError());
486 /* Get 'DefaultUserProfile' name */
487 dwLength
= MAX_PATH
* sizeof(WCHAR
);
488 if (RegQueryValueExW (hKey
,
489 L
"DefaultUserProfile",
495 DPRINT1("Error: %lu\n", GetLastError());
502 wcscat (szProfilePath
, L
"\\");
503 wcscat (szProfilePath
, szBuffer
);
505 dwLength
= wcslen (szProfilePath
);
506 if (lpProfileDir
!= NULL
)
508 if (*lpcchSize
< dwLength
)
510 *lpcchSize
= dwLength
;
511 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
515 wcscpy (lpProfileDir
, szProfilePath
);
518 *lpcchSize
= dwLength
;
525 GetProfilesDirectoryA (LPSTR lpProfileDir
,
531 lpBuffer
= GlobalAlloc (GMEM_FIXED
,
532 *lpcchSize
* sizeof(WCHAR
));
533 if (lpBuffer
== NULL
)
536 bResult
= GetProfilesDirectoryW (lpBuffer
,
540 WideCharToMultiByte (CP_ACP
,
550 GlobalFree (lpBuffer
);
557 GetProfilesDirectoryW (LPWSTR lpProfilesDir
,
560 WCHAR szProfilesPath
[MAX_PATH
];
561 WCHAR szBuffer
[MAX_PATH
];
565 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
566 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
571 DPRINT1("Error: %lu\n", GetLastError());
575 /* Get profiles path */
576 dwLength
= MAX_PATH
* sizeof(WCHAR
);
577 if (RegQueryValueExW (hKey
,
578 L
"ProfilesDirectory",
584 DPRINT1("Error: %lu\n", GetLastError());
592 if (!ExpandEnvironmentStringsW (szBuffer
,
596 DPRINT1("Error: %lu\n", GetLastError());
600 dwLength
= wcslen (szProfilesPath
);
601 if (lpProfilesDir
!= NULL
)
603 if (*lpcchSize
< dwLength
)
605 *lpcchSize
= dwLength
;
606 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
610 wcscpy (lpProfilesDir
, szProfilesPath
);
613 *lpcchSize
= dwLength
;
620 GetUserProfileDirectoryA (HANDLE hToken
,
627 lpBuffer
= GlobalAlloc (GMEM_FIXED
,
628 *lpcchSize
* sizeof(WCHAR
));
629 if (lpBuffer
== NULL
)
632 bResult
= GetUserProfileDirectoryW (hToken
,
637 WideCharToMultiByte (CP_ACP
,
647 GlobalFree (lpBuffer
);
654 GetUserProfileDirectoryW (HANDLE hToken
,
658 UNICODE_STRING SidString
;
659 WCHAR szKeyName
[MAX_PATH
];
660 WCHAR szRawImagePath
[MAX_PATH
];
661 WCHAR szImagePath
[MAX_PATH
];
665 if (!GetUserSidFromToken (hToken
,
668 DPRINT1 ("GetUserSidFromToken() failed\n");
672 DPRINT ("SidString: '%wZ'\n", &SidString
);
675 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
679 RtlFreeUnicodeString (&SidString
);
681 DPRINT ("KeyName: '%S'\n", szKeyName
);
683 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
689 DPRINT1 ("Error: %lu\n", GetLastError());
693 dwLength
= MAX_PATH
* sizeof(WCHAR
);
694 if (RegQueryValueExW (hKey
,
698 (LPBYTE
)szRawImagePath
,
701 DPRINT1 ("Error: %lu\n", GetLastError());
708 DPRINT ("RawImagePath: '%S'\n", szRawImagePath
);
711 if (!ExpandEnvironmentStringsW (szRawImagePath
,
715 DPRINT1 ("Error: %lu\n", GetLastError());
719 DPRINT ("ImagePath: '%S'\n", szImagePath
);
721 dwLength
= wcslen (szImagePath
);
722 if (dwLength
> *lpcchSize
)
724 DPRINT1 ("Buffer too small\n");
725 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
729 *lpcchSize
= dwLength
;
730 wcscpy (lpProfileDir
,
738 CheckForLoadedProfile (HANDLE hToken
)
740 UNICODE_STRING SidString
;
743 DPRINT ("CheckForLoadedProfile() called \n");
745 if (!GetUserSidFromToken (hToken
,
748 DPRINT1 ("GetUserSidFromToken() failed\n");
752 if (RegOpenKeyExW (HKEY_USERS
,
758 DPRINT ("Profile not loaded\n");
759 RtlFreeUnicodeString (&SidString
);
765 RtlFreeUnicodeString (&SidString
);
767 DPRINT ("Profile already loaded\n");
774 LoadUserProfileA (HANDLE hToken
,
775 LPPROFILEINFOA lpProfileInfo
)
777 DPRINT ("LoadUserProfileA() not implemented\n");
783 LoadUserProfileW (HANDLE hToken
,
784 LPPROFILEINFOW lpProfileInfo
)
786 WCHAR szUserHivePath
[MAX_PATH
];
787 UNICODE_STRING SidString
;
790 DPRINT ("LoadUserProfileW() called\n");
792 /* Check profile info */
793 if (lpProfileInfo
->dwSize
!= sizeof(PROFILEINFOW
) ||
794 lpProfileInfo
->lpUserName
== NULL
||
795 lpProfileInfo
->lpUserName
[0] == 0)
797 SetLastError (ERROR_INVALID_PARAMETER
);
801 /* Don't load a profile twice */
802 if (CheckForLoadedProfile (hToken
))
804 DPRINT ("Profile already loaded\n");
805 lpProfileInfo
->hProfile
= NULL
;
809 if (!GetProfilesDirectoryW (szUserHivePath
,
812 DPRINT1("GetProfilesDirectoryW() failed\n", GetLastError());
816 wcscat (szUserHivePath
, L
"\\");
817 wcscat (szUserHivePath
, lpProfileInfo
->lpUserName
);
818 if (!AppendSystemPostfix (szUserHivePath
, MAX_PATH
))
820 DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
824 /* Create user hive name */
825 wcscat (szUserHivePath
, L
"\\ntuser.dat");
827 DPRINT ("szUserHivePath: %S\n", szUserHivePath
);
829 if (!GetUserSidFromToken (hToken
,
832 DPRINT1 ("GetUserSidFromToken() failed\n");
836 DPRINT ("SidString: '%wZ'\n", &SidString
);
838 if (RegLoadKeyW (HKEY_USERS
,
842 DPRINT1 ("RegLoadKeyW() failed (Error %ld)\n", GetLastError());
843 RtlFreeUnicodeString (&SidString
);
847 if (RegOpenKeyExW (HKEY_USERS
,
851 (PHKEY
)&lpProfileInfo
->hProfile
))
853 DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", GetLastError());
854 RtlFreeUnicodeString (&SidString
);
858 RtlFreeUnicodeString (&SidString
);
860 DPRINT ("LoadUserProfileW() done\n");
867 UnloadUserProfile (HANDLE hToken
,
870 UNICODE_STRING SidString
;
872 DPRINT ("UnloadUserProfile() called\n");
874 if (hProfile
== NULL
)
876 DPRINT1 ("Invalide profile handle\n");
877 SetLastError (ERROR_INVALID_PARAMETER
);
881 RegCloseKey (hProfile
);
883 if (!GetUserSidFromToken (hToken
,
886 DPRINT1 ("GetUserSidFromToken() failed\n");
890 DPRINT ("SidString: '%wZ'\n", &SidString
);
892 if (RegUnLoadKeyW (HKEY_USERS
,
895 DPRINT1 ("RegUnLoadKeyW() failed (Error %ld)\n", GetLastError());
896 RtlFreeUnicodeString (&SidString
);
900 RtlFreeUnicodeString (&SidString
);
902 DPRINT ("UnloadUserProfile() done\n");