[PATCH 2/2] mountmgr.sys: Implement StorageDeviceSeekPenaltyProperty
David Koolhoven
david at koolhoven-home.net
Mon Apr 26 14:57:55 CDT 2021
Implements StorageDeviceSeekPenaltyProperty for
query_propery()
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51065
Signed-off-by: David Koolhoven <david at koolhoven-home.net>
---
dlls/mountmgr.sys/device.c | 120 ++++++++++++++++++++++++++++++++++++-
include/ntddstor.h | 9 ++-
2 files changed, 126 insertions(+), 3 deletions(-)
diff --git a/dlls/mountmgr.sys/device.c b/dlls/mountmgr.sys/device.c
index 04e8fe3c0f5..d031080c459 100644
--- a/dlls/mountmgr.sys/device.c
+++ b/dlls/mountmgr.sys/device.c
@@ -28,6 +28,10 @@
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
+#ifdef linux
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
@@ -1867,8 +1871,6 @@ static NTSTATUS query_property( struct disk_device *device, IRP *irp )
}
else
{
- FIXME( "Faking StorageDeviceProperty data\n" );
-
memset( irp->AssociatedIrp.SystemBuffer, 0, irpsp->Parameters.DeviceIoControl.OutputBufferLength );
descriptor = irp->AssociatedIrp.SystemBuffer;
descriptor->Version = sizeof(STORAGE_DEVICE_DESCRIPTOR);
@@ -1894,6 +1896,120 @@ static NTSTATUS query_property( struct disk_device *device, IRP *irp )
break;
}
+ case StorageDeviceSeekPenaltyProperty:
+ {
+#ifdef linux
+ FILE *fp;
+ char isrotapathstr[260];
+ char evpath[260];
+ char ueventbufstr[260];
+ char isrotastrbuf[2];
+ char *fgetsret = NULL;
+ int ret = 0;
+ char *rptr = NULL;
+ char *sptr = NULL;
+ char *devstr_edited = NULL;
+ char *mountstr = NULL;
+ char mountpath[260];
+ char *part_dev = NULL;
+ char *path, *p = NULL;
+ int c = 0;
+ struct stat statbuf;
+ DEVICE_SEEK_PENALTY_DESCRIPTOR *descriptor;
+
+ memset( irp->AssociatedIrp.SystemBuffer, 0, irpsp->Parameters.DeviceIoControl.OutputBufferLength );
+ descriptor = irp->AssociatedIrp.SystemBuffer;
+ descriptor->Version = sizeof(DEVICE_SEEK_PENALTY_DESCRIPTOR);
+ descriptor->Size = sizeof(DEVICE_SEEK_PENALTY_DESCRIPTOR);
+
+ if (!device->unix_mount) {
+ status = STATUS_DATA_ERROR;
+ break;
+ }
+
+ if (!(path = get_dosdevices_path( &p ))) {
+ status = STATUS_DATA_ERROR;
+ break;
+ }
+
+ /* Crop any drive letters off the end of the string */
+ if (!strncmp(&path[strlen(path) - 2], "::", 2)) {
+ path[strlen(path) - 3] = '\0';
+ }
+
+ snprintf (mountpath, 260, "%s%s", path, device->unix_mount);
+ ret = stat (mountpath, &statbuf);
+ if (ret == -1) {
+ status = STATUS_DATA_ERROR;
+ break;
+ }
+ HeapFree( GetProcessHeap(), 0, path );
+ sprintf (evpath, "/sys/dev/block/%d:%d/uevent", major(statbuf.st_dev), minor(statbuf.st_dev));
+ fp = fopen(evpath, "r");
+ if (!fp) {
+ status = STATUS_DATA_ERROR;
+ break;
+ }
+ while ((rptr = fgets (ueventbufstr, 260, fp))) {
+ sptr = strstr (rptr, "DEVNAME=");
+ if (sptr) {
+ sptr += strlen ("DEVNAME=");
+ break;
+ }
+ }
+ fclose (fp);
+ devstr_edited = sptr;
+ if (!devstr_edited) {
+ status = STATUS_DATA_ERROR;
+ break;
+ }
+ /* Find first character after forwardslash '/' */
+ part_dev = strrchr (devstr_edited, '/');
+ if (!part_dev || (part_dev == devstr_edited)) part_dev = devstr_edited;
+ else part_dev++;
+ /* Trim off trailing digits and whitespace */
+ c = strlen (devstr_edited);
+ c--;
+ while ((devstr_edited[c] >= '0' && devstr_edited[c] <= '9')
+ || (devstr_edited[c] == '\n' || devstr_edited[c] == '\r'))
+ devstr_edited[c--] = '\0';
+
+ ret = snprintf (isrotapathstr, 260, "/sys/block/%s/queue/rotational", part_dev);
+ if (ret < 1 || ret == 260) {
+ status = STATUS_DATA_ERROR;
+ break;
+ }
+
+ fp = fopen(isrotapathstr, "r");
+ if (!fp) {
+ status = STATUS_DATA_ERROR;
+ break;
+ }
+
+ fgetsret = fgets(isrotastrbuf, 2, fp);
+ if (!fgetsret) {
+ status = STATUS_DATA_ERROR;
+ break;
+ }
+
+ fclose (fp);
+
+ if (isrotastrbuf[0] == '1') {
+ descriptor->IncursSeekPenalty = TRUE;
+ } else if (isrotastrbuf[0] == '0') {
+ descriptor->IncursSeekPenalty = FALSE;
+ } else {
+ status = STATUS_DATA_ERROR;
+ break;
+ }
+
+ status = STATUS_SUCCESS;
+#else
+ FIXME( "Unsupported property StorageDeviceSeekPenalty\n" );
+ status = STATUS_NOT_SUPPORTED;
+#endif
+ 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
--
2.19.1
More information about the wine-devel
mailing list