3 * Copyright (C) 2004 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* $Id: profile.c,v 1.15 2004/10/05 13:39:42 ekohl Exp $
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS system libraries
23 * FILE: lib/userenv/profile.c
24 * PURPOSE: User profile code
25 * PROGRAMMER: Eric Kohl
31 /* FUNCTIONS ***************************************************************/
34 AppendSystemPostfix (LPWSTR lpName
,
37 WCHAR szSystemRoot
[MAX_PATH
];
41 /* Build profile name postfix */
42 if (!ExpandEnvironmentStringsW (L
"%SystemRoot%",
46 DPRINT1("Error: %lu\n", GetLastError());
50 _wcsupr (szSystemRoot
);
52 /* Get name postfix */
53 szSystemRoot
[2] = L
'.';
54 lpszPostfix
= &szSystemRoot
[2];
55 lpszPtr
= lpszPostfix
;
56 while (*lpszPtr
!= (WCHAR
)0)
58 if (*lpszPtr
== L
'\\')
63 if (wcslen(lpName
) + wcslen(lpszPostfix
) >= dwMaxLength
)
65 DPRINT1("Error: buffer overflow\n");
69 wcscat(lpName
, lpszPostfix
);
76 CreateUserProfileA (PSID Sid
,
79 UNICODE_STRING UserName
;
83 Status
= RtlCreateUnicodeStringFromAsciiz (&UserName
,
85 if (!NT_SUCCESS(Status
))
87 SetLastError (RtlNtStatusToDosError (Status
));
91 bResult
= CreateUserProfileW (Sid
,
94 RtlFreeUnicodeString (&UserName
);
101 CreateUserProfileW (PSID Sid
,
104 WCHAR szRawProfilesPath
[MAX_PATH
];
105 WCHAR szProfilesPath
[MAX_PATH
];
106 WCHAR szUserProfilePath
[MAX_PATH
];
107 WCHAR szDefaultUserPath
[MAX_PATH
];
108 WCHAR szBuffer
[MAX_PATH
];
109 UNICODE_STRING SidString
;
115 DPRINT("CreateUserProfileW() called\n");
117 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
118 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
123 DPRINT1("Error: %lu\n", GetLastError());
127 /* Get profiles path */
128 dwLength
= MAX_PATH
* sizeof(WCHAR
);
129 if (RegQueryValueExW (hKey
,
130 L
"ProfilesDirectory",
133 (LPBYTE
)szRawProfilesPath
,
136 DPRINT1("Error: %lu\n", GetLastError());
142 if (!ExpandEnvironmentStringsW (szRawProfilesPath
,
146 DPRINT1("Error: %lu\n", GetLastError());
151 /* Get default user path */
152 dwLength
= MAX_PATH
* sizeof(WCHAR
);
153 if (RegQueryValueExW (hKey
,
154 L
"DefaultUserProfile",
160 DPRINT1("Error: %lu\n", GetLastError());
167 wcscpy (szUserProfilePath
, szProfilesPath
);
168 wcscat (szUserProfilePath
, L
"\\");
169 wcscat (szUserProfilePath
, lpUserName
);
170 if (!AppendSystemPostfix (szUserProfilePath
, MAX_PATH
))
172 DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
173 RtlFreeUnicodeString (&SidString
);
178 wcscpy (szDefaultUserPath
, szProfilesPath
);
179 wcscat (szDefaultUserPath
, L
"\\");
180 wcscat (szDefaultUserPath
, szBuffer
);
182 /* Create user profile directory */
183 if (!CreateDirectoryW (szUserProfilePath
, NULL
))
185 if (GetLastError () != ERROR_ALREADY_EXISTS
)
187 DPRINT1("Error: %lu\n", GetLastError());
192 /* Copy default user directory */
193 if (!CopyDirectory (szUserProfilePath
, szDefaultUserPath
))
195 DPRINT1("Error: %lu\n", GetLastError());
199 /* Add profile to profile list */
200 Status
= RtlConvertSidToUnicodeString (&SidString
, Sid
, TRUE
);
201 if (!NT_SUCCESS(Status
))
203 DPRINT1("Status: %lx\n", Status
);
208 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
209 wcscat (szBuffer
, SidString
.Buffer
);
211 /* Create user profile key */
212 if (RegCreateKeyExW (HKEY_LOCAL_MACHINE
,
216 REG_OPTION_NON_VOLATILE
,
222 DPRINT1("Error: %lu\n", GetLastError());
223 RtlFreeUnicodeString (&SidString
);
227 /* Create non-expanded user profile path */
228 wcscpy (szBuffer
, szRawProfilesPath
);
229 wcscat (szBuffer
, L
"\\");
230 wcscat (szBuffer
, lpUserName
);
231 if (!AppendSystemPostfix (szBuffer
, MAX_PATH
))
233 DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
234 RtlFreeUnicodeString (&SidString
);
239 /* Set 'ProfileImagePath' value (non-expanded) */
240 if (RegSetValueExW (hKey
,
245 (wcslen (szBuffer
) + 1) * sizeof(WCHAR
)))
247 DPRINT1("Error: %lu\n", GetLastError());
248 RtlFreeUnicodeString (&SidString
);
253 /* Set 'Sid' value */
254 if (RegSetValueExW (hKey
,
261 DPRINT1("Error: %lu\n", GetLastError());
262 RtlFreeUnicodeString (&SidString
);
269 /* Create user hive name */
270 wcscpy (szBuffer
, szUserProfilePath
);
271 wcscat (szBuffer
, L
"\\ntuser.dat");
273 /* Create new user hive */
274 if (RegLoadKeyW (HKEY_USERS
,
278 DPRINT1("Error: %lu\n", GetLastError());
279 RtlFreeUnicodeString (&SidString
);
283 /* Initialize user hive */
284 if (!CreateUserHive (SidString
.Buffer
, szUserProfilePath
))
286 DPRINT1("Error: %lu\n", GetLastError());
287 RtlFreeUnicodeString (&SidString
);
291 RegUnLoadKeyW (HKEY_USERS
,
294 RtlFreeUnicodeString (&SidString
);
296 DPRINT("CreateUserProfileW() done\n");
303 GetAllUsersProfileDirectoryA (LPSTR lpProfileDir
,
309 lpBuffer
= GlobalAlloc (GMEM_FIXED
,
310 *lpcchSize
* sizeof(WCHAR
));
311 if (lpBuffer
== NULL
)
314 bResult
= GetAllUsersProfileDirectoryW (lpBuffer
,
318 WideCharToMultiByte (CP_ACP
,
328 GlobalFree (lpBuffer
);
335 GetAllUsersProfileDirectoryW (LPWSTR lpProfileDir
,
338 WCHAR szProfilePath
[MAX_PATH
];
339 WCHAR szBuffer
[MAX_PATH
];
343 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
344 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
349 DPRINT1("Error: %lu\n", GetLastError());
353 /* Get profiles path */
354 dwLength
= MAX_PATH
* sizeof(WCHAR
);
355 if (RegQueryValueExW (hKey
,
356 L
"ProfilesDirectory",
362 DPRINT1("Error: %lu\n", GetLastError());
368 if (!ExpandEnvironmentStringsW (szBuffer
,
372 DPRINT1("Error: %lu\n", GetLastError());
377 /* Get 'AllUsersProfile' name */
378 dwLength
= MAX_PATH
* sizeof(WCHAR
);
379 if (RegQueryValueExW (hKey
,
386 DPRINT1("Error: %lu\n", GetLastError());
393 wcscat (szProfilePath
, L
"\\");
394 wcscat (szProfilePath
, szBuffer
);
396 dwLength
= wcslen (szProfilePath
);
397 if (lpProfileDir
!= NULL
)
399 if (*lpcchSize
< dwLength
)
401 *lpcchSize
= dwLength
;
402 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
406 wcscpy (lpProfileDir
, szProfilePath
);
409 *lpcchSize
= dwLength
;
416 GetDefaultUserProfileDirectoryA (LPSTR lpProfileDir
,
422 lpBuffer
= GlobalAlloc (GMEM_FIXED
,
423 *lpcchSize
* sizeof(WCHAR
));
424 if (lpBuffer
== NULL
)
427 bResult
= GetDefaultUserProfileDirectoryW (lpBuffer
,
431 WideCharToMultiByte (CP_ACP
,
441 GlobalFree (lpBuffer
);
448 GetDefaultUserProfileDirectoryW (LPWSTR lpProfileDir
,
451 WCHAR szProfilePath
[MAX_PATH
];
452 WCHAR szBuffer
[MAX_PATH
];
456 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
457 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
462 DPRINT1("Error: %lu\n", GetLastError());
466 /* Get profiles path */
467 dwLength
= MAX_PATH
* sizeof(WCHAR
);
468 if (RegQueryValueExW (hKey
,
469 L
"ProfilesDirectory",
475 DPRINT1("Error: %lu\n", GetLastError());
481 if (!ExpandEnvironmentStringsW (szBuffer
,
485 DPRINT1("Error: %lu\n", GetLastError());
490 /* Get 'DefaultUserProfile' name */
491 dwLength
= MAX_PATH
* sizeof(WCHAR
);
492 if (RegQueryValueExW (hKey
,
493 L
"DefaultUserProfile",
499 DPRINT1("Error: %lu\n", GetLastError());
506 wcscat (szProfilePath
, L
"\\");
507 wcscat (szProfilePath
, szBuffer
);
509 dwLength
= wcslen (szProfilePath
);
510 if (lpProfileDir
!= NULL
)
512 if (*lpcchSize
< dwLength
)
514 *lpcchSize
= dwLength
;
515 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
519 wcscpy (lpProfileDir
, szProfilePath
);
522 *lpcchSize
= dwLength
;
529 GetProfilesDirectoryA (LPSTR lpProfileDir
,
535 lpBuffer
= GlobalAlloc (GMEM_FIXED
,
536 *lpcchSize
* sizeof(WCHAR
));
537 if (lpBuffer
== NULL
)
540 bResult
= GetProfilesDirectoryW (lpBuffer
,
544 WideCharToMultiByte (CP_ACP
,
554 GlobalFree (lpBuffer
);
561 GetProfilesDirectoryW (LPWSTR lpProfilesDir
,
564 WCHAR szProfilesPath
[MAX_PATH
];
565 WCHAR szBuffer
[MAX_PATH
];
569 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
570 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
575 DPRINT1("Error: %lu\n", GetLastError());
579 /* Get profiles path */
580 dwLength
= MAX_PATH
* sizeof(WCHAR
);
581 if (RegQueryValueExW (hKey
,
582 L
"ProfilesDirectory",
588 DPRINT1("Error: %lu\n", GetLastError());
596 if (!ExpandEnvironmentStringsW (szBuffer
,
600 DPRINT1("Error: %lu\n", GetLastError());
604 dwLength
= wcslen (szProfilesPath
);
605 if (lpProfilesDir
!= NULL
)
607 if (*lpcchSize
< dwLength
)
609 *lpcchSize
= dwLength
;
610 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
614 wcscpy (lpProfilesDir
, szProfilesPath
);
617 *lpcchSize
= dwLength
;
624 GetUserProfileDirectoryA (HANDLE hToken
,
631 lpBuffer
= GlobalAlloc (GMEM_FIXED
,
632 *lpcchSize
* sizeof(WCHAR
));
633 if (lpBuffer
== NULL
)
636 bResult
= GetUserProfileDirectoryW (hToken
,
641 WideCharToMultiByte (CP_ACP
,
651 GlobalFree (lpBuffer
);
658 GetUserProfileDirectoryW (HANDLE hToken
,
662 UNICODE_STRING SidString
;
663 WCHAR szKeyName
[MAX_PATH
];
664 WCHAR szRawImagePath
[MAX_PATH
];
665 WCHAR szImagePath
[MAX_PATH
];
669 if (!GetUserSidFromToken (hToken
,
672 DPRINT1 ("GetUserSidFromToken() failed\n");
676 DPRINT ("SidString: '%wZ'\n", &SidString
);
679 L
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
683 RtlFreeUnicodeString (&SidString
);
685 DPRINT ("KeyName: '%S'\n", szKeyName
);
687 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE
,
693 DPRINT1 ("Error: %lu\n", GetLastError());
697 dwLength
= MAX_PATH
* sizeof(WCHAR
);
698 if (RegQueryValueExW (hKey
,
702 (LPBYTE
)szRawImagePath
,
705 DPRINT1 ("Error: %lu\n", GetLastError());
712 DPRINT ("RawImagePath: '%S'\n", szRawImagePath
);
715 if (!ExpandEnvironmentStringsW (szRawImagePath
,
719 DPRINT1 ("Error: %lu\n", GetLastError());
723 DPRINT ("ImagePath: '%S'\n", szImagePath
);
725 dwLength
= wcslen (szImagePath
);
726 if (dwLength
> *lpcchSize
)
728 DPRINT1 ("Buffer too small\n");
729 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
733 *lpcchSize
= dwLength
;
734 wcscpy (lpProfileDir
,
742 CheckForLoadedProfile (HANDLE hToken
)
744 UNICODE_STRING SidString
;
747 DPRINT ("CheckForLoadedProfile() called \n");
749 if (!GetUserSidFromToken (hToken
,
752 DPRINT1 ("GetUserSidFromToken() failed\n");
756 if (RegOpenKeyExW (HKEY_USERS
,
762 DPRINT ("Profile not loaded\n");
763 RtlFreeUnicodeString (&SidString
);
769 RtlFreeUnicodeString (&SidString
);
771 DPRINT ("Profile already loaded\n");
778 LoadUserProfileA (HANDLE hToken
,
779 LPPROFILEINFOA lpProfileInfo
)
781 DPRINT ("LoadUserProfileA() not implemented\n");
787 LoadUserProfileW (HANDLE hToken
,
788 LPPROFILEINFOW lpProfileInfo
)
790 WCHAR szUserHivePath
[MAX_PATH
];
791 UNICODE_STRING SidString
;
794 DPRINT ("LoadUserProfileW() called\n");
796 /* Check profile info */
797 if (lpProfileInfo
->dwSize
!= sizeof(PROFILEINFOW
) ||
798 lpProfileInfo
->lpUserName
== NULL
||
799 lpProfileInfo
->lpUserName
[0] == 0)
801 SetLastError (ERROR_INVALID_PARAMETER
);
805 /* Don't load a profile twice */
806 if (CheckForLoadedProfile (hToken
))
808 DPRINT ("Profile already loaded\n");
809 lpProfileInfo
->hProfile
= NULL
;
813 if (!GetProfilesDirectoryW (szUserHivePath
,
816 DPRINT1("GetProfilesDirectoryW() failed\n", GetLastError());
820 wcscat (szUserHivePath
, L
"\\");
821 wcscat (szUserHivePath
, lpProfileInfo
->lpUserName
);
822 if (!AppendSystemPostfix (szUserHivePath
, MAX_PATH
))
824 DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
828 /* Create user hive name */
829 wcscat (szUserHivePath
, L
"\\ntuser.dat");
831 DPRINT ("szUserHivePath: %S\n", szUserHivePath
);
833 if (!GetUserSidFromToken (hToken
,
836 DPRINT1 ("GetUserSidFromToken() failed\n");
840 DPRINT ("SidString: '%wZ'\n", &SidString
);
842 if (RegLoadKeyW (HKEY_USERS
,
846 DPRINT1 ("RegLoadKeyW() failed (Error %ld)\n", GetLastError());
847 RtlFreeUnicodeString (&SidString
);
851 if (RegOpenKeyExW (HKEY_USERS
,
855 (PHKEY
)&lpProfileInfo
->hProfile
))
857 DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", GetLastError());
858 RtlFreeUnicodeString (&SidString
);
862 RtlFreeUnicodeString (&SidString
);
864 DPRINT ("LoadUserProfileW() done\n");
871 UnloadUserProfile (HANDLE hToken
,
874 UNICODE_STRING SidString
;
876 DPRINT ("UnloadUserProfile() called\n");
878 if (hProfile
== NULL
)
880 DPRINT1 ("Invalide profile handle\n");
881 SetLastError (ERROR_INVALID_PARAMETER
);
885 RegCloseKey (hProfile
);
887 if (!GetUserSidFromToken (hToken
,
890 DPRINT1 ("GetUserSidFromToken() failed\n");
894 DPRINT ("SidString: '%wZ'\n", &SidString
);
896 if (RegUnLoadKeyW (HKEY_USERS
,
899 DPRINT1 ("RegUnLoadKeyW() failed (Error %ld)\n", GetLastError());
900 RtlFreeUnicodeString (&SidString
);
904 RtlFreeUnicodeString (&SidString
);
906 DPRINT ("UnloadUserProfile() done\n");