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