Update a new users private shell folder paths when a new user profile is created.
[reactos.git] / reactos / lib / userenv / profile.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2004 ReactOS Team
4 *
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.
9 *
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.
14 *
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.
18 */
19 /* $Id: profile.c,v 1.14 2004/10/03 09:27:22 ekohl Exp $
20 *
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
26 */
27
28 #include "precomp.h"
29
30
31 /* FUNCTIONS ***************************************************************/
32
33 BOOL
34 AppendSystemPostfix (LPWSTR lpName,
35 DWORD dwMaxLength)
36 {
37 WCHAR szSystemRoot[MAX_PATH];
38 WCHAR szDrivePostfix[3];
39 LPWSTR lpszPostfix;
40 LPWSTR lpszPtr;
41 DWORD dwPostfixLength;
42
43 /* Build profile name postfix */
44 if (!ExpandEnvironmentStringsW (L"%SystemRoot%",
45 szSystemRoot,
46 MAX_PATH))
47 {
48 DPRINT1("Error: %lu\n", GetLastError());
49 return FALSE;
50 }
51
52 _wcsupr (szSystemRoot);
53
54 /* Get name postfix */
55 szSystemRoot[2] = L'.';
56 lpszPostfix = &szSystemRoot[2];
57 lpszPtr = lpszPostfix;
58 while (*lpszPtr != (WCHAR)0)
59 {
60 if (*lpszPtr == L'\\')
61 *lpszPtr = '_';
62 lpszPtr++;
63 }
64
65 dwPostfixLength = wcslen (lpszPostfix);
66 if (szSystemRoot[0] != L'C')
67 {
68 dwPostfixLength += 2;
69 szDrivePostfix[0] = L'_';
70 szDrivePostfix[1] = szSystemRoot[0];
71 szDrivePostfix[2] = (WCHAR)0;
72 }
73
74 if (wcslen (lpName) + dwPostfixLength >= dwMaxLength)
75 {
76 DPRINT1("Error: buffer overflow\n");
77 return FALSE;
78 }
79
80 wcscat (lpName, lpszPostfix);
81 if (szSystemRoot[0] != L'C')
82 {
83 wcscat (lpName, szDrivePostfix);
84 }
85
86 return TRUE;
87 }
88
89
90 BOOL WINAPI
91 CreateUserProfileA (PSID Sid,
92 LPCSTR lpUserName)
93 {
94 UNICODE_STRING UserName;
95 BOOL bResult;
96 NTSTATUS Status;
97
98 Status = RtlCreateUnicodeStringFromAsciiz (&UserName,
99 (LPSTR)lpUserName);
100 if (!NT_SUCCESS(Status))
101 {
102 SetLastError (RtlNtStatusToDosError (Status));
103 return FALSE;
104 }
105
106 bResult = CreateUserProfileW (Sid,
107 UserName.Buffer);
108
109 RtlFreeUnicodeString (&UserName);
110
111 return bResult;
112 }
113
114
115 BOOL WINAPI
116 CreateUserProfileW (PSID Sid,
117 LPCWSTR lpUserName)
118 {
119 WCHAR szRawProfilesPath[MAX_PATH];
120 WCHAR szProfilesPath[MAX_PATH];
121 WCHAR szUserProfilePath[MAX_PATH];
122 WCHAR szDefaultUserPath[MAX_PATH];
123 WCHAR szBuffer[MAX_PATH];
124 UNICODE_STRING SidString;
125 DWORD dwLength;
126 DWORD dwDisposition;
127 HKEY hKey;
128 NTSTATUS Status;
129
130 DPRINT("CreateUserProfileW() called\n");
131
132 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
133 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
134 0,
135 KEY_ALL_ACCESS,
136 &hKey))
137 {
138 DPRINT1("Error: %lu\n", GetLastError());
139 return FALSE;
140 }
141
142 /* Get profiles path */
143 dwLength = MAX_PATH * sizeof(WCHAR);
144 if (RegQueryValueExW (hKey,
145 L"ProfilesDirectory",
146 NULL,
147 NULL,
148 (LPBYTE)szRawProfilesPath,
149 &dwLength))
150 {
151 DPRINT1("Error: %lu\n", GetLastError());
152 RegCloseKey (hKey);
153 return FALSE;
154 }
155
156 /* Expand it */
157 if (!ExpandEnvironmentStringsW (szRawProfilesPath,
158 szProfilesPath,
159 MAX_PATH))
160 {
161 DPRINT1("Error: %lu\n", GetLastError());
162 RegCloseKey (hKey);
163 return FALSE;
164 }
165
166 /* Get default user path */
167 dwLength = MAX_PATH * sizeof(WCHAR);
168 if (RegQueryValueExW (hKey,
169 L"DefaultUserProfile",
170 NULL,
171 NULL,
172 (LPBYTE)szBuffer,
173 &dwLength))
174 {
175 DPRINT1("Error: %lu\n", GetLastError());
176 RegCloseKey (hKey);
177 return FALSE;
178 }
179
180 RegCloseKey (hKey);
181
182 wcscpy (szUserProfilePath, szProfilesPath);
183 wcscat (szUserProfilePath, L"\\");
184 wcscat (szUserProfilePath, lpUserName);
185 if (!AppendSystemPostfix (szUserProfilePath, MAX_PATH))
186 {
187 DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
188 RtlFreeUnicodeString (&SidString);
189 RegCloseKey (hKey);
190 return FALSE;
191 }
192
193 wcscpy (szDefaultUserPath, szProfilesPath);
194 wcscat (szDefaultUserPath, L"\\");
195 wcscat (szDefaultUserPath, szBuffer);
196
197 /* Create user profile directory */
198 if (!CreateDirectoryW (szUserProfilePath, NULL))
199 {
200 if (GetLastError () != ERROR_ALREADY_EXISTS)
201 {
202 DPRINT1("Error: %lu\n", GetLastError());
203 return FALSE;
204 }
205 }
206
207 /* Copy default user directory */
208 if (!CopyDirectory (szUserProfilePath, szDefaultUserPath))
209 {
210 DPRINT1("Error: %lu\n", GetLastError());
211 return FALSE;
212 }
213
214 /* Add profile to profile list */
215 Status = RtlConvertSidToUnicodeString (&SidString, Sid, TRUE);
216 if (!NT_SUCCESS(Status))
217 {
218 DPRINT1("Status: %lx\n", Status);
219 return FALSE;
220 }
221
222 wcscpy (szBuffer,
223 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
224 wcscat (szBuffer, SidString.Buffer);
225
226 /* Create user profile key */
227 if (RegCreateKeyExW (HKEY_LOCAL_MACHINE,
228 szBuffer,
229 0,
230 NULL,
231 REG_OPTION_NON_VOLATILE,
232 KEY_ALL_ACCESS,
233 NULL,
234 &hKey,
235 &dwDisposition))
236 {
237 DPRINT1("Error: %lu\n", GetLastError());
238 RtlFreeUnicodeString (&SidString);
239 return FALSE;
240 }
241
242 /* Create non-expanded user profile path */
243 wcscpy (szBuffer, szRawProfilesPath);
244 wcscat (szBuffer, L"\\");
245 wcscat (szBuffer, lpUserName);
246 if (!AppendSystemPostfix (szBuffer, MAX_PATH))
247 {
248 DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
249 RtlFreeUnicodeString (&SidString);
250 RegCloseKey (hKey);
251 return FALSE;
252 }
253
254 /* Set 'ProfileImagePath' value (non-expanded) */
255 if (RegSetValueExW (hKey,
256 L"ProfileImagePath",
257 0,
258 REG_EXPAND_SZ,
259 (LPBYTE)szBuffer,
260 (wcslen (szBuffer) + 1) * sizeof(WCHAR)))
261 {
262 DPRINT1("Error: %lu\n", GetLastError());
263 RtlFreeUnicodeString (&SidString);
264 RegCloseKey (hKey);
265 return FALSE;
266 }
267
268 /* Set 'Sid' value */
269 if (RegSetValueExW (hKey,
270 L"Sid",
271 0,
272 REG_BINARY,
273 Sid,
274 RtlLengthSid (Sid)))
275 {
276 DPRINT1("Error: %lu\n", GetLastError());
277 RtlFreeUnicodeString (&SidString);
278 RegCloseKey (hKey);
279 return FALSE;
280 }
281
282 RegCloseKey (hKey);
283
284 /* Create user hive name */
285 wcscpy (szBuffer, szUserProfilePath);
286 wcscat (szBuffer, L"\\ntuser.dat");
287
288 /* Create new user hive */
289 if (RegLoadKeyW (HKEY_USERS,
290 SidString.Buffer,
291 szBuffer))
292 {
293 DPRINT1("Error: %lu\n", GetLastError());
294 RtlFreeUnicodeString (&SidString);
295 return FALSE;
296 }
297
298 /* Initialize user hive */
299 if (!CreateUserHive (SidString.Buffer, szUserProfilePath))
300 {
301 DPRINT1("Error: %lu\n", GetLastError());
302 RtlFreeUnicodeString (&SidString);
303 return FALSE;
304 }
305
306 RegUnLoadKeyW (HKEY_USERS,
307 SidString.Buffer);
308
309 RtlFreeUnicodeString (&SidString);
310
311 DPRINT("CreateUserProfileW() done\n");
312
313 return TRUE;
314 }
315
316
317 BOOL WINAPI
318 GetAllUsersProfileDirectoryA (LPSTR lpProfileDir,
319 LPDWORD lpcchSize)
320 {
321 LPWSTR lpBuffer;
322 BOOL bResult;
323
324 lpBuffer = GlobalAlloc (GMEM_FIXED,
325 *lpcchSize * sizeof(WCHAR));
326 if (lpBuffer == NULL)
327 return FALSE;
328
329 bResult = GetAllUsersProfileDirectoryW (lpBuffer,
330 lpcchSize);
331 if (bResult)
332 {
333 WideCharToMultiByte (CP_ACP,
334 0,
335 lpBuffer,
336 -1,
337 lpProfileDir,
338 *lpcchSize,
339 NULL,
340 NULL);
341 }
342
343 GlobalFree (lpBuffer);
344
345 return bResult;
346 }
347
348
349 BOOL WINAPI
350 GetAllUsersProfileDirectoryW (LPWSTR lpProfileDir,
351 LPDWORD lpcchSize)
352 {
353 WCHAR szProfilePath[MAX_PATH];
354 WCHAR szBuffer[MAX_PATH];
355 DWORD dwLength;
356 HKEY hKey;
357
358 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
359 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
360 0,
361 KEY_READ,
362 &hKey))
363 {
364 DPRINT1("Error: %lu\n", GetLastError());
365 return FALSE;
366 }
367
368 /* Get profiles path */
369 dwLength = MAX_PATH * sizeof(WCHAR);
370 if (RegQueryValueExW (hKey,
371 L"ProfilesDirectory",
372 NULL,
373 NULL,
374 (LPBYTE)szBuffer,
375 &dwLength))
376 {
377 DPRINT1("Error: %lu\n", GetLastError());
378 RegCloseKey (hKey);
379 return FALSE;
380 }
381
382 /* Expand it */
383 if (!ExpandEnvironmentStringsW (szBuffer,
384 szProfilePath,
385 MAX_PATH))
386 {
387 DPRINT1("Error: %lu\n", GetLastError());
388 RegCloseKey (hKey);
389 return FALSE;
390 }
391
392 /* Get 'AllUsersProfile' name */
393 dwLength = MAX_PATH * sizeof(WCHAR);
394 if (RegQueryValueExW (hKey,
395 L"AllUsersProfile",
396 NULL,
397 NULL,
398 (LPBYTE)szBuffer,
399 &dwLength))
400 {
401 DPRINT1("Error: %lu\n", GetLastError());
402 RegCloseKey (hKey);
403 return FALSE;
404 }
405
406 RegCloseKey (hKey);
407
408 wcscat (szProfilePath, L"\\");
409 wcscat (szProfilePath, szBuffer);
410
411 dwLength = wcslen (szProfilePath);
412 if (lpProfileDir != NULL)
413 {
414 if (*lpcchSize < dwLength)
415 {
416 *lpcchSize = dwLength;
417 SetLastError (ERROR_INSUFFICIENT_BUFFER);
418 return FALSE;
419 }
420
421 wcscpy (lpProfileDir, szProfilePath);
422 }
423
424 *lpcchSize = dwLength;
425
426 return TRUE;
427 }
428
429
430 BOOL WINAPI
431 GetDefaultUserProfileDirectoryA (LPSTR lpProfileDir,
432 LPDWORD lpcchSize)
433 {
434 LPWSTR lpBuffer;
435 BOOL bResult;
436
437 lpBuffer = GlobalAlloc (GMEM_FIXED,
438 *lpcchSize * sizeof(WCHAR));
439 if (lpBuffer == NULL)
440 return FALSE;
441
442 bResult = GetDefaultUserProfileDirectoryW (lpBuffer,
443 lpcchSize);
444 if (bResult)
445 {
446 WideCharToMultiByte (CP_ACP,
447 0,
448 lpBuffer,
449 -1,
450 lpProfileDir,
451 *lpcchSize,
452 NULL,
453 NULL);
454 }
455
456 GlobalFree (lpBuffer);
457
458 return bResult;
459 }
460
461
462 BOOL WINAPI
463 GetDefaultUserProfileDirectoryW (LPWSTR lpProfileDir,
464 LPDWORD lpcchSize)
465 {
466 WCHAR szProfilePath[MAX_PATH];
467 WCHAR szBuffer[MAX_PATH];
468 DWORD dwLength;
469 HKEY hKey;
470
471 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
472 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
473 0,
474 KEY_READ,
475 &hKey))
476 {
477 DPRINT1("Error: %lu\n", GetLastError());
478 return FALSE;
479 }
480
481 /* Get profiles path */
482 dwLength = MAX_PATH * sizeof(WCHAR);
483 if (RegQueryValueExW (hKey,
484 L"ProfilesDirectory",
485 NULL,
486 NULL,
487 (LPBYTE)szBuffer,
488 &dwLength))
489 {
490 DPRINT1("Error: %lu\n", GetLastError());
491 RegCloseKey (hKey);
492 return FALSE;
493 }
494
495 /* Expand it */
496 if (!ExpandEnvironmentStringsW (szBuffer,
497 szProfilePath,
498 MAX_PATH))
499 {
500 DPRINT1("Error: %lu\n", GetLastError());
501 RegCloseKey (hKey);
502 return FALSE;
503 }
504
505 /* Get 'DefaultUserProfile' name */
506 dwLength = MAX_PATH * sizeof(WCHAR);
507 if (RegQueryValueExW (hKey,
508 L"DefaultUserProfile",
509 NULL,
510 NULL,
511 (LPBYTE)szBuffer,
512 &dwLength))
513 {
514 DPRINT1("Error: %lu\n", GetLastError());
515 RegCloseKey (hKey);
516 return FALSE;
517 }
518
519 RegCloseKey (hKey);
520
521 wcscat (szProfilePath, L"\\");
522 wcscat (szProfilePath, szBuffer);
523
524 dwLength = wcslen (szProfilePath);
525 if (lpProfileDir != NULL)
526 {
527 if (*lpcchSize < dwLength)
528 {
529 *lpcchSize = dwLength;
530 SetLastError (ERROR_INSUFFICIENT_BUFFER);
531 return FALSE;
532 }
533
534 wcscpy (lpProfileDir, szProfilePath);
535 }
536
537 *lpcchSize = dwLength;
538
539 return TRUE;
540 }
541
542
543 BOOL WINAPI
544 GetProfilesDirectoryA (LPSTR lpProfileDir,
545 LPDWORD lpcchSize)
546 {
547 LPWSTR lpBuffer;
548 BOOL bResult;
549
550 lpBuffer = GlobalAlloc (GMEM_FIXED,
551 *lpcchSize * sizeof(WCHAR));
552 if (lpBuffer == NULL)
553 return FALSE;
554
555 bResult = GetProfilesDirectoryW (lpBuffer,
556 lpcchSize);
557 if (bResult)
558 {
559 WideCharToMultiByte (CP_ACP,
560 0,
561 lpBuffer,
562 -1,
563 lpProfileDir,
564 *lpcchSize,
565 NULL,
566 NULL);
567 }
568
569 GlobalFree (lpBuffer);
570
571 return bResult;
572 }
573
574
575 BOOL WINAPI
576 GetProfilesDirectoryW (LPWSTR lpProfilesDir,
577 LPDWORD lpcchSize)
578 {
579 WCHAR szProfilesPath[MAX_PATH];
580 WCHAR szBuffer[MAX_PATH];
581 DWORD dwLength;
582 HKEY hKey;
583
584 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
585 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
586 0,
587 KEY_READ,
588 &hKey))
589 {
590 DPRINT1("Error: %lu\n", GetLastError());
591 return FALSE;
592 }
593
594 /* Get profiles path */
595 dwLength = MAX_PATH * sizeof(WCHAR);
596 if (RegQueryValueExW (hKey,
597 L"ProfilesDirectory",
598 NULL,
599 NULL,
600 (LPBYTE)szBuffer,
601 &dwLength))
602 {
603 DPRINT1("Error: %lu\n", GetLastError());
604 RegCloseKey (hKey);
605 return FALSE;
606 }
607
608 RegCloseKey (hKey);
609
610 /* Expand it */
611 if (!ExpandEnvironmentStringsW (szBuffer,
612 szProfilesPath,
613 MAX_PATH))
614 {
615 DPRINT1("Error: %lu\n", GetLastError());
616 return FALSE;
617 }
618
619 dwLength = wcslen (szProfilesPath);
620 if (lpProfilesDir != NULL)
621 {
622 if (*lpcchSize < dwLength)
623 {
624 *lpcchSize = dwLength;
625 SetLastError (ERROR_INSUFFICIENT_BUFFER);
626 return FALSE;
627 }
628
629 wcscpy (lpProfilesDir, szProfilesPath);
630 }
631
632 *lpcchSize = dwLength;
633
634 return TRUE;
635 }
636
637
638 BOOL WINAPI
639 GetUserProfileDirectoryA (HANDLE hToken,
640 LPSTR lpProfileDir,
641 LPDWORD lpcchSize)
642 {
643 LPWSTR lpBuffer;
644 BOOL bResult;
645
646 lpBuffer = GlobalAlloc (GMEM_FIXED,
647 *lpcchSize * sizeof(WCHAR));
648 if (lpBuffer == NULL)
649 return FALSE;
650
651 bResult = GetUserProfileDirectoryW (hToken,
652 lpBuffer,
653 lpcchSize);
654 if (bResult)
655 {
656 WideCharToMultiByte (CP_ACP,
657 0,
658 lpBuffer,
659 -1,
660 lpProfileDir,
661 *lpcchSize,
662 NULL,
663 NULL);
664 }
665
666 GlobalFree (lpBuffer);
667
668 return bResult;
669 }
670
671
672 BOOL WINAPI
673 GetUserProfileDirectoryW (HANDLE hToken,
674 LPWSTR lpProfileDir,
675 LPDWORD lpcchSize)
676 {
677 UNICODE_STRING SidString;
678 WCHAR szKeyName[MAX_PATH];
679 WCHAR szRawImagePath[MAX_PATH];
680 WCHAR szImagePath[MAX_PATH];
681 DWORD dwLength;
682 HKEY hKey;
683
684 if (!GetUserSidFromToken (hToken,
685 &SidString))
686 {
687 DPRINT1 ("GetUserSidFromToken() failed\n");
688 return FALSE;
689 }
690
691 DPRINT ("SidString: '%wZ'\n", &SidString);
692
693 wcscpy (szKeyName,
694 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
695 wcscat (szKeyName,
696 SidString.Buffer);
697
698 RtlFreeUnicodeString (&SidString);
699
700 DPRINT ("KeyName: '%S'\n", szKeyName);
701
702 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
703 szKeyName,
704 0,
705 KEY_ALL_ACCESS,
706 &hKey))
707 {
708 DPRINT1 ("Error: %lu\n", GetLastError());
709 return FALSE;
710 }
711
712 dwLength = MAX_PATH * sizeof(WCHAR);
713 if (RegQueryValueExW (hKey,
714 L"ProfileImagePath",
715 NULL,
716 NULL,
717 (LPBYTE)szRawImagePath,
718 &dwLength))
719 {
720 DPRINT1 ("Error: %lu\n", GetLastError());
721 RegCloseKey (hKey);
722 return FALSE;
723 }
724
725 RegCloseKey (hKey);
726
727 DPRINT ("RawImagePath: '%S'\n", szRawImagePath);
728
729 /* Expand it */
730 if (!ExpandEnvironmentStringsW (szRawImagePath,
731 szImagePath,
732 MAX_PATH))
733 {
734 DPRINT1 ("Error: %lu\n", GetLastError());
735 return FALSE;
736 }
737
738 DPRINT ("ImagePath: '%S'\n", szImagePath);
739
740 dwLength = wcslen (szImagePath);
741 if (dwLength > *lpcchSize)
742 {
743 DPRINT1 ("Buffer too small\n");
744 SetLastError (ERROR_INSUFFICIENT_BUFFER);
745 return FALSE;
746 }
747
748 *lpcchSize = dwLength;
749 wcscpy (lpProfileDir,
750 szImagePath);
751
752 return TRUE;
753 }
754
755
756 static BOOL
757 CheckForLoadedProfile (HANDLE hToken)
758 {
759 UNICODE_STRING SidString;
760 HKEY hKey;
761
762 DPRINT ("CheckForLoadedProfile() called \n");
763
764 if (!GetUserSidFromToken (hToken,
765 &SidString))
766 {
767 DPRINT1 ("GetUserSidFromToken() failed\n");
768 return FALSE;
769 }
770
771 if (RegOpenKeyExW (HKEY_USERS,
772 SidString.Buffer,
773 0,
774 KEY_ALL_ACCESS,
775 &hKey))
776 {
777 DPRINT ("Profile not loaded\n");
778 RtlFreeUnicodeString (&SidString);
779 return FALSE;
780 }
781
782 RegCloseKey (hKey);
783
784 RtlFreeUnicodeString (&SidString);
785
786 DPRINT ("Profile already loaded\n");
787
788 return TRUE;
789 }
790
791
792 BOOL WINAPI
793 LoadUserProfileA (HANDLE hToken,
794 LPPROFILEINFOA lpProfileInfo)
795 {
796 DPRINT ("LoadUserProfileA() not implemented\n");
797 return FALSE;
798 }
799
800
801 BOOL WINAPI
802 LoadUserProfileW (HANDLE hToken,
803 LPPROFILEINFOW lpProfileInfo)
804 {
805 WCHAR szUserHivePath[MAX_PATH];
806 UNICODE_STRING SidString;
807 DWORD dwLength;
808
809 DPRINT ("LoadUserProfileW() called\n");
810
811 /* Check profile info */
812 if (lpProfileInfo->dwSize != sizeof(PROFILEINFOW) ||
813 lpProfileInfo->lpUserName == NULL ||
814 lpProfileInfo->lpUserName[0] == 0)
815 {
816 SetLastError (ERROR_INVALID_PARAMETER);
817 return FALSE;
818 }
819
820 /* Don't load a profile twice */
821 if (CheckForLoadedProfile (hToken))
822 {
823 DPRINT ("Profile already loaded\n");
824 lpProfileInfo->hProfile = NULL;
825 return TRUE;
826 }
827
828 if (!GetProfilesDirectoryW (szUserHivePath,
829 &dwLength))
830 {
831 DPRINT1("GetProfilesDirectoryW() failed\n", GetLastError());
832 return FALSE;
833 }
834
835 wcscat (szUserHivePath, L"\\");
836 wcscat (szUserHivePath, lpProfileInfo->lpUserName);
837 if (!AppendSystemPostfix (szUserHivePath, MAX_PATH))
838 {
839 DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
840 return FALSE;
841 }
842
843 /* Create user hive name */
844 wcscat (szUserHivePath, L"\\ntuser.dat");
845
846 DPRINT ("szUserHivePath: %S\n", szUserHivePath);
847
848 if (!GetUserSidFromToken (hToken,
849 &SidString))
850 {
851 DPRINT1 ("GetUserSidFromToken() failed\n");
852 return FALSE;
853 }
854
855 DPRINT ("SidString: '%wZ'\n", &SidString);
856
857 if (RegLoadKeyW (HKEY_USERS,
858 SidString.Buffer,
859 szUserHivePath))
860 {
861 DPRINT1 ("RegLoadKeyW() failed (Error %ld)\n", GetLastError());
862 RtlFreeUnicodeString (&SidString);
863 return FALSE;
864 }
865
866 if (RegOpenKeyExW (HKEY_USERS,
867 SidString.Buffer,
868 0,
869 KEY_ALL_ACCESS,
870 (PHKEY)&lpProfileInfo->hProfile))
871 {
872 DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", GetLastError());
873 RtlFreeUnicodeString (&SidString);
874 return FALSE;
875 }
876
877 RtlFreeUnicodeString (&SidString);
878
879 DPRINT ("LoadUserProfileW() done\n");
880
881 return TRUE;
882 }
883
884
885 BOOL WINAPI
886 UnloadUserProfile (HANDLE hToken,
887 HANDLE hProfile)
888 {
889 UNICODE_STRING SidString;
890
891 DPRINT ("UnloadUserProfile() called\n");
892
893 if (hProfile == NULL)
894 {
895 DPRINT1 ("Invalide profile handle\n");
896 SetLastError (ERROR_INVALID_PARAMETER);
897 return FALSE;
898 }
899
900 RegCloseKey (hProfile);
901
902 if (!GetUserSidFromToken (hToken,
903 &SidString))
904 {
905 DPRINT1 ("GetUserSidFromToken() failed\n");
906 return FALSE;
907 }
908
909 DPRINT ("SidString: '%wZ'\n", &SidString);
910
911 if (RegUnLoadKeyW (HKEY_USERS,
912 SidString.Buffer))
913 {
914 DPRINT1 ("RegUnLoadKeyW() failed (Error %ld)\n", GetLastError());
915 RtlFreeUnicodeString (&SidString);
916 return FALSE;
917 }
918
919 RtlFreeUnicodeString (&SidString);
920
921 DPRINT ("UnloadUserProfile() done\n");
922
923 return TRUE;
924 }
925
926 /* EOF */