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