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を以下のソースで読み取ることができたみたいです(データの解析をしていないので、本当に読み込んだかどうかは後日)。
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
となるので、これを詳細に読むのかな?

