Jacek Caban : ntoskrnl.exe/tests: Add object reference tests.

Alexandre Julliard julliard at winehq.org
Tue Feb 26 15:13:56 CST 2019


Module: wine
Branch: master
Commit: 99876873b8421aaf0ddca0f9795acf158c9dd575
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=99876873b8421aaf0ddca0f9795acf158c9dd575

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Feb 26 13:38:50 2019 +0100

ntoskrnl.exe/tests: Add object reference tests.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntoskrnl.exe/ntoskrnl.exe.spec |   6 +-
 dlls/ntoskrnl.exe/tests/driver.c    | 139 +++++++++++++++++++++++++++++++++++-
 2 files changed, 140 insertions(+), 5 deletions(-)

diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
index d087422..286d688 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
+++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
@@ -1313,8 +1313,8 @@
 @ stub ZwCloseObjectAuditAlarm
 @ stdcall -private ZwConnectPort(ptr ptr ptr ptr ptr ptr ptr ptr) NtConnectPort
 @ stdcall -private ZwCreateDirectoryObject(ptr long ptr) NtCreateDirectoryObject
-@ stdcall -private ZwCreateEvent(ptr long ptr long long) NtCreateEvent
-@ stdcall -private ZwCreateFile(ptr long ptr ptr ptr long long long long ptr long) NtCreateFile
+@ stdcall ZwCreateEvent(ptr long ptr long long) NtCreateEvent
+@ stdcall ZwCreateFile(ptr long ptr ptr ptr long long long long ptr long) NtCreateFile
 @ stdcall -private ZwCreateJobObject(ptr long ptr) NtCreateJobObject
 @ stdcall -private ZwCreateKey(ptr long ptr long ptr long ptr) NtCreateKey
 @ stdcall -private ZwCreateSection(ptr long ptr ptr long long long) NtCreateSection
@@ -1326,7 +1326,7 @@
 @ stdcall -private ZwDeleteValueKey(long ptr) NtDeleteValueKey
 @ stdcall -private ZwDeviceIoControlFile(long long ptr ptr ptr long ptr long ptr long) NtDeviceIoControlFile
 @ stdcall -private ZwDisplayString(ptr) NtDisplayString
-@ stdcall -private ZwDuplicateObject(long long long ptr long long long) NtDuplicateObject
+@ stdcall ZwDuplicateObject(long long long ptr long long long) NtDuplicateObject
 @ stdcall -private ZwDuplicateToken(long long ptr long long ptr) NtDuplicateToken
 @ stub ZwEnumerateBootEntries
 @ stdcall -private ZwEnumerateKey(long long long ptr long ptr) NtEnumerateKey
diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c
index 3984240..b16c428 100644
--- a/dlls/ntoskrnl.exe/tests/driver.c
+++ b/dlls/ntoskrnl.exe/tests/driver.c
@@ -49,6 +49,10 @@ static int running_under_wine;
 static int winetest_debug;
 static int winetest_report_success;
 
+static POBJECT_TYPE *pExEventObjectType, *pIoFileObjectType, *pPsThreadType;
+
+void WINAPI ObfReferenceObject( void *obj );
+
 extern int CDECL _vsnprintf(char *str, size_t len, const char *format, __ms_va_list argptr);
 
 static void kvprintf(const char *format, __ms_va_list ap)
@@ -174,6 +178,21 @@ static void winetest_end_todo(void)
 #define todo_wine_if(is_todo)   todo_if((is_todo) && running_under_wine)
 #define win_skip(...)           win_skip_(__FILE__, __LINE__, __VA_ARGS__)
 
+static unsigned int strlenW( const WCHAR *str )
+{
+    const WCHAR *s = str;
+    while (*s) s++;
+    return s - str;
+}
+
+void *kmemcpy(void *dest, const void *src, SIZE_T n)
+{
+    const char *s = src;
+    char *d = dest;
+    while (n--) *d++ = *s++;
+    return dest;
+}
+
 static void *get_proc_address(const char *name)
 {
     UNICODE_STRING name_u;
@@ -636,6 +655,113 @@ static void test_version(void)
     ok(*pNtBuildNumber == build, "Expected build number %u, got %u\n", build, *pNtBuildNumber);
 }
 
