Отправка пользовательских команд на запоминающее устройство

Я разработал запоминающее устройство, и мне бы хотелось, чтобы приложение для ПК отправляло/получало на него некоторые пользовательские команды. Обычно для этого создается составное USB-устройство (MSC+HID) и отправляются команды через HID. Но возможно ли сделать это только с классом запоминающих устройств? Некоторые вещи, о которых я подумал:

  • Отправлять данные в неиспользуемых командах SCSI (для Vista требуются права администратора)
  • Запишите данные в «магический» сектор и проанализируйте их на устройстве, как только оно заметит, что этот конкретный сектор также записывается (некоторые версии Windows не разрешают доступ к необработанному диску)
  • Отправьте данные, поместив их в файл .txt на диске (очень сложно, потому что устройству необходимо проанализировать таблицы FAT, чтобы прочитать файл, и у него нет возможности получать уведомления об обновлении файла .txt).

Может ли кто-нибудь придумать какие-либо другие хаки, которые будут работать для этой цели? Или единственный вариант создать HID-устройство?


person Muis    schedule 16.01.2013    source источник
comment
Кажется, не было никакого способа связаться с пользователем, кроме как через комментарии. Вы когда-нибудь находили ответ или способ отправки команд/данных на запоминающее устройство? Любой совет будет высоко оценен. Спасибо   -  person Naze Kimi    schedule 13.06.2014


Ответы (1)


Упомянутый вами MSC также является запоминающим устройством USB?

Если да, то вы можете использовать SCSI_PATH_THROUGH для связи с этим USB MSC!

Бывший. Выдача команды записи на USB MSC может быть достигнута с помощью приведенного ниже фрагмента кода:

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;

}

И вы можете создать свои собственные команды поставщика/пользователя, а затем отправить их на USB MSC указанным выше способом. Но ваше устройство должно правильно их идентифицировать!

person liaoo    schedule 17.01.2013
comment
Я согласен, что это был бы лучший способ сделать это, но моя основная проблема заключается в KB241374: Обратите внимание, что только члены группы администратора имеют правильные полномочия для отправки запросов SCSI pass through. Поэтому мое приложение всегда нужно запускать от имени пользователя-администратора. - person Muis; 17.01.2013
comment
да ! Это точно... До того, как я использовал ASPI для доступа к USB MSD (пожалуйста, проверьте en.wikipedia.org /wiki/Advanced_SCSI_Programming_Interface) - person liaoo; 18.01.2013