Author: tfaber
Date: Sat Apr 16 20:30:11 2016
New Revision: 71173
URL:
http://svn.reactos.org/svn/reactos?rev=71173&view=rev
Log:
[USER32_APITEST]
- Add a test for window station reference counts
CORE-11124
Modified:
trunk/rostests/apitests/user32/desktop.c
Modified: trunk/rostests/apitests/user32/desktop.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/user32/desktop.c…
==============================================================================
--- trunk/rostests/apitests/user32/desktop.c [iso-8859-1] (original)
+++ trunk/rostests/apitests/user32/desktop.c [iso-8859-1] Sat Apr 16 20:30:11 2016
@@ -3,16 +3,19 @@
* LICENSE: GPL - See COPYING in the top level directory
* PURPOSE: Test for desktop objects
* PROGRAMMERS: Giannis Adamopoulos
+ * Thomas Faber
*/
+#define WIN32_NO_STATUS
#include <apitest.h>
#include <stdio.h>
#include <wingdi.h>
#include <winuser.h>
#include "helper.h"
-
-#define STATUS_DLL_INIT_FAILED (0xC0000142)
+#include <ndk/umtypes.h>
+#include <ndk/obfuncs.h>
+
#define DESKTOP_ALL_ACCESS 0x01ff
struct test_info {
@@ -196,6 +199,148 @@
}
+static HWINSTA open_winsta(PCWSTR winstaName, DWORD *error)
+{
+ HWINSTA hwinsta;
+ SetLastError(0xfeedf00d);
+ hwinsta = OpenWindowStationW(winstaName, FALSE, WINSTA_ALL_ACCESS);
+ *error = GetLastError();
+ return hwinsta;
+}
+
+static HWINSTA create_winsta(PCWSTR winstaName, DWORD *error)
+{
+ HWINSTA hwinsta;
+ SetLastError(0xfeedf00d);
+ hwinsta = CreateWindowStationW(winstaName, 0, WINSTA_ALL_ACCESS, NULL);
+ *error = GetLastError();
+ return hwinsta;
+}
+
+static HDESK open_desk(PCWSTR deskName, DWORD *error)
+{
+ HDESK hdesk;
+ SetLastError(0xfeedf00d);
+ hdesk = OpenDesktopW(deskName, 0, FALSE, DESKTOP_ALL_ACCESS);
+ *error = GetLastError();
+ return hdesk;
+}
+
+static HDESK create_desk(PCWSTR deskName, DWORD *error)
+{
+ HDESK hdesk;
+ SetLastError(0xfeedf00d);
+ hdesk = CreateDesktopW(deskName, NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL);
+ *error = GetLastError();
+ return hdesk;
+}
+
+static void Test_References(void)
+{
+ PCWSTR winstaName = L"RefTestWinsta";
+ PCWSTR deskName = L"RefTestDesktop";
+ HWINSTA hwinsta;
+ HWINSTA hwinsta2;
+ HWINSTA hwinstaProcess;
+ DWORD error;
+ NTSTATUS status;
+ OBJECT_BASIC_INFORMATION objectInfo = { 0 };
+ HDESK hdesk;
+ BOOL ret;
+ ULONG baseRefs;
+
+#define check_ref(handle, hdlcnt, ptrcnt) \
+ status = NtQueryObject(handle, ObjectBasicInformation, &objectInfo,
sizeof(objectInfo), NULL); \
+ ok(status == STATUS_SUCCESS, "status = %lx\n", status);
\
+ ok(objectInfo.HandleCount == (hdlcnt), "HandleCount = %lx\n",
objectInfo.HandleCount); \
+ ok(objectInfo.PointerCount == (ptrcnt), "PointerCount = %lx\n",
objectInfo.PointerCount);
+
+ /* Winsta shouldn't exist */
+ hwinsta = open_winsta(winstaName, &error);
+ ok(hwinsta == NULL && error == ERROR_FILE_NOT_FOUND, "Got %p,
%lu\n", hwinsta, error);
+
+ /* Create it -- we get 1/4 instead of 1/3 because Winstas are kept in a list */
+ hwinsta = create_winsta(winstaName, &error);
+ ok(hwinsta != NULL && error == NO_ERROR, "Got %p, %lu\n", hwinsta,
error);
+ check_ref(hwinsta, 1, 4);
+ baseRefs = objectInfo.PointerCount;
+ ok(baseRefs == 4, "Window station initially has %lu references, expected
4\n", baseRefs);
+ check_ref(hwinsta, 1, baseRefs);
+
+ /* Open a second handle */
+ hwinsta2 = open_winsta(winstaName, &error);
+ ok(hwinsta2 != NULL && error == 0xfeedf00d, "Got %p, %lu\n",
hwinsta, error);
+ check_ref(hwinsta, 2, baseRefs + 1);
+
+ /* Close second handle -- back to 1/4 */
+ ret = CloseHandle(hwinsta2);
+ ok(ret == TRUE, "ret = %d\n", ret);
+ check_ref(hwinsta, 1, baseRefs);
+
+ /* Same game but using CloseWindowStation */
+ hwinsta2 = open_winsta(winstaName, &error);
+ ok(hwinsta2 != NULL && error == 0xfeedf00d, "Got %p, %lu\n",
hwinsta, error);
+ check_ref(hwinsta, 2, baseRefs + 1);
+ ret = CloseWindowStation(hwinsta2);
+ ok(ret == TRUE, "ret = %d\n", ret);
+ check_ref(hwinsta, 1, baseRefs);
+
+ /* Set it as the process Winsta */
+ hwinstaProcess = GetProcessWindowStation();
+ SetProcessWindowStation(hwinsta);
+ check_ref(hwinsta, 2, baseRefs + 2);
+
+ /* Create a desktop. It takes a reference */
+ hdesk = create_desk(deskName, &error);
+ ok(hdesk != NULL && error == 0xfeedf00d, "Got %p, %lu\n", hdesk,
error);
+ check_ref(hwinsta, 2, baseRefs + 3);
+
+ /* CloseHandle fails, must use CloseDesktop */
+ ret = CloseHandle(hdesk);
+ ok(ret == FALSE, "ret = %d\n", ret);
+ check_ref(hwinsta, 2, baseRefs + 3);
+ ret = CloseDesktop(hdesk);
+ ok(ret == TRUE, "ret = %d\n", ret);
+ check_ref(hwinsta, 2, baseRefs + 2); // 2/7 on Win7?
+
+ /* Desktop no longer exists */
+ hdesk = open_desk(deskName, &error);
+ ok(hdesk == NULL && error == ERROR_FILE_NOT_FOUND, "Got %p, %lu\n",
hdesk, error);
+ check_ref(hwinsta, 2, baseRefs + 2);
+
+ /* Restore the original process Winsta */
+ SetProcessWindowStation(hwinstaProcess);
+ check_ref(hwinsta, 1, baseRefs);
+
+ /* Close our last handle */
+ ret = CloseHandle(hwinsta);
+ ok(ret == TRUE, "ret = %d\n", ret);
+
+ /* Winsta no longer exists */
+ hwinsta = open_winsta(winstaName, &error);
+ ok(hwinsta == NULL && error == ERROR_FILE_NOT_FOUND, "Got %p,
%lu\n", hwinsta, error);
+
+ /* Create the Winsta again, and close it while there's still a desktop */
+ hwinsta = create_winsta(winstaName, &error);
+ ok(hwinsta != NULL && error == NO_ERROR, "Got %p, %lu\n", hwinsta,
error);
+ check_ref(hwinsta, 1, baseRefs);
+ hwinstaProcess = GetProcessWindowStation();
+ SetProcessWindowStation(hwinsta);
+ check_ref(hwinsta, 2, baseRefs + 2);
+
+ hdesk = create_desk(deskName, &error);
+ ok(hdesk != NULL && error == 0xfeedf00d, "Got %p, %lu\n", hdesk,
error);
+ check_ref(hwinsta, 2, baseRefs + 3);
+
+ /* The reference from the desktop is still there, hence 1/5 */
+ SetProcessWindowStation(hwinstaProcess);
+ check_ref(hwinsta, 1, baseRefs + 1);
+ ret = CloseHandle(hwinsta);
+ ok(ret == TRUE, "ret = %d\n", ret);
+ hwinsta = open_winsta(winstaName, &error);
+ ok(hwinsta == NULL && error == ERROR_FILE_NOT_FOUND, "Got %p,
%lu\n", hwinsta, error);
+}
+
START_TEST(desktop)
{
char **test_argv;
@@ -216,4 +361,5 @@
Test_InitialDesktop(test_argv[0]);
Test_OpenInputDesktop();
-}
+ Test_References();
+}