From 33de7fb7a8522052d34c0d26067720d007a9dad7 Mon Sep 17 00:00:00 2001 From: Zhiyi Zhang Date: Mon, 19 Nov 2018 10:54:42 +0800 Subject: [PATCH] mountmgr: Add IOCTL_STORAGE_QUERY_PROPERTY stub. Signed-off-by: Zhiyi Zhang Signed-off-by: Alexandre Julliard --- dlls/kernel32/tests/volume.c | 46 +++++++++++++++++++++++ dlls/mountmgr.sys/device.c | 71 ++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c index 2de66cdfd0f..21a2b313e56 100644 --- a/dlls/kernel32/tests/volume.c +++ b/dlls/kernel32/tests/volume.c @@ -21,6 +21,7 @@ #include "wine/test.h" #include "winbase.h" #include "winioctl.h" +#include "ntddstor.h" #include #include "ddk/ntddcdvd.h" @@ -590,6 +591,50 @@ static void test_disk_extents(void) CloseHandle( handle ); } +static void test_disk_query_property(void) +{ + STORAGE_PROPERTY_QUERY query = {0}; + STORAGE_DESCRIPTOR_HEADER header = {0}; + STORAGE_DEVICE_DESCRIPTOR descriptor = {0}; + HANDLE handle; + DWORD error; + DWORD size; + BOOL ret; + + handle = CreateFileA("\\\\.\\PhysicalDrive0", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + 0, 0); + if (handle == INVALID_HANDLE_VALUE) + { + win_skip("can't open \\\\.\\PhysicalDrive0 %#x\n", GetLastError()); + return; + } + + query.PropertyId = StorageDeviceProperty; + query.QueryType = PropertyStandardQuery; + + SetLastError(0xdeadbeef); + ret = DeviceIoControl(handle, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), &header, sizeof(header), &size, + NULL); + error = GetLastError(); + ok(ret, "expect ret %#x, got %#x\n", TRUE, ret); + ok(error == 0xdeadbeef, "expect err %#x, got err %#x\n", 0xdeadbeef, error); + ok(size == sizeof(header), "got size %d\n", size); + ok(header.Version == sizeof(descriptor), "got header.Version %d\n", header.Version); + ok(header.Size >= sizeof(descriptor), "got header.Size %d\n", header.Size); + + SetLastError(0xdeadbeef); + ret = DeviceIoControl(handle, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), &descriptor, sizeof(descriptor), + &size, NULL); + error = GetLastError(); + ok(ret, "expect ret %#x, got %#x\n", TRUE, ret); + ok(error == 0xdeadbeef, "expect err %#x, got err %#x\n", 0xdeadbeef, error); + ok(size == sizeof(descriptor), "got size %d\n", size); + ok(descriptor.Version == sizeof(descriptor), "got descriptor.Version %d\n", descriptor.Version); + ok(descriptor.Size >= sizeof(descriptor), "got descriptor.Size %d\n", descriptor.Size); + + CloseHandle(handle); +} + static void test_GetVolumePathNameA(void) { char volume_path[MAX_PATH], cwd[MAX_PATH]; @@ -1238,6 +1283,7 @@ START_TEST(volume) test_GetVolumeInformationA(); test_enum_vols(); test_disk_extents(); + test_disk_query_property(); test_GetVolumePathNamesForVolumeNameA(); test_GetVolumePathNamesForVolumeNameW(); test_cdrom_ioctl(); diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c index f96b05e4dae..6604b69ef89 100644 --- a/dlls/mountmgr.sys/device.c +++ b/dlls/mountmgr.sys/device.c @@ -890,6 +890,74 @@ NTSTATUS query_dos_device( int letter, enum device_type *type, char **device, ch return status; } +static void query_property(IRP *irp) +{ + IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); + STORAGE_PROPERTY_QUERY *query = irp->AssociatedIrp.SystemBuffer; + + if (!irp->AssociatedIrp.SystemBuffer + || irpsp->Parameters.DeviceIoControl.InputBufferLength < sizeof(STORAGE_PROPERTY_QUERY)) + { + irp->IoStatus.u.Status = STATUS_INVALID_PARAMETER; + return; + } + + /* Try to persuade application not to check property */ + if (query->QueryType == PropertyExistsQuery) + { + irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED; + return; + } + + switch (query->PropertyId) + { + case StorageDeviceProperty: + { + STORAGE_DEVICE_DESCRIPTOR *descriptor; + + if (!irp->UserBuffer + || irpsp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_DESCRIPTOR_HEADER)) + irp->IoStatus.u.Status = STATUS_INVALID_PARAMETER; + else if (irpsp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_DEVICE_DESCRIPTOR)) + { + descriptor = irp->UserBuffer; + descriptor->Version = sizeof(STORAGE_DEVICE_DESCRIPTOR); + descriptor->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR); + irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER); + irp->IoStatus.u.Status = STATUS_SUCCESS; + } + else + { + FIXME( "Faking StorageDeviceProperty data\n" ); + + memset( irp->UserBuffer, 0, irpsp->Parameters.DeviceIoControl.OutputBufferLength ); + descriptor = irp->UserBuffer; + descriptor->Version = sizeof(STORAGE_DEVICE_DESCRIPTOR); + descriptor->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR); + descriptor->DeviceType = FILE_DEVICE_DISK; + descriptor->DeviceTypeModifier = 0; + descriptor->RemovableMedia = FALSE; + descriptor->CommandQueueing = FALSE; + descriptor->VendorIdOffset = 0; + descriptor->ProductIdOffset = 0; + descriptor->ProductRevisionOffset = 0; + descriptor->SerialNumberOffset = 0; + descriptor->BusType = BusTypeScsi; + descriptor->RawPropertiesLength = 0; + + irp->IoStatus.Information = sizeof(STORAGE_DEVICE_DESCRIPTOR); + irp->IoStatus.u.Status = STATUS_SUCCESS; + } + + break; + } + default: + FIXME( "Unsupported property %#x\n", query->PropertyId ); + irp->IoStatus.u.Status = STATUS_NOT_SUPPORTED; + break; + } +} + /* handler for ioctls on the harddisk device */ static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp ) { @@ -962,6 +1030,9 @@ static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp ) irp->IoStatus.u.Status = STATUS_SUCCESS; break; } + case IOCTL_STORAGE_QUERY_PROPERTY: + query_property( irp ); + break; default: { ULONG code = irpsp->Parameters.DeviceIoControl.IoControlCode;