none
SCSI RRS feed

  • Question

  • Hi,

    In the following code to read sector 0

    bool ReadMBRUsingScsiPassThruDirect10()
    {
        BOOL status = 0;
        DWORD accessMode = 0, shareMode = 0;
        ULONG alignmentMask = 0; // default == no alignment requirement
        PUCHAR dataBuffer = NULL;
        PUCHAR pUnAlignedBuffer = NULL;
        SCSI_PASS_THROUGH_DIRECT sptd;
        int sectorSize = 512;

        HANDLE phDisk = NULL;
        phDisk= CreateFile(L"\\\\.\\physicaldrive0",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
        DWORD ret = GetLastError();
        if(!(phDisk != NULL && GetLastError() ==0) )
            return false;

        GetAlignmentMaskForDevice(phDisk,&alignmentMask);
     
        ZeroMemory(&sptd, sizeof(SCSI_PASS_THROUGH_DIRECT));
        dataBuffer = AllocateAlignedBuffer(sectorSize,alignmentMask, &pUnAlignedBuffer);   
     
        ZeroMemory(dataBuffer,sectorSize);

        sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
        sptd.PathId = 0;
        sptd.TargetId = 0;
        sptd.Lun = 0;
        sptd.CdbLength = CDB10GENERIC_LENGTH;
        sptd.DataIn = SCSI_IOCTL_DATA_IN;
        sptd.SenseInfoLength = 0;
        sptd.DataTransferLength = sectorSize;
        sptd.TimeOutValue = 50;
        sptd.DataBuffer = dataBuffer;
        sptd.SenseInfoOffset =
           0;
     
        sptd.Cdb[0] = 0x28;
        sptd.Cdb[1] = 0;    
        sptd.Cdb[2] = 0;
        sptd.Cdb[3] = 0;
        sptd.Cdb[4] = 0;
        sptd.Cdb[5] = 0;
        sptd.Cdb[6] = (UCHAR)(512 >> 8)&0xFF;
        sptd.Cdb[7] = 512 & 0xFF;
        sptd.Cdb[8] = 0;
        sptd.Cdb[9] = 0;   
        ULONG length = sizeof(SCSI_PASS_THROUGH_DIRECT);
        ULONG returned = 0;
        status = DeviceIoControl(phDisk,
                                 IOCTL_SCSI_PASS_THROUGH_DIRECT,
                                 &sptd,
                                 length,
                                 &sptd,
                                 length,
                                 &returned,
                                 FALSE);

     
        if ((sptd.ScsiStatus == 0) && (status != 0)) {
            printf("Using IOCTL SCSI 10\n");
           PrintDataBuffer(dataBuffer,sptd.DataTransferLength);
           }
        DWORD error = GetLastError();
        CloseHandle(phDisk);
        return true;
    }


    I get all 0's and with

    bool ReadMBRUsingScsiPassThruDirect()
    {
        BOOL status = 0;
        DWORD accessMode = 0, shareMode = 0;
        ULONG alignmentMask = 0; // default == no alignment requirement
        PUCHAR dataBuffer = NULL;
        PUCHAR pUnAlignedBuffer = NULL;
        SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptdwb;
        int sectorSize = 512;

        HANDLE phDisk = NULL;
        phDisk= CreateFile(L"\\\\.\\PhysicalDrive0",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
        DWORD ret = GetLastError();
        if(!(phDisk != NULL && GetLastError() ==0) )
            return false;
        DWORD capabilities = 0;
        IO_SCSI_CAPABILITIES scsiCaps;
         DeviceIoControl( phDisk,
        IOCTL_SCSI_GET_CAPABILITIES,
        NULL,
        0,
        &scsiCaps,
        sizeof( scsiCaps ),
        &capabilities,
        FALSE );

        GetAlignmentMaskForDevice(phDisk,&alignmentMask);
     
        ZeroMemory(&sptdwb, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER));
        dataBuffer = AllocateAlignedBuffer(sectorSize,alignmentMask, &pUnAlignedBuffer);   
     
        ZeroMemory(dataBuffer,sectorSize);

        sptdwb.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
        sptdwb.sptd.PathId = 0;
        sptdwb.sptd.TargetId = 0;
        sptdwb.sptd.Lun = 0;
        sptdwb.sptd.CdbLength = CDB16GENERIC_LENGTH;
        sptdwb.sptd.DataIn = SCSI_IOCTL_DATA_IN;
        sptdwb.sptd.SenseInfoLength = SPT_SENSE_LENGTH;
        sptdwb.sptd.DataTransferLength = sectorSize;
        sptdwb.sptd.TimeOutValue = 100;
        sptdwb.sptd.DataBuffer = dataBuffer;
        sptdwb.sptd.SenseInfoOffset =
           offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER,ucSenseBuf);
      
        sptdwb.sptd.Cdb[0] = 0x88;
        sptdwb.sptd.Cdb[1] = 0x8;   //Set to force unit access so that cached data is not used.                     
        sptdwb.sptd.Cdb[2] = 0;
        sptdwb.sptd.Cdb[3] = 0;
        sptdwb.sptd.Cdb[4] = 0;
        sptdwb.sptd.Cdb[5] = 0;
        sptdwb.sptd.Cdb[6] = 0;
        sptdwb.sptd.Cdb[7] = 0;
        sptdwb.sptd.Cdb[8] = 0;
        sptdwb.sptd.Cdb[9] = 0;
        sptdwb.sptd.Cdb[10] = (UCHAR)(512>> 8) & 0xFF;  // Parameter List length
        sptdwb.sptd.Cdb[11] = 512 & 0xFF;;
        sptdwb.sptd.Cdb[15] = 0;
        ULONG length = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER);
        ULONG returned = 0;
        status = DeviceIoControl(phDisk,
                                 IOCTL_SCSI_PASS_THROUGH_DIRECT,
                                 &sptdwb,
                                 length,
                                 &sptdwb,
                                 length,
                                 &returned,
                                 FALSE);

     
        if ((sptdwb.sptd.ScsiStatus == 0) && (status != 0)) {
            printf("Using IOCTL SCSI\n");
           PrintDataBuffer(dataBuffer,sptdwb.sptd.DataTransferLength);
           }
        DWORD error = GetLastError();
        printf("%d",error);
        CloseHandle(phDisk);
        return true;
    }

     

    returns error 1117.

    Is there any obvious mistake.
     This is on a VMware scsi drive.
    When I retrieve sense information I get

    Sense Info -- consult SCSI spec for details
    -------------------------------------------------------------
    70 00 05 00 00 00 00 0A 00 00 00 00 20 00 00 00 00 00


    If there are any suggestions I would appreciate it very much.

    Thanks,
    Sonia.


    SS

    Tuesday, December 10, 2013 11:57 PM

Answers

  • from the storage team:

    Looks like the VMware SCSI drive doesn’t support 16-byte read CDBs.

    The first function, ReadMBRUsingScsiPassThruDirect10, uses a 10-byte read CDB.  The second function, ReadMBRUsingScsiPassThruDirect, uses a 16-byte read CDB and returns ERROR_IO_DEVICE, which unfortunately isn’t very helpful.  However, the sense data indicates that the device doesn’t support this command (sense key = 5h “Illegal Request” and the sense code = 20h 00h “Invalid Command Operation Code”).


    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Wednesday, December 11, 2013 7:27 PM