ReactOS 0.4.17-dev-1190-g4c812f4
profile.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/userenv/profile.c
5 * PURPOSE: User profile code
6 * PROGRAMMERS: Eric Kohl
7 * Hervé Poussineau
8 */
9
10#include "precomp.h"
11
12#include <sddl.h>
13
14#define NDEBUG
15#include <debug.h>
16
17/* FUNCTIONS ***************************************************************/
18
19BOOL
21 DWORD dwMaxLength)
22{
23 WCHAR szSystemRoot[MAX_PATH];
24 LPWSTR lpszPostfix;
25 LPWSTR lpszPtr;
26
27 /* Build profile name postfix */
28 if (!ExpandEnvironmentStringsW(L"%SystemRoot%",
29 szSystemRoot,
30 ARRAYSIZE(szSystemRoot)))
31 {
32 DPRINT1("Error: %lu\n", GetLastError());
33 return FALSE;
34 }
35
36 _wcsupr(szSystemRoot);
37
38 /* Get name postfix */
39 szSystemRoot[2] = L'.';
40 lpszPostfix = &szSystemRoot[2];
41 lpszPtr = lpszPostfix;
42 while (*lpszPtr != (WCHAR)0)
43 {
44 if (*lpszPtr == L'\\')
45 *lpszPtr = L'_';
46 lpszPtr++;
47 }
48
49 if (wcslen(lpName) + wcslen(lpszPostfix) + 1 >= dwMaxLength)
50 {
51 DPRINT1("Error: buffer overflow\n");
53 return FALSE;
54 }
55
56 wcscat(lpName, lpszPostfix);
57
58 return TRUE;
59}
60
61
62static
63BOOL
65{
66 BOOL bRet = FALSE;
68 TOKEN_PRIVILEGES TokenPriv;
69
70 DPRINT("AcquireRemoveRestorePrivilege(%d)\n", bAcquire);
71
74 &Token))
75 {
76 TokenPriv.PrivilegeCount = 1;
77 TokenPriv.Privileges[0].Attributes = (bAcquire ? SE_PRIVILEGE_ENABLED : 0);
78
80 {
81 bRet = AdjustTokenPrivileges(Token, FALSE, &TokenPriv, 0, NULL, NULL);
82
83 if (!bRet)
84 {
85 DPRINT1("AdjustTokenPrivileges() failed with error %lu\n", GetLastError());
86 }
88 {
89 DPRINT1("AdjustTokenPrivileges() succeeded, but with not all privileges assigned\n");
90 bRet = FALSE;
91 }
92 }
93 else
94 {
95 DPRINT1("LookupPrivilegeValue() failed with error %lu\n", GetLastError());
96 }
97
99 }
100 else
101 {
102 DPRINT1("OpenProcessToken() failed with error %lu\n", GetLastError());
103 }
104
105 return bRet;
106}
107
108
109static
110BOOL
112{
113 UNICODE_STRING SidString;
114 HKEY hKey;
115
116 DPRINT("CheckForLoadedProfile() called\n");
117
118 /* Get the user SID string */
119 if (!GetUserSidStringFromToken(hToken, &SidString))
120 {
121 DPRINT1("GetUserSidStringFromToken() failed\n");
122 return FALSE;
123 }
124
126 SidString.Buffer,
127 0,
129 &hKey))
130 {
131 DPRINT("Profile not loaded\n");
132 RtlFreeUnicodeString(&SidString);
133 return FALSE;
134 }
135
137
138 RtlFreeUnicodeString(&SidString);
139
140 DPRINT("Profile already loaded\n");
141
142 return TRUE;
143}
144
145
146static
147HANDLE
149 _In_ PWSTR pszSidString)
150{
152 SECURITY_ATTRIBUTES SecurityAttributes;
153 PWSTR pszMutexName = NULL;
155
156 pszMutexName = HeapAlloc(GetProcessHeap(),
157 0,
158 (wcslen(L"Global\\userenv: User Profile Mutex for ") + wcslen(pszSidString) + 1) * sizeof(WCHAR));
159 if (pszMutexName == NULL)
160 {
161 DPRINT("Failed to allocate the mutex name buffer!\n");
163 return NULL;
164 }
165
166 /* Build the profile mutex name */
167 wcscpy(pszMutexName, L"Global\\userenv: User Profile Mutex for ");
168 wcscat(pszMutexName, pszSidString);
169
170 /* Initialize the security descriptor */
173
174 /* Set a NULL-DACL (everyone has access) */
176 TRUE,
177 NULL,
178 FALSE);
179
180 /* Initialize the security attributes */
181 SecurityAttributes.nLength = sizeof(SecurityAttributes);
182 SecurityAttributes.lpSecurityDescriptor = &SecurityDescriptor;
183 SecurityAttributes.bInheritHandle = FALSE;
184
185 /* Create the profile mutex */
186 hMutex = CreateMutexW(&SecurityAttributes,
187 FALSE,
188 pszMutexName);
189 if (hMutex == NULL)
190 {
191 DPRINT1("Failed to create the profile mutex (Error %lu)\n", GetLastError());
192 }
193
194 HeapFree(GetProcessHeap(), 0, pszMutexName);
195
196 return hMutex;
197}
198
199
200static
201DWORD
203 PWSTR pszSidString,
204 PDWORD pdwRefCount)
205{
206 HKEY hProfilesKey = NULL, hProfileKey = NULL;
207 DWORD dwRefCount = 0, dwLength, dwType;
208 DWORD dwError;
209
210 DPRINT1("IncrementRefCount(%S %p)\n",
211 pszSidString, pdwRefCount);
212
214 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
215 0,
217 &hProfilesKey);
218 if (dwError != ERROR_SUCCESS)
219 {
220 DPRINT1("Error: %lu\n", dwError);
221 goto done;
222 }
223
224 dwError = RegOpenKeyExW(hProfilesKey,
225 pszSidString,
226 0,
228 &hProfileKey);
229 if (dwError != ERROR_SUCCESS)
230 {
231 DPRINT1("Error: %lu\n", dwError);
232 goto done;
233 }
234
235 /* Get the reference counter */
236 dwLength = sizeof(dwRefCount);
237 RegQueryValueExW(hProfileKey,
238 L"RefCount",
239 NULL,
240 &dwType,
241 (PBYTE)&dwRefCount,
242 &dwLength);
243
244 dwRefCount++;
245
246 dwLength = sizeof(dwRefCount);
247 dwError = RegSetValueExW(hProfileKey,
248 L"RefCount",
249 0,
250 REG_DWORD,
251 (PBYTE)&dwRefCount,
252 dwLength);
253 if (dwError != ERROR_SUCCESS)
254 {
255 DPRINT1("Error: %lu\n", dwError);
256 goto done;
257 }
258
259 if (pdwRefCount != NULL)
260 *pdwRefCount = dwRefCount;
261
262done:
263 if (hProfileKey != NULL)
264 RegCloseKey(hProfileKey);
265
266 if (hProfilesKey != NULL)
267 RegCloseKey(hProfilesKey);
268
269 return dwError;
270}
271
272
273static
274DWORD
276 PWSTR pszSidString,
277 PDWORD pdwRefCount)
278{
279 HKEY hProfilesKey = NULL, hProfileKey = NULL;
280 DWORD dwRefCount = 0, dwLength, dwType;
281 DWORD dwError;
282
283 DPRINT1("DecrementRefCount(%S %p)\n",
284 pszSidString, pdwRefCount);
285
287 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
288 0,
290 &hProfilesKey);
291 if (dwError != ERROR_SUCCESS)
292 {
293 DPRINT1("Error: %lu\n", dwError);
294 goto done;
295 }
296
297 dwError = RegOpenKeyExW(hProfilesKey,
298 pszSidString,
299 0,
301 &hProfileKey);
302 if (dwError != ERROR_SUCCESS)
303 {
304 DPRINT1("Error: %lu\n", dwError);
305 goto done;
306 }
307
308 /* Get the reference counter */
309 dwLength = sizeof(dwRefCount);
310 dwError = RegQueryValueExW(hProfileKey,
311 L"RefCount",
312 NULL,
313 &dwType,
314 (PBYTE)&dwRefCount,
315 &dwLength);
316 if (dwError != ERROR_SUCCESS)
317 {
318 DPRINT1("Error: %lu\n", dwError);
319 goto done;
320 }
321
322 dwRefCount--;
323
324 dwLength = sizeof(dwRefCount);
325 dwError = RegSetValueExW(hProfileKey,
326 L"RefCount",
327 0,
328 REG_DWORD,
329 (PBYTE)&dwRefCount,
330 dwLength);
331 if (dwError != ERROR_SUCCESS)
332 {
333 DPRINT1("Error: %lu\n", dwError);
334 goto done;
335 }
336
337 if (pdwRefCount != NULL)
338 *pdwRefCount = dwRefCount;
339
340done:
341 if (hProfileKey != NULL)
342 RegCloseKey(hProfileKey);
343
344 if (hProfilesKey != NULL)
345 RegCloseKey(hProfilesKey);
346
347 return dwError;
348}
349
350
351static
352DWORD
354 _In_ HANDLE hToken,
355 _Out_ PDWORD pdwState)
356{
357 PTOKEN_GROUPS pGroupInfo = NULL;
358 PSID pAdministratorsSID = NULL;
359 PSID pGuestsSID = NULL;
360 DWORD i, dwSize = 0;
361 DWORD dwError = ERROR_SUCCESS;
362
363 DPRINT("CheckForGuestsAndAdmins(%p %p)\n", hToken, pdwState);
364
365 /* Get the buffer size */
367 {
368 dwError = GetLastError();
369 if (dwError != ERROR_INSUFFICIENT_BUFFER)
370 {
371 DPRINT1("GetTokenInformation() failed (Error %lu)\n", dwError);
372 return dwError;
373 }
374
375 dwError = ERROR_SUCCESS;
376 }
377
378 /* Allocate the buffer */
379 pGroupInfo = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(), 0, dwSize);
380 if (pGroupInfo == NULL)
381 {
382 dwError = ERROR_OUTOFMEMORY;
383 DPRINT1("HeapAlloc() failed (Error %lu)\n", dwError);
384 goto done;
385 }
386
387 /* Get the token groups */
388 if (!GetTokenInformation(hToken, TokenGroups, pGroupInfo, dwSize, &dwSize))
389 {
390 dwError = GetLastError();
391 DPRINT1("GetTokenInformation() failed (Error %lu)\n", dwError);
392 goto done;
393 }
394
395 /* Build the Administrators Group SID */
397 2,
400 0, 0, 0, 0, 0, 0,
401 &pAdministratorsSID))
402 {
403 dwError = GetLastError();
404 DPRINT1("AllocateAndInitializeSid() failed (Error %lu)\n", dwError);
405 goto done;
406 }
407
408 /* Build the Guests Group SID */
410 2,
413 0, 0, 0, 0, 0, 0,
414 &pGuestsSID))
415 {
416 dwError = GetLastError();
417 DPRINT1("AllocateAndInitializeSid() failed (Error %lu)\n", dwError);
418 goto done;
419 }
420
421 /* Check for Administratos or Guests group memberships */
422 for (i = 0; i < pGroupInfo->GroupCount; i++)
423 {
424 if (EqualSid(pAdministratorsSID, pGroupInfo->Groups[i].Sid))
425 {
426 *pdwState |= 0x0100; // PROFILE_ADMIN_USER
427 }
428
429 if (EqualSid(pGuestsSID, pGroupInfo->Groups[i].Sid))
430 {
431 *pdwState |= 0x0080; // PROFILE_GUESTS_USER
432 }
433 }
434
435 dwError = ERROR_SUCCESS;
436
437done:
438 if (pGuestsSID != NULL)
439 FreeSid(pGuestsSID);
440
441 if (pAdministratorsSID != NULL)
442 FreeSid(pAdministratorsSID);
443
444 if (pGroupInfo != NULL)
445 HeapFree(GetProcessHeap(), 0, pGroupInfo);
446
447 return dwError;
448}
449
450
451static
452DWORD
454 _In_ PWSTR pszSidString,
456 _In_ HANDLE hToken)
457{
458 HKEY hProfilesKey = NULL, hProfileKey = NULL;
459 FILETIME LoadTime;
460 DWORD dwLength, dwState = 0;
461 DWORD dwError;
462
463 DPRINT("SetProfileData(%S %p)\n", pszSidString, hToken);
464
466 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
467 0,
469 &hProfilesKey);
470 if (dwError != ERROR_SUCCESS)
471 {
472 DPRINT1("Error: %lu\n", dwError);
473 goto done;
474 }
475
476 dwError = RegOpenKeyExW(hProfilesKey,
477 pszSidString,
478 0,
480 &hProfileKey);
481 if (dwError != ERROR_SUCCESS)
482 {
483 DPRINT1("Error: %lu\n", dwError);
484 goto done;
485 }
486
487 /* Set the profile load time */
488 GetSystemTimeAsFileTime(&LoadTime);
489
490 dwLength = sizeof(LoadTime.dwLowDateTime);
491 dwError = RegSetValueExW(hProfileKey,
492 L"ProfileLoadTimeLow",
493 0,
494 REG_DWORD,
495 (PBYTE)&LoadTime.dwLowDateTime,
496 dwLength);
497 if (dwError != ERROR_SUCCESS)
498 {
499 DPRINT1("Error: %lu\n", dwError);
500 goto done;
501 }
502
503 dwLength = sizeof(LoadTime.dwHighDateTime);
504 dwError = RegSetValueExW(hProfileKey,
505 L"ProfileLoadTimeHigh",
506 0,
507 REG_DWORD,
508 (PBYTE)&LoadTime.dwHighDateTime,
509 dwLength);
510 if (dwError != ERROR_SUCCESS)
511 {
512 DPRINT1("Error: %lu\n", dwError);
513 goto done;
514 }
515
516 dwLength = sizeof(dwFlags);
517 dwError = RegSetValueExW(hProfileKey,
518 L"Flags",
519 0,
520 REG_DWORD,
521 (PBYTE)&dwFlags,
522 dwLength);
523 if (dwError != ERROR_SUCCESS)
524 {
525 DPRINT1("Error: %lu\n", dwError);
526 goto done;
527 }
528
529 dwError = CheckForGuestsAndAdmins(hToken,
530 &dwState);
531 if (dwError != ERROR_SUCCESS)
532 {
533 DPRINT1("Error: %lu\n", dwError);
534 goto done;
535 }
536
537 dwLength = sizeof(dwState);
538 dwError = RegSetValueExW(hProfileKey,
539 L"State",
540 0,
541 REG_DWORD,
542 (PBYTE)&dwState,
543 dwLength);
544 if (dwError != ERROR_SUCCESS)
545 {
546 DPRINT1("Error: %lu\n", dwError);
547 goto done;
548 }
549
550done:
551 if (hProfileKey != NULL)
552 RegCloseKey(hProfileKey);
553
554 if (hProfilesKey != NULL)
555 RegCloseKey(hProfilesKey);
556
557 return dwError;
558}
559
560
561/* PUBLIC FUNCTIONS ********************************************************/
562
563BOOL
564WINAPI
567{
568 WCHAR szKeyName[MAX_PATH];
569 WCHAR szRawProfilePath[MAX_PATH];
570 WCHAR szProfilePath[MAX_PATH];
571 WCHAR szDefaultProfilePath[MAX_PATH];
572 UNICODE_STRING SidString = {0, 0, NULL};
573 HANDLE hToken = NULL;
574 PSID pUserSid = NULL;
575 HKEY hProfileKey = NULL;
576 DWORD dwDisposition;
577 BOOL bResult = FALSE;
578 DWORD cchSize;
579 DWORD dwError;
580
581 DPRINT1("CopySystemProfile()\n");
582
585 &hToken))
586 {
587 DPRINT1("Failed to open the process token (Error %lu)\n", GetLastError());
588 return FALSE;
589 }
590
591 pUserSid = GetUserSid(hToken);
592 if (pUserSid == NULL)
593 {
594 DPRINT1("Failed to get the users SID (Error %lu)\n", GetLastError());
595 goto done;
596 }
597
598 /* Get the user SID string */
599 if (!GetUserSidStringFromToken(hToken, &SidString))
600 {
601 DPRINT1("GetUserSidStringFromToken() failed\n");
602 goto done;
603 }
604
605 StringCbCopyW(szKeyName, sizeof(szKeyName),
606 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
607 StringCbCatW(szKeyName, sizeof(szKeyName), SidString.Buffer);
608
609 RtlFreeUnicodeString(&SidString);
610
612 szKeyName,
613 0, NULL, 0,
614 KEY_WRITE,
615 NULL,
616 &hProfileKey,
617 &dwDisposition);
618 if (dwError != ERROR_SUCCESS)
619 {
620 DPRINT1("Failed to create the profile key for the %s profile (Error %lu)\n",
621 SidString.Buffer, dwError);
622 goto done;
623 }
624
625 dwError = RegSetValueExW(hProfileKey,
626 L"Sid",
627 0,
629 (PBYTE)pUserSid,
630 RtlLengthSid(pUserSid));
631 if (dwError != ERROR_SUCCESS)
632 {
633 DPRINT1("Failed to set the SID value (Error %lu)\n", dwError);
634 goto done;
635 }
636
637 wcscpy(szRawProfilePath,
638 L"%systemroot%\\system32\\config\\systemprofile");
639
640 dwError = RegSetValueExW(hProfileKey,
641 L"ProfileImagePath",
642 0,
644 (PBYTE)szRawProfilePath,
645 (wcslen(szRawProfilePath) + 1) * sizeof(WCHAR));
646 if (dwError != ERROR_SUCCESS)
647 {
648 DPRINT1("Failed to set the ProfileImagePath value (Error %lu)\n", dwError);
649 goto done;
650 }
651
652 /* Expand the raw profile path */
653 if (!ExpandEnvironmentStringsW(szRawProfilePath,
654 szProfilePath,
655 ARRAYSIZE(szProfilePath)))
656 {
657 DPRINT1("Failled to expand the raw profile path (Error %lu)\n", GetLastError());
658 goto done;
659 }
660
661 /* Create the profile directory if it does not exist yet */
662 // FIXME: Security!
663 if (!CreateDirectoryW(szProfilePath, NULL))
664 {
666 {
667 DPRINT1("Failed to create the profile directory (Error %lu)\n", GetLastError());
668 goto done;
669 }
670 }
671
672 /* Get the path of the default profile */
673 cchSize = ARRAYSIZE(szDefaultProfilePath);
674 if (!GetDefaultUserProfileDirectoryW(szDefaultProfilePath, &cchSize))
675 {
676 DPRINT1("Failed to create the default profile path (Error %lu)\n", GetLastError());
677 goto done;
678 }
679
680 /* Copy the default profile into the new profile directory */
681 // FIXME: Security!
682 if (!CopyDirectory(szProfilePath, szDefaultProfilePath))
683 {
684 DPRINT1("Failed to copy the default profile directory (Error %lu)\n", GetLastError());
685 goto done;
686 }
687
688 bResult = TRUE;
689
690done:
691 if (hProfileKey != NULL)
692 RegCloseKey(hProfileKey);
693
694 RtlFreeUnicodeString(&SidString);
695
696 if (pUserSid != NULL)
697 LocalFree(pUserSid);
698
699 if (hToken != NULL)
700 CloseHandle(hToken);
701
702 return bResult;
703}
704
705
706BOOL
707WINAPI
709 _In_ PSID pSid,
710 _In_ LPCSTR lpUserName)
711{
712 LPWSTR pUserNameW = NULL;
713 INT nLength;
714 BOOL bResult;
715
716 DPRINT("CreateUserProfileA(%p %s)\n", pSid, lpUserName);
717
718 /* Convert lpUserName to Unicode */
719 nLength = MultiByteToWideChar(CP_ACP, 0, lpUserName, -1, NULL, 0);
720 pUserNameW = HeapAlloc(GetProcessHeap(), 0, nLength * sizeof(WCHAR));
721 if (pUserNameW == NULL)
722 {
724 return FALSE;
725 }
726 MultiByteToWideChar(CP_ACP, 0, lpUserName, -1, pUserNameW, nLength);
727
728 /* Call the Ex function */
729 bResult = CreateUserProfileExW(pSid,
730 pUserNameW,
731 NULL,
732 NULL,
733 0,
734 FALSE);
735
736 HeapFree(GetProcessHeap(), 0, pUserNameW);
737
738 return bResult;
739}
740
741
742BOOL
743WINAPI
745 _In_ PSID pSid,
746 _In_ LPCWSTR lpUserName)
747{
748 DPRINT("CreateUserProfileW(%p %S)\n", pSid, lpUserName);
749
750 /* Call the Ex function */
752 lpUserName,
753 NULL,
754 NULL,
755 0,
756 FALSE);
757}
758
759
760BOOL
761WINAPI
763 _In_ PSID pSid,
764 _In_ LPCSTR lpUserName,
765 _In_opt_ LPCSTR lpUserHive,
766 _Out_opt_ LPSTR lpProfileDir,
767 _In_ DWORD dwDirSize,
768 _In_ BOOL bWin9xUpg)
769{
770 LPWSTR pUserNameW = NULL;
771 LPWSTR pUserHiveW = NULL;
772 LPWSTR pProfileDirW = NULL;
773 INT nLength;
774 BOOL bResult = FALSE;
775
776 DPRINT("CreateUserProfileExA(%p %s %s %p %lu %d)\n",
777 pSid, lpUserName, lpUserHive, lpProfileDir, dwDirSize, bWin9xUpg);
778
779 /* Check the parameters */
780 if (lpProfileDir != NULL && dwDirSize == 0)
781 {
783 return FALSE;
784 }
785
786 /* Convert lpUserName to Unicode */
787 nLength = MultiByteToWideChar(CP_ACP, 0, lpUserName, -1, NULL, 0);
788 pUserNameW = HeapAlloc(GetProcessHeap(), 0, nLength * sizeof(WCHAR));
789 if (pUserNameW == NULL)
790 {
792 goto done;
793 }
794 MultiByteToWideChar(CP_ACP, 0, lpUserName, -1, pUserNameW, nLength);
795
796 /* Convert lpUserHive to Unicode */
797 if (lpUserHive != NULL)
798 {
799 nLength = MultiByteToWideChar(CP_ACP, 0, lpUserHive, -1, NULL, 0);
800 pUserHiveW = HeapAlloc(GetProcessHeap(), 0, nLength * sizeof(WCHAR));
801 if (pUserHiveW == NULL)
802 {
804 goto done;
805 }
806 MultiByteToWideChar(CP_ACP, 0, lpUserHive, -1, pUserHiveW, nLength);
807 }
808
809 /* Allocate a Unicode buffer for lpProfileDir */
810 if (lpProfileDir != NULL)
811 {
812 pProfileDirW = HeapAlloc(GetProcessHeap(), 0, dwDirSize * sizeof(WCHAR));
813 if (pProfileDirW == NULL)
814 {
816 goto done;
817 }
818 }
819
820 /* Call the Unicode function */
821 bResult = CreateUserProfileExW(pSid,
822 (LPCWSTR)pUserNameW,
823 (LPCWSTR)pUserHiveW,
824 pProfileDirW,
825 dwDirSize,
826 bWin9xUpg);
827
828 /* Convert the profile path to ANSI */
829 if (bResult && lpProfileDir != NULL)
830 {
831 WideCharToMultiByte(CP_ACP, 0, pProfileDirW, -1, lpProfileDir, dwDirSize, NULL, NULL);
832 }
833
834done:
835 /* Free the buffers */
836 if (pProfileDirW != NULL)
837 HeapFree(GetProcessHeap(), 0, pProfileDirW);
838
839 if (pUserHiveW != NULL)
840 HeapFree(GetProcessHeap(), 0, pUserHiveW);
841
842 if (pUserNameW != NULL)
843 HeapFree(GetProcessHeap(), 0, pUserNameW);
844
845 return bResult;
846}
847
848
849BOOL
850WINAPI
852 _In_ PSID pSid,
853 _In_ LPCWSTR lpUserName,
854 _In_opt_ LPCWSTR lpUserHive,
855 _Out_opt_ LPWSTR lpProfileDir,
856 _In_ DWORD dwDirSize,
857 _In_ BOOL bWin9xUpg)
858{
859 WCHAR szRawProfilesPath[MAX_PATH];
860 WCHAR szProfilesPath[MAX_PATH];
861 WCHAR szUserProfilePath[MAX_PATH];
862 WCHAR szDefaultUserPath[MAX_PATH];
863 WCHAR szUserProfileName[MAX_PATH];
864 WCHAR szBuffer[MAX_PATH];
865 LPWSTR SidString;
866 DWORD dwType, dwLength;
867 DWORD dwDisposition;
868 UINT i;
869 HKEY hKey;
870 BOOL bRet = TRUE;
871 LONG Error;
872
873 DPRINT("CreateUserProfileExW(%p %S %S %p %lu %d)\n",
874 pSid, lpUserName, lpUserHive, lpProfileDir, dwDirSize, bWin9xUpg);
875
876 /* Parameters validation */
877 if (!pSid || !lpUserName)
878 {
880 return FALSE;
881 }
882
883 /*
884 * TODO:
885 * - Add support for lpUserHive.
886 * - bWin9xUpg is obsolete. Don't waste your time implementing this.
887 */
888
890 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
891 0,
893 &hKey);
894 if (Error != ERROR_SUCCESS)
895 {
896 DPRINT1("Error: %lu\n", Error);
898 return FALSE;
899 }
900
901 /* Get profiles path */
902 dwLength = sizeof(szRawProfilesPath);
904 L"ProfilesDirectory",
905 NULL,
906 &dwType,
907 (LPBYTE)szRawProfilesPath,
908 &dwLength);
909 if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
910 {
911 DPRINT1("Error: %lu\n", Error);
914 return FALSE;
915 }
916
917 /* Expand it */
918 if (!ExpandEnvironmentStringsW(szRawProfilesPath,
919 szProfilesPath,
920 ARRAYSIZE(szProfilesPath)))
921 {
922 DPRINT1("Error: %lu\n", GetLastError());
924 return FALSE;
925 }
926
927 /* Create the profiles directory if it does not exist yet */
928 // FIXME: Security!
929 if (!CreateDirectoryW(szProfilesPath, NULL))
930 {
932 {
933 DPRINT1("Error: %lu\n", GetLastError());
934 return FALSE;
935 }
936 }
937
938 /* Get default user path */
939 dwLength = sizeof(szBuffer);
941 L"Default",
942 NULL,
943 &dwType,
944 (LPBYTE)szBuffer,
945 &dwLength);
946 if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
947 {
948 DPRINT1("Error: %lu\n", Error);
951 return FALSE;
952 }
953
954 if (!ExpandEnvironmentStringsW(szBuffer,
955 szDefaultUserPath,
956 ARRAYSIZE(szDefaultUserPath)))
957 {
958 DPRINT1("Error: %lu\n", GetLastError());
960 return FALSE;
961 }
962
964
965 StringCbCopyW(szUserProfileName, sizeof(szUserProfileName), lpUserName);
966
967 /* Create user profile directory */
968
969 StringCbCopyW(szUserProfilePath, sizeof(szUserProfilePath), szProfilesPath);
970 StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), L"\\");
971 StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), szUserProfileName);
972
973 // FIXME: Security!
974 if (!CreateDirectoryW(szUserProfilePath, NULL))
975 {
977 {
978 DPRINT1("Error: %lu\n", GetLastError());
979 return FALSE;
980 }
981
982 for (i = 0; i < 1000; i++)
983 {
984 _swprintf(szUserProfileName, L"%s.%03u", lpUserName, i);
985
986 StringCbCopyW(szUserProfilePath, sizeof(szUserProfilePath), szProfilesPath);
987 StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), L"\\");
988 StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), szUserProfileName);
989
990 // FIXME: Security!
991 if (CreateDirectoryW(szUserProfilePath, NULL))
992 break;
993
995 {
996 DPRINT1("Error: %lu\n", GetLastError());
997 return FALSE;
998 }
999 }
1000 }
1001
1002 /* Copy default user directory */
1003
1004 // FIXME: Security!
1005 if (!CopyDirectory(szUserProfilePath, szDefaultUserPath))
1006 {
1007 DPRINT1("Error: %lu\n", GetLastError());
1008 return FALSE;
1009 }
1010
1011 /* Add profile to profile list */
1013 &SidString))
1014 {
1015 DPRINT1("Error: %lu\n", GetLastError());
1016 return FALSE;
1017 }
1018
1019 StringCbCopyW(szBuffer, sizeof(szBuffer),
1020 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
1021 StringCbCatW(szBuffer, sizeof(szBuffer), SidString);
1022
1023 /* Create user profile key */
1025 szBuffer,
1026 0,
1027 NULL,
1030 NULL,
1031 &hKey,
1032 &dwDisposition);
1033 if (Error != ERROR_SUCCESS)
1034 {
1035 DPRINT1("Error: %lu\n", Error);
1036 bRet = FALSE;
1037 goto done;
1038 }
1039
1040 /* Create non-expanded user profile path */
1041 StringCbCopyW(szBuffer, sizeof(szBuffer), szRawProfilesPath);
1042 StringCbCatW(szBuffer, sizeof(szBuffer), L"\\");
1043 StringCbCatW(szBuffer, sizeof(szBuffer), szUserProfileName);
1044
1045 /* Set 'ProfileImagePath' value (non-expanded) */
1047 L"ProfileImagePath",
1048 0,
1050 (LPBYTE)szBuffer,
1051 (wcslen(szBuffer) + 1) * sizeof(WCHAR));
1052 if (Error != ERROR_SUCCESS)
1053 {
1054 DPRINT1("Error: %lu\n", Error);
1056 bRet = FALSE;
1057 goto done;
1058 }
1059
1060 /* Set 'Sid' value */
1062 L"Sid",
1063 0,
1064 REG_BINARY,
1065 pSid,
1067 if (Error != ERROR_SUCCESS)
1068 {
1069 DPRINT1("Error: %lu\n", Error);
1071 bRet = FALSE;
1072 goto done;
1073 }
1074
1076
1077 /* Create user hive file */
1078
1079 /* Use the default hive file name */
1080 StringCbCopyW(szBuffer, sizeof(szBuffer), szUserProfilePath);
1081 StringCbCatW(szBuffer, sizeof(szBuffer), L"\\ntuser.dat");
1082
1083 /* Acquire restore privilege */
1085 {
1086 Error = GetLastError();
1087 DPRINT1("Error: %lu\n", Error);
1088 bRet = FALSE;
1089 goto done;
1090 }
1091
1092 /* Load the user hive */
1094 SidString,
1095 szBuffer);
1097 if (Error != ERROR_SUCCESS)
1098 {
1099 DPRINT1("Error: %lu\n", Error);
1100 bRet = FALSE;
1101 goto done;
1102 }
1103
1104 /* Initialize user hive */
1105 if (!CreateUserHive(SidString, szUserProfilePath))
1106 {
1107 Error = GetLastError();
1108 DPRINT1("Error: %lu\n", Error);
1109 bRet = FALSE;
1110 }
1111
1112 /* Unload the hive */
1114 RegUnLoadKeyW(HKEY_USERS, SidString);
1116
1117 /*
1118 * If the caller wants to retrieve the user profile path,
1119 * give it now. 'dwDirSize' is the number of characters.
1120 */
1121 if (lpProfileDir && dwDirSize)
1122 StringCchCopyW(lpProfileDir, dwDirSize, szUserProfilePath);
1123
1124done:
1125 LocalFree((HLOCAL)SidString);
1127
1128 DPRINT("CreateUserProfileExW() done\n");
1129
1130 return bRet;
1131}
1132
1133
1134BOOL
1135WINAPI
1137 _In_ LPCSTR lpSidString,
1138 _In_opt_ LPCSTR lpProfilePath,
1140{
1141 BOOL bResult;
1142 UNICODE_STRING SidString = {0, 0, NULL}, ProfilePath = {0, 0, NULL}, ComputerName = {0, 0, NULL};
1143
1144 DPRINT("DeleteProfileA() called\n");
1145
1146 /* Conversion to UNICODE */
1147 if (lpSidString)
1149 (LPSTR)lpSidString);
1150
1151 if (lpProfilePath)
1153 (LPSTR)lpProfilePath);
1154
1155 if (lpComputerName)
1158
1159 /* Call the UNICODE function */
1160 bResult = DeleteProfileW(SidString.Buffer,
1161 ProfilePath.Buffer,
1162 ComputerName.Buffer);
1163
1164 /* Memory cleanup */
1165 if (lpSidString)
1166 RtlFreeUnicodeString(&SidString);
1167
1168 if (lpProfilePath)
1169 RtlFreeUnicodeString(&ProfilePath);
1170
1171 if (lpComputerName)
1172 RtlFreeUnicodeString(&ComputerName);
1173
1174 return bResult;
1175}
1176
1177
1178BOOL
1179WINAPI
1181 _In_ LPCWSTR lpSidString,
1182 _In_opt_ LPCWSTR lpProfilePath,
1184{
1185 HKEY hProfilesKey = NULL, hProfileKey = NULL;
1186 WCHAR szRawProfilePath[MAX_PATH], szProfilePath[MAX_PATH];
1187 DWORD dwLength, dwType;
1188 DWORD dwError = ERROR_SUCCESS;
1189 BOOL bRet = FALSE;
1190
1191 DPRINT("DeleteProfileW(%S %S %S)\n", lpSidString, lpProfilePath, lpComputerName);
1192
1193 if (lpSidString == NULL)
1194 {
1196 return FALSE;
1197 }
1198
1199 if (lpProfilePath != NULL)
1200 {
1202 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
1203 0,
1205 &hProfilesKey);
1206 if (dwError != ERROR_SUCCESS)
1207 {
1208 DPRINT1("Error: %lu\n", dwError);
1209 goto done;
1210 }
1211
1213 lpSidString,
1214 0,
1216 &hProfileKey);
1217 if (dwError != ERROR_SUCCESS)
1218 {
1219 DPRINT1("Error: %lu\n", dwError);
1220 goto done;
1221 }
1222
1223 /* Get the profile image path */
1224 dwLength = sizeof(szRawProfilePath);
1225 dwError = RegQueryValueExW(hProfileKey,
1226 L"ProfileImagePath",
1227 NULL,
1228 &dwType,
1229 (PBYTE)szRawProfilePath,
1230 &dwLength);
1231 if (dwError != ERROR_SUCCESS)
1232 {
1233 DPRINT1("Error: %lu\n", dwError);
1234 goto done;
1235 }
1236
1237 if (!ExpandEnvironmentStringsW(szRawProfilePath,
1238 szProfilePath,
1239 ARRAYSIZE(szProfilePath)))
1240 {
1241 dwError = GetLastError();
1242 DPRINT1("Failled to expand the raw profile path (Error %lu)\n", dwError);
1243 goto done;
1244 }
1245 }
1246 else
1247 {
1248 StringCchCopyW(szProfilePath, ARRAYSIZE(szProfilePath), lpProfilePath);
1249 }
1250
1251 DPRINT("ProfilePath: %S\n", szProfilePath);
1252
1253 if (!RemoveDirectoryPath(szProfilePath))
1254 {
1255 dwError = GetLastError();
1256 DPRINT1("Error: %lu\n", dwError);
1257 goto done;
1258 }
1259
1260 bRet = TRUE;
1261
1262done:
1263 if (hProfileKey != NULL)
1264 RegCloseKey(hProfileKey);
1265
1266 if (hProfilesKey != NULL)
1267 RegCloseKey(hProfilesKey);
1268
1269 return bRet;
1270}
1271
1272
1273BOOL
1274WINAPI
1276 _Out_opt_ LPSTR lpProfileDir,
1277 _Inout_ LPDWORD lpcchSize)
1278{
1280 BOOL bResult;
1281
1282 if (!lpcchSize)
1283 {
1285 return FALSE;
1286 }
1287
1289 *lpcchSize * sizeof(WCHAR));
1290 if (lpBuffer == NULL)
1291 return FALSE;
1292
1294 lpcchSize);
1295 if (bResult && lpProfileDir)
1296 {
1297 bResult = WideCharToMultiByte(CP_ACP,
1298 0,
1299 lpBuffer,
1300 -1,
1301 lpProfileDir,
1302 *lpcchSize,
1303 NULL,
1304 NULL);
1305 }
1306
1308
1309 return bResult;
1310}
1311
1312
1313BOOL
1314WINAPI
1316 _Out_opt_ LPWSTR lpProfileDir,
1317 _Inout_ LPDWORD lpcchSize)
1318{
1319 WCHAR szProfilePath[MAX_PATH];
1320 WCHAR szBuffer[MAX_PATH];
1321 DWORD dwType, dwLength;
1322 HKEY hKey;
1323 LONG Error;
1324
1325 if (!lpcchSize)
1326 {
1328 return FALSE;
1329 }
1330
1332 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
1333 0,
1335 &hKey);
1336 if (Error != ERROR_SUCCESS)
1337 {
1338 DPRINT1("Error: %lu\n", Error);
1340 return FALSE;
1341 }
1342
1343 /* Get Public profile path */
1344 dwLength = sizeof(szBuffer);
1346 L"ProgramData",
1347 NULL,
1348 &dwType,
1349 (LPBYTE)szBuffer,
1350 &dwLength);
1352 if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
1353 {
1354 DPRINT1("Error: %lu\n", Error);
1356 return FALSE;
1357 }
1358
1359 /* Expand it */
1360 if (!ExpandEnvironmentStringsW(szBuffer,
1361 szProfilePath,
1362 ARRAYSIZE(szProfilePath)))
1363 {
1364 DPRINT1("Error: %lu\n", GetLastError());
1365 return FALSE;
1366 }
1367
1368 dwLength = wcslen(szProfilePath) + 1;
1369 if (lpProfileDir && (*lpcchSize >= dwLength))
1370 {
1371 StringCchCopyW(lpProfileDir, *lpcchSize, szProfilePath);
1372 *lpcchSize = dwLength;
1373 return TRUE;
1374 }
1375 else // if (!lpProfileDir || (*lpcchSize < dwLength))
1376 {
1377 *lpcchSize = dwLength;
1379 return FALSE;
1380 }
1381}
1382
1383
1384BOOL
1385WINAPI
1387 _Out_opt_ LPSTR lpProfileDir,
1388 _Inout_ LPDWORD lpcchSize)
1389{
1391 BOOL bResult;
1392
1393 if (!lpcchSize)
1394 {
1396 return FALSE;
1397 }
1398
1400 *lpcchSize * sizeof(WCHAR));
1401 if (lpBuffer == NULL)
1402 return FALSE;
1403
1405 lpcchSize);
1406 if (bResult && lpProfileDir)
1407 {
1408 bResult = WideCharToMultiByte(CP_ACP,
1409 0,
1410 lpBuffer,
1411 -1,
1412 lpProfileDir,
1413 *lpcchSize,
1414 NULL,
1415 NULL);
1416 }
1417
1419
1420 return bResult;
1421}
1422
1423
1424BOOL
1425WINAPI
1427 _Out_opt_ LPWSTR lpProfileDir,
1428 _Inout_ LPDWORD lpcchSize)
1429{
1430 WCHAR szProfilePath[MAX_PATH];
1431 WCHAR szBuffer[MAX_PATH];
1432 DWORD dwType, dwLength;
1433 HKEY hKey;
1434 LONG Error;
1435
1436 if (!lpcchSize)
1437 {
1439 return FALSE;
1440 }
1441
1443 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
1444 0,
1446 &hKey);
1447 if (Error != ERROR_SUCCESS)
1448 {
1449 DPRINT1("Error: %lu\n", Error);
1451 return FALSE;
1452 }
1453
1454 /* Get profiles path */
1455 dwLength = sizeof(szBuffer);
1457 L"Default",
1458 NULL,
1459 &dwType,
1460 (LPBYTE)szBuffer,
1461 &dwLength);
1463 if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
1464 {
1465 DPRINT1("Error: %lu\n", Error);
1467 return FALSE;
1468 }
1469
1470 /* Expand it */
1471 if (!ExpandEnvironmentStringsW(szBuffer,
1472 szProfilePath,
1473 ARRAYSIZE(szProfilePath)))
1474 {
1475 DPRINT1("Error: %lu\n", GetLastError());
1476 return FALSE;
1477 }
1478
1479 dwLength = wcslen(szProfilePath) + 1;
1480 if (lpProfileDir && (*lpcchSize >= dwLength))
1481 {
1482 StringCchCopyW(lpProfileDir, *lpcchSize, szProfilePath);
1483 *lpcchSize = dwLength;
1484 return TRUE;
1485 }
1486 else // if (!lpProfileDir || (*lpcchSize < dwLength))
1487 {
1488 *lpcchSize = dwLength;
1490 return FALSE;
1491 }
1492}
1493
1494
1495BOOL
1496WINAPI
1498 _Out_ LPSTR lpProfileDir, // _Out_opt_
1499 _Inout_ LPDWORD lpcchSize)
1500{
1502 BOOL bResult;
1503
1504 if (!lpcchSize || !lpProfileDir)
1505 {
1507 return FALSE;
1508 }
1509
1511 *lpcchSize * sizeof(WCHAR));
1512 if (lpBuffer == NULL)
1513 return FALSE;
1514
1516 lpcchSize);
1517 if (bResult && lpProfileDir)
1518 {
1519 bResult = WideCharToMultiByte(CP_ACP,
1520 0,
1521 lpBuffer,
1522 -1,
1523 lpProfileDir,
1524 *lpcchSize,
1525 NULL,
1526 NULL);
1527 }
1528
1530
1531 return bResult;
1532}
1533
1534
1535BOOL
1536WINAPI
1538 _Out_ LPWSTR lpProfilesDir, // _Out_opt_
1539 _Inout_ LPDWORD lpcchSize)
1540{
1541 WCHAR szProfilesPath[MAX_PATH];
1542 WCHAR szBuffer[MAX_PATH];
1543 DWORD dwType, dwLength;
1544 HKEY hKey;
1545 LONG Error;
1546
1547 if (!lpcchSize)
1548 {
1550 return FALSE;
1551 }
1552
1554 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
1555 0,
1557 &hKey);
1558 if (Error != ERROR_SUCCESS)
1559 {
1560 DPRINT1("Error: %lu\n", Error);
1562 return FALSE;
1563 }
1564
1565 /* Get profiles path */
1566 dwLength = sizeof(szBuffer);
1568 L"ProfilesDirectory",
1569 NULL,
1570 &dwType,
1571 (LPBYTE)szBuffer,
1572 &dwLength);
1573 if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
1574 {
1575 DPRINT1("Error: %lu\n", Error);
1578 return FALSE;
1579 }
1580
1582
1583 /* Expand it */
1584 if (!ExpandEnvironmentStringsW(szBuffer,
1585 szProfilesPath,
1586 ARRAYSIZE(szProfilesPath)))
1587 {
1588 DPRINT1("Error: %lu\n", GetLastError());
1589 return FALSE;
1590 }
1591
1592 dwLength = wcslen(szProfilesPath) + 1;
1593 if (lpProfilesDir && (*lpcchSize >= dwLength))
1594 {
1595 StringCchCopyW(lpProfilesDir, *lpcchSize, szProfilesPath);
1596 *lpcchSize = dwLength;
1597 return TRUE;
1598 }
1599 else // if (!lpProfilesDir || (*lpcchSize < dwLength))
1600 {
1601 *lpcchSize = dwLength;
1603 return FALSE;
1604 }
1605}
1606
1607
1608BOOL
1609WINAPI
1611 _Out_ PDWORD pdwFlags)
1612{
1613 UNICODE_STRING SidString = {0, 0, NULL};
1614 HANDLE hToken;
1615 HKEY hProfilesKey = NULL, hProfileKey = NULL;
1616 DWORD dwType, dwLength, dwState = 0;
1617 DWORD dwError;
1618 BOOL bResult = FALSE;
1619
1620 DPRINT("GetProfileType(%p)\n", pdwFlags);
1621
1622 if (pdwFlags == NULL)
1623 {
1625 return FALSE;
1626 }
1627
1629 {
1631 {
1632 DPRINT1("Failed to open a token (Error %lu)\n", GetLastError());
1633 return FALSE;
1634 }
1635 }
1636
1637 /* Get the user SID string */
1638 if (!GetUserSidStringFromToken(hToken, &SidString))
1639 {
1640 DPRINT1("GetUserSidStringFromToken() failed\n");
1641 goto done;
1642 }
1643
1644 DPRINT("SID: %wZ\n", &SidString);
1645
1647 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
1648 0,
1650 &hProfilesKey);
1651 if (dwError != ERROR_SUCCESS)
1652 {
1653 DPRINT1("Error: %lu\n", dwError);
1654 SetLastError(dwError);
1655 goto done;
1656 }
1657
1658 dwError = RegOpenKeyExW(hProfilesKey,
1659 SidString.Buffer,
1660 0,
1662 &hProfileKey);
1663 if (dwError != ERROR_SUCCESS)
1664 {
1665 DPRINT1("Error: %lu\n", dwError);
1666 SetLastError(dwError);
1667 goto done;
1668 }
1669
1670 /* Get the State value */
1671 dwLength = sizeof(dwState);
1672 dwError = RegQueryValueExW(hProfileKey,
1673 L"State",
1674 NULL,
1675 &dwType,
1676 (PBYTE)&dwState,
1677 &dwLength);
1678 if (dwError != ERROR_SUCCESS)
1679 {
1680 DPRINT1("Error: %lu\n", dwError);
1681 SetLastError(dwError);
1682 goto done;
1683 }
1684
1685 *pdwFlags = 0;
1686
1687 if (dwState & 0x80) /* PROFILE_GUEST_USER */
1688 *pdwFlags |= PT_TEMPORARY;
1689
1690 /* FIXME: Add checks for PT_MANDATORY and PT_ROAMING */
1691
1692 bResult = TRUE;
1693
1694done:
1695 if (hProfileKey != NULL)
1696 RegCloseKey(hProfileKey);
1697
1698 if (hProfilesKey != NULL)
1699 RegCloseKey(hProfilesKey);
1700
1701 RtlFreeUnicodeString(&SidString);
1702
1703 CloseHandle(hToken);
1704
1705 return bResult;
1706}
1707
1708
1709BOOL
1710WINAPI
1712 _In_ HANDLE hToken,
1713 _Out_opt_ LPSTR lpProfileDir,
1714 _Inout_ LPDWORD lpcchSize)
1715{
1717 BOOL bResult;
1718
1719 if (!lpcchSize || !lpProfileDir)
1720 {
1722 return FALSE;
1723 }
1724
1726 *lpcchSize * sizeof(WCHAR));
1727 if (lpBuffer == NULL)
1728 return FALSE;
1729
1730 bResult = GetUserProfileDirectoryW(hToken,
1731 lpBuffer,
1732 lpcchSize);
1733 if (bResult && lpProfileDir)
1734 {
1735 bResult = WideCharToMultiByte(CP_ACP,
1736 0,
1737 lpBuffer,
1738 -1,
1739 lpProfileDir,
1740 *lpcchSize,
1741 NULL,
1742 NULL);
1743 }
1744
1746
1747 return bResult;
1748}
1749
1750
1751BOOL
1752WINAPI
1754 _In_ HANDLE hToken,
1755 _Out_opt_ LPWSTR lpProfileDir,
1756 _Inout_ LPDWORD lpcchSize)
1757{
1758 UNICODE_STRING SidString;
1759 WCHAR szKeyName[MAX_PATH];
1760 WCHAR szRawImagePath[MAX_PATH];
1761 WCHAR szImagePath[MAX_PATH];
1762 DWORD dwType, dwLength;
1763 HKEY hKey;
1764 LONG Error;
1765
1766 if (!hToken)
1767 {
1769 return FALSE;
1770 }
1771
1772 if (!lpcchSize)
1773 {
1775 return FALSE;
1776 }
1777
1778 /* Get the user SID string */
1779 if (!GetUserSidStringFromToken(hToken, &SidString))
1780 {
1781 DPRINT1("GetUserSidStringFromToken() failed\n");
1782 return FALSE;
1783 }
1784
1785 DPRINT("SidString: '%wZ'\n", &SidString);
1786
1787 StringCbCopyW(szKeyName, sizeof(szKeyName),
1788 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
1789 StringCbCatW(szKeyName, sizeof(szKeyName), SidString.Buffer);
1790
1791 RtlFreeUnicodeString(&SidString);
1792
1793 DPRINT("KeyName: '%S'\n", szKeyName);
1794
1796 szKeyName,
1797 0,
1799 &hKey);
1800 if (Error != ERROR_SUCCESS)
1801 {
1802 DPRINT1("Error: %lu\n", Error);
1804 return FALSE;
1805 }
1806
1807 dwLength = sizeof(szRawImagePath);
1809 L"ProfileImagePath",
1810 NULL,
1811 &dwType,
1812 (LPBYTE)szRawImagePath,
1813 &dwLength);
1814 if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
1815 {
1816 DPRINT1("Error: %lu\n", Error);
1819 return FALSE;
1820 }
1821
1823
1824 DPRINT("RawImagePath: '%S'\n", szRawImagePath);
1825
1826 /* Expand it */
1827 if (!ExpandEnvironmentStringsW(szRawImagePath,
1828 szImagePath,
1829 ARRAYSIZE(szImagePath)))
1830 {
1831 DPRINT1("Error: %lu\n", GetLastError());
1832 return FALSE;
1833 }
1834
1835 DPRINT("ImagePath: '%S'\n", szImagePath);
1836
1837 dwLength = wcslen(szImagePath) + 1;
1838 if (lpProfileDir && (*lpcchSize >= dwLength))
1839 {
1840 StringCchCopyW(lpProfileDir, *lpcchSize, szImagePath);
1841 *lpcchSize = dwLength;
1842 return TRUE;
1843 }
1844 else // if (!lpProfileDir || (*lpcchSize < dwLength))
1845 {
1846 *lpcchSize = dwLength;
1848 return FALSE;
1849 }
1850}
1851
1852
1853BOOL
1854WINAPI
1856 _In_ HANDLE hToken,
1857 _Inout_ LPPROFILEINFOA lpProfileInfo)
1858{
1859 BOOL bResult = FALSE;
1860 PROFILEINFOW ProfileInfoW = {0};
1861 int len;
1862
1863 DPRINT("LoadUserProfileA() called\n");
1864
1865 /* Check profile info */
1866 if (!lpProfileInfo || (lpProfileInfo->dwSize != sizeof(PROFILEINFOA)) ||
1867 (lpProfileInfo->lpUserName == NULL) || (lpProfileInfo->lpUserName[0] == 0))
1868 {
1870 return FALSE;
1871 }
1872
1873 /* Convert the structure to UNICODE... */
1874 ProfileInfoW.dwSize = sizeof(ProfileInfoW);
1875 ProfileInfoW.dwFlags = lpProfileInfo->dwFlags;
1876
1877 if (lpProfileInfo->lpUserName)
1878 {
1879 len = MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpUserName, -1, NULL, 0);
1880 ProfileInfoW.lpUserName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1881 if (!ProfileInfoW.lpUserName)
1882 {
1884 goto cleanup;
1885 }
1886 MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpUserName, -1, ProfileInfoW.lpUserName, len);
1887 }
1888
1889 if (lpProfileInfo->lpProfilePath)
1890 {
1891 len = MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpProfilePath, -1, NULL, 0);
1892 ProfileInfoW.lpProfilePath = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1893 if (!ProfileInfoW.lpProfilePath)
1894 {
1896 goto cleanup;
1897 }
1898 MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpProfilePath, -1, ProfileInfoW.lpProfilePath, len);
1899 }
1900
1901 if (lpProfileInfo->lpDefaultPath)
1902 {
1903 len = MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpDefaultPath, -1, NULL, 0);
1904 ProfileInfoW.lpDefaultPath = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1905 if (!ProfileInfoW.lpDefaultPath)
1906 {
1908 goto cleanup;
1909 }
1910 MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpDefaultPath, -1, ProfileInfoW.lpDefaultPath, len);
1911 }
1912
1913 if (lpProfileInfo->lpServerName)
1914 {
1915 len = MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpServerName, -1, NULL, 0);
1916 ProfileInfoW.lpServerName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1917 if (!ProfileInfoW.lpServerName)
1918 {
1920 goto cleanup;
1921 }
1922 MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpServerName, -1, ProfileInfoW.lpServerName, len);
1923 }
1924
1925 if ((ProfileInfoW.dwFlags & PI_APPLYPOLICY) != 0 && lpProfileInfo->lpPolicyPath)
1926 {
1927 len = MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpPolicyPath, -1, NULL, 0);
1928 ProfileInfoW.lpPolicyPath = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1929 if (!ProfileInfoW.lpPolicyPath)
1930 {
1932 goto cleanup;
1933 }
1934 MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpPolicyPath, -1, ProfileInfoW.lpPolicyPath, len);
1935 }
1936
1937 /* ... and call the UNICODE function */
1938 bResult = LoadUserProfileW(hToken, &ProfileInfoW);
1939
1940 /* Save the returned value */
1941 lpProfileInfo->hProfile = ProfileInfoW.hProfile;
1942
1943cleanup:
1944 /* Memory cleanup */
1945 if (ProfileInfoW.lpUserName)
1946 HeapFree(GetProcessHeap(), 0, ProfileInfoW.lpUserName);
1947
1948 if (ProfileInfoW.lpProfilePath)
1949 HeapFree(GetProcessHeap(), 0, ProfileInfoW.lpProfilePath);
1950
1951 if (ProfileInfoW.lpDefaultPath)
1952 HeapFree(GetProcessHeap(), 0, ProfileInfoW.lpDefaultPath);
1953
1954 if (ProfileInfoW.lpServerName)
1955 HeapFree(GetProcessHeap(), 0, ProfileInfoW.lpServerName);
1956
1957 if ((ProfileInfoW.dwFlags & PI_APPLYPOLICY) != 0 && ProfileInfoW.lpPolicyPath)
1958 HeapFree(GetProcessHeap(), 0, ProfileInfoW.lpPolicyPath);
1959
1960 return bResult;
1961}
1962
1963
1964BOOL
1965WINAPI
1967 _In_ HANDLE hToken,
1968 _Inout_ LPPROFILEINFOW lpProfileInfo)
1969{
1970 WCHAR szUserHivePath[MAX_PATH];
1972 PTOKEN_USER UserSid = NULL;
1973 UNICODE_STRING SidString = { 0, 0, NULL };
1974 HANDLE hProfileMutex = NULL;
1975 DWORD dwError = MAXDWORD;
1976 BOOL ret = FALSE;
1977
1978 DPRINT("LoadUserProfileW(%p %p)\n", hToken, lpProfileInfo);
1979
1980 /* Check profile info */
1981 if (!lpProfileInfo || (lpProfileInfo->dwSize != sizeof(PROFILEINFOW)) ||
1982 (lpProfileInfo->lpUserName == NULL) || (lpProfileInfo->lpUserName[0] == 0))
1983 {
1985 return FALSE;
1986 }
1987
1988 DPRINT("UserName: %S\n", lpProfileInfo->lpUserName);
1989
1990 /* Get the user SID string */
1991 ret = GetUserSidStringFromToken(hToken, &SidString);
1992 if (!ret)
1993 {
1994 DPRINT1("GetUserSidStringFromToken() failed\n");
1995 goto cleanup;
1996 }
1997 ret = FALSE;
1998
1999 /* Create the profile mutex */
2000 hProfileMutex = CreateProfileMutex(SidString.Buffer);
2001 if (hProfileMutex == NULL)
2002 {
2003 DPRINT1("Failed to create the profile mutex\n");
2004 goto cleanup;
2005 }
2006
2007 /* Wait for the profile mutex */
2008 WaitForSingleObject(hProfileMutex, INFINITE);
2009
2010 /* Don't load a profile twice */
2011 if (CheckForLoadedProfile(hToken))
2012 {
2013 DPRINT1("Profile %S already loaded\n", SidString.Buffer);
2014 }
2015 else
2016 {
2017 DPRINT1("Loading profile %S\n", SidString.Buffer);
2018
2019 /*
2020 * NOTE: lpProfilePath specifies the path to a *roaming* user profile,
2021 * for example on a domain server, if any. It is then used to create
2022 * a local image (copy) of the profile on the local computer.
2023 *
2024 * FIXME: We currently don't implement this in ReactOS; instead, we use
2025 * it directly as *the* user's profile path, without doing any copy...
2026 */
2027 if (lpProfileInfo->lpProfilePath)
2028 {
2029 /* Use the caller's specified roaming user profile path */
2030 StringCbCopyW(szUserHivePath, sizeof(szUserHivePath), lpProfileInfo->lpProfilePath);
2031 }
2032 else
2033 {
2034 /* Build a default user profile path */
2035 dwLength = _countof(szUserHivePath);
2036 if (!GetProfilesDirectoryW(szUserHivePath, &dwLength))
2037 {
2038 DPRINT1("GetProfilesDirectoryW() failed (Error %ld)\n", GetLastError());
2039 goto cleanup;
2040 }
2041 StringCbCatW(szUserHivePath, sizeof(szUserHivePath), L"\\");
2042 StringCbCatW(szUserHivePath, sizeof(szUserHivePath), lpProfileInfo->lpUserName);
2043 }
2044
2045 /* Create user hive name */
2046 StringCbCatW(szUserHivePath, sizeof(szUserHivePath), L"\\ntuser.dat");
2047 DPRINT("szUserHivePath: %S\n", szUserHivePath);
2048
2049 /* Create user profile directory if needed */
2050 if (GetFileAttributesW(szUserHivePath) == INVALID_FILE_ATTRIBUTES)
2051 {
2052 /* Get user sid */
2053 if (GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLength) ||
2055 {
2056 DPRINT1("GetTokenInformation() failed\n");
2057 goto cleanup;
2058 }
2059
2060 UserSid = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), 0, dwLength);
2061 if (!UserSid)
2062 {
2063 dwError = ERROR_NOT_ENOUGH_MEMORY;
2064 DPRINT1("HeapAlloc() failed\n");
2065 goto cleanup;
2066 }
2067
2068 if (!GetTokenInformation(hToken, TokenUser, UserSid, dwLength, &dwLength))
2069 {
2070 DPRINT1("GetTokenInformation() failed\n");
2071 goto cleanup;
2072 }
2073
2074 /* Create profile */
2075 ret = CreateUserProfileW(UserSid->User.Sid, lpProfileInfo->lpUserName);
2076 if (!ret)
2077 {
2078 DPRINT1("CreateUserProfileW() failed\n");
2079 goto cleanup;
2080 }
2081 ret = FALSE;
2082 }
2083
2084 /* Acquire restore privilege */
2086 {
2087 DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
2088 goto cleanup;
2089 }
2090
2091 /* Load the user registry hive */
2092 dwError = RegLoadKeyW(HKEY_USERS,
2093 SidString.Buffer,
2094 szUserHivePath);
2096
2097 /* HACK: Do not fail if the profile has already been loaded! */
2098 if (dwError == ERROR_SHARING_VIOLATION)
2099 dwError = ERROR_SUCCESS;
2100
2101 if (dwError != ERROR_SUCCESS)
2102 {
2103 DPRINT1("RegLoadKeyW() failed (Error %ld)\n", dwError);
2104 goto cleanup;
2105 }
2106
2107 SetProfileData(SidString.Buffer,
2108 lpProfileInfo->dwFlags,
2109 hToken);
2110 }
2111
2112 /* Open future HKEY_CURRENT_USER */
2113 dwError = RegOpenKeyExW(HKEY_USERS,
2114 SidString.Buffer,
2115 0,
2117 (PHKEY)&lpProfileInfo->hProfile);
2118 if (dwError != ERROR_SUCCESS)
2119 {
2120 DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", dwError);
2121 goto cleanup;
2122 }
2123
2124 dwError = IncrementRefCount(SidString.Buffer, NULL);
2125 if (dwError != ERROR_SUCCESS)
2126 {
2127 DPRINT1("IncrementRefCount() failed (Error %ld)\n", dwError);
2128 goto cleanup;
2129 }
2130
2131 ret = TRUE;
2132
2133cleanup:
2134 if (dwError == MAXDWORD)
2135 dwError = GetLastError();
2136
2137 if (UserSid != NULL)
2138 HeapFree(GetProcessHeap(), 0, UserSid);
2139
2140 if (hProfileMutex != NULL)
2141 {
2142 ReleaseMutex(hProfileMutex);
2143 CloseHandle(hProfileMutex);
2144 }
2145
2146 RtlFreeUnicodeString(&SidString);
2147
2148 /* Report any error occurred */
2149 if (!ret)
2150 {
2151 // TODO: Use a localized *.mc resource message* error.
2152 ReportError(lpProfileInfo->dwFlags,
2153 L"ReactOS could not load the locally stored user profile. "
2154 L"Possible causes of this error include insufficient security rights or a corrupt local profile.\n"
2155 L"\nError: %lu\n",
2156 dwError);
2157 }
2158
2159 DPRINT("LoadUserProfileW() done\n");
2160 SetLastError(dwError);
2161 return ret;
2162}
2163
2164
2165BOOL
2166WINAPI
2168 _In_ HANDLE hToken,
2169 _In_ HANDLE hProfile)
2170{
2171 UNICODE_STRING SidString = {0, 0, NULL};
2172 HANDLE hProfileMutex = NULL;
2173 HKEY hProfilesKey = NULL, hProfileKey = NULL;
2174 DWORD dwRefCount = 0, dwLength, dwType, dwState = 0;
2175 DWORD dwError;
2176 BOOL bRet = FALSE;
2177
2178 DPRINT("UnloadUserProfile() called\n");
2179
2180 if (hProfile == NULL)
2181 {
2182 DPRINT1("Invalid profile handle\n");
2184 return FALSE;
2185 }
2186
2187 /* Get the user SID string */
2188 if (!GetUserSidStringFromToken(hToken, &SidString))
2189 {
2190 DPRINT1("GetUserSidStringFromToken() failed\n");
2191 return FALSE;
2192 }
2193
2194 DPRINT("SidString: '%wZ'\n", &SidString);
2195
2196 /* Create the profile mutex */
2197 hProfileMutex = CreateProfileMutex(SidString.Buffer);
2198 if (hProfileMutex == NULL)
2199 {
2200 DPRINT1("Failed to create the profile mutex\n");
2201 goto cleanup;
2202 }
2203
2204 /* Wait for the profile mutex */
2205 WaitForSingleObject(hProfileMutex, INFINITE);
2206
2207 /* Close the profile handle */
2208 RegFlushKey(hProfile);
2209 RegCloseKey(hProfile);
2210
2211 dwError = DecrementRefCount(SidString.Buffer, &dwRefCount);
2212 if (dwError != ERROR_SUCCESS)
2213 {
2214 DPRINT1("DecrementRefCount() failed (Error %lu)\n", dwError);
2215 SetLastError(dwError);
2216 goto cleanup;
2217 }
2218
2219 if (dwRefCount == 0)
2220 {
2221 DPRINT("RefCount is 0: Unload the Hive!\n");
2222
2223 /* Acquire restore privilege */
2225 {
2226 DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %lu)\n", GetLastError());
2227 goto cleanup;
2228 }
2229
2230 /* HACK */
2231 {
2232 HKEY hUserKey;
2233
2234 dwError = RegOpenKeyExW(HKEY_USERS,
2235 SidString.Buffer,
2236 0,
2237 KEY_WRITE,
2238 &hUserKey);
2239 if (dwError == ERROR_SUCCESS)
2240 {
2241 RegDeleteKeyW(hUserKey,
2242 L"Volatile Environment");
2243
2244 RegCloseKey(hUserKey);
2245 }
2246 }
2247 /* End of HACK */
2248
2249 /* Unload the hive */
2250 dwError = RegUnLoadKeyW(HKEY_USERS,
2251 SidString.Buffer);
2252
2253 /* Remove restore privilege */
2255
2256 if (dwError != ERROR_SUCCESS)
2257 {
2258 DPRINT1("RegUnLoadKeyW() failed (Error %lu)\n", dwError);
2259 SetLastError(dwError);
2260 goto cleanup;
2261 }
2262
2264 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
2265 0,
2267 &hProfilesKey);
2268 if (dwError != ERROR_SUCCESS)
2269 {
2270 DPRINT1("RegOpenKeyExW() failed (Error %lu)\n", dwError);
2271 SetLastError(dwError);
2272 goto cleanup;
2273 }
2274
2275 dwError = RegOpenKeyExW(hProfilesKey,
2276 SidString.Buffer,
2277 0,
2279 &hProfileKey);
2280 if (dwError != ERROR_SUCCESS)
2281 {
2282 DPRINT1("RegOpenKeyExW() failed (Error %lu)\n", dwError);
2283 SetLastError(dwError);
2284 goto cleanup;
2285 }
2286
2287 /* Get the State value */
2288 dwLength = sizeof(dwState);
2289 dwError = RegQueryValueExW(hProfileKey,
2290 L"State",
2291 NULL,
2292 &dwType,
2293 (PBYTE)&dwState,
2294 &dwLength);
2295 if (dwError != ERROR_SUCCESS)
2296 {
2297 DPRINT1("RegQueryValueExW() failed (Error %lu)\n", dwError);
2298 SetLastError(dwError);
2299 goto cleanup;
2300 }
2301
2302 /* Delete a guest profile */
2303 if (dwState & 0x80) // PROFILE_GUEST_USER
2304 {
2305 if (!DeleteProfileW(SidString.Buffer, NULL, NULL))
2306 {
2307 DPRINT1("DeleteProfile(%S, NULL, NULL) failed (Error %lu)\n",
2308 SidString.Buffer, GetLastError());
2309 goto cleanup;
2310 }
2311 }
2312 }
2313
2314 bRet = TRUE;
2315
2316cleanup:
2317 if (hProfileKey != NULL)
2318 RegCloseKey(hProfileKey);
2319
2320 if (hProfilesKey != NULL)
2321 RegCloseKey(hProfilesKey);
2322
2323 if (hProfileMutex != NULL)
2324 {
2325 ReleaseMutex(hProfileMutex);
2326 CloseHandle(hProfileMutex);
2327 }
2328
2329 RtlFreeUnicodeString(&SidString);
2330
2331 DPRINT("UnloadUserProfile() done\n");
2332
2333 return bRet;
2334}
2335
2336/* EOF */
#define SE_RESTORE_NAME
#define REG_SZ
Definition: layer.c:22
#define DPRINT1
Definition: precomp.h:8
BOOL Error
Definition: chkdsk.c:66
#define RegCloseKey(hKey)
Definition: registry.h:49
#define ARRAYSIZE(a)
Definition: cat.c:25
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegUnLoadKeyW(HKEY hKey, LPCWSTR lpSubKey)
Definition: reg.c:5078
LONG WINAPI RegFlushKey(HKEY hKey)
Definition: reg.c:2951
LONG WINAPI RegLoadKeyW(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpFile)
Definition: reg.c:3079
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
BOOL WINAPI AdjustTokenPrivileges(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength)
Definition: security.c:374
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:411
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:294
BOOL WINAPI ConvertSidToStringSidW(PSID Sid, LPWSTR *StringSid)
Definition: security.c:3583
BOOL WINAPI AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, BYTE nSubAuthorityCount, DWORD nSubAuthority0, DWORD nSubAuthority1, DWORD nSubAuthority2, DWORD nSubAuthority3, DWORD nSubAuthority4, DWORD nSubAuthority5, DWORD nSubAuthority6, DWORD nSubAuthority7, PSID *pSid)
Definition: security.c:674
BOOL WINAPI InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD dwRevision)
Definition: security.c:929
DWORD WINAPI GetLengthSid(PSID pSid)
Definition: security.c:919
BOOL WINAPI OpenThreadToken(HANDLE ThreadHandle, DWORD DesiredAccess, BOOL OpenAsSelf, HANDLE *TokenHandle)
Definition: security.c:336
PVOID WINAPI FreeSid(PSID pSid)
Definition: security.c:698
BOOL WINAPI EqualSid(PSID pSid1, PSID pSid2)
Definition: security.c:829
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define HeapAlloc
Definition: compat.h:733
#define GetCurrentProcess()
Definition: compat.h:759
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
static DWORD DWORD * dwLength
Definition: fusion.c:86
static void cleanup(void)
Definition: main.c:1335
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:492
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:58
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:636
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
Definition: time.c:128
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
BOOL CopyDirectory(LPCWSTR lpDestinationPath, LPCWSTR lpSourcePath)
Definition: directory.c:82
BOOL RemoveDirectoryPath(LPCWSTR lpPathName)
Definition: directory.c:324
VOID __cdecl ReportError(_In_ DWORD dwFlags, _In_ PCWSTR pszStr,...)
Definition: misc.c:481
BOOL CreateUserHive(LPCWSTR lpKeyName, LPCWSTR lpProfilePath)
Definition: registry.c:57
SID_IDENTIFIER_AUTHORITY LocalSystemAuthority
Definition: misc.c:35
BOOL GetUserSidStringFromToken(HANDLE hToken, PUNICODE_STRING SidString)
Definition: sid.c:102
BOOL WINAPI CopySystemProfile(_In_ ULONG Unused)
Definition: profile.c:565
BOOL WINAPI LoadUserProfileW(_In_ HANDLE hToken, _Inout_ LPPROFILEINFOW lpProfileInfo)
Definition: profile.c:1966
static DWORD DecrementRefCount(PWSTR pszSidString, PDWORD pdwRefCount)
Definition: profile.c:275
BOOL WINAPI GetUserProfileDirectoryA(_In_ HANDLE hToken, _Out_opt_ LPSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1711
BOOL WINAPI DeleteProfileA(_In_ LPCSTR lpSidString, _In_opt_ LPCSTR lpProfilePath, _In_opt_ LPCSTR lpComputerName)
Definition: profile.c:1136
static HANDLE CreateProfileMutex(_In_ PWSTR pszSidString)
Definition: profile.c:148
BOOL WINAPI CreateUserProfileA(_In_ PSID pSid, _In_ LPCSTR lpUserName)
Definition: profile.c:708
static BOOL CheckForLoadedProfile(HANDLE hToken)
Definition: profile.c:111
BOOL WINAPI GetAllUsersProfileDirectoryW(_Out_opt_ LPWSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1315
BOOL WINAPI CreateUserProfileExA(_In_ PSID pSid, _In_ LPCSTR lpUserName, _In_opt_ LPCSTR lpUserHive, _Out_opt_ LPSTR lpProfileDir, _In_ DWORD dwDirSize, _In_ BOOL bWin9xUpg)
Definition: profile.c:762
static DWORD CheckForGuestsAndAdmins(_In_ HANDLE hToken, _Out_ PDWORD pdwState)
Definition: profile.c:353
BOOL WINAPI GetDefaultUserProfileDirectoryW(_Out_opt_ LPWSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1426
BOOL WINAPI UnloadUserProfile(_In_ HANDLE hToken, _In_ HANDLE hProfile)
Definition: profile.c:2167
BOOL WINAPI DeleteProfileW(_In_ LPCWSTR lpSidString, _In_opt_ LPCWSTR lpProfilePath, _In_opt_ LPCWSTR lpComputerName)
Definition: profile.c:1180
BOOL WINAPI GetAllUsersProfileDirectoryA(_Out_opt_ LPSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1275
BOOL AppendSystemPostfix(LPWSTR lpName, DWORD dwMaxLength)
Definition: profile.c:20
BOOL WINAPI GetProfileType(_Out_ PDWORD pdwFlags)
Definition: profile.c:1610
BOOL WINAPI CreateUserProfileW(_In_ PSID pSid, _In_ LPCWSTR lpUserName)
Definition: profile.c:744
BOOL WINAPI CreateUserProfileExW(_In_ PSID pSid, _In_ LPCWSTR lpUserName, _In_opt_ LPCWSTR lpUserHive, _Out_opt_ LPWSTR lpProfileDir, _In_ DWORD dwDirSize, _In_ BOOL bWin9xUpg)
Definition: profile.c:851
BOOL WINAPI LoadUserProfileA(_In_ HANDLE hToken, _Inout_ LPPROFILEINFOA lpProfileInfo)
Definition: profile.c:1855
BOOL WINAPI GetProfilesDirectoryA(_Out_ LPSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1497
BOOL WINAPI GetDefaultUserProfileDirectoryA(_Out_opt_ LPSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1386
static DWORD IncrementRefCount(PWSTR pszSidString, PDWORD pdwRefCount)
Definition: profile.c:202
BOOL WINAPI GetUserProfileDirectoryW(_In_ HANDLE hToken, _Out_opt_ LPWSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1753
BOOL WINAPI GetProfilesDirectoryW(_Out_ LPWSTR lpProfilesDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1537
static DWORD SetProfileData(_In_ PWSTR pszSidString, _In_ DWORD dwFlags, _In_ HANDLE hToken)
Definition: profile.c:453
static BOOL AcquireRemoveRestorePrivilege(IN BOOL bAcquire)
Definition: profile.c:64
PSID WINAPI GetUserSid(HANDLE hToken)
Definition: sid.c:36
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
#define INFINITE
Definition: serial.h:102
LPWSTR lpComputerName
Definition: eventvwr.c:74
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int UINT
Definition: sysinfo.c:13
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
#define Unused(x)
Definition: atlwin.h:28
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
#define _swprintf(buf, format,...)
Definition: sprintf.c:56
HANDLE hMutex
Definition: mutex.c:11
static PSID pSid
Definition: security.c:85
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
_Out_ LPWSTR lpBuffer
Definition: netsh.h:68
#define _Out_opt_
Definition: no_sal2.h:214
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define REG_BINARY
Definition: nt_native.h:1499
#define KEY_ALL_ACCESS
Definition: nt_native.h:1044
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1060
#define KEY_QUERY_VALUE
Definition: nt_native.h:1019
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define KEY_WRITE
Definition: nt_native.h:1034
#define REG_EXPAND_SZ
Definition: nt_native.h:1497
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
#define KEY_SET_VALUE
Definition: nt_native.h:1020
#define MAXDWORD
BYTE * PBYTE
Definition: pedump.c:66
short WCHAR
Definition: pedump.c:58
DWORD * PDWORD
Definition: pedump.c:68
long LONG
Definition: pedump.c:60
#define REG_DWORD
Definition: sdbapi.c:615
wcscat
_wcsupr
wcscpy
BOOL WINAPI SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, BOOL bDaclPresent, PACL pDacl, BOOL bDaclDefaulted)
Definition: sec.c:262
#define DPRINT
Definition: sndvol32.h:73
#define _countof(array)
Definition: sndvol32.h:70
STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:166
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
STRSAFEAPI StringCbCatW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:342
DWORD dwHighDateTime
Definition: mapidefs.h:66
DWORD dwLowDateTime
Definition: mapidefs.h:65
LPWSTR lpPolicyPath
Definition: userenv.h:42
LPWSTR lpServerName
Definition: userenv.h:41
LPWSTR lpProfilePath
Definition: userenv.h:39
DWORD dwFlags
Definition: userenv.h:37
DWORD dwSize
Definition: userenv.h:36
HANDLE hProfile
Definition: userenv.h:43
LPWSTR lpUserName
Definition: userenv.h:38
LPWSTR lpDefaultPath
Definition: userenv.h:40
LPVOID lpSecurityDescriptor
Definition: compat.h:193
SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]
Definition: setypes.h:1030
$ULONG GroupCount
Definition: setypes.h:1026
$ULONG PrivilegeCount
Definition: setypes.h:1035
LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]
Definition: setypes.h:1036
SID_AND_ATTRIBUTES User
Definition: setypes.h:1022
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexW(IN LPSECURITY_ATTRIBUTES lpMutexAttributes OPTIONAL, IN BOOL bInitialOwner, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:525
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseMutex(IN HANDLE hMutex)
Definition: synch.c:554
uint16_t * PWSTR
Definition: typedefs.h:56
const char * LPCSTR
Definition: typedefs.h:52
const uint16_t * LPCWSTR
Definition: typedefs.h:57
unsigned char * LPBYTE
Definition: typedefs.h:53
uint16_t * LPWSTR
Definition: typedefs.h:56
uint32_t * LPDWORD
Definition: typedefs.h:59
char * LPSTR
Definition: typedefs.h:51
int32_t INT
Definition: typedefs.h:58
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define PI_APPLYPOLICY
Definition: userenv.h:9
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
#define LookupPrivilegeValue
Definition: winbase.h:3593
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1197
_In_ LPCSTR lpName
Definition: winbase.h:2519
#define GMEM_FIXED
Definition: winbase.h:317
WINBASEAPI _In_ DWORD nLength
Definition: wincon.h:682
#define WINAPI
Definition: msvc.h:6
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:307
#define ERROR_SHARING_VIOLATION
Definition: winerror.h:257
#define ERROR_NOT_ALL_ASSIGNED
Definition: winerror.h:1127
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_USERS
Definition: winreg.h:13
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:191
#define DOMAIN_ALIAS_RID_GUESTS
Definition: setypes.h:654
struct _TOKEN_GROUPS * PTOKEN_GROUPS
#define SECURITY_BUILTIN_DOMAIN_RID
Definition: setypes.h:581
#define TOKEN_ADJUST_PRIVILEGES
Definition: setypes.h:942
struct _TOKEN_USER * PTOKEN_USER
#define TOKEN_QUERY
Definition: setypes.h:940
@ TokenGroups
Definition: setypes.h:979
@ TokenUser
Definition: setypes.h:978
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define TOKEN_IMPERSONATE
Definition: setypes.h:939
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63
#define DOMAIN_ALIAS_RID_ADMINS
Definition: setypes.h:652