Zhiyi Zhang : mountmgr: Add IOCTL_STORAGE_QUERY_PROPERTY stub.

Alexandre Julliard julliard at winehq.org
Tue Nov 20 15:39:50 CST 2018


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

Author: Zhiyi Zhang <zzhang at codeweavers.com>
Date:   Mon Nov 19 10:54:42 2018 +0800

mountmgr: Add IOCTL_STORAGE_QUERY_PROPERTY stub.

Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 2de66cd..21a2b31 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 <stdio.h>
 #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 f96b05e..6604b69 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;




More information about the wine-cvs mailing list