+static void WINAPI thread_proc(void *arg)
+{
+    PsTerminateSystemThread(STATUS_SUCCESS);
+}
+
+static void test_ob_reference(const WCHAR *test_path)
+{
+    OBJECT_ATTRIBUTES attr = { sizeof(attr) };
+    HANDLE event_handle, file_handle, file_handle2, thread_handle;
+    void *obj1, *obj2;
+    UNICODE_STRING pathU;
+    IO_STATUS_BLOCK io;
+    WCHAR *tmp_path;
+    SIZE_T len;
+    NTSTATUS status;
+
+    static const WCHAR tmpW[] = {'.','t','m','p',0};
+
+    InitializeObjectAttributes(&attr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
+    status = ZwCreateEvent(&event_handle, SYNCHRONIZE, &attr, NotificationEvent, TRUE);
+    ok(!status, "ZwCreateEvent failed: %#x\n", status);
+
+    len = strlenW(test_path);
+    tmp_path = ExAllocatePool(PagedPool, len * sizeof(WCHAR) + sizeof(tmpW));
+    kmemcpy(tmp_path, test_path, len * sizeof(WCHAR));
+    kmemcpy(tmp_path + len, tmpW, sizeof(tmpW));
+
+    RtlInitUnicodeString(&pathU, tmp_path);
+    attr.ObjectName = &pathU;
+    attr.Attributes = OBJ_KERNEL_HANDLE;
+    status = ZwCreateFile(&file_handle,  DELETE | FILE_WRITE_DATA | SYNCHRONIZE, &attr, &io, NULL, 0, 0, FILE_CREATE,
+                          FILE_DELETE_ON_CLOSE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
+    ok(!status, "ZwCreateFile failed: %#x\n", status);
+    ExFreePool(tmp_path);
+
+    status = ZwDuplicateObject(NtCurrentProcess(), file_handle, NtCurrentProcess(), &file_handle2,
+                               0, OBJ_KERNEL_HANDLE, DUPLICATE_SAME_ACCESS);
+    ok(!status, "ZwDuplicateObject failed: %#x\n", status);
+
+    InitializeObjectAttributes(&attr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
+    status = PsCreateSystemThread(&thread_handle, SYNCHRONIZE, &attr, NULL, NULL, thread_proc, NULL);
+    ok(!status, "PsCreateSystemThread returned: %#x\n", status);
+
+    status = ObReferenceObjectByHandle(NULL, SYNCHRONIZE, *pExEventObjectType, KernelMode, &obj1, NULL);
+    todo_wine
+    ok(status == STATUS_INVALID_HANDLE, "ObReferenceObjectByHandle failed: %#x\n", status);
+    if (!status) ObDereferenceObject(obj1);
+
+    status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, *pIoFileObjectType, KernelMode, &obj1, NULL);
+    todo_wine
+    ok(status == STATUS_OBJECT_TYPE_MISMATCH, "ObReferenceObjectByHandle returned: %#x\n", status);
+    if (!status) ObDereferenceObject(obj1);
+
+    status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, *pExEventObjectType, KernelMode, &obj1, NULL);
+    ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
+
+    if (sizeof(void *) != 4) /* avoid dealing with fastcall */
+    {
+        ObfReferenceObject(obj1);
+        ObDereferenceObject(obj1);
+    }
+
+    status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, *pIoFileObjectType, KernelMode, &obj2, NULL);
+    todo_wine
+    ok(status == STATUS_OBJECT_TYPE_MISMATCH, "ObReferenceObjectByHandle returned: %#x\n", status);
+    if (!status) ObDereferenceObject(obj2);
+
+    status = ObReferenceObjectByHandle(event_handle, SYNCHRONIZE, *pExEventObjectType, KernelMode, &obj2, NULL);
+    ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
+    ok(obj1 == obj2, "obj1 != obj2\n");
+
+    ObDereferenceObject(obj1);
+    ObDereferenceObject(obj2);
+
+    status = ObReferenceObjectByHandle(file_handle, SYNCHRONIZE, *pIoFileObjectType, KernelMode, &obj1, NULL);
+    ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
+
+    status = ObReferenceObjectByHandle(file_handle2, SYNCHRONIZE, *pIoFileObjectType, KernelMode, &obj2, NULL);
+    ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
+    ok(obj1 == obj2, "obj1 != obj2\n");
+
+    ObDereferenceObject(obj1);
+    ObDereferenceObject(obj2);
+
+    status = ObReferenceObjectByHandle(thread_handle, SYNCHRONIZE, *pPsThreadType, KernelMode, &obj1, NULL);
+    ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
+
+    status = ObReferenceObjectByHandle(thread_handle, SYNCHRONIZE, *pPsThreadType, KernelMode, &obj2, NULL);
+    ok(!status, "ObReferenceObjectByHandle failed: %#x\n", status);
+    ok(obj1 == obj2, "obj1 != obj2\n");
+
+    ObDereferenceObject(obj1);
+    ObDereferenceObject(obj2);
+
+    status = ZwClose(thread_handle);
+    ok(!status, "ZwClose failed: %#x\n", status);
+
+    status = ZwClose(event_handle);
+    ok(!status, "ZwClose failed: %#x\n", status);
+
+    status = ZwClose(file_handle);
+    ok(!status, "ZwClose failed: %#x\n", status);
+
+    status = ZwClose(file_handle2);
+    ok(!status, "ZwClose failed: %#x\n", status);
+}
+
 static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
 {
     ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength;
@@ -647,7 +773,6 @@ static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *st
 
     if (!buffer)
         return STATUS_ACCESS_VIOLATION;
-
     if (length < sizeof(failures))
         return STATUS_BUFFER_TOO_SMALL;
 
@@ -660,6 +785,15 @@ static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *st
     attr.Attributes = OBJ_KERNEL_HANDLE; /* needed to be accessible from system threads */
     ZwOpenFile(&okfile, FILE_APPEND_DATA | SYNCHRONIZE, &attr, &io, 0, FILE_SYNCHRONOUS_IO_NONALERT);
 
+    pExEventObjectType = get_proc_address("ExEventObjectType");
+    ok(!!pExEventObjectType, "ExEventObjectType not found\n");
+
+    pIoFileObjectType = get_proc_address("IoFileObjectType");
+    ok(!!pIoFileObjectType, "IofileObjectType not found\n");
+
+    pPsThreadType = get_proc_address("PsThreadType");
+    ok(!!pPsThreadType, "IofileObjectType not found\n");
+
     test_irp_struct(irp, device);
     test_currentprocess();
     test_mdl_map();
@@ -669,9 +803,10 @@ static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *st
     test_version();
     test_stack_callout();
     test_lookaside_list();
+    test_ob_reference(test_input->path);
 
     /* print process report */
-    if (test_input->winetest_debug)
+    if (winetest_debug)
     {
         kprintf("%04x:ntoskrnl: %d tests executed (%d marked as todo, %d %s), %d skipped.\n",
             PsGetCurrentProcessId(), successes + failures + todo_successes + todo_failures,




More information about the wine-cvs mailing list