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
10 // #include <winbase.h>
15 #undef SE_RESTORE_NAME
17 #define SE_RESTORE_NAME L"SeRestorePrivilege"
18 #define SE_BACKUP_NAME L"SeBackupPrivilege"
21 * Taken from dll/win32/shell32/dialogs/dialogs.cpp ;
22 * See also base/applications/shutdown/shutdown.c .
25 EnablePrivilege(LPCWSTR lpszPrivilegeName
, BOOL bEnablePrivilege
)
31 Success
= OpenProcessToken(GetCurrentProcess(),
32 TOKEN_ADJUST_PRIVILEGES
,
34 if (!Success
) return Success
;
36 Success
= LookupPrivilegeValueW(NULL
,
38 &tp
.Privileges
[0].Luid
);
39 if (!Success
) goto Quit
;
41 tp
.PrivilegeCount
= 1;
42 tp
.Privileges
[0].Attributes
= (bEnablePrivilege
? SE_PRIVILEGE_ENABLED
: 0);
44 Success
= AdjustTokenPrivileges(hToken
, FALSE
, &tp
, 0, NULL
, NULL
);
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).
59 GetUserSid(IN HANDLE hToken
)
64 PTOKEN_USER UserBuffer
;
65 PTOKEN_USER TempBuffer
;
68 UserBuffer
= LocalAlloc(LPTR
, Length
);
69 if (UserBuffer
== NULL
)
72 Success
= GetTokenInformation(hToken
,
77 if (!Success
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
))
79 TempBuffer
= LocalReAlloc(UserBuffer
, Length
, LMEM_MOVEABLE
);
80 if (TempBuffer
== NULL
)
82 LocalFree(UserBuffer
);
86 UserBuffer
= TempBuffer
;
87 Success
= GetTokenInformation(hToken
,
96 LocalFree(UserBuffer
);
100 Length
= GetLengthSid(UserBuffer
->User
.Sid
);
102 pSid
= LocalAlloc(LPTR
, Length
);
105 LocalFree(UserBuffer
);
109 Success
= CopySid(Length
, pSid
, UserBuffer
->User
.Sid
);
111 LocalFree(UserBuffer
);
122 START_TEST(LoadUserProfile
)
125 HANDLE hToken
= NULL
;
126 PSID pUserSid
= NULL
;
128 PROFILEINFOW ProfileInfo
[2] = { {0}, {0} };
130 Success
= OpenThreadToken(GetCurrentThread(),
131 TOKEN_QUERY
| TOKEN_IMPERSONATE
| TOKEN_DUPLICATE
,
134 if (!Success
&& (GetLastError() == ERROR_NO_TOKEN
))
136 trace("OpenThreadToken failed with error %lu, falling back to OpenProcessToken\n", GetLastError());
137 Success
= OpenProcessToken(GetCurrentProcess(),
138 TOKEN_QUERY
| TOKEN_IMPERSONATE
| TOKEN_DUPLICATE
,
141 if (!Success
|| (hToken
== NULL
))
143 skip("Open[Thread|Process]Token failed with error %lu\n", GetLastError());
147 pUserSid
= GetUserSid(hToken
);
148 ok(pUserSid
!= NULL
, "GetUserSid failed with error %lu\n", GetLastError());
151 LPWSTR pSidStr
= NULL
;
152 Success
= ConvertSidToStringSidW(pUserSid
, &pSidStr
);
153 ok(Success
, "ConvertSidToStringSidW failed with error %lu\n", GetLastError());
156 trace("User SID is '%ls'\n", pSidStr
);
164 trace("No SID available!\n");
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... */
178 trace("LoadUserProfileW(ProfileInfo[0]) unexpectedly succeeded, unload the user profile just in case...\n");
179 UnloadUserProfile(hToken
, ProfileInfo
[0].hProfile
);
182 /* TODO: Check which privileges we do need */
184 /* Enable both the SE_RESTORE_NAME and SE_BACKUP_NAME privileges */
185 Success
= EnablePrivilege(SE_RESTORE_NAME
, TRUE
);
186 ok(Success
, "EnablePrivilege(SE_RESTORE_NAME) failed with error %lu\n", GetLastError());
187 Success
= EnablePrivilege(SE_BACKUP_NAME
, TRUE
);
188 ok(Success
, "EnablePrivilege(SE_BACKUP_NAME) failed with error %lu\n", GetLastError());
190 /* Check whether we can load multiple times the same user profile */
191 for (i
= 0; i
< ARRAYSIZE(ProfileInfo
); ++i
)
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
);
203 i
= ARRAYSIZE(ProfileInfo
);
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());
211 /* Disable the privileges */
212 EnablePrivilege(SE_BACKUP_NAME
, FALSE
);
213 EnablePrivilege(SE_RESTORE_NAME
, FALSE
);