線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:6836
推到 Plurk!
推到 Facebook!

在 C# 使用 deviceiocontrol 控制 usb device

缺席
jason8668
一般會員


發表:17
回覆:31
積分:9
註冊:2003-11-01

發送簡訊給我
#1 引用回覆 回覆 發表時間:2009-01-20 23:08:01 IP:60.250.xxx.xxx 訂閱
請問站上的大大們,我參考 vc++ 的 deviceiocontrol 控制 usb device,現在要把它翻譯成 c# 遇到了瓶頸。可望大大們解答~情況是這樣的:
我對 usb device 下 SCSI CMD(INQUIRY = 0x12),依照spec所說,如果執行順利的話,應該會回傳36 Bytes 以上的資料出來,但是我在info.data 裡看不到任何資料有回傳,不過已經確定執行 deviceiocontrol 之後,return 回來的值是1,表示應該是有找到此裝置且也有把cmd送出去才對,但是就一直看不到有任何資料回傳,不知道我的程式出了什麼問題?以下是我比較完整的程式。

[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateFile(
string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr lpSecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile);

[DllImport("kernel32.dll", SetLastError = true)]
static extern int DeviceIoControl(
[In] IntPtr hDevice,
[In] int dwIoControlCode,
[In] IntPtr lpInBuffer,
[In] int nInBufferSize,
[Out] IntPtr lpOutBuffer,
[In] int nOutBufferSize,
ref int lpBytesReturned,
[In] IntPtr lpOverlapped);

[StructLayout(LayoutKind.Sequential)]
struct SCSI_PASS_THROUGH_DIRECT
{
public short Length;
public byte ScsiStatus;
public byte PathId;
public byte TargetId;
public byte Lun;
public byte Cdblength;
public byte SenseInfoLength;
public byte DataIn;
public int DataTransferLength;
public int TimeOutValue;
public IntPtr DataBufferOffset;
public uint SenseInfoOffset;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] cdb;
}

[StructLayout(LayoutKind.Sequential)]
class SCSI_PASS_THROUGH_WITH_BUFFERS
{
internal SCSI_PASS_THROUGH_DIRECT sptd = new SCSI_PASS_THROUGH_DIRECT();
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 18)]
internal byte[] sense;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 56)]
internal char[] data;
}


hDevice = CreateFile(Path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
SCSI_PASS_THROUGH_WITH_BUFFERS info = new SCSI_PASS_THROUGH_WITH_BUFFERS();
info.sptd.cdb = new byte[16];
info.data = new byte[512];
info.sptd.Length = (short)Marshal.SizeOf(info.sptd);
info.sptd.SenseInfoOffset = 0;
info.sptd.SenseInfoLength = 0;
info.sptd.DataTransferLength = info.data.Length;
info.sptd.DataBufferOffset = Marshal.OffsetOf(typeof(SCSI_PASS_THROUGH_WITH_BUFFERS), "data");
info.sptd.TimeOutValue = 4;
info.sptd.PathId = 0;
info.sptd.Lun = 0;
info.sptd.Cdblength = 16;
info.sptd.SenseInfoLength = 0;
info.sptd.DataIn = 1;

info.sptd.cdb[0] = 0x12;
info.sptd.cdb[1] = 0x00;
info.sptd.cdb[2] = 0x00;
info.sptd.cdb[3] = 0x00;
info.sptd.cdb[4] = 512;
info.sptd.cdb[5] = 0x00;
info.sptd.cdb[6] = 0x00;
info.sptd.cdb[7] = 0x00;
info.sptd.cdb[8] = 0x00;
info.sptd.cdb[9] = 0x00;
info.sptd.cdb[10] = 0x00;
info.sptd.cdb[11] = 0x00;
info.sptd.cdb[12] = 0x00;
info.sptd.cdb[13] = 0x00;
info.sptd.cdb[14] = 0x00;
info.sptd.cdb[15] = 0x00;

inputbuf_length = Marshal.SizeOf(typeof(SCSI_PASS_THROUGH_DIRECT));
outputbuf_length = ((int)Marshal.OffsetOf(typeof(SCSI_PASS_THROUGH_WITH_BUFFERS), "data")) info.sptd.DataTransferLength;
IntPtr inpbuffer = Marshal.AllocHGlobal((Marshal.SizeOf(info)));
Marshal.StructureToPtr(info, inpbuffer, false);
int fResult = DeviceIoControl(hDevice, FSConstants.IOCTL_SCSI_PASS_THROUGH, inpbuffer, inputbuf_length, inpbuffer, outputbuf_length, ref outbyte, System.IntPtr.Zero);

系統時間:2024-05-02 21:02:25
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!