From b8df58d71441422b11704e7c9c7f8f935fb0f47e Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 23 Jul 2016 18:37:21 +0200 Subject: [PATCH] Added patch to use sysfs to populate SCSI registry keys. --- ...-scsi-device-type-in-SCSI_getprocent.patch | 90 +++++++++++ ...port-for-reading-scsi-devices-from-s.patch | 151 ++++++++++++++++++ patches/kernel32-SCSI_Sysfs/definition | 1 + patches/patchinstall.sh | 21 +++ 4 files changed, 263 insertions(+) create mode 100644 patches/kernel32-SCSI_Sysfs/0001-kernel32-Convert-scsi-device-type-in-SCSI_getprocent.patch create mode 100644 patches/kernel32-SCSI_Sysfs/0002-kernel32-Add-support-for-reading-scsi-devices-from-s.patch create mode 100644 patches/kernel32-SCSI_Sysfs/definition diff --git a/patches/kernel32-SCSI_Sysfs/0001-kernel32-Convert-scsi-device-type-in-SCSI_getprocent.patch b/patches/kernel32-SCSI_Sysfs/0001-kernel32-Convert-scsi-device-type-in-SCSI_getprocent.patch new file mode 100644 index 00000000..8d427df9 --- /dev/null +++ b/patches/kernel32-SCSI_Sysfs/0001-kernel32-Convert-scsi-device-type-in-SCSI_getprocent.patch @@ -0,0 +1,90 @@ +From 553c390a55bb9184aa4d35cc2e6689f6633e4a9b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +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 + diff --git a/patches/kernel32-SCSI_Sysfs/0002-kernel32-Add-support-for-reading-scsi-devices-from-s.patch b/patches/kernel32-SCSI_Sysfs/0002-kernel32-Add-support-for-reading-scsi-devices-from-s.patch new file mode 100644 index 00000000..009a794b --- /dev/null +++ b/patches/kernel32-SCSI_Sysfs/0002-kernel32-Add-support-for-reading-scsi-devices-from-s.patch @@ -0,0 +1,151 @@ +From 49435131943ae82e369d2a666de25e6242d242ab Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +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 + diff --git a/patches/kernel32-SCSI_Sysfs/definition b/patches/kernel32-SCSI_Sysfs/definition new file mode 100644 index 00000000..79f4c8f8 --- /dev/null +++ b/patches/kernel32-SCSI_Sysfs/definition @@ -0,0 +1 @@ +Fixes: [31592] Use sysfs to populate SCSI registry keys diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 30124fba..21fcd121 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -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: