Allows programs which demand support for StorageDeviceSeekPenaltyProperty to function.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51065 Signed-off-by: David Koolhoven david@koolhoven-home.net --- v12: Fixed whitespace. --- dlls/mountmgr.sys/device.c | 17 +++++++++++++++++ include/ntddstor.h | 9 ++++++++- 2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c index 04e8fe3c0f5..3c412354429 100644 --- a/dlls/mountmgr.sys/device.c +++ b/dlls/mountmgr.sys/device.c @@ -1894,6 +1894,23 @@ static NTSTATUS query_property( struct disk_device *device, IRP *irp )
break; } + case StorageDeviceSeekPenaltyProperty: + { + DEVICE_SEEK_PENALTY_DESCRIPTOR *descriptor; + FIXME( "Faking StorageDeviceSeekPenaltyProperty data with no penalty\n" ); + if (irpsp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DEVICE_SEEK_PENALTY_DESCRIPTOR)) { + status = STATUS_INVALID_PARAMETER; + break; + } + memset( irp->AssociatedIrp.SystemBuffer, 0, sizeof(DEVICE_SEEK_PENALTY_DESCRIPTOR) ); + descriptor = irp->AssociatedIrp.SystemBuffer; + descriptor->Version = sizeof(DEVICE_SEEK_PENALTY_DESCRIPTOR); + descriptor->Size = sizeof(DEVICE_SEEK_PENALTY_DESCRIPTOR); + descriptor->IncursSeekPenalty = FALSE; + status = STATUS_SUCCESS; + irp->IoStatus.Information = sizeof(DEVICE_SEEK_PENALTY_DESCRIPTOR); + break; + } default: FIXME( "Unsupported property %#x\n", query->PropertyId ); status = STATUS_NOT_SUPPORTED; diff --git a/include/ntddstor.h b/include/ntddstor.h index b8c4bb73b0d..836def413fe 100644 --- a/include/ntddstor.h +++ b/include/ntddstor.h @@ -214,7 +214,8 @@ typedef enum _STORAGE_QUERY_TYPE {
typedef enum _STORAGE_PROPERTY_ID { StorageDeviceProperty = 0, - StorageAdapterProperty + StorageAdapterProperty = 1, + StorageDeviceSeekPenaltyProperty = 7, } STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID;
typedef struct _STORAGE_PROPERTY_QUERY { @@ -272,6 +273,12 @@ typedef struct _STORAGE_ADAPTER_DESCRIPTOR { USHORT BusMinorVersion; } STORAGE_ADAPTER_DESCRIPTOR, *PSTORAGE_ADAPTER_DESCRIPTOR;
+typedef struct _DEVICE_SEEK_PENALTY_DESCRIPTOR { + ULONG Version; + ULONG Size; + BOOLEAN IncursSeekPenalty; +} DEVICE_SEEK_PENALTY_DESCRIPTOR, *PDEVICE_SEEK_PENALTY_DESCRIPTOR; + #ifdef __cplusplus } #endif
Helps test for compatibility with SeekPenaltyQueryProperty.
Signed-off-by: David Koolhoven david@koolhoven-home.net --- v12: Update with complementary feature introduction. --- dlls/kernel32/tests/volume.c | 45 ++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)
diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c index ed3897a6b94..386dfcd6166 100644 --- a/dlls/kernel32/tests/volume.c +++ b/dlls/kernel32/tests/volume.c @@ -654,6 +654,50 @@ static void test_disk_query_property(void) CloseHandle(handle); }
+static void test_disk_query_seek_penalty_property(void) +{ + STORAGE_PROPERTY_QUERY query = {0}; + DEVICE_SEEK_PENALTY_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 = (STORAGE_PROPERTY_ID)StorageDeviceSeekPenaltyProperty; + query.QueryType = PropertyStandardQuery; + + SetLastError(0xdeadbeef); + ret = DeviceIoControl(handle, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), &descriptor, sizeof(descriptor), + &size, NULL); + error = GetLastError(); + /* Only should complete on Win7 and Win10 */ + if (!ret && error == ERROR_INVALID_FUNCTION) + { + win_skip("This function is not implemented before Win7, got error %#x\n", error); + return; + } + if (!ret && error == ERROR_GEN_FAILURE) + { + win_skip("Host system does not support this call, likely a VM, must complete on a reporting drive Error: %#x\n", error); + return; + } + 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], expect_path[MAX_PATH]; @@ -1645,6 +1689,7 @@ START_TEST(volume) test_enum_vols(); test_disk_extents(); test_disk_query_property(); + test_disk_query_seek_penalty_property(); test_GetVolumePathNamesForVolumeNameA(); test_GetVolumePathNamesForVolumeNameW(); test_cdrom_ioctl();