ReactOS 0.4.15-dev-7918-g2a2556c
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 */
24static BOOL
25EnablePrivilege(LPCWSTR lpszPrivilegeName, BOOL bEnablePrivilege)
26{
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
45
46Quit:
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 */
57PSID
60{
62 PSID pSid;
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
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;
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 {
116 return NULL;
117 }
118
119 return pSid;
120}
121
123{
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}
PSID WINAPI GetUserSid(IN HANDLE hToken)
static BOOL EnablePrivilege(LPCWSTR lpszPrivilegeName, BOOL bEnablePrivilege)
#define SE_BACKUP_NAME
#define SE_RESTORE_NAME
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
BOOL WINAPI LookupPrivilegeValueW(LPCWSTR lpSystemName, LPCWSTR lpPrivilegeName, PLUID lpLuid)
Definition: misc.c:782
BOOL WINAPI AdjustTokenPrivileges(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength)
Definition: security.c:374
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:411
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:294
BOOL WINAPI ConvertSidToStringSidW(PSID Sid, LPWSTR *StringSid)
Definition: security.c:3583
BOOL WINAPI CopySid(DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid)
Definition: security.c:712
DWORD WINAPI GetLengthSid(PSID pSid)
Definition: security.c:919
BOOL WINAPI OpenThreadToken(HANDLE ThreadHandle, DWORD DesiredAccess, BOOL OpenAsSelf, HANDLE *TokenHandle)
Definition: security.c:336
#define CloseHandle
Definition: compat.h:739
#define GetCurrentProcess()
Definition: compat.h:759
BOOL WINAPI LoadUserProfileW(_In_ HANDLE hToken, _Inout_ LPPROFILEINFOW lpProfileInfo)
Definition: profile.c:2005
BOOL WINAPI UnloadUserProfile(_In_ HANDLE hToken, _In_ HANDLE hProfile)
Definition: profile.c:2184
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
Definition: btrfs.c:2996
@ Success
Definition: eventcreate.c:712
unsigned int BOOL
Definition: ntddk_ex.h:94
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
HLOCAL NTAPI LocalReAlloc(HLOCAL hMem, SIZE_T dwBytes, UINT uFlags)
Definition: heapmem.c:1625
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
static PSID pSid
Definition: security.c:74
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
DWORD dwFlags
Definition: userenv.h:37
DWORD dwSize
Definition: userenv.h:36
LPWSTR lpUserName
Definition: userenv.h:38
SID_AND_ATTRIBUTES User
Definition: setypes.h:1010
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define LoadUserProfile
Definition: userenv.h:216
#define PI_NOUI
Definition: userenv.h:8
#define LMEM_MOVEABLE
Definition: winbase.h:369
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1148
#define LPTR
Definition: winbase.h:381
#define WINAPI
Definition: msvc.h:6
#define ERROR_NO_TOKEN
Definition: winerror.h:587
#define TOKEN_DUPLICATE
Definition: setypes.h:926
#define TOKEN_ADJUST_PRIVILEGES
Definition: setypes.h:930
#define TOKEN_QUERY
Definition: setypes.h:928
@ TokenUser
Definition: setypes.h:966
#define TOKEN_IMPERSONATE
Definition: setypes.h:927
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185