天天看點

簡單說說USB協定之GetLastError() 函數錯誤傳回值為:拒絕通路

今天在嘗試往U盤寫入Write指令(0x2A)時,發現前面幾次寫成功了,後來無論怎麼寫,都無法成功。

用Bus Hound 抓協定,發現Write指令(0x2a),Read(0x2a)一直沒有發出去。

嘗試發其他指令,如Read Capacity(0x25)等,卻可以完好無損發出去。

在幾十次的調試後,各種參數完全沒有問題,也沒有出現調用錯函數,占用等情況。

利用GetLastError()函數擷取 DeviceIoControl()錯誤傳回值,傳回值為05,即拒絕通路。

第一反應是沒有權限,于是VS編譯器用管理者運作,發現也沒卵用。

折騰了好久,發現原因在于U盤中的MBR區域資料被修改了。

在通過DeviceIoControl()函數發送Write指令給裝置時,邏輯位址LBA被設定在了0x00000000~0x000001FE之間,導緻寫資料覆寫了原本MBR主引導程式的資料,導緻檔案系統完全除了問題。

終于發現了問題,U盤換一個檔案系統,注意在Write過程中避免MBR資料被修改就好了。

此外還有一個辦法:

就是用SCSI指令識别不到的私有指令去讀寫。

因為0x28和0x2a是标準指令,一旦出現類似“拒絕通路”這樣的錯誤,0x28和0x2a标準指令會立即被識别并攔截下來,根本就沒能成功發送給U盤,是以才失去了讀寫功能。

但是如果你用自己定的私有指令,這樣它就識别不到了,隻會被當作普通的資料發送給U盤。

當然這裡有個前提,U盤裡必須要有能識别你私有指令的驅動,否則白搭。