From 0a783e0ff3113d2ff8aa7ddc4a7d7222d54482ad Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Tue, 4 Oct 2016 15:14:30 +0000 Subject: [PATCH] [USER32_APITEST] - Extend GetUserObjectInformation tests by adding tests for UOI_NAME on the default as well as custom window stations/desktops. CORE-12073 svn path=/trunk/; revision=72900 --- .../user32/GetUserObjectInformation.c | 256 ++++++++++++++---- 1 file changed, 210 insertions(+), 46 deletions(-) diff --git a/rostests/apitests/user32/GetUserObjectInformation.c b/rostests/apitests/user32/GetUserObjectInformation.c index 69fbd0c62f7..e509f31e0ad 100644 --- a/rostests/apitests/user32/GetUserObjectInformation.c +++ b/rostests/apitests/user32/GetUserObjectInformation.c @@ -6,9 +6,11 @@ */ #include +#include #include #include #include +#include static BOOLEAN @@ -117,6 +119,36 @@ FreeGuarded( ok(_Error == ERROR_NOACCESS, "Error = %lu\n", _Error); \ } while (0) +#define TestUserObjectInfoWithString(Handle, Index, Buffer, BufferSize, String) do \ + { \ + BOOLEAN _Check; \ + ULONG SizeOfString = wcslen(String) * sizeof(WCHAR) + sizeof(UNICODE_NULL); \ + TestUserObjectInfo(Handle, Index, NULL, 0, FALSE, ERROR_INSUFFICIENT_BUFFER, SizeOfString); \ + TestUserObjectInfo(Handle, Index, (PVOID)1, 0, FALSE, ERROR_INSUFFICIENT_BUFFER, SizeOfString); \ + TestUserObjectInfo(Handle, Index, NULL, 1, FALSE, ERROR_NOACCESS, NOTSET); \ + TestUserObjectInfo(Handle, Index, (PVOID)1, 1, FALSE, ERROR_NOACCESS, NOTSET); \ + RtlFillMemory(Buffer, BufferSize, 0x55); \ + TestUserObjectInfo(Handle, Index, Buffer, SizeOfString - 2, FALSE, ERROR_INSUFFICIENT_BUFFER, SizeOfString); \ + _Check = CheckBuffer(Buffer, BufferSize, 0x55); \ + ok(_Check == TRUE, "CheckBuffer failed\n"); \ + RtlFillMemory(Buffer, BufferSize, 0x55); \ + TestUserObjectInfo(Handle, Index, Buffer, SizeOfString - 1, FALSE, ERROR_INSUFFICIENT_BUFFER, SizeOfString); \ + _Check = CheckBuffer(Buffer, BufferSize, 0x55); \ + ok(_Check == TRUE, "CheckBuffer failed\n"); \ + RtlFillMemory(Buffer, BufferSize, 0x55); \ + Buffer[BufferSize / sizeof(WCHAR) - 1] = UNICODE_NULL; \ + TestUserObjectInfo(Handle, Index, Buffer, SizeOfString, TRUE, 0xdeadbeef, SizeOfString); \ + ok(wcscmp(Buffer, String) == 0, "Buffer '%ls', expected '%ls'\n", Buffer, String); \ + _Check = CheckBuffer(Buffer + SizeOfString / sizeof(Buffer[0]), BufferSize - SizeOfString - sizeof(WCHAR), 0x55); \ + ok(_Check == TRUE, "CheckBuffer failed\n"); \ + RtlFillMemory(Buffer, BufferSize, 0x55); \ + Buffer[BufferSize / sizeof(WCHAR) - 1] = UNICODE_NULL; \ + TestUserObjectInfo(Handle, Index, Buffer, BufferSize, TRUE, 0xdeadbeef, SizeOfString); \ + ok(wcscmp(Buffer, String) == 0, "Buffer '%ls', expected '%ls'\n", Buffer, String); \ + _Check = CheckBuffer(Buffer + SizeOfString / sizeof(Buffer[0]), BufferSize - SizeOfString - sizeof(WCHAR), 0x55); \ + ok(_Check == TRUE, "CheckBuffer failed\n"); \ + } while (0) + static void TestGetUserObjectInfoW(void) @@ -125,7 +157,13 @@ TestGetUserObjectInfoW(void) PWCHAR Buffer; ULONG BufferSize = 64 * sizeof(WCHAR); HDESK Desktop; - BOOLEAN Check; + HDESK Desktop2; + HWINSTA WinSta; + HANDLE Token; + TOKEN_STATISTICS Statistics; + WCHAR WinStaName[64]; + BOOL Success; + ULONG Length; Buffer = AllocateGuarded(BufferSize); @@ -142,10 +180,25 @@ TestGetUserObjectInfoW(void) TestUserObjectInfo(NULL, UOI_TYPE, (PVOID)1, 1, FALSE, ERROR_NOACCESS, NOTSET); TestUserObjectInfo(NULL, UOI_TYPE, Buffer, BufferSize, FALSE, ERROR_INVALID_HANDLE, 0); + TestUserObjectInfo(NULL, UOI_NAME, NULL, 0, FALSE, ERROR_INVALID_HANDLE, 0); + TestUserObjectInfo(NULL, UOI_NAME, (PVOID)1, 0, FALSE, ERROR_INVALID_HANDLE, 0); + TestUserObjectInfo(NULL, UOI_NAME, NULL, 1, FALSE, ERROR_NOACCESS, NOTSET); + TestUserObjectInfo(NULL, UOI_NAME, (PVOID)1, 1, FALSE, ERROR_NOACCESS, NOTSET); + TestUserObjectInfo(NULL, UOI_NAME, Buffer, BufferSize, FALSE, ERROR_INVALID_HANDLE, 0); + Desktop = GetThreadDesktop(GetCurrentThreadId()); if (!Desktop) { skip("Failed to get desktop handle\n"); + FreeGuarded(Buffer); + return; + } + + WinSta = GetProcessWindowStation(); + if (!WinSta) + { + skip("Failed to get winsta handle\n"); + FreeGuarded(Buffer); return; } @@ -156,31 +209,115 @@ TestGetUserObjectInfoW(void) TestUserObjectInfo(Desktop, UOI_FLAGS, (PVOID)1, 1, FALSE, ERROR_NOACCESS, NOTSET); TestUserObjectInfo(Desktop, UOI_FLAGS, &UserObjectFlags, sizeof(UserObjectFlags), TRUE, 0xdeadbeef, sizeof(USEROBJECTFLAGS)); - TestUserObjectInfo(Desktop, UOI_TYPE, NULL, 0, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(L"Desktop")); - TestUserObjectInfo(Desktop, UOI_TYPE, (PVOID)1, 0, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(L"Desktop")); - TestUserObjectInfo(Desktop, UOI_TYPE, NULL, 1, FALSE, ERROR_NOACCESS, NOTSET); - TestUserObjectInfo(Desktop, UOI_TYPE, (PVOID)1, 1, FALSE, ERROR_NOACCESS, NOTSET); - RtlFillMemory(Buffer, BufferSize, 0x55); - TestUserObjectInfo(Desktop, UOI_TYPE, Buffer, sizeof(L"Desktop") - 2, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(L"Desktop")); - Check = CheckBuffer(Buffer, BufferSize, 0x55); - ok(Check == TRUE, "CheckBuffer failed\n"); - RtlFillMemory(Buffer, BufferSize, 0x55); - TestUserObjectInfo(Desktop, UOI_TYPE, Buffer, sizeof(L"Desktop") - 1, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(L"Desktop")); - Check = CheckBuffer(Buffer, BufferSize, 0x55); - ok(Check == TRUE, "CheckBuffer failed\n"); - RtlFillMemory(Buffer, BufferSize, 0x55); - TestUserObjectInfo(Desktop, UOI_TYPE, Buffer, sizeof(L"Desktop"), TRUE, 0xdeadbeef, sizeof(L"Desktop")); - ok(wcscmp(Buffer, L"Desktop") == 0, "Buffer '%ls'\n", Buffer); - Check = CheckBuffer(Buffer + sizeof("Desktop"), BufferSize - sizeof(L"Desktop"), 0x55); - ok(Check == TRUE, "CheckBuffer failed\n"); - RtlFillMemory(Buffer, BufferSize, 0x55); - TestUserObjectInfo(Desktop, UOI_TYPE, Buffer, BufferSize, TRUE, 0xdeadbeef, sizeof(L"Desktop")); - ok(wcscmp(Buffer, L"Desktop") == 0, "Buffer '%ls'\n", Buffer); - Check = CheckBuffer(Buffer + sizeof("Desktop"), BufferSize - sizeof(L"Desktop"), 0x55); - ok(Check == TRUE, "CheckBuffer failed\n"); + TestUserObjectInfoWithString(Desktop, UOI_TYPE, Buffer, BufferSize, L"Desktop"); + TestUserObjectInfoWithString(Desktop, UOI_NAME, Buffer, BufferSize, L"Default"); + + TestUserObjectInfoWithString(WinSta, UOI_TYPE, Buffer, BufferSize, L"WindowStation"); + TestUserObjectInfoWithString(WinSta, UOI_NAME, Buffer, BufferSize, L"WinSta0"); + + /* Autogenerated name will be Service-0x-$ */ + StringCbCopyW(WinStaName, sizeof(WinStaName), L""); + Success = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token); + ok(Success == TRUE, "OpenProcessToken failed with %lu\n", GetLastError()); + if (Success) + { + Success = GetTokenInformation(Token, + TokenStatistics, + &Statistics, + sizeof(Statistics), + &Length); + ok(Success == TRUE, "GetTokenInformation failed with %lu\n", GetLastError()); + if (Success) + { + StringCbPrintfW(WinStaName, + sizeof(WinStaName), + L"Service-0x%lx-%lx$", + Statistics.AuthenticationId.HighPart, + Statistics.AuthenticationId.LowPart); + trace("Expected autogenerated Winsta name: %ls\n", WinStaName); + } + CloseHandle(Token); + } + + /* Create our own Winsta */ + WinSta = CreateWindowStationW(NULL, 0, WINSTA_READATTRIBUTES, NULL); + ok(WinSta != NULL, "CreateWindowStationW failed with %lu\n", GetLastError()); + if (WinSta) + { + TestUserObjectInfoWithString(WinSta, UOI_TYPE, Buffer, BufferSize, L"WindowStation"); + TestUserObjectInfoWithString(WinSta, UOI_NAME, Buffer, BufferSize, WinStaName); + CloseWindowStation(WinSta); + } + else + { + skip("Failed to create winsta\n"); + } + + WinSta = CreateWindowStationW(L"", 0, WINSTA_READATTRIBUTES, NULL); + ok(WinSta != NULL, "CreateWindowStationW failed with %lu\n", GetLastError()); + if (WinSta) + { + TestUserObjectInfoWithString(WinSta, UOI_TYPE, Buffer, BufferSize, L"WindowStation"); + TestUserObjectInfoWithString(WinSta, UOI_NAME, Buffer, BufferSize, WinStaName); + CloseWindowStation(WinSta); + } + else + { + skip("Failed to create winsta\n"); + } + + WinSta = CreateWindowStationW(L"GetUserObjectInformation_apitest_winsta", 0, WINSTA_READATTRIBUTES, NULL); + ok(WinSta != NULL, "CreateWindowStationW failed with %lu\n", GetLastError()); + if (WinSta) + { + TestUserObjectInfoWithString(WinSta, UOI_TYPE, Buffer, BufferSize, L"WindowStation"); + TestUserObjectInfoWithString(WinSta, UOI_NAME, Buffer, BufferSize, L"GetUserObjectInformation_apitest_winsta"); + CloseWindowStation(WinSta); + } + else + { + skip("Failed to create winsta\n"); + } + + WinSta = CreateWindowStationW(L"1", 0, WINSTA_READATTRIBUTES, NULL); + ok(WinSta != NULL, "CreateWindowStationW failed with %lu\n", GetLastError()); + if (WinSta) + { + TestUserObjectInfoWithString(WinSta, UOI_TYPE, Buffer, BufferSize, L"WindowStation"); + TestUserObjectInfoWithString(WinSta, UOI_NAME, Buffer, BufferSize, L"1"); + CloseWindowStation(WinSta); + } + else + { + skip("Failed to create winsta\n"); + } + + /* Create our own desktop */ + Desktop2 = CreateDesktopW(NULL, NULL, NULL, 0, DESKTOP_CREATEWINDOW | DESKTOP_READOBJECTS, NULL); + ok(Desktop2 == NULL, "CreateDesktopW succeeded\n"); + if (Desktop2) CloseDesktop(Desktop2); + + Desktop2 = CreateDesktopW(L"", NULL, NULL, 0, DESKTOP_CREATEWINDOW | DESKTOP_READOBJECTS, NULL); + ok(Desktop2 == NULL, "CreateDesktopW succeeded\n"); + if (Desktop2) CloseDesktop(Desktop2); + + Desktop2 = CreateDesktopW(L"2", NULL, NULL, 0, DESKTOP_CREATEWINDOW | DESKTOP_READOBJECTS, NULL); + ok(Desktop2 != NULL, "CreateDesktopW failed with %lu\n", GetLastError()); + if (Desktop2) + { + TestUserObjectInfoWithString(Desktop2, UOI_TYPE, Buffer, BufferSize, L"Desktop"); + TestUserObjectInfoWithString(Desktop2, UOI_NAME, Buffer, BufferSize, L"2"); + } + else + { + skip("Failed to create winsta\n"); + } + + CloseDesktop(Desktop2); FreeGuarded(Buffer); + /* Make sure nothing behind the needed buffer is touched */ BufferSize = sizeof(L"Desktop"); Buffer = AllocateGuarded(BufferSize); TestUserObjectInfo(Desktop, UOI_TYPE, Buffer, BufferSize, TRUE, 0xdeadbeef, sizeof(L"Desktop")); @@ -226,6 +363,34 @@ TestGetUserObjectInfoW(void) ok(_Error == ERROR_NOACCESS, "Error = %lu\n", _Error); \ } while (0) +#undef TestUserObjectInfoWithString +#define TestUserObjectInfoWithString(Handle, Index, Buffer, BufferSize, String) do \ + { \ + BOOLEAN _Check; \ + TestUserObjectInfo(Handle, Index, NULL, 0, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(String) * sizeof(WCHAR));\ + TestUserObjectInfo(Handle, Index, (PVOID)1, 0, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(String) * sizeof(WCHAR));\ + TestUserObjectInfo(Handle, Index, NULL, 1, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(String) * sizeof(WCHAR));\ + TestUserObjectInfo(Handle, Index, (PVOID)1, 1, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(String) * sizeof(WCHAR));\ + RtlFillMemory(Buffer, BufferSize, 0x55); \ + TestUserObjectInfo(Handle, Index, Buffer, sizeof(String) - 2, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(String) * sizeof(WCHAR));\ + _Check = CheckBuffer(Buffer, BufferSize, 0x55); \ + ok(_Check == TRUE, "CheckBuffer failed\n"); \ + RtlFillMemory(Buffer, BufferSize, 0x55); \ + TestUserObjectInfo(Handle, Index, Buffer, sizeof(String) - 1, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(String) * sizeof(WCHAR));\ + _Check = CheckBuffer(Buffer, BufferSize, 0x55); \ + ok(_Check == TRUE, "CheckBuffer failed\n"); \ + RtlFillMemory(Buffer, BufferSize, 0x55); \ + TestUserObjectInfo(Handle, Index, Buffer, sizeof(String), TRUE, 0xdeadbeef, sizeof(String)); \ + ok(strcmp(Buffer, String) == 0, "Buffer '%s'\n", Buffer); \ + _Check = CheckBuffer(Buffer + sizeof(String), BufferSize - sizeof(String), 0x55); \ + ok(_Check == TRUE, "CheckBuffer failed\n"); \ + RtlFillMemory(Buffer, BufferSize, 0x55); \ + TestUserObjectInfo(Handle, Index, Buffer, BufferSize, TRUE, 0xdeadbeef, sizeof(String)); \ + ok(strcmp(Buffer, String) == 0, "Buffer '%s'\n", Buffer); \ + _Check = CheckBuffer(Buffer + sizeof(String), BufferSize - sizeof(String), 0x55); \ + ok(_Check == TRUE, "CheckBuffer failed\n"); \ + } while (0) + static void TestGetUserObjectInfoA(void) @@ -234,7 +399,7 @@ TestGetUserObjectInfoA(void) PCHAR Buffer; ULONG BufferSize = 64; HDESK Desktop; - BOOLEAN Check; + HWINSTA WinSta; Buffer = AllocateGuarded(BufferSize); @@ -251,10 +416,25 @@ TestGetUserObjectInfoA(void) TestUserObjectInfo(NULL, UOI_TYPE, (PVOID)1, 1, FALSE, ERROR_INVALID_HANDLE, 0); TestUserObjectInfo(NULL, UOI_TYPE, Buffer, BufferSize, FALSE, ERROR_INVALID_HANDLE, 0); + TestUserObjectInfo(NULL, UOI_NAME, NULL, 0, FALSE, ERROR_INVALID_HANDLE, 0); + TestUserObjectInfo(NULL, UOI_NAME, (PVOID)1, 0, FALSE, ERROR_INVALID_HANDLE, 0); + TestUserObjectInfo(NULL, UOI_NAME, NULL, 1, FALSE, ERROR_INVALID_HANDLE, 0); + TestUserObjectInfo(NULL, UOI_NAME, (PVOID)1, 1, FALSE, ERROR_INVALID_HANDLE, 0); + TestUserObjectInfo(NULL, UOI_NAME, Buffer, BufferSize, FALSE, ERROR_INVALID_HANDLE, 0); + Desktop = GetThreadDesktop(GetCurrentThreadId()); if (!Desktop) { skip("Failed to get desktop handle\n"); + FreeGuarded(Buffer); + return; + } + + WinSta = GetProcessWindowStation(); + if (!WinSta) + { + skip("Failed to get winsta handle\n"); + FreeGuarded(Buffer); return; } @@ -265,31 +445,15 @@ TestGetUserObjectInfoA(void) TestUserObjectInfo(Desktop, UOI_FLAGS, (PVOID)1, 1, FALSE, ERROR_NOACCESS, NOTSET); TestUserObjectInfo(Desktop, UOI_FLAGS, &UserObjectFlags, sizeof(UserObjectFlags), TRUE, 0xdeadbeef, sizeof(USEROBJECTFLAGS)); - TestUserObjectInfo(Desktop, UOI_TYPE, NULL, 0, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(L"Desktop")); - TestUserObjectInfo(Desktop, UOI_TYPE, (PVOID)1, 0, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(L"Desktop")); - TestUserObjectInfo(Desktop, UOI_TYPE, NULL, 1, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(L"Desktop")); - TestUserObjectInfo(Desktop, UOI_TYPE, (PVOID)1, 1, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(L"Desktop")); - RtlFillMemory(Buffer, BufferSize, 0x55); - TestUserObjectInfo(Desktop, UOI_TYPE, Buffer, sizeof("Desktop") - 2, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(L"Desktop")); - Check = CheckBuffer(Buffer, BufferSize, 0x55); - ok(Check == TRUE, "CheckBuffer failed\n"); - RtlFillMemory(Buffer, BufferSize, 0x55); - TestUserObjectInfo(Desktop, UOI_TYPE, Buffer, sizeof("Desktop") - 1, FALSE, ERROR_INSUFFICIENT_BUFFER, sizeof(L"Desktop")); - Check = CheckBuffer(Buffer, BufferSize, 0x55); - ok(Check == TRUE, "CheckBuffer failed\n"); - RtlFillMemory(Buffer, BufferSize, 0x55); - TestUserObjectInfo(Desktop, UOI_TYPE, Buffer, sizeof("Desktop"), TRUE, 0xdeadbeef, sizeof("Desktop")); - ok(strcmp(Buffer, "Desktop") == 0, "Buffer '%s'\n", Buffer); - Check = CheckBuffer(Buffer + sizeof("Desktop"), BufferSize - sizeof("Desktop"), 0x55); - ok(Check == TRUE, "CheckBuffer failed\n"); - RtlFillMemory(Buffer, BufferSize, 0x55); - TestUserObjectInfo(Desktop, UOI_TYPE, Buffer, BufferSize, TRUE, 0xdeadbeef, sizeof("Desktop")); - ok(strcmp(Buffer, "Desktop") == 0, "Buffer '%s'\n", Buffer); - Check = CheckBuffer(Buffer + sizeof("Desktop"), BufferSize - sizeof("Desktop"), 0x55); - ok(Check == TRUE, "CheckBuffer failed\n"); + TestUserObjectInfoWithString(Desktop, UOI_TYPE, Buffer, BufferSize, "Desktop"); + TestUserObjectInfoWithString(Desktop, UOI_NAME, Buffer, BufferSize, "Default"); + + TestUserObjectInfoWithString(WinSta, UOI_TYPE, Buffer, BufferSize, "WindowStation"); + TestUserObjectInfoWithString(WinSta, UOI_NAME, Buffer, BufferSize, "WinSta0"); FreeGuarded(Buffer); + /* Make sure nothing behind the needed buffer is touched */ BufferSize = sizeof("Desktop"); Buffer = AllocateGuarded(BufferSize); TestUserObjectInfo(Desktop, UOI_TYPE, Buffer, BufferSize, TRUE, 0xdeadbeef, sizeof("Desktop"));