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

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2021-09-03 23:11:40 -05:00 committed by Alexandre Julliard
parent 32347fcf08
commit 0f7c784fb7
2 changed files with 93 additions and 10 deletions

View File

@ -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;
}

View File

@ -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. */