Resubmit: Try 3:Implement IOCTL_SCSI_GET_INQUIRY_DATA

Vitaliy Margolen wine-patch at kievinfo.com
Tue Aug 2 10:07:44 CDT 2005


Move #ifdef to protect some variables as well.

Check for HAVE_SG_IO_HDR_T_INTERFACE_ID instead of defined Linux

Implement IOCTL_SCSI_GET_INQUIRY_DATA. It is somewhat limited right now -
doesn't enumerate all devices on a given bus.

Vitaliy Margolen

changelog:
  Implement IOCTL_SCSI_GET_INQUIRY_DATA
-------------- 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	28 Jul 2005 13:48:28 -0000
@@ -288,6 +288,7 @@ X(IOCTL_DVD_SEND_KEY)
 X(IOCTL_DVD_START_SESSION)
 X(IOCTL_SCSI_GET_ADDRESS)
 X(IOCTL_SCSI_GET_CAPABILITIES)
+X(IOCTL_SCSI_GET_INQUIRY_DATA)
 X(IOCTL_SCSI_PASS_THROUGH)
 X(IOCTL_SCSI_PASS_THROUGH_DIRECT)
 X(IOCTL_STORAGE_CHECK_VERIFY)
@@ -310,6 +311,8 @@ static const char *iocodex(DWORD code)
    return buffer;
 }
 
+#define INQ_REPLY_LEN 36
+#define INQ_CMD_LEN 6
 WINE_DEFAULT_DEBUG_CHANNEL(cdrom);
 
 #define FRAME_OF_ADDR(a) (((int)(a)[1] * CD_SECS + (a)[2]) * CD_FRAMES + (a)[3])
@@ -1920,6 +1927,66 @@ static NTSTATUS DVD_ReadStructure(int de
     return STATUS_SUCCESS;
 
 }
+
+/******************************************************************
+ *        GetInquiryData
+ *        Implements the IOCTL_GET_INQUIRY_DATA ioctl.
+ *        Returns Inquiry data for all devices on the specified scsi bus
+ *        Returns STATUS_BUFFER_TOO_SMALL if the output buffer is to small, 
+ *        STATUS_INVALID_DEVICE_REQUEST if the given handle isn't to a SCSI device,
+ *        or STATUS_NOT_SUPPORTED if the OS driver is too old
+ */
+static NTSTATUS GetInquiryData(int fd, PSCSI_ADAPTER_BUS_INFO BufferOut, DWORD OutBufferSize)
+{
+    PSCSI_INQUIRY_DATA pInquiryData = NULL;
+    UCHAR sense_buffer[32];
+    int iochk, version;
+#ifdef HAVE_SG_IO_HDR_T_INTERFACE_ID
+    sg_io_hdr_t iocmd;
+    UCHAR inquiry[INQ_CMD_LEN] = {INQUIRY, 0, 0, 0, INQ_REPLY_LEN, 0};
+
+    /* Check we have a SCSI device and a supported driver */
+    if(ioctl(fd, SG_GET_VERSION_NUM, &version) != 0)
+    {
+        ERR("IOCTL_SCSI_GET_INQUIRY_DATA sg driver is not loaded\n");
+        return STATUS_INVALID_DEVICE_REQUEST;
+    }
+    if(version < 30000 )
+        return STATUS_NOT_SUPPORTED;
+
+    /* FIXME: Enumerate devices on the bus */
+    BufferOut->NumberOfBuses = 1;
+    BufferOut->BusData[0].NumberOfLogicalUnits = 1;
+    BufferOut->BusData[0].InquiryDataOffset = sizeof(SCSI_ADAPTER_BUS_INFO);
+
+    pInquiryData = (PSCSI_INQUIRY_DATA)(BufferOut + 1);
+
+    RtlZeroMemory(&iocmd, sizeof(iocmd));
+    iocmd.interface_id = 'S';
+    iocmd.cmd_len = sizeof(inquiry);
+    iocmd.mx_sb_len = sizeof(sense_buffer);
+    iocmd.dxfer_direction = SG_DXFER_FROM_DEV;
+    iocmd.dxfer_len = INQ_REPLY_LEN;
+    iocmd.dxferp = pInquiryData->InquiryData;
+    iocmd.cmdp = inquiry;
+    iocmd.sbp = sense_buffer;
+    iocmd.timeout = 1000;
+
+    iochk = ioctl(fd, SG_IO, &iocmd);
+    if(iochk != 0)
+        ERR("ioctl SG_IO returned %d, error (%s)\n", iochk, strerror(errno));
+
+    CDROM_GetInterfaceInfo(fd, &BufferOut->BusData[0].InitiatorBusId, &pInquiryData->PathId, &pInquiryData->TargetId, &pInquiryData->Lun);
+    pInquiryData->DeviceClaimed = TRUE;
+    pInquiryData->InquiryDataLength = INQ_REPLY_LEN;
+    pInquiryData->NextInquiryDataOffset = 0;
+    return STATUS_SUCCESS;
+#else
+    FIXME("not implemented for nonlinux\n");
+    return STATUS_NOT_SUPPORTED;
+#endif
+}
+
 /******************************************************************
  *		CDROM_DeviceIoControl
  *
@@ -2183,6 +2250,11 @@ NTSTATUS CDROM_DeviceIoControl(HANDLE hD
         else if (nOutBufferSize < sz) status = STATUS_BUFFER_TOO_SMALL;
         TRACE("doing DVD_READ_STRUCTURE\n");
         status = DVD_ReadStructure(fd, (PDVD_READ_STRUCTURE)lpInBuffer, (PDVD_LAYER_DESCRIPTOR)lpOutBuffer);
+        break;
+
+    case IOCTL_SCSI_GET_INQUIRY_DATA:
+        sz = INQ_REPLY_LEN;
+        status = GetInquiryData(fd, (PSCSI_ADAPTER_BUS_INFO)lpOutBuffer, nOutBufferSize);
         break;
 
     default:


More information about the wine-patches mailing list