ntdll: Try2: Fix IOCTL_SCSI_GET_ADDRESS and HKLM\HARDWARE\DEVICEMAP\Scsi entries

Vitaliy Margolen wine-patch at kievinfo.com
Wed Jul 27 14:01:05 CDT 2005


Sorry for the prior buzz. I have found the real problem somewhere else.

Fix compiler warnings about type mismatch. Type should be UCHAR not int.

Reverse port and iface the way it should be. Tested against win2k on system with
and without real scsi drivers.

In CDROM_GetInterfaceInfo:
iface - is the controller # (ide: 0 for primary, 1 for secondary, etc.)
port  - is the port/bus # on the controller (ide has only one port per
        controller. SCSI might have more than one.)
device - is the device # (ide: 0 for master, 1 for slave. SCSI: DeviceId set on
         a device with jumpers/SCA back plain)
lun    - is the logical unit # (ide: always 0. SCSI: only used on big systems.)

I have no idea how to create a conformance test for this, since there are no
other functions that I know of that will return the same information.

Fix creation of HKLM\HARDWARE\DEVICEMAP\Scsi entries. There are should be
one more level "Logical Unit Id" at the end.

Vitaliy Margolen

changelog:
  dlls/ntdll/cdrom.c
    Fix IOCTL_SCSI_GET_ADDRESS
  dlls/kernel/oldconfig.c
    Fix creation of HKLM\HARDWARE\DEVICEMAP\Scsi entries.
    Enumerate cd-roms only.
