Module: wine Branch: master Commit: 7099c0be2cc93a46d916e9a5cb2057be8af7b911 URL: https://source.winehq.org/git/wine.git/?a=commit;h=7099c0be2cc93a46d916e9a5c...
Author: Jacek Caban jacek@codeweavers.com Date: Wed May 1 17:54:39 2019 +0200
ntoskrnl.exe: Add work item tests.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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