USB/ATA変換によりディスクドライブを接続している場合、ディスクに対してDeviceIoControlにてATAPIコマンド(のようなもの?)を発行できると某サイトに書いてありました。
IOCTLコードにIOCTL_STORAGE_EJECT_MEDIA(イジェクト)、IOCTL_STORAGE_LOAD_MEDIA(ロード)を設定できるのは確認したのですが、今回「Mt.Fujiコマンド」により発行しなければなりません。
仕様書を見ると入力パラメータが12バイトで、「OperationCode(0バイト目)が1Bh」「LoEj(4バイト目の1ビット目)が1b」と書いてあるのですが、このような場合はIOCTLコードを何に設定すれば良いのでしょうか?
分かりにくい説明(今ひとつ理解できていないため?)でスミマセンが、助言頂ければ助かります。
宜しくお願いします。
例えば、へろぱさんのところの
http://www31.ocn.ne.jp/~heropa/vb31.htm
の特に IOCTL_STORAGE_MEDIA_REMOVAL と対比してみるとか。
K.J.K.さん、ありがとうございます。
教えて頂いた点を元に、MSDNサイトにてIOCTLコードを確認中です。
http://msdn.microsoft.com/ja-jp/library/cc429164.aspx
どうもシックリくるIOCTLコードが見つからないような気がします。
もしかするとベンダーファンクション的な事をお聞きしてしまっているのかもしれません。
もう少し検証してみます。何か判明した際にはこちらで報告させて頂きます。
こちらのサイトにて以前質問があった内容を参考にしてテストプログラミング
してみました。
http://madia.world.coocan.jp/cgi-bin/VBBBS/wwwlng.cgi?print+200807/08070022.txt
[構造体定義部]
Public Type SCSI_PASS_THROUGH
length As Integer
ScsiStatus As Byte
PathId As Byte
TargetId As Byte
Lun As Byte
CdbLength As Byte
SenseInfoLength As Byte
DataIn As Byte
DataTransferLength As Long
TimeOutValue As Long
DataBuffer As Long
SenseInfoOffset As Long
Cdb(0 To 11) As Byte
End Type
Public Type SCSI_PASS_THROUGH_WITH_BUFFERS
spt As SCSI_PASS_THROUGH
Fill As Long
SenseBuf(31) As Byte
End Type
Public sptwb As SCSI_PASS_THROUGH_WITH_BUFFERS
[コマンド発行部]
''デバイスコマンド構造体(入力)を設定する
With sptwb
.spt.length = LenB(.spt)
.spt.PathId = 0
.spt.TargetId = 0
.spt.Lun = 0
.spt.CdbLength = 12
.spt.SenseInfoLength = 24
.spt.DataIn = 1
.spt.DataTransferLength = 1
.spt.TimeOutValue = 10
.spt.SenseInfoOffset = 48
.spt.DataBuffer = 80
.spt.Cdb(0) = lngOpeCode
.spt.Cdb(1) = lngLun * (2 ^ 5) Or lngImmed * (2 ^ 0)
.spt.Cdb(2) = &H0
.spt.Cdb(3) = &H0
.spt.Cdb(4) = lngPowCond * (2 ^ 4) Or lngLoEj * (2 ^ 1) Or lngStart * (2 ^ 0)
.spt.Cdb(5) = &H0
.spt.Cdb(6) = &H0
.spt.Cdb(7) = &H0
.spt.Cdb(8) = &H0
.spt.Cdb(9) = &H0
.spt.Cdb(10) = &H0
.spt.Cdb(11) = &H0
lnglength = 4 + .spt.DataTransferLength
End With
''デバイスをオープンする
lngDevice = CreateFile(strDriveName, GENERIC_READ, FILE_SHARE_READ Or FILE_SHARE_WRITE, objSecurityAttributes, OPEN_EXISTING, 0, 0)
''デバイス制御コマンドを通知する
lngRet = DeviceIoControl(lngDevice, IOCTL_SCSI_PASS_THROUGH, sptwb, Len(sptwb), sptwb, Len(sptwb), lngBytesReturned, objOverLapped)
:
:
:
DeviceIoControl関数の戻り値がエラー(0)になってしまい、拡張エラー情報のErr.LastDllErrorを
確認すると(5)となっていました。
このエラーの内容が何を指すのでしょうか?(どこかに書かれているとは思いますが・・・)
「Visual Basic for Applications でのエラー トラップ 」のページに
載ってました。
http://support.microsoft.com/kb/146864/ja
「5:プロシージャの呼び出し、または引数が不正です。」
うーん、不正と言われても・・・。
IOCTL_SCSI_PASS_THROUGH を用いた質問だと、ここの過去ログの
http://madia.world.coocan.jp/cgi-bin/VBBBS/wwwlng.cgi?print+200807/08070022.txt
が参考になるかも知れません。
K.J.K.さん、ありがとうございます。
教えて頂いたページについては、既に見つけて色々と試しているところです(汗)
たぶん引数の内容に不備があるのかな?と思っています。
入力パラメータ部分について現在調査中ですので、何か進展がありましたら
こちらで報告させて頂きます。
> 確認すると(5)となっていました。
> このエラーの内容が何を指すのでしょうか?
5 は、『アクセスが拒否されました。』ですね。
> (どこかに書かれているとは思いますが・・・)
手元に ERRLOOK.EXE が無いかどうか探してみてください。
このツールを使うと、エラー番号からエラーメッセージを調査できます。
(このツールは、Visual C++、Platform SDK などに付属しています)
もし、ERRLOOK.EXE が無い場合には、FormatMessage API を利用して、
エラーメッセージを調査する事もできます。
http://www.red.oit-net.jp/tatsuya/vb/FormatMessage.htm
あるいは、C 言語用のヘッダファイルをお持ちであれば、
include\*ERR*.H ファイルから探すという手もあります。
たとえば今回のエラー番号でいえば、"WINERROR.H" ファイルにて
下記のような記述を見つけることができます。
//
// MessageId: ERROR_ACCESS_DENIED
//
// MessageText:
//
// Access is denied.
//
#define ERROR_ACCESS_DENIED 5L
魔界の仮面弁士さん、ありがとうございます。
(諸事情によりお礼が大変遅くなりスミマセンでした)
今回の作業に関してはベンダー仕様のインタフェースがシンプルになったため、教えて頂いた内容で無事クリアできました。重ねてお礼致します。
今後のインタフェース仕様の改訂により不明な点が出てくる可能性は高いのですが、その際はまた相談させて頂きます。
ツイート | ![]() |