-------------- next part --------------
Index: dlls/ntdll/cdrom.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/cdrom.c,v
retrieving revision 1.63
diff -u -p -r1.63 cdrom.c
--- dlls/ntdll/cdrom.c	20 Jul 2005 10:28:27 -0000	1.63
+++ dlls/ntdll/cdrom.c	27 Jul 2005 18:37:03 -0000
@@ -547,11 +550,11 @@ static void CDROM_ClearCacheEntry(int de
  *		CDROM_GetInterfaceInfo
  *
  * Determines the ide interface (the number after the ide), and the
- * number of the device on that interface for ide cdroms (*port == 0).
- * Determines the scsi information for scsi cdroms (*port >= 1).
+ * number of the device on that interface for ide cdroms (*iface <= 1).
+ * Determines the scsi information for scsi cdroms (*iface >= 2).
  * Returns false if the info cannot not be obtained.
  */
-static int CDROM_GetInterfaceInfo(int fd, int* port, int* iface, int* device,int* lun)
+static int CDROM_GetInterfaceInfo(int fd, UCHAR* iface, UCHAR* port, UCHAR* device, UCHAR* lun)
 {
 #if defined(linux)
     struct stat st;
@@ -580,8 +583,8 @@ static int CDROM_GetInterfaceInfo(int fd
         UINT32 idlun[2];
         if (ioctl(fd, SCSI_IOCTL_GET_IDLUN, &idlun) != -1)
         {
-            *port = ((idlun[0] >> 24) & 0xff) + 1;
-            *iface = (idlun[0] >> 16) & 0xff;
+            *port = (idlun[0] >> 24) & 0xff;
+            *iface = ((idlun[0] >> 16) & 0xff) + 2;
             *device = idlun[0] & 0xff;
             *lun = (idlun[0] >> 8) & 0xff;
         }
@@ -1702,15 +1709,15 @@ static NTSTATUS CDROM_ScsiGetCaps(PIO_SC
  */
 static NTSTATUS CDROM_GetAddress(int fd, SCSI_ADDRESS* address)
 {
-    int portnum, busid, targetid, lun;
+    UCHAR portnum, busid, targetid, lun;
 
     address->Length = sizeof(SCSI_ADDRESS);
     if ( ! CDROM_GetInterfaceInfo(fd, &portnum, &busid, &targetid, &lun))
         return STATUS_NOT_SUPPORTED;
 
-    address->PortNumber = portnum;
-    address->PathId = busid; /* bus number */
-    address->TargetId = targetid;
+    address->PortNumber = portnum; /* primary=0 secondary=1 for ide */
+    address->PathId = busid;       /* always 0 for ide */
+    address->TargetId = targetid;  /* master=0 slave=1 for ide */
     address->Lun = lun;
     return STATUS_SUCCESS;
 }
Index: dlls/kernel/oldconfig.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/oldconfig.c,v
retrieving revision 1.7
diff -u -p -r1.7 oldconfig.c
--- dlls/kernel/oldconfig.c	11 Jul 2005 20:44:59 -0000	1.7
+++ dlls/kernel/oldconfig.c	27 Jul 2005 18:38:14 -0000
@@ -98,7 +98,7 @@ static ULONG allocate_default_keys(void)
  * NOTE: programs usually read these registry entries after sending the
  *       IOCTL_SCSI_GET_ADDRESS ioctl to the cdrom
  */
-static void init_cdrom_registry( HANDLE handle )
+static void init_cdrom_registry( HANDLE handle, UINT uNumber )
 {
     OBJECT_ATTRIBUTES attr;
     UNICODE_STRING nameW;
@@ -111,9 +111,11 @@ static void init_cdrom_registry( HANDLE 
     HANDLE portKey;
     HANDLE busKey;
     HANDLE targetKey;
+    HANDLE lunKey;
     DWORD disp;
     IO_STATUS_BLOCK io;
     SCSI_ADDRESS scsi_addr;
+    char cDeviceName[] = "Cdrom0";
 
     if (NtDeviceIoControlFile( handle, 0, NULL, NULL, &io, IOCTL_SCSI_GET_ADDRESS,
                                NULL, 0, &scsi_addr, sizeof(scsi_addr) ))
@@ -204,24 +206,36 @@ static void init_cdrom_registry( HANDLE 
     }
     RtlFreeUnicodeString( &nameW );
 
+    
+    snprintf(buffer,40,"Logical Unit Id %d", scsi_addr.Lun);
+    attr.RootDirectory = targetKey;
+    if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) ||
+        NtCreateKey( &lunKey, KEY_ALL_ACCESS, &attr, 0,
+                     NULL, REG_OPTION_VOLATILE, &disp ))
+    {
+        ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus 0\\Target Id registry key\\Logical Unit Id\n" );
+        return;
+    }
+    RtlFreeUnicodeString( &nameW );
+
     RtlCreateUnicodeStringFromAsciiz( &nameW, "Type" );
     data = "CdRomPeripheral";
     RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data));
-    NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
+    NtSetValueKey( lunKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
     RtlFreeUnicodeString( &nameW );
     /* FIXME - maybe read the real identifier?? */
     RtlCreateUnicodeStringFromAsciiz( &nameW, "Identifier" );
     data = "Wine CDROM";
     RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data));
-    NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
+    NtSetValueKey( lunKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
     RtlFreeUnicodeString( &nameW );
-    /* FIXME - we always use Cdrom0 - do not know about the nt behaviour */
     RtlCreateUnicodeStringFromAsciiz( &nameW, "DeviceName" );
-    data = "Cdrom0";
-    RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data));
-    NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
+    cDeviceName[5] = uNumber + '0';
+    RtlMultiByteToUnicodeN( dataW, 50, &lenW, cDeviceName, strlen(cDeviceName));
+    NtSetValueKey( lunKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
     RtlFreeUnicodeString( &nameW );
 
+    NtClose( lunKey );
     NtClose( targetKey );
     NtClose( busKey );
     NtClose( portKey );
@@ -235,14 +249,18 @@ static void create_hardware_branch(void)
     int i;
     HANDLE handle;
     char drive[] = "\\\\.\\A:";
+    char drive1[] = "A:\\";
+    UINT uNumber = 0;
 
     /* create entries for cdroms (skipping A: and B:) */
     for (i = 2; i < 26; i++)
     {
         drive[4] = 'A' + i;
+        drive1[0] = 'A' + i;
+        if (GetDriveTypeA(drive1) != DRIVE_CDROM) continue;
         handle = CreateFileA( drive, 0, 0, NULL, OPEN_EXISTING, 0, 0 );
         if (handle == INVALID_HANDLE_VALUE) continue;
-        init_cdrom_registry( handle );
+        init_cdrom_registry( handle, uNumber++);
         CloseHandle( handle );
     }
 }


More information about the wine-patches mailing list