Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/ntoskrnl.exe/tests/driver.c | 59 +++++++++++++++++++++++++----- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 44 ++++++++++++++++++++++ 2 files changed, 93 insertions(+), 10 deletions(-)
diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c index 0d40053b0e6..8cb97507ab5 100644 --- a/dlls/ntoskrnl.exe/tests/driver.c +++ b/dlls/ntoskrnl.exe/tests/driver.c @@ -1959,15 +1959,12 @@ static void test_object_name(void) ok(!name->Name.MaximumLength, "got maximum length %u\n", name->Name.MaximumLength); }
-static PIO_WORKITEM main_test_work_item; +static PIO_WORKITEM work_item;
static void WINAPI main_test_task(DEVICE_OBJECT *device, void *context) { IRP *irp = context;
- IoFreeWorkItem(main_test_work_item); - main_test_work_item = NULL; - test_current_thread(TRUE); test_critical_region(FALSE); test_call_driver(device); @@ -2337,13 +2334,8 @@ static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *st test_process_memory(test_input); test_permanence();
- if (main_test_work_item) return STATUS_UNEXPECTED_IO_ERROR; - - main_test_work_item = IoAllocateWorkItem(lower_device); - ok(main_test_work_item != NULL, "main_test_work_item = NULL\n"); - IoMarkIrpPending(irp); - IoQueueWorkItem(main_test_work_item, main_test_task, DelayedWorkQueue, irp); + IoQueueWorkItem(work_item, main_test_task, DelayedWorkQueue, irp);
return STATUS_PENDING; } @@ -2611,6 +2603,32 @@ static NTSTATUS WINAPI driver_FlushBuffers(DEVICE_OBJECT *device, IRP *irp) return STATUS_PENDING; }
+static void WINAPI blocking_irp_task(DEVICE_OBJECT *device, void *context) +{ + LARGE_INTEGER timeout; + IRP *irp = context; + + timeout.QuadPart = -100 * 10000; + KeDelayExecutionThread( KernelMode, FALSE, &timeout ); + + irp->IoStatus.Status = STATUS_SUCCESS; + irp->IoStatus.Information = 0; + IoCompleteRequest(irp, IO_NO_INCREMENT); +} + +static void WINAPI blocking_irp_failure_task(DEVICE_OBJECT *device, void *context) +{ + LARGE_INTEGER timeout; + IRP *irp = context; + + timeout.QuadPart = -100 * 10000; + KeDelayExecutionThread( KernelMode, FALSE, &timeout ); + + irp->IoStatus.Status = STATUS_DEVICE_NOT_READY; + irp->IoStatus.Information = 0; + IoCompleteRequest(irp, IO_NO_INCREMENT); +} + static BOOL compare_file_name(const struct file_context *context, const WCHAR *expect) { return context->namelen == wcslen(expect) * sizeof(WCHAR) @@ -2717,6 +2735,21 @@ static NTSTATUS WINAPI driver_QueryVolumeInformation(DEVICE_OBJECT *device, IRP ret = STATUS_SUCCESS; break; } + + case FileFsSizeInformation: + { + IoMarkIrpPending(irp); + IoQueueWorkItem(work_item, blocking_irp_task, DelayedWorkQueue, irp); + return STATUS_PENDING; + } + + case FileFsFullSizeInformation: + { + IoMarkIrpPending(irp); + IoQueueWorkItem(work_item, blocking_irp_failure_task, DelayedWorkQueue, irp); + return STATUS_PENDING; + } + default: ret = STATUS_NOT_IMPLEMENTED; break; @@ -2744,6 +2777,9 @@ static VOID WINAPI driver_Unload(DRIVER_OBJECT *driver)
DbgPrint("unloading driver\n");
+ IoFreeWorkItem(work_item); + work_item = NULL; + RtlInitUnicodeString(&linkW, L"\DosDevices\WineTestDriver"); IoDeleteSymbolicLink(&linkW);
@@ -2802,5 +2838,8 @@ NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, PUNICODE_STRING registry) IoAttachDeviceToDeviceStack(upper_device, lower_device); upper_device->Flags &= ~DO_DEVICE_INITIALIZING;
+ work_item = IoAllocateWorkItem(lower_device); + ok(work_item != NULL, "work_item = NULL\n"); + return STATUS_SUCCESS; } diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index b85c0078620..4f8dd6585a4 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -1139,6 +1139,49 @@ static void test_object_info(void) CloseHandle(file); }
+static void test_blocking_irp(void) +{ + char buffer[40]; + IO_STATUS_BLOCK io; + NTSTATUS status; + HANDLE file; + + file = CreateFileA("\\.\WineTestDriver\", FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, 0, NULL); + ok(file != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError()); + + memset(&io, 0xcc, sizeof(io)); + status = NtQueryVolumeInformationFile(file, &io, buffer, sizeof(buffer), FileFsSizeInformation); + ok(!status, "got %#x\n", status); + ok(!io.Status, "got iosb status %#x\n", io.Status); + ok(!io.Information, "got information %#Ix\n", io.Information); + + io.Status = 0xdeadf00d; + io.Information = 0xdeadf00d; + status = NtQueryVolumeInformationFile(file, &io, buffer, sizeof(buffer), FileFsFullSizeInformation); + ok(status == STATUS_DEVICE_NOT_READY, "got %#x\n", status); + todo_wine ok(io.Status == 0xdeadf00d, "got iosb status %#x\n", io.Status); + todo_wine ok(io.Information == 0xdeadf00d, "got information %#Ix\n", io.Information); + + CloseHandle(file); + + file = CreateFileA("\\.\WineTestDriver\", FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + ok(file != INVALID_HANDLE_VALUE, "failed to open device: %u\n", GetLastError()); + + memset(&io, 0xcc, sizeof(io)); + status = NtQueryVolumeInformationFile(file, &io, buffer, sizeof(buffer), FileFsSizeInformation); + todo_wine ok(!status, "got %#x\n", status); + todo_wine ok(!io.Status, "got iosb status %#x\n", io.Status); + todo_wine ok(!io.Information, "got information %#Ix\n", io.Information); + + memset(&io, 0xcc, sizeof(io)); + status = NtQueryVolumeInformationFile(file, &io, buffer, sizeof(buffer), FileFsFullSizeInformation); + todo_wine ok(status == STATUS_DEVICE_NOT_READY, "got %#x\n", status); + todo_wine ok(io.Status == STATUS_DEVICE_NOT_READY, "got iosb status %#x\n", io.Status); + todo_wine ok(!io.Information, "got information %#Ix\n", io.Information); + + CloseHandle(file); +} + static void test_driver3(struct testsign_context *ctx) { WCHAR filename[MAX_PATH]; @@ -3487,6 +3530,7 @@ START_TEST(ntoskrnl) test_file_handles(); test_return_status(); test_object_info(); + test_blocking_irp();
/* We need a separate ioctl to call IoDetachDevice(); calling it in the * driver unload routine causes a live-lock. */