ReactOS  0.4.13-dev-99-g7e18b6d
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 
19 BOOL
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 
62 static
63 BOOL
65 {
66  BOOL bRet = FALSE;
67  HANDLE Token;
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 
109 static
110 BOOL
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 
136  RegCloseKey(hKey);
137 
138  RtlFreeUnicodeString(&SidString);
139 
140  DPRINT("Profile already loaded\n");
141 
142  return TRUE;
143 }
144 
145 
146 static
147 HANDLE
149  _In_ PWSTR pszSidString)
150 {
152  SECURITY_ATTRIBUTES SecurityAttributes;
153  PWSTR pszMutexName = NULL;
154  HANDLE hMutex = 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 
200 static
201 DWORD
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 
262 done:
263  if (hProfileKey != NULL)
264  RegCloseKey(hProfileKey);
265 
266  if (hProfilesKey != NULL)
267  RegCloseKey(hProfilesKey);
268 
269  return dwError;
270 }
271 
272 
273 static
274 DWORD
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 
340 done:
341  if (hProfileKey != NULL)
342  RegCloseKey(hProfileKey);
343 
344  if (hProfilesKey != NULL)
345  RegCloseKey(hProfilesKey);
346 
347  return dwError;
348 }
349 
350 
351 static
352 DWORD
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 
437 done:
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 
451 static
452 DWORD
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 
550 done:
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 
563 BOOL
564 WINAPI
566  _In_ ULONG Unused)
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,
628  REG_BINARY,
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 
690 done:
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 
706 BOOL
707 WINAPI
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 
742 BOOL
743 WINAPI
745  _In_ PSID pSid,
746  _In_ LPCWSTR lpUserName)
747 {
748  DPRINT("CreateUserProfileW(%p %S)\n", pSid, lpUserName);
749 
750  /* Call the Ex function */
751  return CreateUserProfileExW(pSid,
752  lpUserName,
753  NULL,
754  NULL,
755  0,
756  FALSE);
757 }
758 
759 
760 BOOL
761 WINAPI
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 
834 done:
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 
849 BOOL
850 WINAPI
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);
903  Error = RegQueryValueExW(hKey,
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);
912  RegCloseKey(hKey);
914  return FALSE;
915  }
916 
917  /* Expand it */
918  if (!ExpandEnvironmentStringsW(szRawProfilesPath,
919  szProfilesPath,
920  ARRAYSIZE(szProfilesPath)))
921  {
922  DPRINT1("Error: %lu\n", GetLastError());
923  RegCloseKey(hKey);
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);
940  Error = RegQueryValueExW(hKey,
941  L"DefaultUserProfile",
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);
949  RegCloseKey(hKey);
951  return FALSE;
952  }
953 
954  RegCloseKey(hKey);
955 
956  StringCbCopyW(szUserProfileName, sizeof(szUserProfileName), lpUserName);
957 
958  /* Create user profile directory */
959 
960  StringCbCopyW(szUserProfilePath, sizeof(szUserProfilePath), szProfilesPath);
961  StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), L"\\");
962  StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), szUserProfileName);
963 
964  // FIXME: Security!
965  if (!CreateDirectoryW(szUserProfilePath, NULL))
966  {
968  {
969  DPRINT1("Error: %lu\n", GetLastError());
970  return FALSE;
971  }
972 
973  for (i = 0; i < 1000; i++)
974  {
975  swprintf(szUserProfileName, L"%s.%03u", lpUserName, i);
976 
977  StringCbCopyW(szUserProfilePath, sizeof(szUserProfilePath), szProfilesPath);
978  StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), L"\\");
979  StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), szUserProfileName);
980 
981  // FIXME: Security!
982  if (CreateDirectoryW(szUserProfilePath, NULL))
983  break;
984 
986  {
987  DPRINT1("Error: %lu\n", GetLastError());
988  return FALSE;
989  }
990  }
991  }
992 
993  /* Copy default user directory */
994 
995  StringCbCopyW(szDefaultUserPath, sizeof(szDefaultUserPath), szProfilesPath);
996  StringCbCatW(szDefaultUserPath, sizeof(szDefaultUserPath), L"\\");
997  StringCbCatW(szDefaultUserPath, sizeof(szDefaultUserPath), szBuffer);
998 
999  // FIXME: Security!
1000  if (!CopyDirectory(szUserProfilePath, szDefaultUserPath))
1001  {
1002  DPRINT1("Error: %lu\n", GetLastError());
1003  return FALSE;
1004  }
1005 
1006  /* Add profile to profile list */
1008  &SidString))
1009  {
1010  DPRINT1("Error: %lu\n", GetLastError());
1011  return FALSE;
1012  }
1013 
1014  StringCbCopyW(szBuffer, sizeof(szBuffer),
1015  L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
1016  StringCbCatW(szBuffer, sizeof(szBuffer), SidString);
1017 
1018  /* Create user profile key */
1020  szBuffer,
1021  0,
1022  NULL,
1025  NULL,
1026  &hKey,
1027  &dwDisposition);
1028  if (Error != ERROR_SUCCESS)
1029  {
1030  DPRINT1("Error: %lu\n", Error);
1031  bRet = FALSE;
1032  goto done;
1033  }
1034 
1035  /* Create non-expanded user profile path */
1036  StringCbCopyW(szBuffer, sizeof(szBuffer), szRawProfilesPath);
1037  StringCbCatW(szBuffer, sizeof(szBuffer), L"\\");
1038  StringCbCatW(szBuffer, sizeof(szBuffer), szUserProfileName);
1039 
1040  /* Set 'ProfileImagePath' value (non-expanded) */
1041  Error = RegSetValueExW(hKey,
1042  L"ProfileImagePath",
1043  0,
1044  REG_EXPAND_SZ,
1045  (LPBYTE)szBuffer,
1046  (wcslen(szBuffer) + 1) * sizeof(WCHAR));
1047  if (Error != ERROR_SUCCESS)
1048  {
1049  DPRINT1("Error: %lu\n", Error);
1050  RegCloseKey(hKey);
1051  bRet = FALSE;
1052  goto done;
1053  }
1054 
1055  /* Set 'Sid' value */
1056  Error = RegSetValueExW(hKey,
1057  L"Sid",
1058  0,
1059  REG_BINARY,
1060  pSid,
1061  GetLengthSid(pSid));
1062  if (Error != ERROR_SUCCESS)
1063  {
1064  DPRINT1("Error: %lu\n", Error);
1065  RegCloseKey(hKey);
1066  bRet = FALSE;
1067  goto done;
1068  }
1069 
1070  RegCloseKey(hKey);
1071 
1072  /* Create user hive file */
1073 
1074  /* Use the default hive file name */
1075  StringCbCopyW(szBuffer, sizeof(szBuffer), szUserProfilePath);
1076  StringCbCatW(szBuffer, sizeof(szBuffer), L"\\ntuser.dat");
1077 
1078  /* Acquire restore privilege */
1080  {
1081  Error = GetLastError();
1082  DPRINT1("Error: %lu\n", Error);
1083  bRet = FALSE;
1084  goto done;
1085  }
1086 
1087  /* Load the user hive */
1089  SidString,
1090  szBuffer);
1092  if (Error != ERROR_SUCCESS)
1093  {
1094  DPRINT1("Error: %lu\n", Error);
1095  bRet = FALSE;
1096  goto done;
1097  }
1098 
1099  /* Initialize user hive */
1100  if (!CreateUserHive(SidString, szUserProfilePath))
1101  {
1102  Error = GetLastError();
1103  DPRINT1("Error: %lu\n", Error);
1104  bRet = FALSE;
1105  }
1106 
1107  /* Unload the hive */
1109  RegUnLoadKeyW(HKEY_USERS, SidString);
1111 
1112  /*
1113  * If the caller wants to retrieve the user profile path,
1114  * give it now. 'dwDirSize' is the number of characters.
1115  */
1116  if (lpProfileDir && dwDirSize)
1117  StringCchCopyW(lpProfileDir, dwDirSize, szUserProfilePath);
1118 
1119 done:
1120  LocalFree((HLOCAL)SidString);
1122 
1123  DPRINT("CreateUserProfileExW() done\n");
1124 
1125  return bRet;
1126 }
1127 
1128 
1129 BOOL
1130 WINAPI
1132  _In_ LPCSTR lpSidString,
1133  _In_opt_ LPCSTR lpProfilePath,
1135 {
1136  BOOL bResult;
1137  UNICODE_STRING SidString = {0, 0, NULL}, ProfilePath = {0, 0, NULL}, ComputerName = {0, 0, NULL};
1138 
1139  DPRINT("DeleteProfileA() called\n");
1140 
1141  /* Conversion to UNICODE */
1142  if (lpSidString)
1144  (LPSTR)lpSidString);
1145 
1146  if (lpProfilePath)
1147  RtlCreateUnicodeStringFromAsciiz(&ProfilePath,
1148  (LPSTR)lpProfilePath);
1149 
1150  if (lpComputerName)
1151  RtlCreateUnicodeStringFromAsciiz(&ComputerName,
1153 
1154  /* Call the UNICODE function */
1155  bResult = DeleteProfileW(SidString.Buffer,
1156  ProfilePath.Buffer,
1157  ComputerName.Buffer);
1158 
1159  /* Memory cleanup */
1160  if (lpSidString)
1161  RtlFreeUnicodeString(&SidString);
1162 
1163  if (lpProfilePath)
1164  RtlFreeUnicodeString(&ProfilePath);
1165 
1166  if (lpComputerName)
1167  RtlFreeUnicodeString(&ComputerName);
1168 
1169  return bResult;
1170 }
1171 
1172 
1173 BOOL
1174 WINAPI
1176  _In_ LPCWSTR lpSidString,
1177  _In_opt_ LPCWSTR lpProfilePath,
1179 {
1180  DPRINT1("DeleteProfileW(%S %S %S) not implemented!\n", lpSidString, lpProfilePath, lpComputerName);
1181  return TRUE; //FALSE;
1182 }
1183 
1184 
1185 BOOL
1186 WINAPI
1188  _Out_opt_ LPSTR lpProfileDir,
1189  _Inout_ LPDWORD lpcchSize)
1190 {
1191  LPWSTR lpBuffer;
1192  BOOL bResult;
1193 
1194  if (!lpcchSize)
1195  {
1197  return FALSE;
1198  }
1199 
1201  *lpcchSize * sizeof(WCHAR));
1202  if (lpBuffer == NULL)
1203  return FALSE;
1204 
1206  lpcchSize);
1207  if (bResult && lpProfileDir)
1208  {
1209  bResult = WideCharToMultiByte(CP_ACP,
1210  0,
1211  lpBuffer,
1212  -1,
1213  lpProfileDir,
1214  *lpcchSize,
1215  NULL,
1216  NULL);
1217  }
1218 
1220 
1221  return bResult;
1222 }
1223 
1224 
1225 BOOL
1226 WINAPI
1228  _Out_opt_ LPWSTR lpProfileDir,
1229  _Inout_ LPDWORD lpcchSize)
1230 {
1231  WCHAR szProfilePath[MAX_PATH];
1232  WCHAR szBuffer[MAX_PATH];
1233  DWORD dwType, dwLength;
1234  HKEY hKey;
1235  LONG Error;
1236 
1237  if (!lpcchSize)
1238  {
1240  return FALSE;
1241  }
1242 
1244  L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
1245  0,
1247  &hKey);
1248  if (Error != ERROR_SUCCESS)
1249  {
1250  DPRINT1("Error: %lu\n", Error);
1252  return FALSE;
1253  }
1254 
1255  /* Get profiles path */
1256  dwLength = sizeof(szBuffer);
1257  Error = RegQueryValueExW(hKey,
1258  L"ProfilesDirectory",
1259  NULL,
1260  &dwType,
1261  (LPBYTE)szBuffer,
1262  &dwLength);
1263  if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
1264  {
1265  DPRINT1("Error: %lu\n", Error);
1266  RegCloseKey(hKey);
1268  return FALSE;
1269  }
1270 
1271  /* Expand it */
1272  if (!ExpandEnvironmentStringsW(szBuffer,
1273  szProfilePath,
1274  ARRAYSIZE(szProfilePath)))
1275  {
1276  DPRINT1("Error: %lu\n", GetLastError());
1277  RegCloseKey(hKey);
1278  return FALSE;
1279  }
1280 
1281  /* Get 'AllUsersProfile' name */
1282  dwLength = sizeof(szBuffer);
1283  Error = RegQueryValueExW(hKey,
1284  L"AllUsersProfile",
1285  NULL,
1286  &dwType,
1287  (LPBYTE)szBuffer,
1288  &dwLength);
1289  if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
1290  {
1291  DPRINT1("Error: %lu\n", Error);
1292  RegCloseKey(hKey);
1294  return FALSE;
1295  }
1296 
1297  RegCloseKey(hKey);
1298 
1299  StringCbCatW(szProfilePath, sizeof(szProfilePath), L"\\");
1300  StringCbCatW(szProfilePath, sizeof(szProfilePath), szBuffer);
1301 
1302  dwLength = wcslen(szProfilePath) + 1;
1303  if (lpProfileDir && (*lpcchSize >= dwLength))
1304  {
1305  StringCchCopyW(lpProfileDir, *lpcchSize, szProfilePath);
1306  *lpcchSize = dwLength;
1307  return TRUE;
1308  }
1309  else // if (!lpProfileDir || (*lpcchSize < dwLength))
1310  {
1311  *lpcchSize = dwLength;
1313  return FALSE;
1314  }
1315 }
1316 
1317 
1318 BOOL
1319 WINAPI
1321  _Out_opt_ LPSTR lpProfileDir,
1322  _Inout_ LPDWORD lpcchSize)
1323 {
1324  LPWSTR lpBuffer;
1325  BOOL bResult;
1326 
1327  if (!lpcchSize)
1328  {
1330  return FALSE;
1331  }
1332 
1334  *lpcchSize * sizeof(WCHAR));
1335  if (lpBuffer == NULL)
1336  return FALSE;
1337 
1339  lpcchSize);
1340  if (bResult && lpProfileDir)
1341  {
1342  bResult = WideCharToMultiByte(CP_ACP,
1343  0,
1344  lpBuffer,
1345  -1,
1346  lpProfileDir,
1347  *lpcchSize,
1348  NULL,
1349  NULL);
1350  }
1351 
1353 
1354  return bResult;
1355 }
1356 
1357 
1358 BOOL
1359 WINAPI
1361  _Out_opt_ LPWSTR lpProfileDir,
1362  _Inout_ LPDWORD lpcchSize)
1363 {
1364  WCHAR szProfilePath[MAX_PATH];
1365  WCHAR szBuffer[MAX_PATH];
1366  DWORD dwType, dwLength;
1367  HKEY hKey;
1368  LONG Error;
1369 
1370  if (!lpcchSize)
1371  {
1373  return FALSE;
1374  }
1375 
1377  L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
1378  0,
1380  &hKey);
1381  if (Error != ERROR_SUCCESS)
1382  {
1383  DPRINT1("Error: %lu\n", Error);
1385  return FALSE;
1386  }
1387 
1388  /* Get profiles path */
1389  dwLength = sizeof(szBuffer);
1390  Error = RegQueryValueExW(hKey,
1391  L"ProfilesDirectory",
1392  NULL,
1393  &dwType,
1394  (LPBYTE)szBuffer,
1395  &dwLength);
1396  if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
1397  {
1398  DPRINT1("Error: %lu\n", Error);
1399  RegCloseKey(hKey);
1401  return FALSE;
1402  }
1403 
1404  /* Expand it */
1405  if (!ExpandEnvironmentStringsW(szBuffer,
1406  szProfilePath,
1407  ARRAYSIZE(szProfilePath)))
1408  {
1409  DPRINT1("Error: %lu\n", GetLastError());
1410  RegCloseKey(hKey);
1411  return FALSE;
1412  }
1413 
1414  /* Get 'DefaultUserProfile' name */
1415  dwLength = sizeof(szBuffer);
1416  Error = RegQueryValueExW(hKey,
1417  L"DefaultUserProfile",
1418  NULL,
1419  &dwType,
1420  (LPBYTE)szBuffer,
1421  &dwLength);
1422  if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
1423  {
1424  DPRINT1("Error: %lu\n", Error);
1425  RegCloseKey(hKey);
1427  return FALSE;
1428  }
1429 
1430  RegCloseKey(hKey);
1431 
1432  StringCbCatW(szProfilePath, sizeof(szProfilePath), L"\\");
1433  StringCbCatW(szProfilePath, sizeof(szProfilePath), szBuffer);
1434 
1435  dwLength = wcslen(szProfilePath) + 1;
1436  if (lpProfileDir && (*lpcchSize >= dwLength))
1437  {
1438  StringCchCopyW(lpProfileDir, *lpcchSize, szProfilePath);
1439  *lpcchSize = dwLength;
1440  return TRUE;
1441  }
1442  else // if (!lpProfileDir || (*lpcchSize < dwLength))
1443  {
1444  *lpcchSize = dwLength;
1446  return FALSE;
1447  }
1448 }
1449 
1450 
1451 BOOL
1452 WINAPI
1454  _Out_ LPSTR lpProfileDir, // _Out_opt_
1455  _Inout_ LPDWORD lpcchSize)
1456 {
1457  LPWSTR lpBuffer;
1458  BOOL bResult;
1459 
1460  if (!lpcchSize || !lpProfileDir)
1461  {
1463  return FALSE;
1464  }
1465 
1467  *lpcchSize * sizeof(WCHAR));
1468  if (lpBuffer == NULL)
1469  return FALSE;
1470 
1471  bResult = GetProfilesDirectoryW(lpBuffer,
1472  lpcchSize);
1473  if (bResult && lpProfileDir)
1474  {
1475  bResult = WideCharToMultiByte(CP_ACP,
1476  0,
1477  lpBuffer,
1478  -1,
1479  lpProfileDir,
1480  *lpcchSize,
1481  NULL,
1482  NULL);
1483  }
1484 
1486 
1487  return bResult;
1488 }
1489 
1490 
1491 BOOL
1492 WINAPI
1494  _Out_ LPWSTR lpProfilesDir, // _Out_opt_
1495  _Inout_ LPDWORD lpcchSize)
1496 {
1497  WCHAR szProfilesPath[MAX_PATH];
1498  WCHAR szBuffer[MAX_PATH];
1499  DWORD dwType, dwLength;
1500  HKEY hKey;
1501  LONG Error;
1502 
1503  if (!lpcchSize)
1504  {
1506  return FALSE;
1507  }
1508 
1510  L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
1511  0,
1513  &hKey);
1514  if (Error != ERROR_SUCCESS)
1515  {
1516  DPRINT1("Error: %lu\n", Error);
1518  return FALSE;
1519  }
1520 
1521  /* Get profiles path */
1522  dwLength = sizeof(szBuffer);
1523  Error = RegQueryValueExW(hKey,
1524  L"ProfilesDirectory",
1525  NULL,
1526  &dwType,
1527  (LPBYTE)szBuffer,
1528  &dwLength);
1529  if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
1530  {
1531  DPRINT1("Error: %lu\n", Error);
1532  RegCloseKey(hKey);
1534  return FALSE;
1535  }
1536 
1537  RegCloseKey(hKey);
1538 
1539  /* Expand it */
1540  if (!ExpandEnvironmentStringsW(szBuffer,
1541  szProfilesPath,
1542  ARRAYSIZE(szProfilesPath)))
1543  {
1544  DPRINT1("Error: %lu\n", GetLastError());
1545  return FALSE;
1546  }
1547 
1548  dwLength = wcslen(szProfilesPath) + 1;
1549  if (lpProfilesDir && (*lpcchSize >= dwLength))
1550  {
1551  StringCchCopyW(lpProfilesDir, *lpcchSize, szProfilesPath);
1552  *lpcchSize = dwLength;
1553  return TRUE;
1554  }
1555  else // if (!lpProfilesDir || (*lpcchSize < dwLength))
1556  {
1557  *lpcchSize = dwLength;
1559  return FALSE;
1560  }
1561 }
1562 
1563 
1564 BOOL
1565 WINAPI
1567  _Out_ PDWORD pdwFlags)
1568 {
1569  UNICODE_STRING SidString = {0, 0, NULL};
1570  HANDLE hToken;
1571  HKEY hProfilesKey = NULL, hProfileKey = NULL;
1572  DWORD dwType, dwLength, dwState = 0;
1573  DWORD dwError;
1574  BOOL bResult = FALSE;
1575 
1576  DPRINT("GetProfileType(%p)\n", pdwFlags);
1577 
1578  if (pdwFlags == NULL)
1579  {
1581  return FALSE;
1582  }
1583 
1584  if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &hToken))
1585  {
1587  {
1588  DPRINT1("Failed to open a token (Error %lu)\n", GetLastError());
1589  return FALSE;
1590  }
1591  }
1592 
1593  /* Get the user SID string */
1594  if (!GetUserSidStringFromToken(hToken, &SidString))
1595  {
1596  DPRINT1("GetUserSidStringFromToken() failed\n");
1597  goto done;
1598  }
1599 
1600  DPRINT("SID: %wZ\n", &SidString);
1601 
1603  L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
1604  0,
1606  &hProfilesKey);
1607  if (dwError != ERROR_SUCCESS)
1608  {
1609  DPRINT1("Error: %lu\n", dwError);
1610  SetLastError(dwError);
1611  goto done;
1612  }
1613 
1614  dwError = RegOpenKeyExW(hProfilesKey,
1615  SidString.Buffer,
1616  0,
1618  &hProfileKey);
1619  if (dwError != ERROR_SUCCESS)
1620  {
1621  DPRINT1("Error: %lu\n", dwError);
1622  SetLastError(dwError);
1623  goto done;
1624  }
1625 
1626  /* Get the State value */
1627  dwLength = sizeof(dwState);
1628  dwError = RegQueryValueExW(hProfileKey,
1629  L"State",
1630  NULL,
1631  &dwType,
1632  (PBYTE)&dwState,
1633  &dwLength);
1634  if (dwError != ERROR_SUCCESS)
1635  {
1636  DPRINT1("Error: %lu\n", dwError);
1637  SetLastError(dwError);
1638  goto done;
1639  }
1640 
1641  *pdwFlags = 0;
1642 
1643  if (dwState & 0x80) /* PROFILE_GUEST_USER */
1644  *pdwFlags |= PT_TEMPORARY;
1645 
1646  /* FIXME: Add checks for PT_MANDATORY and PT_ROAMING */
1647 
1648  bResult = TRUE;
1649 
1650 done:
1651  if (hProfileKey != NULL)
1652  RegCloseKey(hProfileKey);
1653 
1654  if (hProfilesKey != NULL)
1655  RegCloseKey(hProfilesKey);
1656 
1657  RtlFreeUnicodeString(&SidString);
1658 
1659  CloseHandle(hToken);
1660 
1661  return bResult;
1662 }
1663 
1664 
1665 BOOL
1666 WINAPI
1668  _In_ HANDLE hToken,
1669  _Out_opt_ LPSTR lpProfileDir,
1670  _Inout_ LPDWORD lpcchSize)
1671 {
1672  LPWSTR lpBuffer;
1673  BOOL bResult;
1674 
1675  if (!lpcchSize || !lpProfileDir)
1676  {
1678  return FALSE;
1679  }
1680 
1682  *lpcchSize * sizeof(WCHAR));
1683  if (lpBuffer == NULL)
1684  return FALSE;
1685 
1686  bResult = GetUserProfileDirectoryW(hToken,
1687  lpBuffer,
1688  lpcchSize);
1689  if (bResult && lpProfileDir)
1690  {
1691  bResult = WideCharToMultiByte(CP_ACP,
1692  0,
1693  lpBuffer,
1694  -1,
1695  lpProfileDir,
1696  *lpcchSize,
1697  NULL,
1698  NULL);
1699  }
1700 
1702 
1703  return bResult;
1704 }
1705 
1706 
1707 BOOL
1708 WINAPI
1710  _In_ HANDLE hToken,
1711  _Out_opt_ LPWSTR lpProfileDir,
1712  _Inout_ LPDWORD lpcchSize)
1713 {
1714  UNICODE_STRING SidString;
1715  WCHAR szKeyName[MAX_PATH];
1716  WCHAR szRawImagePath[MAX_PATH];
1717  WCHAR szImagePath[MAX_PATH];
1718  DWORD dwType, dwLength;
1719  HKEY hKey;
1720  LONG Error;
1721 
1722  if (!hToken)
1723  {
1725  return FALSE;
1726  }
1727 
1728  if (!lpcchSize)
1729  {
1731  return FALSE;
1732  }
1733 
1734  /* Get the user SID string */
1735  if (!GetUserSidStringFromToken(hToken, &SidString))
1736  {
1737  DPRINT1("GetUserSidStringFromToken() failed\n");
1738  return FALSE;
1739  }
1740 
1741  DPRINT("SidString: '%wZ'\n", &SidString);
1742 
1743  StringCbCopyW(szKeyName, sizeof(szKeyName),
1744  L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
1745  StringCbCatW(szKeyName, sizeof(szKeyName), SidString.Buffer);
1746 
1747  RtlFreeUnicodeString(&SidString);
1748 
1749  DPRINT("KeyName: '%S'\n", szKeyName);
1750 
1752  szKeyName,
1753  0,
1755  &hKey);
1756  if (Error != ERROR_SUCCESS)
1757  {
1758  DPRINT1("Error: %lu\n", Error);
1760  return FALSE;
1761  }
1762 
1763  dwLength = sizeof(szRawImagePath);
1764  Error = RegQueryValueExW(hKey,
1765  L"ProfileImagePath",
1766  NULL,
1767  &dwType,
1768  (LPBYTE)szRawImagePath,
1769  &dwLength);
1770  if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
1771  {
1772  DPRINT1("Error: %lu\n", Error);
1773  RegCloseKey(hKey);
1775  return FALSE;
1776  }
1777 
1778  RegCloseKey(hKey);
1779 
1780  DPRINT("RawImagePath: '%S'\n", szRawImagePath);
1781 
1782  /* Expand it */
1783  if (!ExpandEnvironmentStringsW(szRawImagePath,
1784  szImagePath,
1785  ARRAYSIZE(szImagePath)))
1786  {
1787  DPRINT1("Error: %lu\n", GetLastError());
1788  return FALSE;
1789  }
1790 
1791  DPRINT("ImagePath: '%S'\n", szImagePath);
1792 
1793  dwLength = wcslen(szImagePath) + 1;
1794  if (lpProfileDir && (*lpcchSize >= dwLength))
1795  {
1796  StringCchCopyW(lpProfileDir, *lpcchSize, szImagePath);
1797  *lpcchSize = dwLength;
1798  return TRUE;
1799  }
1800  else // if (!lpProfileDir || (*lpcchSize < dwLength))
1801  {
1802  *lpcchSize = dwLength;
1804  return FALSE;
1805  }
1806 }
1807 
1808 
1809 BOOL
1810 WINAPI
1812  _In_ HANDLE hToken,
1813  _Inout_ LPPROFILEINFOA lpProfileInfo)
1814 {
1815  BOOL bResult = FALSE;
1816  PROFILEINFOW ProfileInfoW = {0};
1817  int len;
1818 
1819  DPRINT("LoadUserProfileA() called\n");
1820 
1821  /* Check profile info */
1822  if (!lpProfileInfo || (lpProfileInfo->dwSize != sizeof(PROFILEINFOA)) ||
1823  (lpProfileInfo->lpUserName == NULL) || (lpProfileInfo->lpUserName[0] == 0))
1824  {
1826  return FALSE;
1827  }
1828 
1829  /* Convert the structure to UNICODE... */
1830  ProfileInfoW.dwSize = sizeof(ProfileInfoW);
1831  ProfileInfoW.dwFlags = lpProfileInfo->dwFlags;
1832 
1833  if (lpProfileInfo->lpUserName)
1834  {
1835  len = MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpUserName, -1, NULL, 0);
1836  ProfileInfoW.lpUserName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1837  if (!ProfileInfoW.lpUserName)
1838  {
1840  goto cleanup;
1841  }
1842  MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpUserName, -1, ProfileInfoW.lpUserName, len);
1843  }
1844 
1845  if (lpProfileInfo->lpProfilePath)
1846  {
1847  len = MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpProfilePath, -1, NULL, 0);
1848  ProfileInfoW.lpProfilePath = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1849  if (!ProfileInfoW.lpProfilePath)
1850  {
1852  goto cleanup;
1853  }
1854  MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpProfilePath, -1, ProfileInfoW.lpProfilePath, len);
1855  }
1856 
1857  if (lpProfileInfo->lpDefaultPath)
1858  {
1859  len = MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpDefaultPath, -1, NULL, 0);
1860  ProfileInfoW.lpDefaultPath = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1861  if (!ProfileInfoW.lpDefaultPath)
1862  {
1864  goto cleanup;
1865  }
1866  MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpDefaultPath, -1, ProfileInfoW.lpDefaultPath, len);
1867  }
1868 
1869  if (lpProfileInfo->lpServerName)
1870  {
1871  len = MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpServerName, -1, NULL, 0);
1872  ProfileInfoW.lpServerName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1873  if (!ProfileInfoW.lpServerName)
1874  {
1876  goto cleanup;
1877  }
1878  MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpServerName, -1, ProfileInfoW.lpServerName, len);
1879  }
1880 
1881  if ((ProfileInfoW.dwFlags & PI_APPLYPOLICY) != 0 && lpProfileInfo->lpPolicyPath)
1882  {
1883  len = MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpPolicyPath, -1, NULL, 0);
1884  ProfileInfoW.lpPolicyPath = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1885  if (!ProfileInfoW.lpPolicyPath)
1886  {
1888  goto cleanup;
1889  }
1890  MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpPolicyPath, -1, ProfileInfoW.lpPolicyPath, len);
1891  }
1892 
1893  /* ... and call the UNICODE function */
1894  bResult = LoadUserProfileW(hToken, &ProfileInfoW);
1895 
1896  /* Save the returned value */
1897  lpProfileInfo->hProfile = ProfileInfoW.hProfile;
1898 
1899 cleanup:
1900  /* Memory cleanup */
1901  if (ProfileInfoW.lpUserName)
1902  HeapFree(GetProcessHeap(), 0, ProfileInfoW.lpUserName);
1903 
1904  if (ProfileInfoW.lpProfilePath)
1905  HeapFree(GetProcessHeap(), 0, ProfileInfoW.lpProfilePath);
1906 
1907  if (ProfileInfoW.lpDefaultPath)
1908  HeapFree(GetProcessHeap(), 0, ProfileInfoW.lpDefaultPath);
1909 
1910  if (ProfileInfoW.lpServerName)
1911  HeapFree(GetProcessHeap(), 0, ProfileInfoW.lpServerName);
1912 
1913  if ((ProfileInfoW.dwFlags & PI_APPLYPOLICY) != 0 && ProfileInfoW.lpPolicyPath)
1914  HeapFree(GetProcessHeap(), 0, ProfileInfoW.lpPolicyPath);
1915 
1916  return bResult;
1917 }
1918 
1919 
1920 BOOL
1921 WINAPI
1923  _In_ HANDLE hToken,
1924  _Inout_ LPPROFILEINFOW lpProfileInfo)
1925 {
1926  WCHAR szUserHivePath[MAX_PATH];
1927  PTOKEN_USER UserSid = NULL;
1928  UNICODE_STRING SidString = { 0, 0, NULL };
1929  HANDLE hProfileMutex = NULL;
1930  LONG Error;
1931  BOOL ret = FALSE;
1932  DWORD dwLength = sizeof(szUserHivePath) / sizeof(szUserHivePath[0]);
1933 
1934  DPRINT("LoadUserProfileW(%p %p)\n", hToken, lpProfileInfo);
1935 
1936  /* Check profile info */
1937  if (!lpProfileInfo || (lpProfileInfo->dwSize != sizeof(PROFILEINFOW)) ||
1938  (lpProfileInfo->lpUserName == NULL) || (lpProfileInfo->lpUserName[0] == 0))
1939  {
1941  return FALSE;
1942  }
1943 
1944  DPRINT("UserName: %S\n", lpProfileInfo->lpUserName);
1945 
1946  /* Get the user SID string */
1947  ret = GetUserSidStringFromToken(hToken, &SidString);
1948  if (!ret)
1949  {
1950  DPRINT1("GetUserSidStringFromToken() failed\n");
1951  goto cleanup;
1952  }
1953  ret = FALSE;
1954 
1955  /* Create the profile mutex */
1956  hProfileMutex = CreateProfileMutex(SidString.Buffer);
1957  if (hProfileMutex == NULL)
1958  {
1959  DPRINT1("Failed to create the profile mutex\n");
1960  goto cleanup;
1961  }
1962 
1963  /* Wait for the profile mutex */
1964  WaitForSingleObject(hProfileMutex, INFINITE);
1965 
1966  /* Don't load a profile twice */
1967  if (CheckForLoadedProfile(hToken))
1968  {
1969  DPRINT1("Profile %S already loaded\n", SidString.Buffer);
1970  }
1971  else
1972  {
1973  DPRINT1("Loading profile %S\n", SidString.Buffer);
1974 
1975  if (lpProfileInfo->lpProfilePath)
1976  {
1977  /* Use the caller's specified roaming user profile path */
1978  StringCbCopyW(szUserHivePath, sizeof(szUserHivePath), lpProfileInfo->lpProfilePath);
1979  }
1980  else
1981  {
1982  /* FIXME: check if MS Windows allows lpProfileInfo->lpProfilePath to be NULL */
1983  if (!GetProfilesDirectoryW(szUserHivePath, &dwLength))
1984  {
1985  DPRINT1("GetProfilesDirectoryW() failed (error %ld)\n", GetLastError());
1986  goto cleanup;
1987  }
1988  }
1989 
1990  /* Create user hive name */
1991  StringCbCatW(szUserHivePath, sizeof(szUserHivePath), L"\\");
1992  StringCbCatW(szUserHivePath, sizeof(szUserHivePath), lpProfileInfo->lpUserName);
1993  StringCbCatW(szUserHivePath, sizeof(szUserHivePath), L"\\ntuser.dat");
1994  DPRINT("szUserHivePath: %S\n", szUserHivePath);
1995 
1996  /* Create user profile directory if needed */
1997  if (GetFileAttributesW(szUserHivePath) == INVALID_FILE_ATTRIBUTES)
1998  {
1999  /* Get user sid */
2000  if (GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLength) ||
2002  {
2003  DPRINT1 ("GetTokenInformation() failed\n");
2004  goto cleanup;
2005  }
2006 
2007  UserSid = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), 0, dwLength);
2008  if (!UserSid)
2009  {
2010  DPRINT1("HeapAlloc() failed\n");
2012  goto cleanup;
2013  }
2014 
2015  if (!GetTokenInformation(hToken, TokenUser, UserSid, dwLength, &dwLength))
2016  {
2017  DPRINT1("GetTokenInformation() failed\n");
2018  goto cleanup;
2019  }
2020 
2021  /* Create profile */
2022  ret = CreateUserProfileW(UserSid->User.Sid, lpProfileInfo->lpUserName);
2023  if (!ret)
2024  {
2025  DPRINT1("CreateUserProfileW() failed\n");
2026  goto cleanup;
2027  }
2028  }
2029 
2030  /* Acquire restore privilege */
2032  {
2033  DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
2034  goto cleanup;
2035  }
2036 
2037  /* Load user registry hive */
2039  SidString.Buffer,
2040  szUserHivePath);
2042 
2043  /* HACK: Do not fail if the profile has already been loaded! */
2045  Error = ERROR_SUCCESS;
2046 
2047  if (Error != ERROR_SUCCESS)
2048  {
2049  DPRINT1("RegLoadKeyW() failed (Error %ld)\n", Error);
2051  goto cleanup;
2052  }
2053 
2054  SetProfileData(SidString.Buffer,
2055  lpProfileInfo->dwFlags,
2056  hToken);
2057  }
2058 
2059  /* Open future HKEY_CURRENT_USER */
2061  SidString.Buffer,
2062  0,
2064  (PHKEY)&lpProfileInfo->hProfile);
2065  if (Error != ERROR_SUCCESS)
2066  {
2067  DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error);
2069  goto cleanup;
2070  }
2071 
2072  Error = IncrementRefCount(SidString.Buffer, NULL);
2073  if (Error != ERROR_SUCCESS)
2074  {
2075  DPRINT1("IncrementRefCount() failed (Error %ld)\n", Error);
2077  goto cleanup;
2078  }
2079 
2080  ret = TRUE;
2081 
2082 cleanup:
2083  if (UserSid != NULL)
2084  HeapFree(GetProcessHeap(), 0, UserSid);
2085 
2086  if (hProfileMutex != NULL)
2087  {
2088  ReleaseMutex(hProfileMutex);
2089  CloseHandle(hProfileMutex);
2090  }
2091 
2092  RtlFreeUnicodeString(&SidString);
2093 
2094  DPRINT("LoadUserProfileW() done\n");
2095  return ret;
2096 }
2097 
2098 
2099 BOOL
2100 WINAPI
2102  _In_ HANDLE hToken,
2103  _In_ HANDLE hProfile)
2104 {
2105  UNICODE_STRING SidString = {0, 0, NULL};
2106  HANDLE hProfileMutex = NULL;
2107  HKEY hProfilesKey = NULL, hProfileKey = NULL;
2108  DWORD dwRefCount = 0, dwLength, dwType, dwState = 0;
2109  DWORD dwError;
2110  BOOL bRet = FALSE;
2111 
2112  DPRINT("UnloadUserProfile() called\n");
2113 
2114  if (hProfile == NULL)
2115  {
2116  DPRINT1("Invalid profile handle\n");
2118  return FALSE;
2119  }
2120 
2121  /* Get the user SID string */
2122  if (!GetUserSidStringFromToken(hToken, &SidString))
2123  {
2124  DPRINT1("GetUserSidStringFromToken() failed\n");
2125  return FALSE;
2126  }
2127 
2128  DPRINT("SidString: '%wZ'\n", &SidString);
2129 
2130  /* Create the profile mutex */
2131  hProfileMutex = CreateProfileMutex(SidString.Buffer);
2132  if (hProfileMutex == NULL)
2133  {
2134  DPRINT1("Failed to create the profile mutex\n");
2135  goto cleanup;
2136  }
2137 
2138  /* Wait for the profile mutex */
2139  WaitForSingleObject(hProfileMutex, INFINITE);
2140 
2141  /* Close the profile handle */
2142  RegFlushKey(hProfile);
2143  RegCloseKey(hProfile);
2144 
2145  dwError = DecrementRefCount(SidString.Buffer, &dwRefCount);
2146  if (dwError != ERROR_SUCCESS)
2147  {
2148  DPRINT1("DecrementRefCount() failed (Error %lu)\n", dwError);
2149  SetLastError(dwError);
2150  goto cleanup;
2151  }
2152 
2153  if (dwRefCount == 0)
2154  {
2155  DPRINT("RefCount is 0: Unload the Hive!\n");
2156 
2157  /* Acquire restore privilege */
2159  {
2160  DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %lu)\n", GetLastError());
2161  goto cleanup;
2162  }
2163 
2164  /* HACK */
2165  {
2166  HKEY hUserKey;
2167 
2168  dwError = RegOpenKeyExW(HKEY_USERS,
2169  SidString.Buffer,
2170  0,
2171  KEY_WRITE,
2172  &hUserKey);
2173  if (dwError == ERROR_SUCCESS)
2174  {
2175  RegDeleteKeyW(hUserKey,
2176  L"Volatile Environment");
2177 
2178  RegCloseKey(hUserKey);
2179  }
2180  }
2181  /* End of HACK */
2182 
2183  /* Unload the hive */
2184  dwError = RegUnLoadKeyW(HKEY_USERS,
2185  SidString.Buffer);
2186 
2187  /* Remove restore privilege */
2189 
2190  if (dwError != ERROR_SUCCESS)
2191  {
2192  DPRINT1("RegUnLoadKeyW() failed (Error %lu)\n", dwError);
2193  SetLastError(dwError);
2194  goto cleanup;
2195  }
2196 
2198  L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
2199  0,
2201  &hProfilesKey);
2202  if (dwError != ERROR_SUCCESS)
2203  {
2204  DPRINT1("RegOpenKeyExW() failed (Error %lu)\n", dwError);
2205  SetLastError(dwError);
2206  goto cleanup;
2207  }
2208 
2209  dwError = RegOpenKeyExW(hProfilesKey,
2210  SidString.Buffer,
2211  0,
2213  &hProfileKey);
2214  if (dwError != ERROR_SUCCESS)
2215  {
2216  DPRINT1("RegOpenKeyExW() failed (Error %lu)\n", dwError);
2217  SetLastError(dwError);
2218  goto cleanup;
2219  }
2220 
2221  /* Get the State value */
2222  dwLength = sizeof(dwState);
2223  dwError = RegQueryValueExW(hProfileKey,
2224  L"State",
2225  NULL,
2226  &dwType,
2227  (PBYTE)&dwState,
2228  &dwLength);
2229  if (dwError != ERROR_SUCCESS)
2230  {
2231  DPRINT1("RegQueryValueExW() failed (Error %lu)\n", dwError);
2232  SetLastError(dwError);
2233  goto cleanup;
2234  }
2235 
2236  /* Delete a guest profile */
2237  if (dwState & 0x80) // PROFILE_GUEST_USER
2238  {
2239  if (!DeleteProfileW(SidString.Buffer, NULL, NULL))
2240  {
2241  DPRINT1("DeleteProfile(%S, NULL, NULL) failed (Error %lu)\n",
2242  SidString.Buffer, GetLastError());
2243  goto cleanup;
2244  }
2245  }
2246  }
2247 
2248  bRet = TRUE;
2249 
2250 cleanup:
2251  if (hProfileKey != NULL)
2252  RegCloseKey(hProfileKey);
2253 
2254  if (hProfilesKey != NULL)
2255  RegCloseKey(hProfilesKey);
2256 
2257  if (hProfileMutex != NULL)
2258  {
2259  ReleaseMutex(hProfileMutex);
2260  CloseHandle(hProfileMutex);
2261  }
2262 
2263  RtlFreeUnicodeString(&SidString);
2264 
2265  DPRINT("UnloadUserProfile() done\n");
2266 
2267  return bRet;
2268 }
2269 
2270 /* EOF */
#define HKEY_USERS
Definition: winreg.h:13
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
_Must_inspect_result_ typedef _In_ PVOID Unused
Definition: iotypes.h:1128
SID_IDENTIFIER_AUTHORITY LocalSystemAuthority
Definition: misc.c:34
BOOL WINAPI GetDefaultUserProfileDirectoryW(_Out_opt_ LPWSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1360
#define IN
Definition: typedefs.h:38
BOOL WINAPI CreateUserProfileW(_In_ PSID pSid, _In_ LPCWSTR lpUserName)
Definition: profile.c:744
VOID WINAPI GetSystemTimeAsFileTime(OUT PFILETIME lpFileTime)
Definition: time.c:128
#define TRUE
Definition: types.h:120
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
#define DOMAIN_ALIAS_RID_GUESTS
Definition: setypes.h:626
#define CloseHandle
Definition: compat.h:398
HANDLE hProfile
Definition: userenv.h:43
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL WINAPI GetProfilesDirectoryA(_Out_ LPSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1453
#define WideCharToMultiByte
Definition: compat.h:101
#define KEY_SET_VALUE
Definition: nt_native.h:1017
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
BOOL WINAPI GetUserProfileDirectoryW(_In_ HANDLE hToken, _Out_opt_ LPWSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1709
#define REG_BINARY
Definition: nt_native.h:1496
_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:182
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:185
#define PI_APPLYPOLICY
Definition: userenv.h:9
uint16_t * PWSTR
Definition: typedefs.h:54
#define CP_ACP
Definition: compat.h:99
BOOL WINAPI InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD dwRevision)
Definition: security.c:808
BOOL WINAPI EqualSid(PSID pSid1, PSID pSid2)
Definition: security.c:708
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
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
BOOL GetUserSidStringFromToken(HANDLE hToken, PUNICODE_STRING SidString)
Definition: sid.c:102
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID _Out_ PHANDLE Token
_In_ DWORD nLength
Definition: wincon.h:461
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1240
_In_ LPCSTR lpName
Definition: winbase.h:2729
$ULONG PrivilegeCount
Definition: setypes.h:969
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
BOOL WINAPI DeleteProfileA(_In_ LPCSTR lpSidString, _In_opt_ LPCSTR lpProfilePath, _In_opt_ LPCSTR lpComputerName)
Definition: profile.c:1131
#define TOKEN_IMPERSONATE
Definition: setypes.h:873
BOOL AppendSystemPostfix(LPWSTR lpName, DWORD dwMaxLength)
Definition: profile.c:20
BOOL WINAPI LoadUserProfileA(_In_ HANDLE hToken, _Inout_ LPPROFILEINFOA lpProfileInfo)
Definition: profile.c:1811
LONG WINAPI RegFlushKey(HKEY hKey)
Definition: reg.c:2988
char * LPSTR
Definition: xmlstorage.h:182
BOOL WINAPI ConvertSidToStringSidW(PSID Sid, LPWSTR *StringSid)
Definition: security.c:3259
#define LookupPrivilegeValue
Definition: winbase.h:3684
BOOL CreateUserHive(LPCWSTR lpKeyName, LPCWSTR lpProfilePath)
Definition: registry.c:279
int32_t INT
Definition: typedefs.h:56
BOOL WINAPI UnloadUserProfile(_In_ HANDLE hToken, _In_ HANDLE hProfile)
Definition: profile.c:2101
LPWSTR lpDefaultPath
Definition: userenv.h:40
STRSAFEAPI StringCbCatW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:342
#define _In_opt_
Definition: no_sal2.h:213
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:1094
LPWSTR lpUserName
Definition: userenv.h:38
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
DWORD dwHighDateTime
Definition: mapidefs.h:66
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63
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
BOOL CopyDirectory(LPCWSTR lpDestinationPath, LPCWSTR lpSourcePath)
Definition: directory.c:82
static DWORD CheckForGuestsAndAdmins(_In_ HANDLE hToken, _Out_ PDWORD pdwState)
Definition: profile.c:353
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
HANDLE WINAPI GetCurrentThread(VOID)
Definition: proc.c:1178
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
static BOOL AcquireRemoveRestorePrivilege(IN BOOL bAcquire)
Definition: profile.c:64
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:802
PVOID WINAPI FreeSid(PSID pSid)
Definition: security.c:577
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
BOOL WINAPI DeleteProfileW(_In_ LPCWSTR lpSidString, _In_opt_ LPCWSTR lpProfilePath, _In_opt_ LPCWSTR lpComputerName)
Definition: profile.c:1175
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:173
smooth NULL
Definition: ftsmooth.c:416
#define _Out_
Definition: no_sal2.h:323
void DPRINT(...)
Definition: polytest.cpp:61
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
const char * LPCSTR
Definition: xmlstorage.h:183
HANDLE hMutex
Definition: mutex.c:11
BOOL WINAPI GetProfilesDirectoryW(_Out_ LPWSTR lpProfilesDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1493
_CRTIMP wchar_t *__cdecl _wcsupr(_Inout_z_ wchar_t *_String)
struct _TOKEN_GROUPS * PTOKEN_GROUPS
LPWSTR lpServerName
Definition: userenv.h:41
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_WRITE
Definition: nt_native.h:1031
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:4917
#define _Out_opt_
Definition: no_sal2.h:339
BOOL WINAPI CopySystemProfile(_In_ ULONG Unused)
Definition: profile.c:565
static DWORD SetProfileData(_In_ PWSTR pszSidString, _In_ DWORD dwFlags, _In_ HANDLE hToken)
Definition: profile.c:453
LPWSTR lpPolicyPath
Definition: userenv.h:42
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define SECURITY_BUILTIN_DOMAIN_RID
Definition: setypes.h:553
#define TOKEN_QUERY
Definition: setypes.h:874
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4134
BOOL WINAPI GetUserProfileDirectoryA(_In_ HANDLE hToken, _Out_opt_ LPSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1667
__wchar_t WCHAR
Definition: xmlstorage.h:180
static DWORD DWORD * dwLength
Definition: fusion.c:83
DWORD WINAPI GetLengthSid(PSID pSid)
Definition: security.c:798
LONG WINAPI RegUnLoadKeyW(HKEY hKey, LPCWSTR lpSubKey)
Definition: reg.c:5114
HANDLE WINAPI GetCurrentProcess(VOID)
Definition: proc.c:1168
#define MAX_PATH
Definition: compat.h:26
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define WINAPI
Definition: msvc.h:8
static HANDLE CreateProfileMutex(_In_ PWSTR pszSidString)
Definition: profile.c:148
BOOL WINAPI CreateUserProfileA(_In_ PSID pSid, _In_ LPCSTR lpUserName)
Definition: profile.c:708
unsigned long DWORD
Definition: ntddk_ex.h:95
static BOOL CheckForLoadedProfile(HANDLE hToken)
Definition: profile.c:111
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
BOOL Error
Definition: chkdsk.c:66
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
#define SetLastError(x)
Definition: compat.h:409
#define _Inout_
Definition: no_sal2.h:244
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
DWORD dwSize
Definition: userenv.h:36
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseMutex(IN HANDLE hMutex)
Definition: synch.c:564
static DWORD IncrementRefCount(PWSTR pszSidString, PDWORD pdwRefCount)
Definition: profile.c:202
int ret
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
#define SE_RESTORE_NAME
#define GMEM_FIXED
Definition: winbase.h:290
DWORD dwFlags
Definition: userenv.h:37
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
BOOL WINAPI GetDefaultUserProfileDirectoryA(_Out_opt_ LPSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1320
GLenum GLsizei len
Definition: glext.h:6722
#define ERROR_SHARING_VIOLATION
Definition: winerror.h:135
BOOL WINAPI AdjustTokenPrivileges(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength)
Definition: security.c:376
LPWSTR lpComputerName
Definition: eventvwr.c:91
#define _In_
Definition: no_sal2.h:204
BOOL WINAPI OpenThreadToken(HANDLE ThreadHandle, DWORD DesiredAccess, BOOL OpenAsSelf, HANDLE *TokenHandle)
Definition: security.c:338
LPWSTR lpProfilePath
Definition: userenv.h:39
LPVOID lpSecurityDescriptor
Definition: compat.h:181
BOOL WINAPI GetAllUsersProfileDirectoryW(_Out_opt_ LPWSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1227
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]
Definition: setypes.h:964
HANDLE WINAPI DECLSPEC_HOTPATCH CreateMutexW(IN LPSECURITY_ATTRIBUTES lpMutexAttributes OPTIONAL, IN BOOL bInitialOwner, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:522
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
BOOL WINAPI GetProfileType(_Out_ PDWORD pdwFlags)
Definition: profile.c:1566
BOOL WINAPI SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, BOOL bDaclPresent, PACL pDacl, BOOL bDaclDefaulted)
Definition: sec.c:262
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:296
static PSID pSid
Definition: security.c:74
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
BOOL WINAPI GetAllUsersProfileDirectoryA(_Out_opt_ LPSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1187
DWORD * PDWORD
Definition: pedump.c:68
static DWORD DecrementRefCount(PWSTR pszSidString, PDWORD pdwRefCount)
Definition: profile.c:275
#define MultiByteToWideChar
Definition: compat.h:100
LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]
Definition: setypes.h:970
#define DPRINT1
Definition: precomp.h:8
#define ERROR_NOT_ALL_ASSIGNED
Definition: winerror.h:782
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
PSID WINAPI GetUserSid(HANDLE hToken)
Definition: sid.c:36
$ULONG GroupCount
Definition: setypes.h:960
uint32_t * LPDWORD
Definition: typedefs.h:57
BOOL WINAPI LoadUserProfileW(_In_ HANDLE hToken, _Inout_ LPPROFILEINFOW lpProfileInfo)
Definition: profile.c:1922
unsigned int ULONG
Definition: retypes.h:1
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:413
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3381
struct _TOKEN_USER * PTOKEN_USER
SID_AND_ATTRIBUTES User
Definition: setypes.h:956
char * cleanup(char *str)
Definition: wpickclick.c:99
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define INFINITE
Definition: serial.h:102
STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:166
#define REG_DWORD
Definition: sdbapi.c:596
#define TOKEN_ADJUST_PRIVILEGES
Definition: setypes.h:876
#define DOMAIN_ALIAS_RID_ADMINS
Definition: setypes.h:624
BYTE * PBYTE
Definition: pedump.c:66
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:394
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
DWORD dwLowDateTime
Definition: mapidefs.h:65
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
LONG WINAPI RegLoadKeyW(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpFile)
Definition: reg.c:3116
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:553
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define REG_SZ
Definition: layer.c:22