ReactOS  0.4.12-dev-712-ge6be187
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 /* PUBLIC FUNCTIONS ********************************************************/
147 
148 BOOL
149 WINAPI
151  _In_ ULONG Unused)
152 {
153  WCHAR szKeyName[MAX_PATH];
154  WCHAR szRawProfilePath[MAX_PATH];
155  WCHAR szProfilePath[MAX_PATH];
156  WCHAR szDefaultProfilePath[MAX_PATH];
157  UNICODE_STRING SidString = {0, 0, NULL};
158  HANDLE hToken = NULL;
159  PSID pUserSid = NULL;
160  HKEY hProfileKey = NULL;
161  DWORD dwDisposition;
162  BOOL bResult = FALSE;
163  DWORD cchSize;
164  DWORD dwError;
165 
166  DPRINT1("CopySystemProfile()\n");
167 
170  &hToken))
171  {
172  DPRINT1("Failed to open the process token (Error %lu)\n", GetLastError());
173  return FALSE;
174  }
175 
176  pUserSid = GetUserSid(hToken);
177  if (pUserSid == NULL)
178  {
179  DPRINT1("Failed to get the users SID (Error %lu)\n", GetLastError());
180  goto done;
181  }
182 
183  /* Get the user SID string */
184  if (!GetUserSidStringFromToken(hToken, &SidString))
185  {
186  DPRINT1("GetUserSidStringFromToken() failed\n");
187  goto done;
188  }
189 
190  StringCbCopyW(szKeyName, sizeof(szKeyName),
191  L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
192  StringCbCatW(szKeyName, sizeof(szKeyName), SidString.Buffer);
193 
194  RtlFreeUnicodeString(&SidString);
195 
197  szKeyName,
198  0, NULL, 0,
199  KEY_WRITE,
200  NULL,
201  &hProfileKey,
202  &dwDisposition);
203  if (dwError != ERROR_SUCCESS)
204  {
205  DPRINT1("Failed to create the profile key for the %s profile (Error %lu)\n",
206  SidString.Buffer, dwError);
207  goto done;
208  }
209 
210  dwError = RegSetValueExW(hProfileKey,
211  L"Sid",
212  0,
213  REG_BINARY,
214  (PBYTE)pUserSid,
215  RtlLengthSid(pUserSid));
216  if (dwError != ERROR_SUCCESS)
217  {
218  DPRINT1("Failed to set the SID value (Error %lu)\n", dwError);
219  goto done;
220  }
221 
222  wcscpy(szRawProfilePath,
223  L"%systemroot%\\system32\\config\\systemprofile");
224 
225  dwError = RegSetValueExW(hProfileKey,
226  L"ProfileImagePath",
227  0,
229  (PBYTE)szRawProfilePath,
230  (wcslen(szRawProfilePath) + 1) * sizeof(WCHAR));
231  if (dwError != ERROR_SUCCESS)
232  {
233  DPRINT1("Failed to set the ProfileImagePath value (Error %lu)\n", dwError);
234  goto done;
235  }
236 
237  /* Expand the raw profile path */
238  if (!ExpandEnvironmentStringsW(szRawProfilePath,
239  szProfilePath,
240  ARRAYSIZE(szProfilePath)))
241  {
242  DPRINT1("Failled to expand the raw profile path (Error %lu)\n", GetLastError());
243  goto done;
244  }
245 
246  /* Create the profile directory if it does not exist yet */
247  // FIXME: Security!
248  if (!CreateDirectoryW(szProfilePath, NULL))
249  {
251  {
252  DPRINT1("Failed to create the profile directory (Error %lu)\n", GetLastError());
253  goto done;
254  }
255  }
256 
257  /* Get the path of the default profile */
258  cchSize = ARRAYSIZE(szDefaultProfilePath);
259  if (!GetDefaultUserProfileDirectoryW(szDefaultProfilePath, &cchSize))
260  {
261  DPRINT1("Failed to create the default profile path (Error %lu)\n", GetLastError());
262  goto done;
263  }
264 
265  /* Copy the default profile into the new profile directory */
266  // FIXME: Security!
267  if (!CopyDirectory(szProfilePath, szDefaultProfilePath))
268  {
269  DPRINT1("Failed to copy the default profile directory (Error %lu)\n", GetLastError());
270  goto done;
271  }
272 
273  bResult = TRUE;
274 
275 done:
276  if (hProfileKey != NULL)
277  RegCloseKey(hProfileKey);
278 
279  RtlFreeUnicodeString(&SidString);
280 
281  if (pUserSid != NULL)
282  LocalFree(pUserSid);
283 
284  if (hToken != NULL)
285  CloseHandle(hToken);
286 
287  return bResult;
288 }
289 
290 
291 BOOL
292 WINAPI
294  _In_ PSID pSid,
295  _In_ LPCSTR lpUserName)
296 {
297  LPWSTR pUserNameW = NULL;
298  INT nLength;
299  BOOL bResult;
300 
301  DPRINT("CreateUserProfileA(%p %s)\n", pSid, lpUserName);
302 
303  /* Convert lpUserName to Unicode */
304  nLength = MultiByteToWideChar(CP_ACP, 0, lpUserName, -1, NULL, 0);
305  pUserNameW = HeapAlloc(GetProcessHeap(), 0, nLength * sizeof(WCHAR));
306  if (pUserNameW == NULL)
307  {
309  return FALSE;
310  }
311  MultiByteToWideChar(CP_ACP, 0, lpUserName, -1, pUserNameW, nLength);
312 
313  /* Call the Ex function */
314  bResult = CreateUserProfileExW(pSid,
315  pUserNameW,
316  NULL,
317  NULL,
318  0,
319  FALSE);
320 
321  HeapFree(GetProcessHeap(), 0, pUserNameW);
322 
323  return bResult;
324 }
325 
326 
327 BOOL
328 WINAPI
330  _In_ PSID pSid,
331  _In_ LPCWSTR lpUserName)
332 {
333  DPRINT("CreateUserProfileW(%p %S)\n", pSid, lpUserName);
334 
335  /* Call the Ex function */
336  return CreateUserProfileExW(pSid,
337  lpUserName,
338  NULL,
339  NULL,
340  0,
341  FALSE);
342 }
343 
344 
345 BOOL
346 WINAPI
348  _In_ PSID pSid,
349  _In_ LPCSTR lpUserName,
350  _In_opt_ LPCSTR lpUserHive,
351  _Out_opt_ LPSTR lpProfileDir,
352  _In_ DWORD dwDirSize,
353  _In_ BOOL bWin9xUpg)
354 {
355  LPWSTR pUserNameW = NULL;
356  LPWSTR pUserHiveW = NULL;
357  LPWSTR pProfileDirW = NULL;
358  INT nLength;
359  BOOL bResult = FALSE;
360 
361  DPRINT("CreateUserProfileExA(%p %s %s %p %lu %d)\n",
362  pSid, lpUserName, lpUserHive, lpProfileDir, dwDirSize, bWin9xUpg);
363 
364  /* Check the parameters */
365  if (lpProfileDir != NULL && dwDirSize == 0)
366  {
368  return FALSE;
369  }
370 
371  /* Convert lpUserName to Unicode */
372  nLength = MultiByteToWideChar(CP_ACP, 0, lpUserName, -1, NULL, 0);
373  pUserNameW = HeapAlloc(GetProcessHeap(), 0, nLength * sizeof(WCHAR));
374  if (pUserNameW == NULL)
375  {
377  goto done;
378  }
379  MultiByteToWideChar(CP_ACP, 0, lpUserName, -1, pUserNameW, nLength);
380 
381  /* Convert lpUserHive to Unicode */
382  if (lpUserHive != NULL)
383  {
384  nLength = MultiByteToWideChar(CP_ACP, 0, lpUserHive, -1, NULL, 0);
385  pUserHiveW = HeapAlloc(GetProcessHeap(), 0, nLength * sizeof(WCHAR));
386  if (pUserHiveW == NULL)
387  {
389  goto done;
390  }
391  MultiByteToWideChar(CP_ACP, 0, lpUserHive, -1, pUserHiveW, nLength);
392  }
393 
394  /* Allocate a Unicode buffer for lpProfileDir */
395  if (lpProfileDir != NULL)
396  {
397  pProfileDirW = HeapAlloc(GetProcessHeap(), 0, dwDirSize * sizeof(WCHAR));
398  if (pProfileDirW == NULL)
399  {
401  goto done;
402  }
403  }
404 
405  /* Call the Unicode function */
406  bResult = CreateUserProfileExW(pSid,
407  (LPCWSTR)pUserNameW,
408  (LPCWSTR)pUserHiveW,
409  pProfileDirW,
410  dwDirSize,
411  bWin9xUpg);
412 
413  /* Convert the profile path to ANSI */
414  if (bResult && lpProfileDir != NULL)
415  {
416  WideCharToMultiByte(CP_ACP, 0, pProfileDirW, -1, lpProfileDir, dwDirSize, NULL, NULL);
417  }
418 
419 done:
420  /* Free the buffers */
421  if (pProfileDirW != NULL)
422  HeapFree(GetProcessHeap(), 0, pProfileDirW);
423 
424  if (pUserHiveW != NULL)
425  HeapFree(GetProcessHeap(), 0, pUserHiveW);
426 
427  if (pUserNameW != NULL)
428  HeapFree(GetProcessHeap(), 0, pUserNameW);
429 
430  return bResult;
431 }
432 
433 
434 BOOL
435 WINAPI
437  _In_ PSID pSid,
438  _In_ LPCWSTR lpUserName,
439  _In_opt_ LPCWSTR lpUserHive,
440  _Out_opt_ LPWSTR lpProfileDir,
441  _In_ DWORD dwDirSize,
442  _In_ BOOL bWin9xUpg)
443 {
444  WCHAR szRawProfilesPath[MAX_PATH];
445  WCHAR szProfilesPath[MAX_PATH];
446  WCHAR szUserProfilePath[MAX_PATH];
447  WCHAR szDefaultUserPath[MAX_PATH];
448  WCHAR szUserProfileName[MAX_PATH];
449  WCHAR szBuffer[MAX_PATH];
450  LPWSTR SidString;
451  DWORD dwType, dwLength;
452  DWORD dwDisposition;
453  UINT i;
454  HKEY hKey;
455  BOOL bRet = TRUE;
456  LONG Error;
457 
458  DPRINT("CreateUserProfileExW(%p %S %S %p %lu %d)\n",
459  pSid, lpUserName, lpUserHive, lpProfileDir, dwDirSize, bWin9xUpg);
460 
461  /* Parameters validation */
462  if (!pSid || !lpUserName)
463  {
465  return FALSE;
466  }
467 
468  /*
469  * TODO:
470  * - Add support for lpUserHive.
471  * - bWin9xUpg is obsolete. Don't waste your time implementing this.
472  */
473 
475  L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
476  0,
478  &hKey);
479  if (Error != ERROR_SUCCESS)
480  {
481  DPRINT1("Error: %lu\n", Error);
483  return FALSE;
484  }
485 
486  /* Get profiles path */
487  dwLength = sizeof(szRawProfilesPath);
488  Error = RegQueryValueExW(hKey,
489  L"ProfilesDirectory",
490  NULL,
491  &dwType,
492  (LPBYTE)szRawProfilesPath,
493  &dwLength);
494  if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
495  {
496  DPRINT1("Error: %lu\n", Error);
497  RegCloseKey(hKey);
499  return FALSE;
500  }
501 
502  /* Expand it */
503  if (!ExpandEnvironmentStringsW(szRawProfilesPath,
504  szProfilesPath,
505  ARRAYSIZE(szProfilesPath)))
506  {
507  DPRINT1("Error: %lu\n", GetLastError());
508  RegCloseKey(hKey);
509  return FALSE;
510  }
511 
512  /* Create the profiles directory if it does not exist yet */
513  // FIXME: Security!
514  if (!CreateDirectoryW(szProfilesPath, NULL))
515  {
517  {
518  DPRINT1("Error: %lu\n", GetLastError());
519  return FALSE;
520  }
521  }
522 
523  /* Get default user path */
524  dwLength = sizeof(szBuffer);
525  Error = RegQueryValueExW(hKey,
526  L"DefaultUserProfile",
527  NULL,
528  &dwType,
529  (LPBYTE)szBuffer,
530  &dwLength);
531  if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
532  {
533  DPRINT1("Error: %lu\n", Error);
534  RegCloseKey(hKey);
536  return FALSE;
537  }
538 
539  RegCloseKey(hKey);
540 
541  StringCbCopyW(szUserProfileName, sizeof(szUserProfileName), lpUserName);
542 
543  /* Create user profile directory */
544 
545  StringCbCopyW(szUserProfilePath, sizeof(szUserProfilePath), szProfilesPath);
546  StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), L"\\");
547  StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), szUserProfileName);
548 
549  // FIXME: Security!
550  if (!CreateDirectoryW(szUserProfilePath, NULL))
551  {
553  {
554  DPRINT1("Error: %lu\n", GetLastError());
555  return FALSE;
556  }
557 
558  for (i = 0; i < 1000; i++)
559  {
560  swprintf(szUserProfileName, L"%s.%03u", lpUserName, i);
561 
562  StringCbCopyW(szUserProfilePath, sizeof(szUserProfilePath), szProfilesPath);
563  StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), L"\\");
564  StringCbCatW(szUserProfilePath, sizeof(szUserProfilePath), szUserProfileName);
565 
566  // FIXME: Security!
567  if (CreateDirectoryW(szUserProfilePath, NULL))
568  break;
569 
571  {
572  DPRINT1("Error: %lu\n", GetLastError());
573  return FALSE;
574  }
575  }
576  }
577 
578  /* Copy default user directory */
579 
580  StringCbCopyW(szDefaultUserPath, sizeof(szDefaultUserPath), szProfilesPath);
581  StringCbCatW(szDefaultUserPath, sizeof(szDefaultUserPath), L"\\");
582  StringCbCatW(szDefaultUserPath, sizeof(szDefaultUserPath), szBuffer);
583 
584  // FIXME: Security!
585  if (!CopyDirectory(szUserProfilePath, szDefaultUserPath))
586  {
587  DPRINT1("Error: %lu\n", GetLastError());
588  return FALSE;
589  }
590 
591  /* Add profile to profile list */
593  &SidString))
594  {
595  DPRINT1("Error: %lu\n", GetLastError());
596  return FALSE;
597  }
598 
599  StringCbCopyW(szBuffer, sizeof(szBuffer),
600  L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
601  StringCbCatW(szBuffer, sizeof(szBuffer), SidString);
602 
603  /* Create user profile key */
605  szBuffer,
606  0,
607  NULL,
610  NULL,
611  &hKey,
612  &dwDisposition);
613  if (Error != ERROR_SUCCESS)
614  {
615  DPRINT1("Error: %lu\n", Error);
616  bRet = FALSE;
617  goto done;
618  }
619 
620  /* Create non-expanded user profile path */
621  StringCbCopyW(szBuffer, sizeof(szBuffer), szRawProfilesPath);
622  StringCbCatW(szBuffer, sizeof(szBuffer), L"\\");
623  StringCbCatW(szBuffer, sizeof(szBuffer), szUserProfileName);
624 
625  /* Set 'ProfileImagePath' value (non-expanded) */
626  Error = RegSetValueExW(hKey,
627  L"ProfileImagePath",
628  0,
630  (LPBYTE)szBuffer,
631  (wcslen(szBuffer) + 1) * sizeof(WCHAR));
632  if (Error != ERROR_SUCCESS)
633  {
634  DPRINT1("Error: %lu\n", Error);
635  RegCloseKey(hKey);
636  bRet = FALSE;
637  goto done;
638  }
639 
640  /* Set 'Sid' value */
641  Error = RegSetValueExW(hKey,
642  L"Sid",
643  0,
644  REG_BINARY,
645  pSid,
646  GetLengthSid(pSid));
647  if (Error != ERROR_SUCCESS)
648  {
649  DPRINT1("Error: %lu\n", Error);
650  RegCloseKey(hKey);
651  bRet = FALSE;
652  goto done;
653  }
654 
655  RegCloseKey(hKey);
656 
657  /* Create user hive file */
658 
659  /* Use the default hive file name */
660  StringCbCopyW(szBuffer, sizeof(szBuffer), szUserProfilePath);
661  StringCbCatW(szBuffer, sizeof(szBuffer), L"\\ntuser.dat");
662 
663  /* Acquire restore privilege */
665  {
666  Error = GetLastError();
667  DPRINT1("Error: %lu\n", Error);
668  bRet = FALSE;
669  goto done;
670  }
671 
672  /* Load the user hive */
674  SidString,
675  szBuffer);
677  if (Error != ERROR_SUCCESS)
678  {
679  DPRINT1("Error: %lu\n", Error);
680  bRet = FALSE;
681  goto done;
682  }
683 
684  /* Initialize user hive */
685  if (!CreateUserHive(SidString, szUserProfilePath))
686  {
687  Error = GetLastError();
688  DPRINT1("Error: %lu\n", Error);
689  bRet = FALSE;
690  }
691 
692  /* Unload the hive */
694  RegUnLoadKeyW(HKEY_USERS, SidString);
696 
697  /*
698  * If the caller wants to retrieve the user profile path,
699  * give it now. 'dwDirSize' is the number of characters.
700  */
701  if (lpProfileDir && dwDirSize)
702  StringCchCopyW(lpProfileDir, dwDirSize, szUserProfilePath);
703 
704 done:
705  LocalFree((HLOCAL)SidString);
707 
708  DPRINT("CreateUserProfileExW() done\n");
709 
710  return bRet;
711 }
712 
713 
714 BOOL
715 WINAPI
717  _In_ LPCSTR lpSidString,
718  _In_opt_ LPCSTR lpProfilePath,
720 {
721  BOOL bResult;
722  UNICODE_STRING SidString, ProfilePath, ComputerName;
723 
724  DPRINT("DeleteProfileA() called\n");
725 
726  /* Conversion to UNICODE */
727  if (lpSidString)
729  (LPSTR)lpSidString);
730 
731  if (lpProfilePath)
733  (LPSTR)lpProfilePath);
734 
735  if (lpComputerName)
736  RtlCreateUnicodeStringFromAsciiz(&ComputerName,
738 
739  /* Call the UNICODE function */
740  bResult = DeleteProfileW(SidString.Buffer,
741  ProfilePath.Buffer,
742  ComputerName.Buffer);
743 
744  /* Memory cleanup */
745  if (lpSidString)
746  RtlFreeUnicodeString(&SidString);
747 
748  if (lpProfilePath)
749  RtlFreeUnicodeString(&ProfilePath);
750 
751  if (lpComputerName)
752  RtlFreeUnicodeString(&ComputerName);
753 
754  return bResult;
755 }
756 
757 
758 BOOL
759 WINAPI
761  _In_ LPCWSTR lpSidString,
762  _In_opt_ LPCWSTR lpProfilePath,
764 {
765  DPRINT1("DeleteProfileW() not implemented!\n");
766  return FALSE;
767 }
768 
769 
770 BOOL
771 WINAPI
773  _Out_opt_ LPSTR lpProfileDir,
774  _Inout_ LPDWORD lpcchSize)
775 {
777  BOOL bResult;
778 
779  if (!lpcchSize)
780  {
782  return FALSE;
783  }
784 
786  *lpcchSize * sizeof(WCHAR));
787  if (lpBuffer == NULL)
788  return FALSE;
789 
791  lpcchSize);
792  if (bResult && lpProfileDir)
793  {
794  bResult = WideCharToMultiByte(CP_ACP,
795  0,
796  lpBuffer,
797  -1,
798  lpProfileDir,
799  *lpcchSize,
800  NULL,
801  NULL);
802  }
803 
805 
806  return bResult;
807 }
808 
809 
810 BOOL
811 WINAPI
813  _Out_opt_ LPWSTR lpProfileDir,
814  _Inout_ LPDWORD lpcchSize)
815 {
816  WCHAR szProfilePath[MAX_PATH];
817  WCHAR szBuffer[MAX_PATH];
818  DWORD dwType, dwLength;
819  HKEY hKey;
820  LONG Error;
821 
822  if (!lpcchSize)
823  {
825  return FALSE;
826  }
827 
829  L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
830  0,
832  &hKey);
833  if (Error != ERROR_SUCCESS)
834  {
835  DPRINT1("Error: %lu\n", Error);
837  return FALSE;
838  }
839 
840  /* Get profiles path */
841  dwLength = sizeof(szBuffer);
842  Error = RegQueryValueExW(hKey,
843  L"ProfilesDirectory",
844  NULL,
845  &dwType,
846  (LPBYTE)szBuffer,
847  &dwLength);
848  if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
849  {
850  DPRINT1("Error: %lu\n", Error);
851  RegCloseKey(hKey);
853  return FALSE;
854  }
855 
856  /* Expand it */
857  if (!ExpandEnvironmentStringsW(szBuffer,
858  szProfilePath,
859  ARRAYSIZE(szProfilePath)))
860  {
861  DPRINT1("Error: %lu\n", GetLastError());
862  RegCloseKey(hKey);
863  return FALSE;
864  }
865 
866  /* Get 'AllUsersProfile' name */
867  dwLength = sizeof(szBuffer);
868  Error = RegQueryValueExW(hKey,
869  L"AllUsersProfile",
870  NULL,
871  &dwType,
872  (LPBYTE)szBuffer,
873  &dwLength);
874  if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
875  {
876  DPRINT1("Error: %lu\n", Error);
877  RegCloseKey(hKey);
879  return FALSE;
880  }
881 
882  RegCloseKey(hKey);
883 
884  StringCbCatW(szProfilePath, sizeof(szProfilePath), L"\\");
885  StringCbCatW(szProfilePath, sizeof(szProfilePath), szBuffer);
886 
887  dwLength = wcslen(szProfilePath) + 1;
888  if (lpProfileDir && (*lpcchSize >= dwLength))
889  {
890  StringCchCopyW(lpProfileDir, *lpcchSize, szProfilePath);
891  *lpcchSize = dwLength;
892  return TRUE;
893  }
894  else // if (!lpProfileDir || (*lpcchSize < dwLength))
895  {
896  *lpcchSize = dwLength;
898  return FALSE;
899  }
900 }
901 
902 
903 BOOL
904 WINAPI
906  _Out_opt_ LPSTR lpProfileDir,
907  _Inout_ LPDWORD lpcchSize)
908 {
910  BOOL bResult;
911 
912  if (!lpcchSize)
913  {
915  return FALSE;
916  }
917 
919  *lpcchSize * sizeof(WCHAR));
920  if (lpBuffer == NULL)
921  return FALSE;
922 
924  lpcchSize);
925  if (bResult && lpProfileDir)
926  {
927  bResult = WideCharToMultiByte(CP_ACP,
928  0,
929  lpBuffer,
930  -1,
931  lpProfileDir,
932  *lpcchSize,
933  NULL,
934  NULL);
935  }
936 
938 
939  return bResult;
940 }
941 
942 
943 BOOL
944 WINAPI
946  _Out_opt_ LPWSTR lpProfileDir,
947  _Inout_ LPDWORD lpcchSize)
948 {
949  WCHAR szProfilePath[MAX_PATH];
950  WCHAR szBuffer[MAX_PATH];
951  DWORD dwType, dwLength;
952  HKEY hKey;
953  LONG Error;
954 
955  if (!lpcchSize)
956  {
958  return FALSE;
959  }
960 
962  L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
963  0,
965  &hKey);
966  if (Error != ERROR_SUCCESS)
967  {
968  DPRINT1("Error: %lu\n", Error);
970  return FALSE;
971  }
972 
973  /* Get profiles path */
974  dwLength = sizeof(szBuffer);
975  Error = RegQueryValueExW(hKey,
976  L"ProfilesDirectory",
977  NULL,
978  &dwType,
979  (LPBYTE)szBuffer,
980  &dwLength);
981  if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
982  {
983  DPRINT1("Error: %lu\n", Error);
984  RegCloseKey(hKey);
986  return FALSE;
987  }
988 
989  /* Expand it */
990  if (!ExpandEnvironmentStringsW(szBuffer,
991  szProfilePath,
992  ARRAYSIZE(szProfilePath)))
993  {
994  DPRINT1("Error: %lu\n", GetLastError());
995  RegCloseKey(hKey);
996  return FALSE;
997  }
998 
999  /* Get 'DefaultUserProfile' name */
1000  dwLength = sizeof(szBuffer);
1001  Error = RegQueryValueExW(hKey,
1002  L"DefaultUserProfile",
1003  NULL,
1004  &dwType,
1005  (LPBYTE)szBuffer,
1006  &dwLength);
1007  if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
1008  {
1009  DPRINT1("Error: %lu\n", Error);
1010  RegCloseKey(hKey);
1012  return FALSE;
1013  }
1014 
1015  RegCloseKey(hKey);
1016 
1017  StringCbCatW(szProfilePath, sizeof(szProfilePath), L"\\");
1018  StringCbCatW(szProfilePath, sizeof(szProfilePath), szBuffer);
1019 
1020  dwLength = wcslen(szProfilePath) + 1;
1021  if (lpProfileDir && (*lpcchSize >= dwLength))
1022  {
1023  StringCchCopyW(lpProfileDir, *lpcchSize, szProfilePath);
1024  *lpcchSize = dwLength;
1025  return TRUE;
1026  }
1027  else // if (!lpProfileDir || (*lpcchSize < dwLength))
1028  {
1029  *lpcchSize = dwLength;
1031  return FALSE;
1032  }
1033 }
1034 
1035 
1036 BOOL
1037 WINAPI
1039  _Out_ LPSTR lpProfileDir, // _Out_opt_
1040  _Inout_ LPDWORD lpcchSize)
1041 {
1042  LPWSTR lpBuffer;
1043  BOOL bResult;
1044 
1045  if (!lpcchSize)
1046  {
1048  return FALSE;
1049  }
1050 
1052  *lpcchSize * sizeof(WCHAR));
1053  if (lpBuffer == NULL)
1054  return FALSE;
1055 
1056  bResult = GetProfilesDirectoryW(lpBuffer,
1057  lpcchSize);
1058  if (bResult && lpProfileDir)
1059  {
1060  bResult = WideCharToMultiByte(CP_ACP,
1061  0,
1062  lpBuffer,
1063  -1,
1064  lpProfileDir,
1065  *lpcchSize,
1066  NULL,
1067  NULL);
1068  }
1069 
1071 
1072  return bResult;
1073 }
1074 
1075 
1076 BOOL
1077 WINAPI
1079  _Out_ LPWSTR lpProfilesDir, // _Out_opt_
1080  _Inout_ LPDWORD lpcchSize)
1081 {
1082  WCHAR szProfilesPath[MAX_PATH];
1083  WCHAR szBuffer[MAX_PATH];
1084  DWORD dwType, dwLength;
1085  HKEY hKey;
1086  LONG Error;
1087 
1088  if (!lpcchSize)
1089  {
1091  return FALSE;
1092  }
1093 
1095  L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
1096  0,
1098  &hKey);
1099  if (Error != ERROR_SUCCESS)
1100  {
1101  DPRINT1("Error: %lu\n", Error);
1103  return FALSE;
1104  }
1105 
1106  /* Get profiles path */
1107  dwLength = sizeof(szBuffer);
1108  Error = RegQueryValueExW(hKey,
1109  L"ProfilesDirectory",
1110  NULL,
1111  &dwType,
1112  (LPBYTE)szBuffer,
1113  &dwLength);
1114  if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
1115  {
1116  DPRINT1("Error: %lu\n", Error);
1117  RegCloseKey(hKey);
1119  return FALSE;
1120  }
1121 
1122  RegCloseKey(hKey);
1123 
1124  /* Expand it */
1125  if (!ExpandEnvironmentStringsW(szBuffer,
1126  szProfilesPath,
1127  ARRAYSIZE(szProfilesPath)))
1128  {
1129  DPRINT1("Error: %lu\n", GetLastError());
1130  return FALSE;
1131  }
1132 
1133  dwLength = wcslen(szProfilesPath) + 1;
1134  if (lpProfilesDir && (*lpcchSize >= dwLength))
1135  {
1136  StringCchCopyW(lpProfilesDir, *lpcchSize, szProfilesPath);
1137  *lpcchSize = dwLength;
1138  return TRUE;
1139  }
1140  else // if (!lpProfilesDir || (*lpcchSize < dwLength))
1141  {
1142  *lpcchSize = dwLength;
1144  return FALSE;
1145  }
1146 }
1147 
1148 
1149 BOOL
1150 WINAPI
1152  _Out_ PDWORD pdwFlags)
1153 {
1154  DPRINT1("GetProfileType() not implemented!\n");
1155  return FALSE;
1156 }
1157 
1158 
1159 BOOL
1160 WINAPI
1162  _In_ HANDLE hToken,
1163  _Out_opt_ LPSTR lpProfileDir,
1164  _Inout_ LPDWORD lpcchSize)
1165 {
1166  LPWSTR lpBuffer;
1167  BOOL bResult;
1168 
1169  if (!lpcchSize)
1170  {
1172  return FALSE;
1173  }
1174 
1176  *lpcchSize * sizeof(WCHAR));
1177  if (lpBuffer == NULL)
1178  return FALSE;
1179 
1180  bResult = GetUserProfileDirectoryW(hToken,
1181  lpBuffer,
1182  lpcchSize);
1183  if (bResult && lpProfileDir)
1184  {
1185  bResult = WideCharToMultiByte(CP_ACP,
1186  0,
1187  lpBuffer,
1188  -1,
1189  lpProfileDir,
1190  *lpcchSize,
1191  NULL,
1192  NULL);
1193  }
1194 
1196 
1197  return bResult;
1198 }
1199 
1200 
1201 BOOL
1202 WINAPI
1204  _In_ HANDLE hToken,
1205  _Out_opt_ LPWSTR lpProfileDir,
1206  _Inout_ LPDWORD lpcchSize)
1207 {
1208  UNICODE_STRING SidString;
1209  WCHAR szKeyName[MAX_PATH];
1210  WCHAR szRawImagePath[MAX_PATH];
1211  WCHAR szImagePath[MAX_PATH];
1212  DWORD dwType, dwLength;
1213  HKEY hKey;
1214  LONG Error;
1215 
1216  if (!hToken)
1217  {
1219  return FALSE;
1220  }
1221 
1222  if (!lpcchSize)
1223  {
1225  return FALSE;
1226  }
1227 
1228  /* Get the user SID string */
1229  if (!GetUserSidStringFromToken(hToken, &SidString))
1230  {
1231  DPRINT1("GetUserSidStringFromToken() failed\n");
1232  return FALSE;
1233  }
1234 
1235  DPRINT("SidString: '%wZ'\n", &SidString);
1236 
1237  StringCbCopyW(szKeyName, sizeof(szKeyName),
1238  L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
1239  StringCbCatW(szKeyName, sizeof(szKeyName), SidString.Buffer);
1240 
1241  RtlFreeUnicodeString(&SidString);
1242 
1243  DPRINT("KeyName: '%S'\n", szKeyName);
1244 
1246  szKeyName,
1247  0,
1249  &hKey);
1250  if (Error != ERROR_SUCCESS)
1251  {
1252  DPRINT1("Error: %lu\n", Error);
1254  return FALSE;
1255  }
1256 
1257  dwLength = sizeof(szRawImagePath);
1258  Error = RegQueryValueExW(hKey,
1259  L"ProfileImagePath",
1260  NULL,
1261  &dwType,
1262  (LPBYTE)szRawImagePath,
1263  &dwLength);
1264  if ((Error != ERROR_SUCCESS) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
1265  {
1266  DPRINT1("Error: %lu\n", Error);
1267  RegCloseKey(hKey);
1269  return FALSE;
1270  }
1271 
1272  RegCloseKey(hKey);
1273 
1274  DPRINT("RawImagePath: '%S'\n", szRawImagePath);
1275 
1276  /* Expand it */
1277  if (!ExpandEnvironmentStringsW(szRawImagePath,
1278  szImagePath,
1279  ARRAYSIZE(szImagePath)))
1280  {
1281  DPRINT1("Error: %lu\n", GetLastError());
1282  return FALSE;
1283  }
1284 
1285  DPRINT("ImagePath: '%S'\n", szImagePath);
1286 
1287  dwLength = wcslen(szImagePath) + 1;
1288  if (lpProfileDir && (*lpcchSize >= dwLength))
1289  {
1290  StringCchCopyW(lpProfileDir, *lpcchSize, szImagePath);
1291  *lpcchSize = dwLength;
1292  return TRUE;
1293  }
1294  else // if (!lpProfileDir || (*lpcchSize < dwLength))
1295  {
1296  *lpcchSize = dwLength;
1298  return FALSE;
1299  }
1300 }
1301 
1302 
1303 BOOL
1304 WINAPI
1306  _In_ HANDLE hToken,
1307  _Inout_ LPPROFILEINFOA lpProfileInfo)
1308 {
1309  BOOL bResult = FALSE;
1310  PROFILEINFOW ProfileInfoW = {0};
1311  int len;
1312 
1313  DPRINT("LoadUserProfileA() called\n");
1314 
1315  /* Check profile info */
1316  if (!lpProfileInfo || (lpProfileInfo->dwSize != sizeof(PROFILEINFOA)) ||
1317  (lpProfileInfo->lpUserName == NULL) || (lpProfileInfo->lpUserName[0] == 0))
1318  {
1320  return FALSE;
1321  }
1322 
1323  /* Convert the structure to UNICODE... */
1324  ProfileInfoW.dwSize = sizeof(ProfileInfoW);
1325  ProfileInfoW.dwFlags = lpProfileInfo->dwFlags;
1326 
1327  if (lpProfileInfo->lpUserName)
1328  {
1329  len = MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpUserName, -1, NULL, 0);
1330  ProfileInfoW.lpUserName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1331  if (!ProfileInfoW.lpUserName)
1332  {
1334  goto cleanup;
1335  }
1336  MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpUserName, -1, ProfileInfoW.lpUserName, len);
1337  }
1338 
1339  if (lpProfileInfo->lpProfilePath)
1340  {
1341  len = MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpProfilePath, -1, NULL, 0);
1342  ProfileInfoW.lpProfilePath = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1343  if (!ProfileInfoW.lpProfilePath)
1344  {
1346  goto cleanup;
1347  }
1348  MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpProfilePath, -1, ProfileInfoW.lpProfilePath, len);
1349  }
1350 
1351  if (lpProfileInfo->lpDefaultPath)
1352  {
1353  len = MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpDefaultPath, -1, NULL, 0);
1354  ProfileInfoW.lpDefaultPath = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1355  if (!ProfileInfoW.lpDefaultPath)
1356  {
1358  goto cleanup;
1359  }
1360  MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpDefaultPath, -1, ProfileInfoW.lpDefaultPath, len);
1361  }
1362 
1363  if (lpProfileInfo->lpServerName)
1364  {
1365  len = MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpServerName, -1, NULL, 0);
1366  ProfileInfoW.lpServerName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1367  if (!ProfileInfoW.lpServerName)
1368  {
1370  goto cleanup;
1371  }
1372  MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpServerName, -1, ProfileInfoW.lpServerName, len);
1373  }
1374 
1375  if ((ProfileInfoW.dwFlags & PI_APPLYPOLICY) != 0 && lpProfileInfo->lpPolicyPath)
1376  {
1377  len = MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpPolicyPath, -1, NULL, 0);
1378  ProfileInfoW.lpPolicyPath = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1379  if (!ProfileInfoW.lpPolicyPath)
1380  {
1382  goto cleanup;
1383  }
1384  MultiByteToWideChar(CP_ACP, 0, lpProfileInfo->lpPolicyPath, -1, ProfileInfoW.lpPolicyPath, len);
1385  }
1386 
1387  /* ... and call the UNICODE function */
1388  bResult = LoadUserProfileW(hToken, &ProfileInfoW);
1389 
1390  /* Save the returned value */
1391  lpProfileInfo->hProfile = ProfileInfoW.hProfile;
1392 
1393 cleanup:
1394  /* Memory cleanup */
1395  if (ProfileInfoW.lpUserName)
1396  HeapFree(GetProcessHeap(), 0, ProfileInfoW.lpUserName);
1397 
1398  if (ProfileInfoW.lpProfilePath)
1399  HeapFree(GetProcessHeap(), 0, ProfileInfoW.lpProfilePath);
1400 
1401  if (ProfileInfoW.lpDefaultPath)
1402  HeapFree(GetProcessHeap(), 0, ProfileInfoW.lpDefaultPath);
1403 
1404  if (ProfileInfoW.lpServerName)
1405  HeapFree(GetProcessHeap(), 0, ProfileInfoW.lpServerName);
1406 
1407  if ((ProfileInfoW.dwFlags & PI_APPLYPOLICY) != 0 && ProfileInfoW.lpPolicyPath)
1408  HeapFree(GetProcessHeap(), 0, ProfileInfoW.lpPolicyPath);
1409 
1410  return bResult;
1411 }
1412 
1413 
1414 BOOL
1415 WINAPI
1417  _In_ HANDLE hToken,
1418  _Inout_ LPPROFILEINFOW lpProfileInfo)
1419 {
1420  WCHAR szUserHivePath[MAX_PATH];
1421  PTOKEN_USER UserSid = NULL;
1422  UNICODE_STRING SidString = { 0, 0, NULL };
1423  LONG Error;
1424  BOOL ret = FALSE;
1425  DWORD dwLength = sizeof(szUserHivePath) / sizeof(szUserHivePath[0]);
1426 
1427  DPRINT("LoadUserProfileW(%p %p)\n", hToken, lpProfileInfo);
1428 
1429  /* Check profile info */
1430  if (!lpProfileInfo || (lpProfileInfo->dwSize != sizeof(PROFILEINFOW)) ||
1431  (lpProfileInfo->lpUserName == NULL) || (lpProfileInfo->lpUserName[0] == 0))
1432  {
1434  return FALSE;
1435  }
1436 
1437  DPRINT("UserName: %S\n", lpProfileInfo->lpUserName);
1438 
1439  /* Don't load a profile twice */
1440  if (CheckForLoadedProfile(hToken))
1441  {
1442  DPRINT ("Profile already loaded\n");
1443  lpProfileInfo->hProfile = NULL;
1444  return TRUE;
1445  }
1446 
1447  if (lpProfileInfo->lpProfilePath)
1448  {
1449  /* Use the caller's specified roaming user profile path */
1450  StringCbCopyW(szUserHivePath, sizeof(szUserHivePath), lpProfileInfo->lpProfilePath);
1451  }
1452  else
1453  {
1454  /* FIXME: check if MS Windows allows lpProfileInfo->lpProfilePath to be NULL */
1455  if (!GetProfilesDirectoryW(szUserHivePath, &dwLength))
1456  {
1457  DPRINT1("GetProfilesDirectoryW() failed (error %ld)\n", GetLastError());
1458  return FALSE;
1459  }
1460  }
1461 
1462  /* Create user hive name */
1463  StringCbCatW(szUserHivePath, sizeof(szUserHivePath), L"\\");
1464  StringCbCatW(szUserHivePath, sizeof(szUserHivePath), lpProfileInfo->lpUserName);
1465  StringCbCatW(szUserHivePath, sizeof(szUserHivePath), L"\\ntuser.dat");
1466  DPRINT("szUserHivePath: %S\n", szUserHivePath);
1467 
1468  /* Create user profile directory if needed */
1469  if (GetFileAttributesW(szUserHivePath) == INVALID_FILE_ATTRIBUTES)
1470  {
1471  /* Get user sid */
1472  if (GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLength) ||
1474  {
1475  DPRINT1 ("GetTokenInformation() failed\n");
1476  return FALSE;
1477  }
1478 
1479  UserSid = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), 0, dwLength);
1480  if (!UserSid)
1481  {
1482  DPRINT1("HeapAlloc() failed\n");
1484  goto cleanup;
1485  }
1486 
1487  if (!GetTokenInformation(hToken, TokenUser, UserSid, dwLength, &dwLength))
1488  {
1489  DPRINT1("GetTokenInformation() failed\n");
1490  goto cleanup;
1491  }
1492 
1493  /* Create profile */
1494  ret = CreateUserProfileW(UserSid->User.Sid, lpProfileInfo->lpUserName);
1495  if (!ret)
1496  {
1497  DPRINT1("CreateUserProfileW() failed\n");
1498  goto cleanup;
1499  }
1500  }
1501 
1502  /* Get the user SID string */
1503  ret = GetUserSidStringFromToken(hToken, &SidString);
1504  if (!ret)
1505  {
1506  DPRINT1("GetUserSidStringFromToken() failed\n");
1507  goto cleanup;
1508  }
1509  ret = FALSE;
1510 
1511  /* Acquire restore privilege */
1513  {
1514  DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
1515  goto cleanup;
1516  }
1517 
1518  /* Load user registry hive */
1520  SidString.Buffer,
1521  szUserHivePath);
1523 
1524  /* HACK: Do not fail if the profile has already been loaded! */
1526  Error = ERROR_SUCCESS;
1527 
1528  if (Error != ERROR_SUCCESS)
1529  {
1530  DPRINT1("RegLoadKeyW() failed (Error %ld)\n", Error);
1532  goto cleanup;
1533  }
1534 
1535  /* Open future HKEY_CURRENT_USER */
1537  SidString.Buffer,
1538  0,
1540  (PHKEY)&lpProfileInfo->hProfile);
1541  if (Error != ERROR_SUCCESS)
1542  {
1543  DPRINT1("RegOpenKeyExW() failed (Error %ld)\n", Error);
1545  goto cleanup;
1546  }
1547 
1548  ret = TRUE;
1549 
1550 cleanup:
1551  HeapFree(GetProcessHeap(), 0, UserSid);
1552  RtlFreeUnicodeString(&SidString);
1553 
1554  DPRINT("LoadUserProfileW() done\n");
1555  return ret;
1556 }
1557 
1558 
1559 BOOL
1560 WINAPI
1562  _In_ HANDLE hToken,
1563  _In_ HANDLE hProfile)
1564 {
1565  UNICODE_STRING SidString;
1566  LONG Error;
1567 
1568  DPRINT("UnloadUserProfile() called\n");
1569 
1570  if (hProfile == NULL)
1571  {
1572  DPRINT1("Invalid profile handle\n");
1574  return FALSE;
1575  }
1576 
1577  RegCloseKey(hProfile);
1578 
1579  /* Get the user SID string */
1580  if (!GetUserSidStringFromToken(hToken, &SidString))
1581  {
1582  DPRINT1("GetUserSidStringFromToken() failed\n");
1583  return FALSE;
1584  }
1585 
1586  DPRINT("SidString: '%wZ'\n", &SidString);
1587 
1588  /* Acquire restore privilege */
1590  {
1591  DPRINT1("AcquireRemoveRestorePrivilege() failed (Error %ld)\n", GetLastError());
1592  RtlFreeUnicodeString(&SidString);
1593  return FALSE;
1594  }
1595 
1596  /* HACK */
1597  {
1598  HKEY hUserKey;
1599 
1601  SidString.Buffer,
1602  0,
1603  KEY_WRITE,
1604  &hUserKey);
1605  if (Error == ERROR_SUCCESS)
1606  {
1607  RegDeleteKeyW(hUserKey,
1608  L"Volatile Environment");
1609 
1610  RegCloseKey(hUserKey);
1611  }
1612  }
1613  /* End of HACK */
1614 
1615  /* Unload the hive */
1617  SidString.Buffer);
1618 
1619  /* Remove restore privilege */
1621 
1622  if (Error != ERROR_SUCCESS)
1623  {
1624  DPRINT1("RegUnLoadKeyW() failed (Error %ld)\n", Error);
1625  RtlFreeUnicodeString(&SidString);
1627  return FALSE;
1628  }
1629 
1630  RtlFreeUnicodeString(&SidString);
1631 
1632  DPRINT("UnloadUserProfile() done\n");
1633 
1634  return TRUE;
1635 }
1636 
1637 /* 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
BOOL WINAPI GetDefaultUserProfileDirectoryW(_Out_opt_ LPWSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:945
#define IN
Definition: typedefs.h:38
BOOL WINAPI CreateUserProfileW(_In_ PSID pSid, _In_ LPCWSTR lpUserName)
Definition: profile.c:329
#define TRUE
Definition: types.h:120
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
#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:1038
#define WideCharToMultiByte
Definition: compat.h:101
BOOL WINAPI GetUserProfileDirectoryW(_In_ HANDLE hToken, _Out_opt_ LPWSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1203
#define REG_BINARY
Definition: nt_native.h:1496
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:185
#define PI_APPLYPOLICY
Definition: userenv.h:9
#define CP_ACP
Definition: compat.h:99
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:347
#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
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#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:716
#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:1305
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:1561
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 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
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
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
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:760
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:163
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
BOOL WINAPI GetProfilesDirectoryW(_Out_ LPWSTR lpProfilesDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:1078
_CRTIMP wchar_t *__cdecl _wcsupr(_Inout_z_ wchar_t *_String)
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:150
LPWSTR lpPolicyPath
Definition: userenv.h:42
unsigned int BOOL
Definition: ntddk_ex.h:94
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#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:1161
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
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI CreateUserProfileA(_In_ PSID pSid, _In_ LPCSTR lpUserName)
Definition: profile.c:293
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
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
BOOL WINAPI GetDefaultUserProfileDirectoryA(_Out_opt_ LPSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:905
GLenum GLsizei len
Definition: glext.h:6722
#define ERROR_SHARING_VIOLATION
Definition: winerror.h:135
#define WINAPI
Definition: msvc.h:20
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
LPWSTR lpProfilePath
Definition: userenv.h:39
BOOL WINAPI GetAllUsersProfileDirectoryW(_Out_opt_ LPWSTR lpProfileDir, _Inout_ LPDWORD lpcchSize)
Definition: profile.c:812
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
_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:1151
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:772
DWORD * PDWORD
Definition: pedump.c:68
#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:436
PSID WINAPI GetUserSid(HANDLE hToken)
Definition: sid.c:36
uint32_t * LPDWORD
Definition: typedefs.h:57
BOOL WINAPI LoadUserProfileW(_In_ HANDLE hToken, _Inout_ LPPROFILEINFOW lpProfileInfo)
Definition: profile.c:1416
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
STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:166
#define TOKEN_ADJUST_PRIVILEGES
Definition: setypes.h:876
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
LONG WINAPI RegLoadKeyW(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpFile)
Definition: reg.c:3116
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define REG_SZ
Definition: layer.c:22