ReactOS  0.4.14-dev-52-g6116262
LoadUserProfile.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS api tests
3  * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4  * PURPOSE: Tests for Load/UnloadUserProfile
5  * PROGRAMMERS: Hermes Belusca-Maito
6  */
7 
8 #include <apitest.h>
9 // #include <windef.h>
10 // #include <winbase.h>
11 #include <sddl.h>
12 #include <userenv.h>
13 #include <strsafe.h>
14 
15 #undef SE_RESTORE_NAME
16 #undef SE_BACKUP_NAME
17 #define SE_RESTORE_NAME L"SeRestorePrivilege"
18 #define SE_BACKUP_NAME L"SeBackupPrivilege"
19 
20 /*
21  * Taken from dll/win32/shell32/dialogs/dialogs.cpp ;
22  * See also base/applications/shutdown/shutdown.c .
23  */
24 static BOOL
25 EnablePrivilege(LPCWSTR lpszPrivilegeName, BOOL bEnablePrivilege)
26 {
27  BOOL Success;
28  HANDLE hToken;
30 
33  &hToken);
34  if (!Success) return Success;
35 
37  lpszPrivilegeName,
38  &tp.Privileges[0].Luid);
39  if (!Success) goto Quit;
40 
41  tp.PrivilegeCount = 1;
42  tp.Privileges[0].Attributes = (bEnablePrivilege ? SE_PRIVILEGE_ENABLED : 0);
43 
44  Success = AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL);
45 
46 Quit:
47  CloseHandle(hToken);
48  return Success;
49 }
50 
51 /*
52  * Taken from dll/win32/userenv/sid.c .
53  * We cannot directly use the USERENV.DLL export, because: 1) it is exported
54  * by ordinal (#142), and: 2) it is simply not exported at all in Vista+
55  * (and ordinal #142 is assigned there to LoadUserProfileA).
56  */
57 PSID
58 WINAPI
60 {
61  BOOL Success;
62  PSID pSid;
63  ULONG Length;
64  PTOKEN_USER UserBuffer;
65  PTOKEN_USER TempBuffer;
66 
67  Length = 256;
68  UserBuffer = LocalAlloc(LPTR, Length);
69  if (UserBuffer == NULL)
70  return NULL;
71 
73  TokenUser,
74  (PVOID)UserBuffer,
75  Length,
76  &Length);
78  {
79  TempBuffer = LocalReAlloc(UserBuffer, Length, LMEM_MOVEABLE);
80  if (TempBuffer == NULL)
81  {
82  LocalFree(UserBuffer);
83  return NULL;
84  }
85 
86  UserBuffer = TempBuffer;
88  TokenUser,
89  (PVOID)UserBuffer,
90  Length,
91  &Length);
92  }
93 
94  if (!Success)
95  {
96  LocalFree(UserBuffer);
97  return NULL;
98  }
99 
100  Length = GetLengthSid(UserBuffer->User.Sid);
101 
103  if (pSid == NULL)
104  {
105  LocalFree(UserBuffer);
106  return NULL;
107  }
108 
109  Success = CopySid(Length, pSid, UserBuffer->User.Sid);
110 
111  LocalFree(UserBuffer);
112 
113  if (!Success)
114  {
115  LocalFree(pSid);
116  return NULL;
117  }
118 
119  return pSid;
120 }
121 
123 {
124  BOOL Success;
125  HANDLE hToken = NULL;
126  PSID pUserSid = NULL;
127  USHORT i;
128  PROFILEINFOW ProfileInfo[2] = { {0}, {0} };
129 
132  TRUE,
133  &hToken);
134  if (!Success && (GetLastError() == ERROR_NO_TOKEN))
135  {
136  trace("OpenThreadToken failed with error %lu, falling back to OpenProcessToken\n", GetLastError());
139  &hToken);
140  }
141  if (!Success || (hToken == NULL))
142  {
143  skip("Open[Thread|Process]Token failed with error %lu\n", GetLastError());
144  return;
145  }
146 
147  pUserSid = GetUserSid(hToken);
148  ok(pUserSid != NULL, "GetUserSid failed with error %lu\n", GetLastError());
149  if (pUserSid)
150  {
151  LPWSTR pSidStr = NULL;
152  Success = ConvertSidToStringSidW(pUserSid, &pSidStr);
153  ok(Success, "ConvertSidToStringSidW failed with error %lu\n", GetLastError());
154  if (Success)
155  {
156  trace("User SID is '%ls'\n", pSidStr);
157  LocalFree(pSidStr);
158  }
159  LocalFree(pUserSid);
160  pUserSid = NULL;
161  }
162  else
163  {
164  trace("No SID available!\n");
165  }
166 
167  /* Check whether ProfileInfo.lpUserName is really needed */
168  ZeroMemory(&ProfileInfo[0], sizeof(ProfileInfo[0]));
169  ProfileInfo[0].dwSize = sizeof(ProfileInfo[0]);
170  ProfileInfo[0].dwFlags = PI_NOUI;
171  ProfileInfo[0].lpUserName = NULL;
172  Success = LoadUserProfileW(hToken, &ProfileInfo[0]);
173  ok(!Success, "LoadUserProfile succeeded with error %lu, expected failing\n", GetLastError());
174  ok(ProfileInfo[0].hProfile == NULL, "ProfileInfo[0].hProfile != NULL, expected NULL\n");
175  /* Unload the user profile if we erroneously succeeded, just in case... */
176  if (Success)
177  {
178  trace("LoadUserProfileW(ProfileInfo[0]) unexpectedly succeeded, unload the user profile just in case...\n");
179  UnloadUserProfile(hToken, ProfileInfo[0].hProfile);
180  }
181 
182  /* TODO: Check which privileges we do need */
183 
184  /* Enable both the SE_RESTORE_NAME and SE_BACKUP_NAME privileges */
186  ok(Success, "EnablePrivilege(SE_RESTORE_NAME) failed with error %lu\n", GetLastError());
188  ok(Success, "EnablePrivilege(SE_BACKUP_NAME) failed with error %lu\n", GetLastError());
189 
190  /* Check whether we can load multiple times the same user profile */
191  for (i = 0; i < ARRAYSIZE(ProfileInfo); ++i)
192  {
193  ZeroMemory(&ProfileInfo[i], sizeof(ProfileInfo[i]));
194  ProfileInfo[i].dwSize = sizeof(ProfileInfo[i]);
195  ProfileInfo[i].dwFlags = PI_NOUI;
196  ProfileInfo[i].lpUserName = L"toto"; // Dummy name; normally this should be the user name...
197  Success = LoadUserProfileW(hToken, &ProfileInfo[i]);
198  ok(Success, "LoadUserProfileW(ProfileInfo[%d]) failed with error %lu\n", i, GetLastError());
199  ok(ProfileInfo[i].hProfile != NULL, "ProfileInfo[%d].hProfile == NULL\n", i);
200  trace("ProfileInfo[%d].hProfile = 0x%p\n", i, ProfileInfo[i].hProfile);
201  }
202 
203  i = ARRAYSIZE(ProfileInfo);
204  while (i-- > 0)
205  {
206  trace("UnloadUserProfile(ProfileInfo[%d].hProfile)\n", i);
207  Success = UnloadUserProfile(hToken, ProfileInfo[i].hProfile);
208  ok(Success, "UnloadUserProfile(ProfileInfo[%d].hProfile) failed with error %lu\n", i, GetLastError());
209  }
210 
211  /* Disable the privileges */
214 
215  /* Final cleanup */
216  CloseHandle(hToken);
217 }
#define IN
Definition: typedefs.h:38
static BOOL EnablePrivilege(LPCWSTR lpszPrivilegeName, BOOL bEnablePrivilege)
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
BOOL WINAPI LookupPrivilegeValueW(LPCWSTR lpSystemName, LPCWSTR lpPrivilegeName, PLUID lpLuid)
Definition: misc.c:782
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define SE_BACKUP_NAME
PSID WINAPI GetUserSid(IN HANDLE hToken)
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1635
#define TOKEN_IMPERSONATE
Definition: setypes.h:873
BOOL WINAPI ConvertSidToStringSidW(PSID Sid, LPWSTR *StringSid)
Definition: security.c:3259
BOOL WINAPI UnloadUserProfile(_In_ HANDLE hToken, _In_ HANDLE hProfile)
Definition: profile.c:2101
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
HANDLE WINAPI GetCurrentThread(VOID)
Definition: proc.c:1148
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
#define LoadUserProfile
Definition: userenv.h:216
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
Definition: btrfs.c:2883
#define trace
Definition: atltest.h:70
#define TOKEN_QUERY
Definition: setypes.h:874
DWORD WINAPI GetLengthSid(PSID pSid)
Definition: security.c:798
HANDLE WINAPI GetCurrentProcess(VOID)
Definition: proc.c:1138
#define WINAPI
Definition: msvc.h:8
#define LMEM_MOVEABLE
Definition: winbase.h:350
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
DWORD dwSize
Definition: userenv.h:36
#define TOKEN_DUPLICATE
Definition: setypes.h:872
static const WCHAR L[]
Definition: oid.c:1250
#define SE_RESTORE_NAME
DWORD dwFlags
Definition: userenv.h:37
BOOL WINAPI AdjustTokenPrivileges(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength)
Definition: security.c:376
#define ERROR_NO_TOKEN
Definition: winerror.h:587
BOOL WINAPI OpenThreadToken(HANDLE ThreadHandle, DWORD DesiredAccess, BOOL OpenAsSelf, HANDLE *TokenHandle)
Definition: security.c:338
HLOCAL NTAPI LocalReAlloc(HLOCAL hMem, SIZE_T dwBytes, UINT uFlags)
Definition: heapmem.c:1608
unsigned short USHORT
Definition: pedump.c:61
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1577
#define PI_NOUI
Definition: userenv.h:8
#define ok(value,...)
Definition: atltest.h:57
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:296
static PSID pSid
Definition: security.c:74
#define skip(...)
Definition: atltest.h:64
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
#define LPTR
Definition: winbase.h:362
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1373
WCHAR * LPWSTR
Definition: xmlstorage.h:184
BOOL WINAPI CopySid(DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid)
Definition: security.c:591
#define TOKEN_ADJUST_PRIVILEGES
Definition: setypes.h:876
START_TEST(LoadUserProfile)
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10