0

大容量記憶装置を開発しましたが、カスタム コマンドを送信/受信する PC アプリケーションが必要です。通常、このための複合 USB デバイス (MSC+HID) を作成し、HID 経由でコマンドを送信します。しかし、マスストレージクラスだけでこれを行うことは可能ですか? 私が考えたいくつかのこと:

  • 未使用の SCSI コマンドでデータを送信します (Vista では、これには管理者権限が必要です)。
  • データを「魔法の」セクターに書き込み、特定のセクターも書き込まれていることに気付くとすぐにデバイスで解析します(一部のWindowsバージョンでは未加工のディスクアクセスが許可されていません)
  • データをディスク上の .txt ファイルに配置して送信します (デバイスはファイルを読み取るために FAT テーブルを解析する必要があり、.txt ファイルが更新されたときに通知を受ける方法がないため、非常に複雑です)

誰かがこの目的のために働く他のハックを考えることができますか? それとも、HID デバイスを作成する唯一のオプションですか?

4

1 に答える 1

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 に送信できます。ただし、デバイスはそれらを正しく識別する必要があります。

于 2013-01-17T10:43:35.967 に答える