Zebediah Figura : ntoskrnl/tests: Test a pending NtQueryVolumeInformation call on an overlapped file handle.

Alexandre Julliard julliard at winehq.org
Thu Sep 9 15:42:31 CDT 2021


Module: wine
Branch: master
Commit: 0f7c784fb7b1309382d0b2cf4656f28c297f9383
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=0f7c784fb7b1309382d0b2cf4656f28c297f9383

Author: Zebediah Figura <zfigura at codeweavers.com>
Date:   Fri Sep  3 23:11:40 2021 -0500

ntoskrnl/tests: Test a pending NtQueryVolumeInformation call on an overlapped file handle.

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 7b61f131e96..682af256b43 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. */




More information about the wine-cvs mailing list