Added patch to use sysfs to populate SCSI registry keys.

This commit is contained in:
Sebastian Lackner 2016-07-23 18:37:21 +02:00
parent 7307a7ea4f
commit b8df58d714
4 changed files with 263 additions and 0 deletions

View File

@ -0,0 +1,90 @@
From 553c390a55bb9184aa4d35cc2e6689f6633e4a9b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Fri, 22 Jul 2016 21:00:40 +0200
Subject: kernel32: Convert scsi device type in SCSI_getprocentry.
---
dlls/kernel32/oldconfig.c | 27 ++++++++++++++++-----------
1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/dlls/kernel32/oldconfig.c b/dlls/kernel32/oldconfig.c
index 6c80dc6..8446f2d 100644
--- a/dlls/kernel32/oldconfig.c
+++ b/dlls/kernel32/oldconfig.c
@@ -204,7 +204,7 @@ struct LinuxProcScsiDevice
char vendor[9];
char model[17];
char rev[5];
- char type[33];
+ int type;
int ansirev;
};
@@ -217,6 +217,7 @@ struct LinuxProcScsiDevice
static int SCSI_getprocentry( FILE * procfile, struct LinuxProcScsiDevice * dev )
{
int result;
+ char type[33];
result = fscanf( procfile,
"Host:%*1[ ]scsi%d%*1[ ]Channel:%*1[ ]%d%*1[ ]Id:%*1[ ]%d%*1[ ]Lun:%*1[ ]%d\n",
@@ -247,7 +248,7 @@ static int SCSI_getprocentry( FILE * procfile, struct LinuxProcScsiDevice * dev
result = fscanf( procfile,
" Type:%*3[ ]%32c%*1[ ]ANSI SCSI%*1[ ]revision:%*1[ ]%x\n",
- dev->type,
+ type,
&dev->ansirev );
if( result != 2 )
{
@@ -258,7 +259,15 @@ static int SCSI_getprocentry( FILE * procfile, struct LinuxProcScsiDevice * dev
dev->vendor[8] = 0;
dev->model[16] = 0;
dev->rev[4] = 0;
- dev->type[32] = 0;
+ type[32] = 0;
+
+ if (strncmp(type, "Direct-Access", 13) == 0) dev->type = DRIVE_FIXED;
+ else if (strncmp(type, "Sequential-Access", 17) == 0) dev->type = DRIVE_REMOVABLE;
+ else if (strncmp(type, "CD-ROM", 6) == 0) dev->type = DRIVE_CDROM;
+ else if (strncmp(type, "Processor", 9) == 0) dev->type = DRIVE_NO_ROOT_DIR;
+ else if (strncmp(type, "Scanner", 7) == 0) dev->type = DRIVE_NO_ROOT_DIR;
+ else if (strncmp(type, "Printer", 7) == 0) dev->type = DRIVE_NO_ROOT_DIR;
+ else dev->type = DRIVE_UNKNOWN;
return 1;
}
@@ -362,26 +371,22 @@ static void create_hardware_branch(void)
/* Read info for one device */
while ((result = SCSI_getprocentry(procfile, &dev)) > 0)
{
+ if (dev.type == DRIVE_UNKNOWN)
+ continue;
+
scsi_addr.PortNumber = dev.host;
scsi_addr.PathId = dev.channel;
scsi_addr.TargetId = dev.target;
scsi_addr.Lun = dev.lun;
scsi_addr.PortNumber += uFirstSCSIPort;
- if (strncmp(dev.type, "Direct-Access", 13) == 0) nType = DRIVE_FIXED;
- else if (strncmp(dev.type, "Sequential-Access", 17) == 0) nType = DRIVE_REMOVABLE;
- else if (strncmp(dev.type, "CD-ROM", 6) == 0) nType = DRIVE_CDROM;
- else if (strncmp(dev.type, "Processor", 9) == 0) nType = DRIVE_NO_ROOT_DIR;
- else if (strncmp(dev.type, "Scanner", 7) == 0) nType = DRIVE_NO_ROOT_DIR;
- else if (strncmp(dev.type, "Printer", 7) == 0) nType = DRIVE_NO_ROOT_DIR;
- else continue;
strcpy(cDevModel, dev.vendor);
strcat(cDevModel, dev.model);
strcat(cDevModel, dev.rev);
sprintf(cUnixDeviceName, "/dev/sg%d", nSgNumber++);
/* FIXME: get real driver name */
- create_scsi_entry(&scsi_addr, "WINE SCSI", nType, cDevModel, cUnixDeviceName);
+ create_scsi_entry(&scsi_addr, "WINE SCSI", dev.type, cDevModel, cUnixDeviceName);
}
if( result != EOF )
WARN("Incorrect %s format\n", procname_scsi);
--
2.8.0

View File

@ -0,0 +1,151 @@
From 49435131943ae82e369d2a666de25e6242d242ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Fri, 22 Jul 2016 21:01:33 +0200
Subject: kernel32: Add support for reading scsi devices from sysfs.
---
dlls/kernel32/oldconfig.c | 114 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 113 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/oldconfig.c b/dlls/kernel32/oldconfig.c
index 8446f2d..9001a04 100644
--- a/dlls/kernel32/oldconfig.c
+++ b/dlls/kernel32/oldconfig.c
@@ -272,6 +272,89 @@ static int SCSI_getprocentry( FILE * procfile, struct LinuxProcScsiDevice * dev
return 1;
}
+static BOOL read_file_content(char *path, char *buffer, int length)
+{
+ size_t read;
+
+ FILE *f = fopen(path, "r");
+ if (!f) return FALSE;
+
+ read = fread(buffer, 1, length-1, f);
+ fclose(f);
+ if (!read) return FALSE;
+
+ /* ensure NULL termination */
+ buffer[read] = 0;
+ return TRUE;
+}
+
+static BOOL read_file_content_int(char *path, int *result)
+{
+ char buffer[20];
+
+ if (!read_file_content(path, buffer, sizeof(buffer)))
+ return FALSE;
+
+ *result = atoi(buffer);
+ return TRUE;
+}
+
+static BOOL SCSI_getsysentry(char *device_key, struct LinuxProcScsiDevice *dev, char *unix_path)
+{
+ struct dirent *dent = NULL;
+ char path_buffer[100];
+ DIR *generic_dir;
+ int result, type;
+
+ result = sscanf(device_key, "%d:%d:%d:%d", &dev->host, &dev->channel, &dev->target, &dev->lun);
+ if (result != 4)
+ {
+ ERR("Failed to extract device information from %s\n", device_key);
+ return FALSE;
+ }
+
+ snprintf(path_buffer, sizeof(path_buffer), "/sys/class/scsi_device/%s/device/vendor", device_key);
+ if (!read_file_content(path_buffer, dev->vendor, sizeof(dev->vendor))) return FALSE;
+
+ snprintf(path_buffer, sizeof(path_buffer), "/sys/class/scsi_device/%s/device/model", device_key);
+ if (!read_file_content(path_buffer, dev->model, sizeof(dev->model))) return FALSE;
+
+ snprintf(path_buffer, sizeof(path_buffer), "/sys/class/scsi_device/%s/device/rev", device_key);
+ if (!read_file_content(path_buffer, dev->rev, sizeof(dev->rev))) return FALSE;
+
+ snprintf(path_buffer, sizeof(path_buffer), "/sys/class/scsi_device/%s/device/type", device_key);
+ if (!read_file_content_int(path_buffer, &type)) return FALSE;
+
+ /* see SCSI specification standard for values */
+ if (type == 0x0) dev->type = DRIVE_FIXED;
+ else if (type == 0x1) dev->type = DRIVE_REMOVABLE;
+ else if (type == 0x5) dev->type = DRIVE_CDROM;
+ else dev->type = DRIVE_NO_ROOT_DIR;
+
+ /* FIXME: verify */
+ snprintf(path_buffer, sizeof(path_buffer), "/sys/class/scsi_device/%s/device/scsi_level", device_key);
+ if (!read_file_content_int(path_buffer, &dev->ansirev)) return FALSE;
+
+ result = FALSE;
+
+ snprintf(path_buffer, sizeof(path_buffer), "/sys/class/scsi_device/%s/device/scsi_generic", device_key);
+ generic_dir = opendir(path_buffer);
+ if (generic_dir)
+ {
+ while ((dent = readdir(generic_dir)))
+ {
+ if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
+ continue;
+
+ sprintf(unix_path, "/dev/%s", dent->d_name);
+ result = TRUE;
+ break;
+ }
+ closedir(generic_dir);
+ }
+
+ return result;
+}
/* create the hardware registry branch */
static void create_hardware_branch(void)
@@ -281,7 +364,7 @@ static void create_hardware_branch(void)
static const char procname_ide_media[] = "/proc/ide/%s/media";
static const char procname_ide_model[] = "/proc/ide/%s/model";
static const char procname_scsi[] = "/proc/scsi/scsi";
- DIR *idedir;
+ DIR *idedir, *scsidir;
struct dirent *dent = NULL;
FILE *procfile = NULL;
char cStr[40], cDevModel[40], cUnixDeviceName[40], read1[10] = "\0", read2[10] = "\0";
@@ -346,6 +429,35 @@ static void create_hardware_branch(void)
}
/* Now goes SCSI */
+ scsidir = opendir("/sys/class/scsi_device");
+ if (scsidir)
+ {
+ while ((dent = readdir(scsidir)))
+ {
+ if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
+ continue;
+
+ if (!SCSI_getsysentry(dent->d_name, &dev, cUnixDeviceName))
+ continue;
+
+ scsi_addr.PortNumber = dev.host;
+ scsi_addr.PathId = dev.channel;
+ scsi_addr.TargetId = dev.target;
+ scsi_addr.Lun = dev.lun;
+
+ scsi_addr.PortNumber += uFirstSCSIPort;
+
+ strcpy(cDevModel, dev.vendor);
+ strcat(cDevModel, dev.model);
+ strcat(cDevModel, dev.rev);
+
+ /* FIXME: get real driver name */
+ create_scsi_entry(&scsi_addr, "WINE SCSI", dev.type, cDevModel, cUnixDeviceName);
+ }
+ closedir(scsidir);
+ return;
+ }
+
procfile = fopen(procname_scsi, "r");
if (!procfile)
{
--
2.8.0

View File

@ -0,0 +1 @@
Fixes: [31592] Use sysfs to populate SCSI registry keys

View File

@ -174,6 +174,7 @@ patch_enable_all ()
enable_kernel32_Named_Pipe="$1"
enable_kernel32_NeedCurrentDirectoryForExePath="$1"
enable_kernel32_Profile="$1"
enable_kernel32_SCSI_Sysfs="$1"
enable_kernel32_SetFileCompletionNotificationModes="$1"
enable_kernel32_SetFileInformationByHandle="$1"
enable_kernel32_TimezoneInformation_Registry="$1"
@ -696,6 +697,9 @@ patch_enable ()
kernel32-Profile)
enable_kernel32_Profile="$2"
;;
kernel32-SCSI_Sysfs)
enable_kernel32_SCSI_Sysfs="$2"
;;
kernel32-SetFileCompletionNotificationModes)
enable_kernel32_SetFileCompletionNotificationModes="$2"
;;
@ -4247,6 +4251,23 @@ if test "$enable_kernel32_Profile" -eq 1; then
) >> "$patchlist"
fi
# Patchset kernel32-SCSI_Sysfs
# |
# | This patchset fixes the following Wine bugs:
# | * [#31592] Use sysfs to populate SCSI registry keys
# |
# | Modified files:
# | * dlls/kernel32/oldconfig.c
# |
if test "$enable_kernel32_SCSI_Sysfs" -eq 1; then
patch_apply kernel32-SCSI_Sysfs/0001-kernel32-Convert-scsi-device-type-in-SCSI_getprocent.patch
patch_apply kernel32-SCSI_Sysfs/0002-kernel32-Add-support-for-reading-scsi-devices-from-s.patch
(
echo '+ { "Michael Müller", "kernel32: Convert scsi device type in SCSI_getprocentry.", 1 },';
echo '+ { "Michael Müller", "kernel32: Add support for reading scsi devices from sysfs.", 1 },';
) >> "$patchlist"
fi
# Patchset kernel32-SetFileCompletionNotificationModes
# |
# | This patchset fixes the following Wine bugs: