ReactOS 0.4.15-dev-7991-ge77da17
GetUserObjectInformation.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: 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
15static
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
105static
106void
108{
109 USEROBJECTFLAGS UserObjectFlags;
111 ULONG BufferSize = 64 * sizeof(WCHAR);
112 HDESK Desktop;
113 HDESK Desktop2;
114 HWINSTA WinSta;
116 TOKEN_STATISTICS Statistics;
117 WCHAR WinStaName[64];
120
122
128 TestUserObjectInfo(NULL, UOI_FLAGS, &UserObjectFlags, sizeof(UserObjectFlags), FALSE, ERROR_INVALID_HANDLE, 0);
129
135
141
143 if (!Desktop)
144 {
145 skip("Failed to get desktop handle\n");
147 return;
148 }
149
150 WinSta = GetProcessWindowStation();
151 if (!WinSta)
152 {
153 skip("Failed to get winsta handle\n");
155 return;
156 }
157
163 TestUserObjectInfo(Desktop, UOI_FLAGS, &UserObjectFlags, sizeof(UserObjectFlags), TRUE, 0xdeadbeef, sizeof(USEROBJECTFLAGS));
164
167
168 TestUserObjectInfoWithString(WinSta, UOI_TYPE, Buffer, BufferSize, L"WindowStation");
170
171 /* Autogenerated name will be Service-0x<luidhigh>-<luidlow>$ */
172 StringCbCopyW(WinStaName, sizeof(WinStaName), L"<failed>");
174 ok(Success == TRUE, "OpenProcessToken failed with %lu\n", GetLastError());
175 if (Success)
176 {
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 }
193 }
194
195 /* Create our own Winsta */
197 ok(WinSta != NULL, "CreateWindowStationW failed with %lu\n", GetLastError());
198 if (WinSta)
199 {
200 TestUserObjectInfoWithString(WinSta, UOI_TYPE, Buffer, BufferSize, L"WindowStation");
202 CloseWindowStation(WinSta);
203 }
204 else
205 {
206 skip("Failed to create winsta\n");
207 }
208
210 ok(WinSta != NULL, "CreateWindowStationW failed with %lu\n", GetLastError());
211 if (WinSta)
212 {
213 TestUserObjectInfoWithString(WinSta, UOI_TYPE, Buffer, BufferSize, L"WindowStation");
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
236 ok(WinSta != NULL, "CreateWindowStationW failed with %lu\n", GetLastError());
237 if (WinSta)
238 {
239 TestUserObjectInfoWithString(WinSta, UOI_TYPE, Buffer, BufferSize, L"WindowStation");
241 CloseWindowStation(WinSta);
242 }
243 else
244 {
245 skip("Failed to create winsta\n");
246 }
247
248 /* Create our own desktop */
250 ok(Desktop2 == NULL, "CreateDesktopW succeeded\n");
251 if (Desktop2) CloseDesktop(Desktop2);
252
254 ok(Desktop2 == NULL, "CreateDesktopW succeeded\n");
255 if (Desktop2) CloseDesktop(Desktop2);
256
258 ok(Desktop2 != NULL, "CreateDesktopW failed with %lu\n", GetLastError());
259 if (Desktop2)
260 {
263 }
264 else
265 {
266 skip("Failed to create winsta\n");
267 }
268
269 CloseDesktop(Desktop2);
270
272
273 /* Make sure nothing behind the needed buffer is touched */
274 BufferSize = sizeof(L"Desktop");
276 TestUserObjectInfo(Desktop, UOI_TYPE, Buffer, BufferSize, TRUE, 0xdeadbeef, sizeof(L"Desktop"));
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
347static
348void
350{
351 USEROBJECTFLAGS UserObjectFlags;
353 ULONG BufferSize = 64;
354 HDESK Desktop;
355 HWINSTA WinSta;
356
358
364 TestUserObjectInfo(NULL, UOI_FLAGS, &UserObjectFlags, sizeof(UserObjectFlags), FALSE, ERROR_INVALID_HANDLE, 0);
365
371
377
379 if (!Desktop)
380 {
381 skip("Failed to get desktop handle\n");
383 return;
384 }
385
386 WinSta = GetProcessWindowStation();
387 if (!WinSta)
388 {
389 skip("Failed to get winsta handle\n");
391 return;
392 }
393
399 TestUserObjectInfo(Desktop, UOI_FLAGS, &UserObjectFlags, sizeof(UserObjectFlags), TRUE, 0xdeadbeef, sizeof(USEROBJECTFLAGS));
400
403
404 TestUserObjectInfoWithString(WinSta, UOI_TYPE, Buffer, BufferSize, "WindowStation");
406
408
409 /* Make sure nothing behind the needed buffer is touched */
410 BufferSize = sizeof("Desktop");
412 TestUserObjectInfo(Desktop, UOI_TYPE, Buffer, BufferSize, TRUE, 0xdeadbeef, sizeof("Desktop"));
413 TestUserObjectInfo(Desktop, UOI_TYPE, Buffer, BufferSize + 1, TRUE, 0xdeadbeef, sizeof("Desktop"));
415}
416
418{
421}
#define TestUserObjectInfo(Handle, Index, Buffer, Length, Ret, Error, LengthNeeded)
static void TestGetUserObjectInfoW(void)
#define NOTSET
#define TestUserObjectInfoWithString(Handle, Index, Buffer, BufferSize, String)
static void TestGetUserObjectInfoA(void)
static BOOLEAN CheckBuffer(PVOID Buffer, SIZE_T Size, UCHAR Value)
unsigned char BOOLEAN
static VOID FreeGuarded(_In_ PVOID Pointer)
Definition: apitest_guard.h:45
static PVOID AllocateGuarded(_In_ SIZE_T SizeRequested)
Definition: apitest_guard.h:10
#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
Definition: bufpool.h:45
#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
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
#define CloseHandle
Definition: compat.h:739
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define GetCurrentProcess()
Definition: compat.h:759
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define UlongToPtr(u)
Definition: config.h:106
@ 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
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define L(x)
Definition: ntvdm.h:50
STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:166
STRSAFEAPI StringCbPrintfW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:557
LONG HighPart
DWORD LowPart
LUID AuthenticationId
Definition: setypes.h:1087
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint16_t * PWCHAR
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
HDESK WINAPI CreateDesktopW(LPCWSTR lpszDesktop, LPCWSTR lpszDevice, LPDEVMODEW pDevmode, DWORD dwFlags, ACCESS_MASK dwDesiredAccess, LPSECURITY_ATTRIBUTES lpsa)
Definition: desktop.c:473
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
HWINSTA WINAPI GetProcessWindowStation(void)
Definition: ntwrapper.h:124
#define ERROR_NOACCESS
Definition: winerror.h:578
HDESK WINAPI GetThreadDesktop(_In_ DWORD)
#define DESKTOP_CREATEWINDOW
Definition: winuser.h:217
HWINSTA WINAPI CreateWindowStationW(_In_opt_ LPCWSTR lpwinsta, _In_ DWORD dwFlags, _In_ ACCESS_MASK dwDesiredAccess, _In_opt_ LPSECURITY_ATTRIBUTES lpsa)
#define UOI_NAME
Definition: winuser.h:1084
#define UOI_TYPE
Definition: winuser.h:1085
BOOL WINAPI CloseWindowStation(_In_ HWINSTA)
#define WINSTA_READATTRIBUTES
Definition: winuser.h:414
#define DESKTOP_READOBJECTS
Definition: winuser.h:222
#define UOI_FLAGS
Definition: winuser.h:1083
BOOL WINAPI CloseDesktop(_In_ HDESK)
#define GetUserObjectInformation
Definition: winuser.h:5795
#define TOKEN_QUERY
Definition: setypes.h:928
@ TokenStatistics
Definition: setypes.h:975
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180