[PATCH v2 0/4] MR9941: ntoskrnl: Handle FileFsDeviceInformation.
-- v2: ntoskrnl: Handle FileFsDeviceInformation. ntoskrnl: Fill the Characteristics field of DEVICE_OBJECT. ntoskrnl/tests: Test DEVICE_OBJECT fields. ntoskrnl/tests: Test FileFsDeviceInformation. https://gitlab.winehq.org/wine/wine/-/merge_requests/9941
From: Elizabeth Figura <zfigura@codeweavers.com> --- dlls/ntoskrnl.exe/tests/driver.c | 12 ++++++++++-- dlls/ntoskrnl.exe/tests/ntoskrnl.c | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c index f30c340e9bd..ece4923dd06 100644 --- a/dlls/ntoskrnl.exe/tests/driver.c +++ b/dlls/ntoskrnl.exe/tests/driver.c @@ -2936,6 +2936,11 @@ static NTSTATUS WINAPI driver_QueryVolumeInformation(DEVICE_OBJECT *device, IRP return STATUS_PENDING; } + 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"); + /* fall through */ default: ret = STATUS_NOT_IMPLEMENTED; break; @@ -3011,14 +3016,17 @@ NTSTATUS WINAPI DriverEntry(DRIVER_OBJECT *driver, PUNICODE_STRING registry) RtlInitUnicodeString(&nameW, L"\\Device\\WineTestDriver"); RtlInitUnicodeString(&linkW, L"\\DosDevices\\WineTestDriver"); - status = IoCreateDevice(driver, 0, &nameW, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &lower_device); + status = IoCreateDevice(driver, 0, &nameW, FILE_DEVICE_UNKNOWN, + FILE_DEVICE_SECURE_OPEN | FILE_FLOPPY_DISKETTE | FILE_PORTABLE_DEVICE, + FALSE, &lower_device); ok(!status, "failed to create device, status %#lx\n", status); status = IoCreateSymbolicLink(&linkW, &nameW); ok(!status, "failed to create link, status %#lx\n", status); lower_device->Flags &= ~DO_DEVICE_INITIALIZING; RtlInitUnicodeString(&nameW, L"\\Device\\WineTestUpper"); - status = IoCreateDevice(driver, 0, &nameW, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &upper_device); + status = IoCreateDevice(driver, 16, &nameW, FILE_DEVICE_UNKNOWN, + FILE_DEVICE_SECURE_OPEN | FILE_READ_ONLY_DEVICE, FALSE, &upper_device); ok(!status, "failed to create device, status %#lx\n", status); IoAttachDeviceToDeviceStack(upper_device, lower_device); diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c index 0f0caf76132..944449ca859 100644 --- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c @@ -1187,6 +1187,7 @@ static void test_object_info(void) OBJECT_TYPE_INFORMATION *type_info = (OBJECT_TYPE_INFORMATION *)buffer; FILE_FS_VOLUME_INFORMATION *volume_info = (FILE_FS_VOLUME_INFORMATION *)buffer; FILE_NAME_INFORMATION *file_info = (FILE_NAME_INFORMATION *)buffer; + FILE_FS_DEVICE_INFORMATION device_info; HANDLE file; NTSTATUS status; IO_STATUS_BLOCK io; @@ -1208,6 +1209,26 @@ static void test_object_info(void) status = NtQueryVolumeInformationFile(device, &io, buffer, sizeof(buffer), FileFsVolumeInformation); todo_wine ok(status == STATUS_INVALID_DEVICE_REQUEST, "got %#lx\n", status); + 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(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); + } + file = CreateFileA("\\\\.\\WineTestDriver\\subfile", 0, 0, NULL, OPEN_EXISTING, 0, NULL); todo_wine ok(file != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError()); if (file == INVALID_HANDLE_VALUE) return; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9941
From: Elizabeth Figura <zfigura@codeweavers.com> --- dlls/ntoskrnl.exe/tests/driver.c | 44 ++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c index ece4923dd06..aea0a0bd252 100644 --- a/dlls/ntoskrnl.exe/tests/driver.c +++ b/dlls/ntoskrnl.exe/tests/driver.c @@ -2444,6 +2444,49 @@ static void test_default_security(void) FltFreeSecurityDescriptor(sd); } +static void test_device_object(void) +{ + todo_wine ok(lower_device->Type == 3, "Got type %d.\n", lower_device->Type); + todo_wine ok(lower_device->ReferenceCount == 1, "Got refcount %ld.\n", lower_device->ReferenceCount); + ok(lower_device->DriverObject == driver_obj, "Got driver %p.\n", lower_device->DriverObject); + ok(!lower_device->NextDevice, "Got next device %p.\n", lower_device->NextDevice); + ok(lower_device->AttachedDevice == upper_device, "Got attached device %p.\n", lower_device->AttachedDevice); + ok(!lower_device->CurrentIrp, "Got current IRP %p.\n", lower_device->CurrentIrp); + ok(!lower_device->Timer, "Got timer %p.\n", lower_device->Timer); + todo_wine ok(lower_device->Flags == 0x40, "Got flags %#lx.\n", lower_device->Flags); + todo_wine ok(lower_device->Characteristics == (FILE_DEVICE_SECURE_OPEN | FILE_FLOPPY_DISKETTE | FILE_PORTABLE_DEVICE), + "Got characteristics %#lx.\n", lower_device->Characteristics); + ok(!lower_device->Vpb, "Got VPB %p.\n", lower_device->Vpb); + todo_wine ok(!lower_device->DeviceExtension, "Got extension %p.\n", lower_device->DeviceExtension); + ok(lower_device->DeviceType == FILE_DEVICE_UNKNOWN, "Got device type %#lx.\n", lower_device->DeviceType); + ok(lower_device->StackSize == 1, "Got stack size %u.\n", lower_device->StackSize); + ok(!lower_device->AlignmentRequirement, "Got alignment %lu.\n", lower_device->AlignmentRequirement); + ok(!lower_device->ActiveThreadCount, "Got thread count %lu.\n", lower_device->ActiveThreadCount); + ok(!lower_device->SectorSize, "Got sector size %u.\n", lower_device->SectorSize); + todo_wine ok(lower_device->Spare1 == 0x1, "Got Spare1 %#x.\n", lower_device->Spare1); + ok(!lower_device->Reserved, "Got Reserved %p.\n", lower_device->Reserved); + + todo_wine ok(upper_device->Type == 3, "Got type %d.\n", upper_device->Type); + ok(!upper_device->ReferenceCount, "Got refcount %ld.\n", upper_device->ReferenceCount); + ok(upper_device->DriverObject == driver_obj, "Got driver %p.\n", upper_device->DriverObject); + ok(upper_device->NextDevice == lower_device, "Got next device %p.\n", upper_device->NextDevice); + ok(!upper_device->AttachedDevice, "Got attached device %p.\n", upper_device->AttachedDevice); + todo_wine ok(!upper_device->CurrentIrp, "Got current IRP %p.\n", upper_device->CurrentIrp); + ok(!upper_device->Timer, "Got timer %p.\n", upper_device->Timer); + todo_wine ok(upper_device->Flags == 0x40, "Got flags %#lx.\n", upper_device->Flags); + todo_wine ok(upper_device->Characteristics == (FILE_DEVICE_SECURE_OPEN | FILE_READ_ONLY_DEVICE), + "Got characteristics %#lx.\n", upper_device->Characteristics); + ok(!upper_device->Vpb, "Got VPB %p.\n", upper_device->Vpb); + ok(!!upper_device->DeviceExtension, "Expected extension.\n"); + ok(upper_device->DeviceType == FILE_DEVICE_UNKNOWN, "Got device type %#lx.\n", upper_device->DeviceType); + ok(upper_device->StackSize == 2, "Got stack size %u.\n", upper_device->StackSize); + ok(!upper_device->AlignmentRequirement, "Got alignment %lu.\n", upper_device->AlignmentRequirement); + ok(!upper_device->ActiveThreadCount, "Got thread count %lu.\n", upper_device->ActiveThreadCount); + ok(!upper_device->SectorSize, "Got sector size %u.\n", upper_device->SectorSize); + ok(!upper_device->Spare1, "Got Spare1 %#x.\n", upper_device->Spare1); + ok(!upper_device->Reserved, "Got Reserved %p.\n", upper_device->Reserved); +} + static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *stack) { void *buffer = irp->AssociatedIrp.SystemBuffer; @@ -2489,6 +2532,7 @@ static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *st test_permanence(); test_driver_object_extension(); test_default_security(); + test_device_object(); IoMarkIrpPending(irp); IoQueueWorkItem(work_item, main_test_task, DelayedWorkQueue, irp); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9941
From: Elizabeth Figura <zfigura@codeweavers.com> --- dlls/ntoskrnl.exe/ntoskrnl.c | 1 + dlls/ntoskrnl.exe/tests/driver.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index b3f45751b99..92dbfe7a282 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -1646,6 +1646,7 @@ NTSTATUS WINAPI IoCreateDevice( DRIVER_OBJECT *driver, ULONG ext_size, device = &wine_device->device_obj; device->DriverObject = driver; + device->Characteristics = characteristics; device->DeviceExtension = wine_device + 1; device->DeviceType = type; device->StackSize = 1; diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c index aea0a0bd252..76f7fd8d116 100644 --- a/dlls/ntoskrnl.exe/tests/driver.c +++ b/dlls/ntoskrnl.exe/tests/driver.c @@ -2454,7 +2454,7 @@ static void test_device_object(void) ok(!lower_device->CurrentIrp, "Got current IRP %p.\n", lower_device->CurrentIrp); ok(!lower_device->Timer, "Got timer %p.\n", lower_device->Timer); todo_wine ok(lower_device->Flags == 0x40, "Got flags %#lx.\n", lower_device->Flags); - todo_wine ok(lower_device->Characteristics == (FILE_DEVICE_SECURE_OPEN | FILE_FLOPPY_DISKETTE | FILE_PORTABLE_DEVICE), + ok(lower_device->Characteristics == (FILE_DEVICE_SECURE_OPEN | FILE_FLOPPY_DISKETTE | FILE_PORTABLE_DEVICE), "Got characteristics %#lx.\n", lower_device->Characteristics); ok(!lower_device->Vpb, "Got VPB %p.\n", lower_device->Vpb); todo_wine ok(!lower_device->DeviceExtension, "Got extension %p.\n", lower_device->DeviceExtension); @@ -2474,7 +2474,7 @@ static void test_device_object(void) todo_wine ok(!upper_device->CurrentIrp, "Got current IRP %p.\n", upper_device->CurrentIrp); ok(!upper_device->Timer, "Got timer %p.\n", upper_device->Timer); todo_wine ok(upper_device->Flags == 0x40, "Got flags %#lx.\n", upper_device->Flags); - todo_wine ok(upper_device->Characteristics == (FILE_DEVICE_SECURE_OPEN | FILE_READ_ONLY_DEVICE), + ok(upper_device->Characteristics == (FILE_DEVICE_SECURE_OPEN | FILE_READ_ONLY_DEVICE), "Got characteristics %#lx.\n", upper_device->Characteristics); ok(!upper_device->Vpb, "Got VPB %p.\n", upper_device->Vpb); ok(!!upper_device->DeviceExtension, "Expected extension.\n"); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9941
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
participants (2)
-
Elizabeth Figura -
Elizabeth Figura (@zfigura)