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