0

I have developed a mass-storage device, and I'd a like a PC application to send/receive some custom commands to it. Normally one would create a composite USB device for this (MSC+HID) and send the commands over HID. But is it possible to do this with only the mass-storage class? Some things I thought of:

  • Send the data in unused SCSI commands (Vista requires administrator rights for this)
  • Write the data to a "magic" sector, and parse it on the device as soon as it notices that specific sector being written too (Some windows version dont allow raw disk access)
  • Send the data by placing them in a .txt file on the disk (very complicated, because the device needs to parse the FAT tables to read the file, and has no way of being notified when the .txt file is updated)

Can someone think of any other hacks, that would work for this purpose? Or is the only option to create a HID device?

Thomas Tempelmann
  • 11,045
  • 8
  • 74
  • 149
Maestro
  • 9,046
  • 15
  • 83
  • 116
  • It seems there was no way to contact a user, except via comments. Have you ever found an answer or way to send commands/data to a mass-storage device? Any tip would be much appreciated. Thanks – Naze Kimi Jun 13 '14 at 01:05

1 Answers1

1

The MSC you mentioned is also "USB" Mass Storage Device ?

If yes then you can use SCSI_PATH_THROUGH to communicate with this USB MSC !

Ex. issuing Write command to USB MSC can be achieved by below code snippet:

BOOL LogicalWriteCmd(HANDLE fileHandle,ULONG LBA,ULONG SectorCnt,PVOID DataBuffer)
{
    SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER  sptdwb;
    ULONG returned,length;
    BOOL status;

    ZeroMemory(&sptdwb, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER));    

    length = SectorCnt<<SECTOR_SIZE_SHIFT_BIT;

    sptdwb.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
    sptdwb.sptd.PathId = 0;
    sptdwb.sptd.TargetId = 0;
    sptdwb.sptd.Lun = 0;
    sptdwb.sptd.CdbLength = CDB10GENERIC_LENGTH;
    sptdwb.sptd.DataIn = SCSI_IOCTL_DATA_OUT;
    sptdwb.sptd.SenseInfoLength = SPT_SENSE_LENGTH;
    sptdwb.sptd.DataTransferLength = length;
    sptdwb.sptd.TimeOutValue = g_ulTimeOut;
    sptdwb.sptd.DataBuffer = DataBuffer;
    sptdwb.sptd.SenseInfoOffset =
       offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER,ucSenseBuf);
    sptdwb.sptd.Cdb[0] = SCSIOP_WRITE;

    sptdwb.sptd.Cdb[2] = (UCHAR)(LBA>>24);
    sptdwb.sptd.Cdb[3] = (UCHAR)(LBA>>16);
    sptdwb.sptd.Cdb[4] = (UCHAR)(LBA>>8);
    sptdwb.sptd.Cdb[5] = (UCHAR)(LBA);

    sptdwb.sptd.Cdb[7] = SectorCnt>>8;    
    sptdwb.sptd.Cdb[8] = (UCHAR)SectorCnt;

    length = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER);
    status = DeviceIoControl(fileHandle,
                             IOCTL_SCSI_PASS_THROUGH_DIRECT,
                             &sptdwb,
                             length,
                             &sptdwb,
                             length,
                             &returned,
                             FALSE);


    if ((sptdwb.sptd.ScsiStatus == 0) && (status != 0)) {       
        return TRUE;
    }


    return FALSE;

}

And you can create your own vendor/custom commands then send it to USB MSC by above way. But your device should identify them correctly !

liaoo
  • 193
  • 2
  • 15
  • I agree that this would be the best way to do it, but my main problem is KB241374: "Note that only members of the administrator's group have the correct authority to send SCSI pass through requests." So my application will always need to be launched as an Administrator-user. – Maestro Jan 17 '13 at 11:14
  • yes ! It sure is...Before I used to use ASPI to access USB MSD(please check http://en.wikipedia.org/wiki/Advanced_SCSI_Programming_Interface) – liaoo Jan 18 '13 at 08:07