[USER32_APITEST]
authorThomas Faber <thomas.faber@reactos.org>
Tue, 4 Oct 2016 15:14:30 +0000 (15:14 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Tue, 4 Oct 2016 15:14:30 +0000 (15:14 +0000)
- 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

rostests/apitests/user32/GetUserObjectInformation.c

index 69fbd0c..e509f31 100644 (file)
@@ -6,9 +6,11 @@
  */
 
 #include <apitest.h>
+#include <wingdi.h>
 #include <winuser.h>
 #include <ndk/mmfuncs.h>
 #include <ndk/pstypes.h>
+#include <strsafe.h>
 
 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<luidhigh>-<luidlow>$ */
+    StringCbCopyW(WinStaName, sizeof(WinStaName), L"<failed>");
+    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"));