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 }