[EXPLORER] -Use WM_POPUPSYSTEMMENU to open the system menu of a window. CORE-13400
[reactos.git] / rostests / apitests / user32 / GetUserObjectInformation.c
1 /*
2 * PROJECT: ReactOS API tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test for GetUserObjectInformation
5 * PROGRAMMERS: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include <apitest.h>
9 #include <wingdi.h>
10 #include <winuser.h>
11 #include <ndk/mmfuncs.h>
12 #include <ndk/pstypes.h>
13 #include <strsafe.h>
14
15 static
16 BOOLEAN
17 CheckBuffer(
18 PVOID Buffer,
19 SIZE_T Size,
20 UCHAR Value)
21 {
22 PUCHAR Array = Buffer;
23 SIZE_T i;
24
25 for (i = 0; i < Size; i++)
26 if (Array[i] != Value)
27 {
28 trace("Expected %x, found %x at offset %lu\n", Value, Array[i], (ULONG)i);
29 return FALSE;
30 }
31 return TRUE;
32 }
33
34 static
35 PVOID
36 AllocateGuarded(
37 SIZE_T SizeRequested)
38 {
39 NTSTATUS Status;
40 SIZE_T Size = PAGE_ROUND_UP(SizeRequested + PAGE_SIZE);
41 PVOID VirtualMemory = NULL;
42 PCHAR StartOfBuffer;
43
44 Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_RESERVE, PAGE_NOACCESS);
45
46 if (!NT_SUCCESS(Status))
47 return NULL;
48
49 Size -= PAGE_SIZE;
50 if (Size)
51 {
52 Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_COMMIT, PAGE_READWRITE);
53 if (!NT_SUCCESS(Status))
54 {
55 Size = 0;
56 Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE);
57 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
58 return NULL;
59 }
60 }
61
62 StartOfBuffer = VirtualMemory;
63 StartOfBuffer += Size - SizeRequested;
64
65 return StartOfBuffer;
66 }
67
68 static
69 VOID
70 FreeGuarded(
71 PVOID Pointer)
72 {
73 NTSTATUS Status;
74 PVOID VirtualMemory = (PVOID)PAGE_ROUND_DOWN((SIZE_T)Pointer);
75 SIZE_T Size = 0;
76
77 Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE);
78 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status);
79 }
80
81 #define xok ok // Make the test succeed on Win2003
82 //#define xok(...) // This should make the test succeed on all Windows versions
83 #define NOTSET 1234
84
85 #define TestUserObjectInfo(Handle, Index, Buffer, Length, Ret, Error, LengthNeeded) do \
86 { \
87 DWORD _LengthNeeded = NOTSET; \
88 DECLSPEC_ALIGN(16) CHAR _LengthBuffer[2 * sizeof(DWORD)]; \
89 DWORD _Error; \
90 BOOL _Ret; \
91 \
92 SetLastError(0xdeadbeef); \
93 _Ret = GetUserObjectInformationW(Handle, Index, Buffer, Length, NULL); \
94 _Error = GetLastError(); \
95 ok(_Ret == (Ret), "Ret = %d\n", _Ret); \
96 xok(_Error == (Error), "Error = %lu\n", _Error); \
97 \
98 SetLastError(0xdeadbeef); \
99 _Ret = GetUserObjectInformationW(Handle, Index, Buffer, Length, &_LengthNeeded);\
100 _Error = GetLastError(); \
101 ok(_Ret == (Ret), "Ret = %d\n", _Ret); \
102 xok(_Error == (Error), "Error = %lu\n", _Error); \
103 xok(_LengthNeeded == (LengthNeeded), "LengthNeeded = %lu\n", _LengthNeeded); \
104 \
105 SetLastError(0xdeadbeef); \
106 *(PDWORD)&_LengthBuffer[1] = NOTSET; \
107 _Ret = GetUserObjectInformationW(Handle, Index, Buffer, Length, \
108 (PDWORD)&_LengthBuffer[1]); \
109 _Error = GetLastError(); \
110 ok(_Ret == (Ret), "Ret = %d\n", _Ret); \
111 xok(_Error == (Error), "Error = %lu\n", _Error); \
112 _LengthNeeded = *(PDWORD)&_LengthBuffer[1]; \
113 xok(_LengthNeeded == (LengthNeeded), "LengthNeeded = %lu\n", _LengthNeeded); \
114 \
115 SetLastError(0xdeadbeef); \
116 _Ret = GetUserObjectInformationW(Handle, Index, Buffer, Length, (PVOID)-4); \
117 _Error = GetLastError(); \
118 ok(_Ret == FALSE, "Ret = %d\n", _Ret); \
119 ok(_Error == ERROR_NOACCESS, "Error = %lu\n", _Error); \
120 } while (0)
121
122 #define TestUserObjectInfoWithString(Handle, Index, Buffer, BufferSize, String) do \
123 { \
124 BOOLEAN _Check; \
125 ULONG SizeOfString = wcslen(String) * sizeof(WCHAR) + sizeof(UNICODE_NULL); \
126 TestUserObjectInfo(Handle, Index, NULL, 0, FALSE, ERROR_INSUFFICIENT_BUFFER, SizeOfString); \
127 TestUserObjectInfo(Handle, Index, (PVOID)1, 0, FALSE, ERROR_INSUFFICIENT_BUFFER, SizeOfString); \
128 TestUserObjectInfo(Handle, Index, NULL, 1, FALSE, ERROR_NOACCESS, NOTSET); \
129 TestUserObjectInfo(Handle, Index, (PVOID)1, 1, FALSE, ERROR_NOACCESS, NOTSET); \
130 RtlFillMemory(Buffer, BufferSize, 0x55); \
131 TestUserObjectInfo(Handle, Index, Buffer, SizeOfString - 2, FALSE, ERROR_INSUFFICIENT_BUFFER, SizeOfString); \
132 _Check = CheckBuffer(Buffer, BufferSize, 0x55); \
133 ok(_Check == TRUE, "CheckBuffer failed\n"); \
134 RtlFillMemory(Buffer, BufferSize, 0x55); \
135 TestUserObjectInfo(Handle, Index, Buffer, SizeOfString - 1, FALSE, ERROR_INSUFFICIENT_BUFFER, SizeOfString); \
136 _Check = CheckBuffer(Buffer, BufferSize, 0x55); \
137 ok(_Check == TRUE, "CheckBuffer failed\n"); \
138 RtlFillMemory(Buffer, BufferSize, 0x55); \
139 Buffer[BufferSize / sizeof(WCHAR) - 1] = UNICODE_NULL; \
140 TestUserObjectInfo(Handle, Index, Buffer, SizeOfString, TRUE, 0xdeadbeef, SizeOfString); \
141 ok(wcscmp(Buffer, String) == 0, "Buffer '%ls', expected '%ls'\n", Buffer, String); \
142 _Check = CheckBuffer(Buffer + SizeOfString / sizeof(Buffer[0]), BufferSize - SizeOfString - sizeof(WCHAR), 0x55); \
143 ok(_Check == TRUE, "CheckBuffer failed\n"); \
144 RtlFillMemory(Buffer, BufferSize, 0x55); \
145 Buffer[BufferSize / sizeof(WCHAR) - 1] = UNICODE_NULL; \
146 TestUserObjectInfo(Handle, Index, Buffer, BufferSize, TRUE, 0xdeadbeef, SizeOfString); \
147 ok(wcscmp(Buffer, String) == 0, "Buffer '%ls', expected '%ls'\n", Buffer, String); \
148 _Check = CheckBuffer(Buffer + SizeOfString / sizeof(Buffer[0]), BufferSize - SizeOfString - sizeof(WCHAR), 0x55); \
149 ok(_Check == TRUE, "CheckBuffer failed\n"); \
150 } while (0)
151
152 static
153 void
154 TestGetUserObjectInfoW(void)
155 {
156 USEROBJECTFLAGS UserObjectFlags;
157 PWCHAR Buffer;
158 ULONG BufferSize = 64 * sizeof(WCHAR);
159 HDESK Desktop;
160 HDESK Desktop2;
161 HWINSTA WinSta;
162 HANDLE Token;
163 TOKEN_STATISTICS Statistics;
164 WCHAR WinStaName[64];
165 BOOL Success;
166 ULONG Length;
167
168 Buffer = AllocateGuarded(BufferSize);
169
170 TestUserObjectInfo(NULL, 5, NULL, 0, FALSE, ERROR_INVALID_HANDLE, 0);
171 TestUserObjectInfo(NULL, UOI_FLAGS, NULL, 0, FALSE, ERROR_INVALID_HANDLE, 0);
172 TestUserObjectInfo(NULL, UOI_FLAGS, (PVOID)1, 0, FALSE, ERROR_INVALID_HANDLE, 0);
173 TestUserObjectInfo(NULL, UOI_FLAGS, NULL, 1, FALSE, ERROR_NOACCESS, NOTSET);
174 TestUserObjectInfo(NULL, UOI_FLAGS, (PVOID)1, 1, FALSE, ERROR_NOACCESS, NOTSET);
175 TestUserObjectInfo(NULL, UOI_FLAGS, &UserObjectFlags, sizeof(UserObjectFlags), FALSE, ERROR_INVALID_HANDLE, 0);
176
177 TestUserObjectInfo(NULL, UOI_TYPE, NULL, 0, FALSE, ERROR_INVALID_HANDLE, 0);
178 TestUserObjectInfo(NULL, UOI_TYPE, (PVOID)1, 0, FALSE, ERROR_INVALID_HANDLE, 0);
179 TestUserObjectInfo(NULL, UOI_TYPE, NULL, 1, FALSE, ERROR_NOACCESS, NOTSET);
180 TestUserObjectInfo(NULL, UOI_TYPE, (PVOID)1, 1, FALSE, ERROR_NOACCESS, NOTSET);
181 TestUserObjectInfo(NULL, UOI_TYPE, Buffer, BufferSize, FALSE, ERROR_INVALID_HANDLE, 0);
182
183 TestUserObjectInfo(NULL, UOI_NAME, NULL, 0, FALSE, ERROR_INVALID_HANDLE, 0);
184 TestUserObjectInfo(NULL, UOI_NAME, (PVOID)1, 0, FALSE, ERROR_INVALID_HANDLE, 0);
185 TestUserObjectInfo(NULL, UOI_NAME, NULL, 1, FALSE, ERROR_NOACCESS, NOTSET);
186 TestUserObjectInfo(NULL, UOI_NAME, (PVOID)1, 1, FALSE, ERROR_NOACCESS, NOTSET);
187 TestUserObjectInfo(NULL, UOI_NAME, Buffer, BufferSize, FALSE, ERROR_INVALID_HANDLE, 0);
188
189 Desktop = GetThreadDesktop(GetCurrentThreadId());
190 if (!Desktop)
191 {
192 skip("Failed to get desktop handle\n");
193 FreeGuarded(Buffer);
194 return;
195 }
196
197 WinSta = GetProcessWindowStation();
198 if (!WinSta)
199 {
200 skip("Failed to get winsta handle\n");
201 FreeGuarded(Buffer);
202 return;
203 }
204
205 TestUserObjectInfo(Desktop, 5, NULL, 0, FALSE, ERROR_INVALID_PARAMETER, 0);
206 TestUserObjectInfo(Desktop, UOI_FLAGS, NULL, 0, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(USEROBJECTFLAGS));
207 TestUserObjectInfo(Desktop, UOI_FLAGS, (PVOID)1, 0, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(USEROBJECTFLAGS));
208 TestUserObjectInfo(Desktop, UOI_FLAGS, NULL, 1, FALSE, ERROR_NOACCESS, NOTSET);
209 TestUserObjectInfo(Desktop, UOI_FLAGS, (PVOID)1, 1, FALSE, ERROR_NOACCESS, NOTSET);
210 TestUserObjectInfo(Desktop, UOI_FLAGS, &UserObjectFlags, sizeof(UserObjectFlags), TRUE, 0xdeadbeef, sizeof(USEROBJECTFLAGS));
211
212 TestUserObjectInfoWithString(Desktop, UOI_TYPE, Buffer, BufferSize, L"Desktop");
213 TestUserObjectInfoWithString(Desktop, UOI_NAME, Buffer, BufferSize, L"Default");
214
215 TestUserObjectInfoWithString(WinSta, UOI_TYPE, Buffer, BufferSize, L"WindowStation");
216 TestUserObjectInfoWithString(WinSta, UOI_NAME, Buffer, BufferSize, L"WinSta0");
217
218 /* Autogenerated name will be Service-0x<luidhigh>-<luidlow>$ */
219 StringCbCopyW(WinStaName, sizeof(WinStaName), L"<failed>");
220 Success = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token);
221 ok(Success == TRUE, "OpenProcessToken failed with %lu\n", GetLastError());
222 if (Success)
223 {
224 Success = GetTokenInformation(Token,
225 TokenStatistics,
226 &Statistics,
227 sizeof(Statistics),
228 &Length);
229 ok(Success == TRUE, "GetTokenInformation failed with %lu\n", GetLastError());
230 if (Success)
231 {
232 StringCbPrintfW(WinStaName,
233 sizeof(WinStaName),
234 L"Service-0x%lx-%lx$",
235 Statistics.AuthenticationId.HighPart,
236 Statistics.AuthenticationId.LowPart);
237 trace("Expected autogenerated Winsta name: %ls\n", WinStaName);
238 }
239 CloseHandle(Token);
240 }
241
242 /* Create our own Winsta */
243 WinSta = CreateWindowStationW(NULL, 0, WINSTA_READATTRIBUTES, NULL);
244 ok(WinSta != NULL, "CreateWindowStationW failed with %lu\n", GetLastError());
245 if (WinSta)
246 {
247 TestUserObjectInfoWithString(WinSta, UOI_TYPE, Buffer, BufferSize, L"WindowStation");
248 TestUserObjectInfoWithString(WinSta, UOI_NAME, Buffer, BufferSize, WinStaName);
249 CloseWindowStation(WinSta);
250 }
251 else
252 {
253 skip("Failed to create winsta\n");
254 }
255
256 WinSta = CreateWindowStationW(L"", 0, WINSTA_READATTRIBUTES, NULL);
257 ok(WinSta != NULL, "CreateWindowStationW failed with %lu\n", GetLastError());
258 if (WinSta)
259 {
260 TestUserObjectInfoWithString(WinSta, UOI_TYPE, Buffer, BufferSize, L"WindowStation");
261 TestUserObjectInfoWithString(WinSta, UOI_NAME, Buffer, BufferSize, WinStaName);
262 CloseWindowStation(WinSta);
263 }
264 else
265 {
266 skip("Failed to create winsta\n");
267 }
268
269 WinSta = CreateWindowStationW(L"GetUserObjectInformation_apitest_winsta", 0, WINSTA_READATTRIBUTES, NULL);
270 ok(WinSta != NULL, "CreateWindowStationW failed with %lu\n", GetLastError());
271 if (WinSta)
272 {
273 TestUserObjectInfoWithString(WinSta, UOI_TYPE, Buffer, BufferSize, L"WindowStation");
274 TestUserObjectInfoWithString(WinSta, UOI_NAME, Buffer, BufferSize, L"GetUserObjectInformation_apitest_winsta");
275 CloseWindowStation(WinSta);
276 }
277 else
278 {
279 skip("Failed to create winsta\n");
280 }
281
282 WinSta = CreateWindowStationW(L"1", 0, WINSTA_READATTRIBUTES, NULL);
283 ok(WinSta != NULL, "CreateWindowStationW failed with %lu\n", GetLastError());
284 if (WinSta)
285 {
286 TestUserObjectInfoWithString(WinSta, UOI_TYPE, Buffer, BufferSize, L"WindowStation");
287 TestUserObjectInfoWithString(WinSta, UOI_NAME, Buffer, BufferSize, L"1");
288 CloseWindowStation(WinSta);
289 }
290 else
291 {
292 skip("Failed to create winsta\n");
293 }
294
295 /* Create our own desktop */
296 Desktop2 = CreateDesktopW(NULL, NULL, NULL, 0, DESKTOP_CREATEWINDOW | DESKTOP_READOBJECTS, NULL);
297 ok(Desktop2 == NULL, "CreateDesktopW succeeded\n");
298 if (Desktop2) CloseDesktop(Desktop2);
299
300 Desktop2 = CreateDesktopW(L"", NULL, NULL, 0, DESKTOP_CREATEWINDOW | DESKTOP_READOBJECTS, NULL);
301 ok(Desktop2 == NULL, "CreateDesktopW succeeded\n");
302 if (Desktop2) CloseDesktop(Desktop2);
303
304 Desktop2 = CreateDesktopW(L"2", NULL, NULL, 0, DESKTOP_CREATEWINDOW | DESKTOP_READOBJECTS, NULL);
305 ok(Desktop2 != NULL, "CreateDesktopW failed with %lu\n", GetLastError());
306 if (Desktop2)
307 {
308 TestUserObjectInfoWithString(Desktop2, UOI_TYPE, Buffer, BufferSize, L"Desktop");
309 TestUserObjectInfoWithString(Desktop2, UOI_NAME, Buffer, BufferSize, L"2");
310 }
311 else
312 {
313 skip("Failed to create winsta\n");
314 }
315
316 CloseDesktop(Desktop2);
317
318 FreeGuarded(Buffer);
319
320 /* Make sure nothing behind the needed buffer is touched */
321 BufferSize = sizeof(L"Desktop");
322 Buffer = AllocateGuarded(BufferSize);
323 TestUserObjectInfo(Desktop, UOI_TYPE, Buffer, BufferSize, TRUE, 0xdeadbeef, sizeof(L"Desktop"));
324 TestUserObjectInfo(Desktop, UOI_TYPE, Buffer, BufferSize + 1, FALSE, ERROR_NOACCESS, NOTSET);
325 FreeGuarded(Buffer);
326 }
327
328 #undef TestUserObjectInfo
329 #define TestUserObjectInfo(Handle, Index, Buffer, Length, Ret, Error, LengthNeeded) do \
330 { \
331 DWORD _LengthNeeded = NOTSET; \
332 DECLSPEC_ALIGN(16) CHAR _LengthBuffer[2 * sizeof(DWORD)]; \
333 DWORD _Error; \
334 BOOL _Ret; \
335 \
336 SetLastError(0xdeadbeef); \
337 _Ret = GetUserObjectInformationA(Handle, Index, Buffer, Length, NULL); \
338 _Error = GetLastError(); \
339 ok(_Ret == (Ret), "Ret = %d\n", _Ret); \
340 xok(_Error == (Error), "Error = %lu\n", _Error); \
341 \
342 SetLastError(0xdeadbeef); \
343 _Ret = GetUserObjectInformationA(Handle, Index, Buffer, Length, &_LengthNeeded);\
344 _Error = GetLastError(); \
345 ok(_Ret == (Ret), "Ret = %d\n", _Ret); \
346 xok(_Error == (Error), "Error = %lu\n", _Error); \
347 xok(_LengthNeeded == (LengthNeeded), "LengthNeeded = %lu\n", _LengthNeeded); \
348 \
349 SetLastError(0xdeadbeef); \
350 *(PDWORD)&_LengthBuffer[1] = NOTSET; \
351 _Ret = GetUserObjectInformationA(Handle, Index, Buffer, Length, \
352 (PDWORD)&_LengthBuffer[1]); \
353 _Error = GetLastError(); \
354 ok(_Ret == (Ret), "Ret = %d\n", _Ret); \
355 xok(_Error == (Error), "Error = %lu\n", _Error); \
356 _LengthNeeded = *(PDWORD)&_LengthBuffer[1]; \
357 xok(_LengthNeeded == (LengthNeeded), "LengthNeeded = %lu\n", _LengthNeeded); \
358 \
359 SetLastError(0xdeadbeef); \
360 _Ret = GetUserObjectInformationA(Handle, Index, Buffer, Length, (PVOID)-4); \
361 _Error = GetLastError(); \
362 ok(_Ret == FALSE, "Ret = %d\n", _Ret); \
363 ok(_Error == ERROR_NOACCESS, "Error = %lu\n", _Error); \
364 } while (0)
365
366 #undef TestUserObjectInfoWithString
367 #define TestUserObjectInfoWithString(Handle, Index, Buffer, BufferSize, String) do \
368 { \
369 BOOLEAN _Check; \
370 TestUserObjectInfo(Handle, Index, NULL, 0, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(String) * sizeof(WCHAR));\
371 TestUserObjectInfo(Handle, Index, (PVOID)1, 0, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(String) * sizeof(WCHAR));\
372 TestUserObjectInfo(Handle, Index, NULL, 1, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(String) * sizeof(WCHAR));\
373 TestUserObjectInfo(Handle, Index, (PVOID)1, 1, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(String) * sizeof(WCHAR));\
374 RtlFillMemory(Buffer, BufferSize, 0x55); \
375 TestUserObjectInfo(Handle, Index, Buffer, sizeof(String) - 2, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(String) * sizeof(WCHAR));\
376 _Check = CheckBuffer(Buffer, BufferSize, 0x55); \
377 ok(_Check == TRUE, "CheckBuffer failed\n"); \
378 RtlFillMemory(Buffer, BufferSize, 0x55); \
379 TestUserObjectInfo(Handle, Index, Buffer, sizeof(String) - 1, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(String) * sizeof(WCHAR));\
380 _Check = CheckBuffer(Buffer, BufferSize, 0x55); \
381 ok(_Check == TRUE, "CheckBuffer failed\n"); \
382 RtlFillMemory(Buffer, BufferSize, 0x55); \
383 TestUserObjectInfo(Handle, Index, Buffer, sizeof(String), TRUE, 0xdeadbeef, sizeof(String)); \
384 ok(strcmp(Buffer, String) == 0, "Buffer '%s'\n", Buffer); \
385 _Check = CheckBuffer(Buffer + sizeof(String), BufferSize - sizeof(String), 0x55); \
386 ok(_Check == TRUE, "CheckBuffer failed\n"); \
387 RtlFillMemory(Buffer, BufferSize, 0x55); \
388 TestUserObjectInfo(Handle, Index, Buffer, BufferSize, TRUE, 0xdeadbeef, sizeof(String)); \
389 ok(strcmp(Buffer, String) == 0, "Buffer '%s'\n", Buffer); \
390 _Check = CheckBuffer(Buffer + sizeof(String), BufferSize - sizeof(String), 0x55); \
391 ok(_Check == TRUE, "CheckBuffer failed\n"); \
392 } while (0)
393
394 static
395 void
396 TestGetUserObjectInfoA(void)
397 {
398 USEROBJECTFLAGS UserObjectFlags;
399 PCHAR Buffer;
400 ULONG BufferSize = 64;
401 HDESK Desktop;
402 HWINSTA WinSta;
403
404 Buffer = AllocateGuarded(BufferSize);
405
406 TestUserObjectInfo(NULL, 5, NULL, 0, FALSE, ERROR_INVALID_HANDLE, 0);
407 TestUserObjectInfo(NULL, UOI_FLAGS, NULL, 0, FALSE, ERROR_INVALID_HANDLE, 0);
408 TestUserObjectInfo(NULL, UOI_FLAGS, (PVOID)1, 0, FALSE, ERROR_INVALID_HANDLE, 0);
409 TestUserObjectInfo(NULL, UOI_FLAGS, NULL, 1, FALSE, ERROR_NOACCESS, NOTSET);
410 TestUserObjectInfo(NULL, UOI_FLAGS, (PVOID)1, 1, FALSE, ERROR_NOACCESS, NOTSET);
411 TestUserObjectInfo(NULL, UOI_FLAGS, &UserObjectFlags, sizeof(UserObjectFlags), FALSE, ERROR_INVALID_HANDLE, 0);
412
413 TestUserObjectInfo(NULL, UOI_TYPE, NULL, 0, FALSE, ERROR_INVALID_HANDLE, 0);
414 TestUserObjectInfo(NULL, UOI_TYPE, (PVOID)1, 0, FALSE, ERROR_INVALID_HANDLE, 0);
415 TestUserObjectInfo(NULL, UOI_TYPE, NULL, 1, FALSE, ERROR_INVALID_HANDLE, 0);
416 TestUserObjectInfo(NULL, UOI_TYPE, (PVOID)1, 1, FALSE, ERROR_INVALID_HANDLE, 0);
417 TestUserObjectInfo(NULL, UOI_TYPE, Buffer, BufferSize, FALSE, ERROR_INVALID_HANDLE, 0);
418
419 TestUserObjectInfo(NULL, UOI_NAME, NULL, 0, FALSE, ERROR_INVALID_HANDLE, 0);
420 TestUserObjectInfo(NULL, UOI_NAME, (PVOID)1, 0, FALSE, ERROR_INVALID_HANDLE, 0);
421 TestUserObjectInfo(NULL, UOI_NAME, NULL, 1, FALSE, ERROR_INVALID_HANDLE, 0);
422 TestUserObjectInfo(NULL, UOI_NAME, (PVOID)1, 1, FALSE, ERROR_INVALID_HANDLE, 0);
423 TestUserObjectInfo(NULL, UOI_NAME, Buffer, BufferSize, FALSE, ERROR_INVALID_HANDLE, 0);
424
425 Desktop = GetThreadDesktop(GetCurrentThreadId());
426 if (!Desktop)
427 {
428 skip("Failed to get desktop handle\n");
429 FreeGuarded(Buffer);
430 return;
431 }
432
433 WinSta = GetProcessWindowStation();
434 if (!WinSta)
435 {
436 skip("Failed to get winsta handle\n");
437 FreeGuarded(Buffer);
438 return;
439 }
440
441 TestUserObjectInfo(Desktop, 5, NULL, 0, FALSE, ERROR_INVALID_PARAMETER, 0);
442 TestUserObjectInfo(Desktop, UOI_FLAGS, NULL, 0, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(USEROBJECTFLAGS));
443 TestUserObjectInfo(Desktop, UOI_FLAGS, (PVOID)1, 0, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(USEROBJECTFLAGS));
444 TestUserObjectInfo(Desktop, UOI_FLAGS, NULL, 1, FALSE, ERROR_NOACCESS, NOTSET);
445 TestUserObjectInfo(Desktop, UOI_FLAGS, (PVOID)1, 1, FALSE, ERROR_NOACCESS, NOTSET);
446 TestUserObjectInfo(Desktop, UOI_FLAGS, &UserObjectFlags, sizeof(UserObjectFlags), TRUE, 0xdeadbeef, sizeof(USEROBJECTFLAGS));
447
448 TestUserObjectInfoWithString(Desktop, UOI_TYPE, Buffer, BufferSize, "Desktop");
449 TestUserObjectInfoWithString(Desktop, UOI_NAME, Buffer, BufferSize, "Default");
450
451 TestUserObjectInfoWithString(WinSta, UOI_TYPE, Buffer, BufferSize, "WindowStation");
452 TestUserObjectInfoWithString(WinSta, UOI_NAME, Buffer, BufferSize, "WinSta0");
453
454 FreeGuarded(Buffer);
455
456 /* Make sure nothing behind the needed buffer is touched */
457 BufferSize = sizeof("Desktop");
458 Buffer = AllocateGuarded(BufferSize);
459 TestUserObjectInfo(Desktop, UOI_TYPE, Buffer, BufferSize, TRUE, 0xdeadbeef, sizeof("Desktop"));
460 TestUserObjectInfo(Desktop, UOI_TYPE, Buffer, BufferSize + 1, TRUE, 0xdeadbeef, sizeof("Desktop"));
461 FreeGuarded(Buffer);
462 }
463
464 START_TEST(GetUserObjectInformation)
465 {
466 TestGetUserObjectInfoW();
467 TestGetUserObjectInfoA();
468 }