SPTIによる制御法
http://azuco.smallnews.net/fao/doc/spti.html
DeviceIoControl-SCSI_PASS_THROUGH_DIRECT keeps giving Error 87
http://social.microsoft.com/Forums/en-US/Offtopic/thread/56529bff-ef02-4b67-8dae-bef7a7be0dfd
SCSI read disc structure C++ help
http://cboard.cprogramming.com/cplusplus-programming/113878-scsi-read-disc-structure-cplusplus-help.html
アーカイブ: USB ストレージ – ドライバおよびハードウェア開発者向けの FAQ
http://www.microsoft.com/japan/whdc/archive/usbfaq.mspx
Japan WDK Support Blog : アプリケーションからSCSIコマンドを発行する方法
http://blogs.msdn.com/jpwdkblog/archive/2009/04/15/scsi.aspx
DeviceIoControl と IOCTL_SCSI_PASS_THROUGH_DIRECT をキーワードにして探していくと↑なところに行きつきました。
最初は、SPTIによる制御法を参考にして、直接組んでいたのですが、やっぱり Windows Device Kit(WDK)が必要なようです。つーか、そこにサンプルがあります。
WDKをインストールして、
C:WinDDK6001.18002srcstoragetoolsspti
を見ると、spti.c なソースに IOCTL_SCSI_PASS_THROUGH や IOCTL_SCSI_PASS_THROUGH_DIRECT を指定したサンプルがあります。ちなみに _DIRECT あり/なしの違いを簡単に言うと、読み書きするときのバッファの取り方が違います。_DIRECT なしの場合は、いったんドライバー内部のデータに読み込んだ後にユーザーの指定バッファに転送、_DIRECT ありの場合は、ドライバー内部を経由せずに直接ユーザー指定のバッファに転送します。ってのが、spti.htm に書いてあります。
WDKの入手先は、Microsoft Connect Web サイト か MSDN サブスクリプションとなっています。が、私の見た限り MSDN サブスクリプションには WDK が無い(?) ので、Microsoft Connect Web サイトのほうでダウンロードしました。
Alcohol 52% でマウントしたCDを以下のソースで読み取ることができたみたいです(データの解析をしていないので、本当に読み込んだかどうかは後日)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | printf (" ***** READ DATA BUFFER operation *****n"); if ( dataBuffer == NULL ) { dataBuffer = AllocateAlignedBuffer(sectorSize,alignmentMask, &pUnAlignedBuffer); } ZeroMemory(&sptdwb, sizeof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER)); ZeroMemory(dataBuffer,sectorSize);</pre> sptdwb.sptd.Length = sizeof (SCSI_PASS_THROUGH_DIRECT); sptdwb.sptd.PathId = 0; sptdwb.sptd.TargetId = 1; sptdwb.sptd.Lun = 0; sptdwb.sptd.CdbLength = CDB12GENERIC_LENGTH; sptdwb.sptd.DataIn = SCSI_IOCTL_DATA_IN; sptdwb.sptd.SenseInfoLength = SPT_SENSE_LENGTH; sptdwb.sptd.DataTransferLength = 2352; // SPT_SENSE_LENGTH; sptdwb.sptd.TimeOutValue = 2; sptdwb.sptd.DataBuffer = dataBuffer; sptdwb.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER,ucSenseBuf); // sptdwb.sptd.Cdb[0] = SCSIOP_READ_DATA_BUFF; // sptdwb.sptd.Cdb[1] = 2; // Data mode // sptdwb.sptd.Cdb[7] = (UCHAR)(sectorSize >> 8); // Parameter List length // sptdwb.sptd.Cdb[8] = 0; sptdwb.sptd.Cdb[0] = SCSIOP_READ_CD; sptdwb.sptd.Cdb[2] = 0; sptdwb.sptd.Cdb[3] = 0; sptdwb.sptd.Cdb[4] = 0; sptdwb.sptd.Cdb[5] = 0x10; // どのセクタを読み込むか sptdwb.sptd.Cdb[8] = 1; // 1セクタ分読み込む sptdwb.sptd.Cdb[9] = 0xF8; length = sizeof (SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER); status = DeviceIoControl(fileHandle, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptdwb, length, &sptdwb, length, &returned, FALSE); |
肝心のデジタルフォトミニアルバムのほうは読み込めない。何故に?というか、CDB(Command Discripter Block)をきちんと設定していないので、まぁそりゃそうなんですが。このあたりのコマンド、どういうのを送るのかと言うのが良くわからん。「SPTIによる制御法」を読むとコマンド仕様については、以下を参照のこと、
Information Specification for ATAPI DVD Devices
ftp://ftp.seagate.com/sff/INF-8090.PDF
となるので、これを詳細に読むのかな?