ntoskrnl.exe: Add work item tests.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2019-05-01 17:54:39 +02:00 committed by Alexandre Julliard
parent 43ba0a1bec
commit 7099c0be2c
2 changed files with 60 additions and 19 deletions

View File

@ -51,6 +51,7 @@ static int winetest_debug;
static int winetest_report_success; static int winetest_report_success;
static POBJECT_TYPE *pExEventObjectType, *pIoFileObjectType, *pPsThreadType; static POBJECT_TYPE *pExEventObjectType, *pIoFileObjectType, *pPsThreadType;
static PEPROCESS *pPsInitialSystemProcess;
void WINAPI ObfReferenceObject( void *obj ); void WINAPI ObfReferenceObject( void *obj );
@ -319,7 +320,7 @@ static NTSTATUS wait_single_handle(HANDLE handle, ULONGLONG timeout)
return ZwWaitForSingleObject(handle, FALSE, &integer); return ZwWaitForSingleObject(handle, FALSE, &integer);
} }
static void test_currentprocess(void) static void test_current_thread(BOOL is_system)
{ {
DISPATCHER_HEADER *header; DISPATCHER_HEADER *header;
PEPROCESS current; PEPROCESS current;
@ -334,6 +335,11 @@ static void test_currentprocess(void)
ret = wait_single(current, 0); ret = wait_single(current, 0);
ok(ret == STATUS_TIMEOUT, "got %#x\n", ret); 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"); ok(PsGetProcessId(current) == PsGetCurrentProcessId(), "process IDs don't match\n");
thread = PsGetCurrentThread(); thread = PsGetCurrentThread();
@ -341,7 +347,7 @@ static void test_currentprocess(void)
ok(ret == STATUS_TIMEOUT, "got %#x\n", ret); ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
ok(PsGetThreadId((PETHREAD)KeGetCurrentThread()) == PsGetCurrentThreadId(), "thread IDs don't match\n"); 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) static void sleep(void)
@ -1212,7 +1218,35 @@ static void test_lookup_thread(void)
"PsLookupThreadByThreadId returned %#x\n", status); "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; ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength;
void *buffer = irp->AssociatedIrp.SystemBuffer; 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"); pPsThreadType = get_proc_address("PsThreadType");
ok(!!pPsThreadType, "IofileObjectType not found\n"); ok(!!pPsThreadType, "IofileObjectType not found\n");
pPsInitialSystemProcess = get_proc_address("PsInitialSystemProcess");
ok(!!pPsInitialSystemProcess, "PsInitialSystemProcess not found\n");
test_irp_struct(irp, device); test_irp_struct(irp, device);
test_currentprocess(); test_current_thread(FALSE);
test_mdl_map(); test_mdl_map();
test_init_funcs(); test_init_funcs();
test_load_driver(); test_load_driver();
@ -1257,18 +1294,13 @@ static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *st
test_resource(); test_resource();
test_lookup_thread(); test_lookup_thread();
/* print process report */ if (main_test_work_item) return STATUS_UNEXPECTED_IO_ERROR;
if (winetest_debug)
{ main_test_work_item = IoAllocateWorkItem(device);
kprintf("%04x:ntoskrnl: %d tests executed (%d marked as todo, %d %s), %d skipped.\n", ok(main_test_work_item != NULL, "main_test_work_item = NULL\n");
PsGetCurrentProcessId(), successes + failures + todo_successes + todo_failures,
todo_successes, failures + todo_failures, IoQueueWorkItem(main_test_work_item, main_test_task, DelayedWorkQueue, irp);
(failures + todo_failures != 1) ? "failures" : "failure", skipped ); return STATUS_PENDING;
}
ZwClose(okfile);
*((LONG *)buffer) = failures;
*info = sizeof(failures);
return STATUS_SUCCESS;
} }
static NTSTATUS test_basic_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info) 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); status = test_basic_ioctl(irp, stack, &irp->IoStatus.Information);
break; break;
case IOCTL_WINETEST_MAIN_TEST: case IOCTL_WINETEST_MAIN_TEST:
status = main_test(device, irp, stack, &irp->IoStatus.Information); status = main_test(device, irp, stack);
break; break;
case IOCTL_WINETEST_LOAD_DRIVER: case IOCTL_WINETEST_LOAD_DRIVER:
status = test_load_driver_ioctl(irp, stack, &irp->IoStatus.Information); 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; break;
} }
if (status != STATUS_PENDING)
{
irp->IoStatus.Status = status; irp->IoStatus.Status = status;
IoCompleteRequest(irp, IO_NO_INCREMENT); IoCompleteRequest(irp, IO_NO_INCREMENT);
}
else IoMarkIrpPending(irp);
return status; return status;
} }

View File

@ -1505,6 +1505,11 @@ static inline void IoSetCompletionRoutine(IRP *irp, PIO_COMPLETION_ROUTINE routi
if (on_cancel) irpsp->Control |= SL_INVOKE_ON_CANCEL; 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 KernelMode 0
#define UserMode 1 #define UserMode 1