Jacek Caban : ntoskrnl.exe: Add work item tests.
Alexandre Julliard
julliard at winehq.org
Wed May 1 16:37:07 CDT 2019
Module: wine
Branch: master
Commit: 7099c0be2cc93a46d916e9a5cb2057be8af7b911
URL: https://source.winehq.org/git/wine.git/?a=commit;h=7099c0be2cc93a46d916e9a5cb2057be8af7b911
Author: Jacek Caban <jacek at codeweavers.com>
Date: Wed May 1 17:54:39 2019 +0200
ntoskrnl.exe: Add work item tests.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntoskrnl.exe/tests/driver.c | 74 +++++++++++++++++++++++++++++-----------
include/ddk/wdm.h | 5 +++
2 files changed, 60 insertions(+), 19 deletions(-)
diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c
index e5d5dd8..ac31a4d 100644
--- a/dlls/ntoskrnl.exe/tests/driver.c
+++ b/dlls/ntoskrnl.exe/tests/driver.c
@@ -51,6 +51,7 @@ static int winetest_debug;
static int winetest_report_success;
static POBJECT_TYPE *pExEventObjectType, *pIoFileObjectType, *pPsThreadType;
+static PEPROCESS *pPsInitialSystemProcess;
void WINAPI ObfReferenceObject( void *obj );
@@ -319,7 +320,7 @@ static NTSTATUS wait_single_handle(HANDLE handle, ULONGLONG timeout)
return ZwWaitForSingleObject(handle, FALSE, &integer);
}
-static void test_currentprocess(void)
+static void test_current_thread(BOOL is_system)
{
DISPATCHER_HEADER *header;
PEPROCESS current;
@@ -334,6 +335,11 @@ static void test_currentprocess(void)
ret = wait_single(current, 0);
ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
+ if (is_system)
+ ok(current == *pPsInitialSystemProcess, "current != PsInitialSystemProcess\n");
+ else
+ ok(current != *pPsInitialSystemProcess, "current == PsInitialSystemProcess\n");
+
ok(PsGetProcessId(current) == PsGetCurrentProcessId(), "process IDs don't match\n");
thread = PsGetCurrentThread();
@@ -341,7 +347,7 @@ static void test_currentprocess(void)
ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
ok(PsGetThreadId((PETHREAD)KeGetCurrentThread()) == PsGetCurrentThreadId(), "thread IDs don't match\n");
- ok(!PsIsSystemThread((PETHREAD)KeGetCurrentThread()), "unexpected system thread\n");
+ ok(PsIsSystemThread((PETHREAD)KeGetCurrentThread()) == is_system, "unexpected system thread\n");
}
static void sleep(void)
@@ -1212,7 +1218,35 @@ static void test_lookup_thread(void)
"PsLookupThreadByThreadId returned %#x\n", status);
}
-static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
+static PIO_WORKITEM main_test_work_item;
+
+static void WINAPI main_test_task(DEVICE_OBJECT *device, void *context)
+{
+ IRP *irp = context;
+ void *buffer = irp->AssociatedIrp.SystemBuffer;
+
+ IoFreeWorkItem(main_test_work_item);
+ main_test_work_item = NULL;
+
+ test_current_thread(TRUE);
+
+ /* print process report */
+ 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,
+ todo_successes, failures + todo_failures,
+ (failures + todo_failures != 1) ? "failures" : "failure", skipped );
+ }
+ ZwClose(okfile);
+
+ *((LONG *)buffer) = failures;
+ irp->IoStatus.Status = STATUS_SUCCESS;
+ irp->IoStatus.Information = sizeof(failures);
+ IoCompleteRequest(irp, IO_NO_INCREMENT);
+}
+
+static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *stack)
{
ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength;
void *buffer = irp->AssociatedIrp.SystemBuffer;
@@ -1244,8 +1278,11 @@ static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *st
pPsThreadType = get_proc_address("PsThreadType");
ok(!!pPsThreadType, "IofileObjectType not found\n");
+ pPsInitialSystemProcess = get_proc_address("PsInitialSystemProcess");
+ ok(!!pPsInitialSystemProcess, "PsInitialSystemProcess not found\n");
+
test_irp_struct(irp, device);
- test_currentprocess();
+ test_current_thread(FALSE);
test_mdl_map();
test_init_funcs();
test_load_driver();
@@ -1257,18 +1294,13 @@ static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *st
test_resource();
test_lookup_thread();
- /* print process report */
- 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,
- todo_successes, failures + todo_failures,
- (failures + todo_failures != 1) ? "failures" : "failure", skipped );
- }
- ZwClose(okfile);
- *((LONG *)buffer) = failures;
- *info = sizeof(failures);
- return STATUS_SUCCESS;
+ if (main_test_work_item) return STATUS_UNEXPECTED_IO_ERROR;
+
+ main_test_work_item = IoAllocateWorkItem(device);
+ ok(main_test_work_item != NULL, "main_test_work_item = NULL\n");
+
+ IoQueueWorkItem(main_test_work_item, main_test_task, DelayedWorkQueue, irp);
+ return STATUS_PENDING;
}
static NTSTATUS test_basic_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
@@ -1327,7 +1359,7 @@ static NTSTATUS WINAPI driver_IoControl(DEVICE_OBJECT *device, IRP *irp)
status = test_basic_ioctl(irp, stack, &irp->IoStatus.Information);
break;
case IOCTL_WINETEST_MAIN_TEST:
- status = main_test(device, irp, stack, &irp->IoStatus.Information);
+ status = main_test(device, irp, stack);
break;
case IOCTL_WINETEST_LOAD_DRIVER:
status = test_load_driver_ioctl(irp, stack, &irp->IoStatus.Information);
@@ -1336,8 +1368,12 @@ static NTSTATUS WINAPI driver_IoControl(DEVICE_OBJECT *device, IRP *irp)
break;
}
- irp->IoStatus.Status = status;
- IoCompleteRequest(irp, IO_NO_INCREMENT);
+ if (status != STATUS_PENDING)
+ {
+ irp->IoStatus.Status = status;
+ IoCompleteRequest(irp, IO_NO_INCREMENT);
+ }
+ else IoMarkIrpPending(irp);
return status;
}
diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h
index f2b2723..25f2d49 100644
--- a/include/ddk/wdm.h
+++ b/include/ddk/wdm.h
@@ -1505,6 +1505,11 @@ static inline void IoSetCompletionRoutine(IRP *irp, PIO_COMPLETION_ROUTINE routi
if (on_cancel) irpsp->Control |= SL_INVOKE_ON_CANCEL;
}
+static inline void IoMarkIrpPending(IRP *irp)
+{
+ IoGetCurrentIrpStackLocation(irp)->Control |= SL_PENDING_RETURNED;
+}
+
#define KernelMode 0
#define UserMode 1
More information about the wine-cvs
mailing list