ntoskrnl.exe/tests: Add CancelIo tests.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
5f10c86d5b
commit
60ddf0f09e
|
@ -770,6 +770,15 @@ static void WINAPI cancel_irp(DEVICE_OBJECT *device, IRP *irp)
|
|||
cancel_cnt++;
|
||||
}
|
||||
|
||||
static void WINAPI cancel_ioctl_irp(DEVICE_OBJECT *device, IRP *irp)
|
||||
{
|
||||
IoReleaseCancelSpinLock(irp->CancelIrql);
|
||||
irp->IoStatus.Status = STATUS_CANCELLED;
|
||||
irp->IoStatus.Information = 0;
|
||||
cancel_cnt++;
|
||||
IoCompleteRequest(irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
static NTSTATUS WINAPI cancel_test_completion(DEVICE_OBJECT *device, IRP *irp, void *context)
|
||||
{
|
||||
ok(cancel_cnt == 1, "cancel_cnt = %d\n", cancel_cnt);
|
||||
|
@ -1505,6 +1514,22 @@ static NTSTATUS test_basic_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS get_cancel_count(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
|
||||
{
|
||||
ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
char *buffer = irp->AssociatedIrp.SystemBuffer;
|
||||
|
||||
if (!buffer)
|
||||
return STATUS_ACCESS_VIOLATION;
|
||||
|
||||
if (length < sizeof(DWORD))
|
||||
return STATUS_BUFFER_TOO_SMALL;
|
||||
|
||||
*(DWORD*)buffer = cancel_cnt;
|
||||
*info = sizeof(DWORD);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS test_load_driver_ioctl(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
|
||||
{
|
||||
BOOL *load = irp->AssociatedIrp.SystemBuffer;
|
||||
|
@ -1549,6 +1574,17 @@ static NTSTATUS WINAPI driver_IoControl(DEVICE_OBJECT *device, IRP *irp)
|
|||
case IOCTL_WINETEST_LOAD_DRIVER:
|
||||
status = test_load_driver_ioctl(irp, stack, &irp->IoStatus.Information);
|
||||
break;
|
||||
case IOCTL_WINETEST_RESET_CANCEL:
|
||||
cancel_cnt = 0;
|
||||
status = STATUS_SUCCESS;
|
||||
break;
|
||||
case IOCTL_WINETEST_TEST_CANCEL:
|
||||
IoSetCancelRoutine(irp, cancel_ioctl_irp);
|
||||
IoMarkIrpPending(irp);
|
||||
return STATUS_PENDING;
|
||||
case IOCTL_WINETEST_GET_CANCEL_COUNT:
|
||||
status = get_cancel_count(irp, stack, &irp->IoStatus.Information);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
#define IOCTL_WINETEST_BASIC_IOCTL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_WINETEST_MAIN_TEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_WINETEST_LOAD_DRIVER CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_WINETEST_RESET_CANCEL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_WINETEST_TEST_CANCEL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_WINETEST_GET_CANCEL_COUNT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
static const char teststr[] = "Wine is not an emulator";
|
||||
|
||||
|
|
|
@ -197,6 +197,85 @@ static void test_basic_ioctl(void)
|
|||
ok(!strcmp(buf, teststr), "got '%s'\n", buf);
|
||||
}
|
||||
|
||||
static void test_cancel_io(void)
|
||||
{
|
||||
OVERLAPPED overlapped, overlapped2;
|
||||
DWORD cancel_cnt;
|
||||
HANDLE file;
|
||||
BOOL res;
|
||||
|
||||
overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||
overlapped2.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
file = CreateFileA("\\\\.\\WineTestDriver", 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
|
||||
ok(file != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError());
|
||||
|
||||
/* test cancelling all device requests */
|
||||
res = DeviceIoControl(file, IOCTL_WINETEST_RESET_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
|
||||
todo_wine
|
||||
ok(res, "DeviceIoControl failed: %u\n", GetLastError());
|
||||
if (!res && GetLastError() == ERROR_IO_PENDING) WaitForSingleObject(overlapped.hEvent, INFINITE);
|
||||
|
||||
res = DeviceIoControl(file, IOCTL_WINETEST_TEST_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
|
||||
ok(!res && GetLastError() == ERROR_IO_PENDING, "DeviceIoControl failed: %u\n", GetLastError());
|
||||
|
||||
res = DeviceIoControl(file, IOCTL_WINETEST_TEST_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped2);
|
||||
ok(!res && GetLastError() == ERROR_IO_PENDING, "DeviceIoControl failed: %u\n", GetLastError());
|
||||
|
||||
cancel_cnt = 0xdeadbeef;
|
||||
res = DeviceIoControl(file, IOCTL_WINETEST_GET_CANCEL_COUNT, NULL, 0, &cancel_cnt, sizeof(cancel_cnt), NULL, &overlapped);
|
||||
todo_wine
|
||||
ok(res, "DeviceIoControl failed: %u\n", GetLastError());
|
||||
if (!res && GetLastError() == ERROR_IO_PENDING) WaitForSingleObject(overlapped.hEvent, INFINITE);
|
||||
ok(cancel_cnt == 0, "cancel_cnt = %u\n", cancel_cnt);
|
||||
|
||||
CancelIo(file);
|
||||
|
||||
cancel_cnt = 0xdeadbeef;
|
||||
res = DeviceIoControl(file, IOCTL_WINETEST_GET_CANCEL_COUNT, NULL, 0, &cancel_cnt, sizeof(cancel_cnt), NULL, &overlapped);
|
||||
todo_wine
|
||||
ok(res, "DeviceIoControl failed: %u\n", GetLastError());
|
||||
if (!res && GetLastError() == ERROR_IO_PENDING) WaitForSingleObject(overlapped.hEvent, INFINITE);
|
||||
todo_wine
|
||||
ok(cancel_cnt == 2, "cancel_cnt = %u\n", cancel_cnt);
|
||||
|
||||
/* test cancelling selected overlapped event */
|
||||
res = DeviceIoControl(file, IOCTL_WINETEST_RESET_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
|
||||
todo_wine
|
||||
ok(res, "DeviceIoControl failed: %u\n", GetLastError());
|
||||
if (!res && GetLastError() == ERROR_IO_PENDING) WaitForSingleObject(overlapped.hEvent, INFINITE);
|
||||
|
||||
res = DeviceIoControl(file, IOCTL_WINETEST_TEST_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped);
|
||||
ok(!res && GetLastError() == ERROR_IO_PENDING, "DeviceIoControl failed: %u\n", GetLastError());
|
||||
|
||||
res = DeviceIoControl(file, IOCTL_WINETEST_TEST_CANCEL, NULL, 0, NULL, 0, NULL, &overlapped2);
|
||||
ok(!res && GetLastError() == ERROR_IO_PENDING, "DeviceIoControl failed: %u\n", GetLastError());
|
||||
|
||||
CancelIoEx(file, &overlapped);
|
||||
|
||||
cancel_cnt = 0xdeadbeef;
|
||||
res = DeviceIoControl(file, IOCTL_WINETEST_GET_CANCEL_COUNT, NULL, 0, &cancel_cnt, sizeof(cancel_cnt), NULL, &overlapped);
|
||||
todo_wine
|
||||
ok(res, "DeviceIoControl failed: %u\n", GetLastError());
|
||||
if (!res && GetLastError() == ERROR_IO_PENDING) WaitForSingleObject(overlapped.hEvent, INFINITE);
|
||||
todo_wine
|
||||
ok(cancel_cnt == 1, "cancel_cnt = %u\n", cancel_cnt);
|
||||
|
||||
CancelIoEx(file, &overlapped2);
|
||||
|
||||
cancel_cnt = 0xdeadbeef;
|
||||
res = DeviceIoControl(file, IOCTL_WINETEST_GET_CANCEL_COUNT, NULL, 0, &cancel_cnt, sizeof(cancel_cnt), NULL, &overlapped);
|
||||
todo_wine
|
||||
ok(res, "DeviceIoControl failed: %u\n", GetLastError());
|
||||
if (!res && GetLastError() == ERROR_IO_PENDING) WaitForSingleObject(overlapped.hEvent, INFINITE);
|
||||
todo_wine
|
||||
ok(cancel_cnt == 2, "cancel_cnt = %u\n", cancel_cnt);
|
||||
|
||||
CloseHandle(overlapped.hEvent);
|
||||
CloseHandle(overlapped2.hEvent);
|
||||
CloseHandle(file);
|
||||
}
|
||||
|
||||
static void test_load_driver(SC_HANDLE service)
|
||||
{
|
||||
SERVICE_STATUS status;
|
||||
|
@ -268,6 +347,7 @@ START_TEST(ntoskrnl)
|
|||
|
||||
test_basic_ioctl();
|
||||
main_test();
|
||||
test_cancel_io();
|
||||
test_load_driver(service2);
|
||||
|
||||
unload_driver(service2);
|
||||
|
|
Loading…
Reference in New Issue