[PATCH] kernel32: Populate HKLM\HARDWARE\DEVICEMAP\Scsi on Mac OS.
Charles Davis
cdavis at mymail.mines.edu
Mon Mar 28 11:08:28 CDT 2011
From: Charles Davis <cdavis at mines.edu>
---
dlls/kernel32/Makefile.in | 2 +-
dlls/kernel32/oldconfig.c | 157 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 154 insertions(+), 5 deletions(-)
diff --git a/dlls/kernel32/Makefile.in b/dlls/kernel32/Makefile.in
index 6c60623..4f5648b 100644
--- a/dlls/kernel32/Makefile.in
+++ b/dlls/kernel32/Makefile.in
@@ -2,7 +2,7 @@ EXTRADEFS = -D_KERNEL32_ -D_NORMALIZE_
MODULE = kernel32.dll
IMPORTLIB = kernel32
IMPORTS = winecrt0 ntdll
-EXTRALIBS = @COREFOUNDATIONLIB@ @LIBPOLL@
+EXTRALIBS = @IOKITLIB@ @LIBPOLL@
EXTRADLLFLAGS = -nodefaultlibs -Wb,-F,KERNEL32.dll -Wl,--image-base,0x7b800000
C_SRCS = \
diff --git a/dlls/kernel32/oldconfig.c b/dlls/kernel32/oldconfig.c
index 02dac06..4474d9c 100644
--- a/dlls/kernel32/oldconfig.c
+++ b/dlls/kernel32/oldconfig.c
@@ -41,6 +41,24 @@
#ifdef HAVE_LINUX_HDREG_H
# include <linux/hdreg.h>
#endif
+#ifdef HAVE_COREFOUNDATION_COREFOUNDATION_H
+# include <CoreFoundation/CoreFoundation.h>
+#endif
+#ifdef HAVE_IOKIT_IOKITLIB_H
+# include <IOKit/IOKitLib.h>
+# include <IOKit/IOBSD.h>
+# include <IOKit/scsi/SCSICmds_INQUIRY_Definitions.h>
+
+typedef struct
+{
+ uint64_t bus;
+ uint64_t port;
+ uint64_t target;
+ uint64_t lun;
+} dk_scsi_identify_t;
+
+#define DKIOCSCSIIDENTIFY _IOR('d', 254, dk_scsi_identify_t)
+#endif
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
@@ -84,7 +102,7 @@ static NTSTATUS create_key( HANDLE root, const char *name, HANDLE *key, DWORD *d
* IOCTL_SCSI_GET_ADDRESS ioctl to the cdrom
*/
static void create_scsi_entry( PSCSI_ADDRESS scsi_addr, LPCSTR lpDriver, UINT uDriveType,
- LPSTR lpDriveName, LPSTR lpUnixDeviceName )
+ LPSTR lpDriveName, LPSTR lpUnixDeviceName, UCHAR uInitId )
{
static UCHAR uCdromNumber = 0;
static UCHAR uTapeNumber = 0;
@@ -141,7 +159,7 @@ static void create_scsi_entry( PSCSI_ADDRESS scsi_addr, LPCSTR lpDriver, UINT uD
snprintf(buffer, sizeof(buffer),"Scsi Bus %d", scsi_addr->PathId);
if (create_key( portKey, buffer, &busKey, &disp )) return;
- /* FIXME: get real controller Id for SCSI */
+ snprintf(buffer, sizeof(buffer), "Initiator Id %d", uInitId);
if (create_key( busKey, buffer, &targetKey, &disp )) return;
NtClose( targetKey );
@@ -153,6 +171,50 @@ static void create_scsi_entry( PSCSI_ADDRESS scsi_addr, LPCSTR lpDriver, UINT uD
switch (uDriveType)
{
+#ifdef HAVE_IOKIT_IOKITLIB_H
+ /* With I/O Kit, we do it by SCSI peripheral type */
+ case 0x00: /* Disk drives */
+ data = "DiskPeripheral"; break;
+ case 0x01: /* Tape drives */
+ data = "TapePeripheral";
+ snprintf(buffer, sizeof(buffer), "Tape%d", uTapeNumber++);
+ break;
+ case 0x02: /* Printers */
+ data = "PrinterPeripheral"; break;
+ case 0x04: /* WORM disk drives */
+ data = "WormPeripheral"; break;
+ case 0x05: /* MMC CD/DVD drives */
+ data = "CdRomPeripheral";
+ snprintf(buffer, sizeof(buffer), "Cdrom%d", uCdromNumber++);
+ break;
+ case 0x06: /* Scanners */
+ data = "ScannerPeripheral"; break;
+ case 0x07: /* Optical disk drives (NOT CD-ROMs) */
+ data = "OpticalDiskPeripheral"; break;
+ case 0x08: /* Medium changers */
+ data = "MediumChangerPeripheral"; break;
+ case 0x09: /* Communications devices */
+ data = "CommunicationsPeripheral"; break;
+ case 0x0A: /* ASC IT8 pre-press graphic arts devices */
+ case 0x0B: /* Same here */
+ data = "ASCPrePressGraphicsPeripheral"; break;
+ case 0x0C: /* Disk drive arrays */
+ data = "ArrayPeripheral"; break;
+ case 0x0D: /* Device enclosures */
+ data = "EnclosurePeripheral"; break;
+ case 0x0E: /* Reduced-commands disk drives */
+ data = "RBCPeripheral"; break;
+ case 0x0F: /* Card readers */
+ data = "CardReaderPeripheral"; break;
+ case 0x10: /* Bridge controllers */
+ data = "BridgePeripheral"; break;
+ case 0x11: /* Object-based storage devices */
+ case 0x12: /* Automation/drive controllers */
+ case 0x15: /* Reduced-commands MM devices */
+ case 0x03: /* Processor devices (considered to be "Other" by Windows) */
+ default:
+ data = "OtherPeripheral"; break;
+#else
case DRIVE_NO_ROOT_DIR:
default:
data = "OtherPeripheral"; break;
@@ -166,6 +228,7 @@ static void create_scsi_entry( PSCSI_ADDRESS scsi_addr, LPCSTR lpDriver, UINT uD
data = "CdRomPeripheral";
snprintf(buffer, sizeof(buffer), "Cdrom%d", uCdromNumber++);
break;
+#endif
}
RtlCreateUnicodeStringFromAsciiz( &nameW, "Type" );
RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, data, strlen(data)+1);
@@ -177,7 +240,11 @@ static void create_scsi_entry( PSCSI_ADDRESS scsi_addr, LPCSTR lpDriver, UINT uD
NtSetValueKey( lunKey, &nameW, 0, REG_SZ, dataW, sizeW );
RtlFreeUnicodeString( &nameW );
+#ifdef HAVE_IOKIT_IOKITLIB_H
+ if (uDriveType == 0x01 || uDriveType == 0x05)
+#else
if (uDriveType == DRIVE_CDROM || uDriveType == DRIVE_REMOVABLE)
+#endif
{
RtlCreateUnicodeStringFromAsciiz( &nameW, "DeviceName" );
RtlMultiByteToUnicodeN( dataW, sizeof(dataW), &sizeW, buffer, strlen(buffer)+1);
@@ -197,6 +264,85 @@ static void create_scsi_entry( PSCSI_ADDRESS scsi_addr, LPCSTR lpDriver, UINT uD
NtClose( scsiKey );
}
+#ifdef HAVE_IOKIT_IOKITLIB_H
+static int SCSI_ReadIORegEnt( io_service_t spd, SCSI_ADDRESS *scsi_addr, UINT *init, UINT *pdtype,
+ char *model, UINT model_size, char *unixdev, UINT unixdev_size )
+{
+ CFTypeRef obj;
+ int fd;
+ size_t model_len;
+ dk_scsi_identify_t addr;
+ io_service_t pdn;
+
+ IORegistryEntryGetParentEntry( spd, kIOServicePlane, &pdn );
+ /* First get the vendor, product, and revision strings */
+ obj = IORegistryEntryCreateCFProperty( pdn, CFSTR(kIOPropertySCSIVendorIdentification), NULL, 0 );
+ CFStringGetCString( obj, model, model_size, kCFStringEncodingUTF8 );
+ model_len = CFStringGetLength( obj );
+ CFRelease( obj );
+ model[model_len++] = ' ';
+ obj = IORegistryEntryCreateCFProperty( pdn, CFSTR(kIOPropertySCSIProductIdentification), NULL, 0 );
+ CFStringGetCString( obj, model+model_len, model_size-model_len, kCFStringEncodingUTF8 );
+ model_len += CFStringGetLength( obj );
+ CFRelease( obj );
+ model[model_len++] = ' ';
+ obj = IORegistryEntryCreateCFProperty( pdn, CFSTR(kIOPropertySCSIProductRevisionLevel), NULL, 0 );
+ CFStringGetCString( obj, model+model_len, model_size-model_len, kCFStringEncodingUTF8 );
+ CFRelease( obj );
+ IOObjectRelease( pdn );
+
+ /* Also read the peripheral type */
+ obj = IORegistryEntryCreateCFProperty( spd, CFSTR(kIOPropertySCSIPeripheralDeviceType), NULL, 0 );
+ CFNumberGetValue( obj, kCFNumberIntType, pdtype );
+ CFRelease( obj );
+
+ /* Read the device node name */
+ obj = IORegistryEntryCreateCFProperty( spd, CFSTR(kIOBSDNameKey), NULL, 0 );
+ strcpy( unixdev, "/dev/" );
+ CFStringGetCString( obj, unixdev+strlen("/dev/"), unixdev_size-strlen("/dev/"), kCFStringEncodingUTF8 );
+ CFRelease( obj );
+ /* Get the SCSI address from the device node */
+ fd = open( unixdev, O_RDONLY );
+ if (fd == -1) return 0;
+ if (ioctl( fd, DKIOCSCSIIDENTIFY, &addr ) == -1)
+ {
+ close( fd );
+ return 0;
+ }
+ close( fd );
+ scsi_addr->PortNumber = addr.bus;
+ scsi_addr->PathId = addr.port;
+ scsi_addr->TargetId = addr.target;
+ scsi_addr->Lun = addr.lun;
+ /* FIXME: get real controller Id for SCSI */
+ *init = 255;
+ return 1;
+}
+
+/* create the hardware registry branch */
+static void create_hardware_branch(void)
+{
+ io_service_t svc;
+ io_iterator_t it;
+ char cDevModel[40];
+ char cUnixDeviceName[40];
+ UINT pdtype;
+ UINT init;
+ SCSI_ADDRESS scsi_addr;
+
+ /* Enumerate all the IOSCSIPrimaryCommandsDevices */
+ IOServiceGetMatchingServices( kIOMasterPortDefault, IOServiceMatching( "IOSCSIPrimaryCommandsDevice" ), &it );
+
+ while ((svc = IOIteratorNext( it )))
+ {
+ if (!SCSI_ReadIORegEnt( svc, &scsi_addr, &init, &pdtype, cDevModel, sizeof(cDevModel), cUnixDeviceName, sizeof(cUnixDeviceName) )) continue;
+ /* FIXME: Get real driver name */
+ create_scsi_entry( &scsi_addr, "WINE SCSI", pdtype, cDevModel, cUnixDeviceName, init );
+ IOObjectRelease( svc );
+ }
+ IOObjectRelease( it );
+}
+#else
struct LinuxProcScsiDevice
{
int host;
@@ -332,7 +478,8 @@ static void create_hardware_branch(void)
if (scsi_addr.PortNumber + 1 > uFirstSCSIPort)
uFirstSCSIPort = scsi_addr.PortNumber + 1;
- create_scsi_entry(&scsi_addr, "atapi", nType, cDevModel, cUnixDeviceName);
+ /* FIXME: get real controller Id for SCSI */
+ create_scsi_entry(&scsi_addr, "atapi", nType, cDevModel, cUnixDeviceName, 255);
}
}
closedir(idedir);
@@ -381,12 +528,14 @@ static void create_hardware_branch(void)
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);
+ /* FIXME: get real controller Id for SCSI */
+ create_scsi_entry(&scsi_addr, "WINE SCSI", nType, cDevModel, cUnixDeviceName, 255);
}
if( result != EOF )
WARN("Incorrect %s format\n", procname_scsi);
fclose( procfile );
}
+#endif
/***********************************************************************
--
1.7.4.rc3
More information about the wine-patches
mailing list