1 /* $Id: profile.c,v 1.10 2004/04/29 14:41:26 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 GetAllUsersProfileDirectoryW (LPWSTR lpProfileDir
,
308 WCHAR szProfilePath
[MAX_PATH
];
309 WCHAR szBuffer
[MAX_PATH
];
313 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
314 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
319 DPRINT1("Error: %lu\n", GetLastError());
323 /* Get profiles path */
324 dwLength
= MAX_PATH
* sizeof(WCHAR
);
325 if (RegQueryValueExW (hKey
,
326 L
"ProfilesDirectory",
332 DPRINT1("Error: %lu\n", GetLastError());
338 if (!ExpandEnvironmentStringsW (szBuffer
,
342 DPRINT1("Error: %lu\n", GetLastError());
347 /* Get 'AllUsersProfile' name */
348 dwLength
= MAX_PATH
* sizeof(WCHAR
);
349 if (RegQueryValueExW (hKey
,
356 DPRINT1("Error: %lu\n", GetLastError());
363 wcscat (szProfilePath
, L
"\\");
364 wcscat (szProfilePath
, szBuffer
);
366 dwLength
= wcslen (szProfilePath
);
367 if (lpProfileDir
!= NULL
)
369 if (*lpcchSize
< dwLength
)
371 *lpcchSize
= dwLength
;
372 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
376 wcscpy (lpProfileDir
, szProfilePath
);
379 *lpcchSize
= dwLength
;
386 GetDefaultUserProfileDirectoryW (LPWSTR lpProfileDir
,
389 WCHAR szProfilePath
[MAX_PATH
];
390 WCHAR szBuffer
[MAX_PATH
];
394 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
395 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
400 DPRINT1("Error: %lu\n", GetLastError());
404 /* Get profiles path */
405 dwLength
= MAX_PATH
* sizeof(WCHAR
);
406 if (RegQueryValueExW (hKey
,
407 L
"ProfilesDirectory",
413 DPRINT1("Error: %lu\n", GetLastError());
419 if (!ExpandEnvironmentStringsW (szBuffer
,
423 DPRINT1("Error: %lu\n", GetLastError());
428 /* Get 'DefaultUserProfile' name */
429 dwLength
= MAX_PATH
* sizeof(WCHAR
);
430 if (RegQueryValueExW (hKey
,
431 L
"DefaultUserProfile",
437 DPRINT1("Error: %lu\n", GetLastError());
444 wcscat (szProfilePath
, L
"\\");
445 wcscat (szProfilePath
, szBuffer
);
447 dwLength
= wcslen (szProfilePath
);
448 if (lpProfileDir
!= NULL
)
450 if (*lpcchSize
< dwLength
)
452 *lpcchSize
= dwLength
;
453 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
457 wcscpy (lpProfileDir
, szProfilePath
);
460 *lpcchSize
= dwLength
;
467 GetProfilesDirectoryW (LPWSTR lpProfilesDir
,
470 WCHAR szProfilesPath
[MAX_PATH
];
471 WCHAR szBuffer
[MAX_PATH
];
475 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
476 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
481 DPRINT1("Error: %lu\n", GetLastError());
485 /* Get profiles path */
486 dwLength
= MAX_PATH
* sizeof(WCHAR
);
487 if (RegQueryValueExW (hKey
,
488 L
"ProfilesDirectory",
494 DPRINT1("Error: %lu\n", GetLastError());
502 if (!ExpandEnvironmentStringsW (szBuffer
,
506 DPRINT1("Error: %lu\n", GetLastError());
510 dwLength
= wcslen (szProfilesPath
);
511 if (lpProfilesDir
!= NULL
)
513 if (*lpcchSize
< dwLength
)
515 *lpcchSize
= dwLength
;
516 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
520 wcscpy (lpProfilesDir
, szProfilesPath
);
523 *lpcchSize
= dwLength
;
530 GetUserProfileDirectoryW (HANDLE hToken
,
534 UNICODE_STRING SidString
;
535 WCHAR szKeyName
[MAX_PATH
];
536 WCHAR szRawImagePath
[MAX_PATH
];
537 WCHAR szImagePath
[MAX_PATH
];
541 if (!GetUserSidFromToken (hToken
,
544 DPRINT1 ("GetUserSidFromToken() failed\n");
548 DPRINT ("SidString: '%wZ'\n", &SidString
);
551 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
555 RtlFreeUnicodeString (&SidString
);
557 DPRINT ("KeyName: '%S'\n", szKeyName
);
559 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
565 DPRINT1 ("Error: %lu\n", GetLastError());
569 dwLength
= MAX_PATH
* sizeof(WCHAR
);
570 if (RegQueryValueExW (hKey
,
574 (LPBYTE
)szRawImagePath
,
577 DPRINT1 ("Error: %lu\n", GetLastError());
584 DPRINT ("RawImagePath: '%S'\n", szRawImagePath
);
587 if (!ExpandEnvironmentStringsW (szRawImagePath
,
591 DPRINT1 ("Error: %lu\n", GetLastError());
595 DPRINT ("ImagePath: '%S'\n", szImagePath
);
597 dwLength
= wcslen (szImagePath
);
598 if (dwLength
> *lpcchSize
)
600 DPRINT1 ("Buffer too small\n");
601 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
605 *lpcchSize
= dwLength
;
606 wcscpy (lpProfileDir
,
614 CheckForLoadedProfile (HANDLE hToken
)
616 UNICODE_STRING SidString
;
619 DPRINT ("CheckForLoadedProfile() called \n");
621 if (!GetUserSidFromToken (hToken
,
624 DPRINT1 ("GetUserSidFromToken() failed\n");
628 if (RegOpenKeyExW (HKEY_USERS
,
634 DPRINT ("Profile not loaded\n");
635 RtlFreeUnicodeString (&SidString
);
641 RtlFreeUnicodeString (&SidString
);
643 DPRINT ("Profile already loaded\n");
650 LoadUserProfileA (HANDLE hToken
,
651 LPPROFILEINFOA lpProfileInfo
)
653 DPRINT ("LoadUserProfileA() not implemented\n");
659 LoadUserProfileW (HANDLE hToken
,
660 LPPROFILEINFOW lpProfileInfo
)
662 WCHAR szUserHivePath
[MAX_PATH
];
663 UNICODE_STRING SidString
;
666 DPRINT ("LoadUserProfileW() called\n");
668 /* Check profile info */
669 if (lpProfileInfo
->dwSize
!= sizeof(PROFILEINFOW
) ||
670 lpProfileInfo
->lpUserName
== NULL
||
671 lpProfileInfo
->lpUserName
[0] == 0)
673 SetLastError (ERROR_INVALID_PARAMETER
);
677 /* Don't load a profile twice */
678 if (CheckForLoadedProfile (hToken
))
680 DPRINT ("Profile already loaded\n");
681 lpProfileInfo
->hProfile
= NULL
;
685 if (!GetProfilesDirectoryW (szUserHivePath
,
688 DPRINT1("GetProfilesDirectoryW() failed\n", GetLastError());
692 wcscat (szUserHivePath
, L
"\\");
693 wcscat (szUserHivePath
, lpProfileInfo
->lpUserName
);
694 if (!AppendSystemPostfix (szUserHivePath
, MAX_PATH
))
696 DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
700 /* Create user hive name */
701 wcscat (szUserHivePath
, L
"\\ntuser.dat");
703 DPRINT ("szUserHivePath: %S\n", szUserHivePath
);
705 if (!GetUserSidFromToken (hToken
,
708 DPRINT1 ("GetUserSidFromToken() failed\n");
712 DPRINT ("SidString: '%wZ'\n", &SidString
);
714 if (RegLoadKeyW (HKEY_USERS
,
718 DPRINT1 ("RegLoadKeyW() failed (Error %ld)\n", GetLastError());
719 RtlFreeUnicodeString (&SidString
);
723 if (RegOpenKeyExW (HKEY_USERS
,
727 (PHKEY
)&lpProfileInfo
->hProfile
))
729 DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", GetLastError());
730 RtlFreeUnicodeString (&SidString
);
734 RtlFreeUnicodeString (&SidString
);
736 DPRINT ("LoadUserProfileW() done\n");
743 UnloadUserProfile (HANDLE hToken
,
746 UNICODE_STRING SidString
;
748 DPRINT ("UnloadUserProfile() called\n");
750 if (hProfile
== NULL
)
752 DPRINT1 ("Invalide profile handle\n");
753 SetLastError (ERROR_INVALID_PARAMETER
);
757 RegCloseKey (hProfile
);
759 if (!GetUserSidFromToken (hToken
,
762 DPRINT1 ("GetUserSidFromToken() failed\n");
766 DPRINT ("SidString: '%wZ'\n", &SidString
);
768 if (RegUnLoadKeyW (HKEY_USERS
,
771 DPRINT1 ("RegUnLoadKeyW() failed (Error %ld)\n", GetLastError());
772 RtlFreeUnicodeString (&SidString
);
776 RtlFreeUnicodeString (&SidString
);
778 DPRINT ("UnloadUserProfile() done\n");