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 ULONG SizeOfString = wcslen(String) * sizeof(WCHAR) + sizeof(UNICODE_NULL); \ 125 TestUserObjectInfo(Handle, Index, NULL, 0, FALSE, ERROR_INSUFFICIENT_BUFFER, SizeOfString); \ 126 TestUserObjectInfo(Handle, Index, (PVOID)1, 0, FALSE, ERROR_INSUFFICIENT_BUFFER, SizeOfString); \ 127 TestUserObjectInfo(Handle, Index, NULL, 1, FALSE, ERROR_NOACCESS, NOTSET); \ 128 TestUserObjectInfo(Handle, Index, (PVOID)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, (PVOID)1, 0, FALSE, ERROR_INVALID_HANDLE, 0); 172 TestUserObjectInfo(NULL, UOI_FLAGS, NULL, 1, FALSE, ERROR_NOACCESS, NOTSET); 173 TestUserObjectInfo(NULL, UOI_FLAGS, (PVOID)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, (PVOID)1, 0, FALSE, ERROR_INVALID_HANDLE, 0); 178 TestUserObjectInfo(NULL, UOI_TYPE, NULL, 1, FALSE, ERROR_NOACCESS, NOTSET); 179 TestUserObjectInfo(NULL, UOI_TYPE, (PVOID)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, (PVOID)1, 0, FALSE, ERROR_INVALID_HANDLE, 0); 184 TestUserObjectInfo(NULL, UOI_NAME, NULL, 1, FALSE, ERROR_NOACCESS, NOTSET); 185 TestUserObjectInfo(NULL, UOI_NAME, (PVOID)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, (PVOID)1, 0, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(USEROBJECTFLAGS)); 207 TestUserObjectInfo(Desktop, UOI_FLAGS, NULL, 1, FALSE, ERROR_NOACCESS, NOTSET); 208 TestUserObjectInfo(Desktop, UOI_FLAGS, (PVOID)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 } 468