From: Elizabeth Figura <zfigura@codeweavers.com> --- dlls/ntoskrnl.exe/ntoskrnl.c | 33 ++++++++++++++++++++++++++++-- dlls/ntoskrnl.exe/tests/driver.c | 2 +- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 17 +++++++-------- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 92dbfe7a282..59fff096ca9 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -510,6 +510,10 @@ struct dispatch_context struct irp_data *irp_data; ULONG in_size; void *in_buff; + /* These output fields are only for special IRPs handled by ntoskrnl itself, + * for which we do not actually allocate an IRP structure nor irp_data. */ + void *out_buff; + ULONG_PTR out_size; }; static NTSTATUS dispatch_irp( DEVICE_OBJECT *device, IRP *irp, struct dispatch_context *context ) @@ -807,6 +811,21 @@ static NTSTATUS dispatch_volume( struct dispatch_context *context ) if (!(out_buff = HeapAlloc( GetProcessHeap(), 0, out_size ))) return STATUS_NO_MEMORY; + if (context->params.volume.info_class == FileFsDeviceInformation) + { + /* Handled by ntoskrnl; never passed to the driver. */ + FILE_FS_DEVICE_INFORMATION *info = out_buff; + + if (out_size < sizeof(FILE_FS_DEVICE_INFORMATION)) + return STATUS_INFO_LENGTH_MISMATCH; + + info->DeviceType = file->DeviceObject->DeviceType; + info->Characteristics = file->DeviceObject->Characteristics; + context->out_buff = out_buff; + context->out_size = sizeof(FILE_FS_DEVICE_INFORMATION); + return STATUS_SUCCESS; + } + irp = IoAllocateIrp( device->StackSize, FALSE ); if (!irp) { @@ -981,8 +1000,12 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event ) } else { - req->user_ptr = 0; - req->status = status; + req->user_ptr = 0; + req->status = status; + req->pending = 0; + req->iosb_status = status; + req->result = context.out_size; + if (context.out_size) wine_server_add_data( req, context.out_buff, context.out_size ); } wine_server_set_reply( req, context.in_buff, context.in_size ); @@ -1016,6 +1039,12 @@ NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event ) context.irp_data->async = TRUE; } } + else + { + free( context.out_buff ); + context.out_buff = NULL; + context.out_size = 0; + } LeaveCriticalSection( &irp_completion_cs ); diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c index 76f7fd8d116..9358cf605a4 100644 --- a/dlls/ntoskrnl.exe/tests/driver.c +++ b/dlls/ntoskrnl.exe/tests/driver.c @@ -2983,7 +2983,7 @@ static NTSTATUS WINAPI driver_QueryVolumeInformation(DEVICE_OBJECT *device, IRP case FileFsDeviceInformation: /* This one is actually handled by the I/O manager; * it's never passed down to a driver. */ - todo_wine ok(0, "Unexpected call.\n"); + ok(0, "Unexpected call.\n"); /* fall through */ default: ret = STATUS_NOT_IMPLEMENTED; diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index 944449ca859..06279b1c49e 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -1212,22 +1212,19 @@ static void test_object_info(void) io.Status = 0xdeadf00d; io.Information = 0xdeadf00d; status = NtQueryVolumeInformationFile(device, &io, &device_info, sizeof(device_info) - 1, FileFsDeviceInformation); - todo_wine ok(status == STATUS_INFO_LENGTH_MISMATCH, "got %#lx\n", status); + ok(status == STATUS_INFO_LENGTH_MISMATCH, "got %#lx\n", status); ok(io.Status == 0xdeadf00d, "got status %#lx\n", io.Status); ok(io.Information == 0xdeadf00d, "got information %Iu\n", io.Information); io.Status = 0xdeadf00d; io.Information = 0xdeadf00d; status = NtQueryVolumeInformationFile(device, &io, &device_info, sizeof(device_info), FileFsDeviceInformation); - todo_wine ok(!status, "got %#lx\n", status); - todo_wine ok(!io.Status, "got status %#lx\n", io.Status); - todo_wine ok(io.Information == sizeof(FILE_FS_DEVICE_INFORMATION), "got information %Iu\n", io.Information); - if (!status) - { - ok(device_info.DeviceType == FILE_DEVICE_UNKNOWN, "Got type %#lx.\n", device_info.DeviceType); - ok(device_info.Characteristics == (FILE_DEVICE_SECURE_OPEN | FILE_FLOPPY_DISKETTE | FILE_PORTABLE_DEVICE), - "Got characteristics %#lx.\n", device_info.Characteristics); - } + ok(!status, "got %#lx\n", status); + ok(!io.Status, "got status %#lx\n", io.Status); + ok(io.Information == sizeof(FILE_FS_DEVICE_INFORMATION), "got information %Iu\n", io.Information); + ok(device_info.DeviceType == FILE_DEVICE_UNKNOWN, "Got type %#lx.\n", device_info.DeviceType); + ok(device_info.Characteristics == (FILE_DEVICE_SECURE_OPEN | FILE_FLOPPY_DISKETTE | FILE_PORTABLE_DEVICE), + "Got characteristics %#lx.\n", device_info.Characteristics); file = CreateFileA("\\\\.\\WineTestDriver\\subfile", 0, 0, NULL, OPEN_EXISTING, 0, NULL); todo_wine ok(file != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError()); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9941