青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

USB系列之三:從你的U盤里讀出更多的內容

U盤是我們最常使用的一種USB設備,本文繼續使用DOSUSB做驅動,試圖以讀取扇區的方式讀取你的U盤。
    本文可能涉及的協議可能會比較多。
一、了解你的U盤
    首先我們用上一篇文章介紹的程序usbview.exe去看一下你的U盤,我在本文中用于測試的U盤情況如下:
    Device Descriptor: (設備描述符)
    USB Address:             1
    Length:                  18
    Descriptor Type:         1
    USB Specification nr.:   0x0110
    Calss Code:              Class code specified by interface
    Subclass Code:           0x00
    Protocol Code:           0x00
    MAX Packet Size:         0x08
    Vendor ID:               0x058f
    Product ID:              0x9321
    Device Code:             0x0100
    Manufacture Index:       1
    Product Index:           2
    Serial Number Index:     0
    Number of Configuration: 1

    String Descriptor: (字符串描述符)
    Manufacturer: Alcor Micro
    Product: Mass Storage Device

    Configuration Descriptor: (配置描述符)
    Length:               9
    Descriptor Type:      2
    Total Length:         32
    Number of Interfaces: 1
    Configuration Value:  1
    Configuration Index:  0
    Attributes:           Bus Powered
    Max Power:            50mA

    Interface Descriptor: (接口描述符)
    Length:               9
    Descriptor Type:      4
    Interface Number:     0
    Alternate Setting:    0
    Number of Endpoints:  2
    Interface Class:      Mass Storage Device
    Interface Sub Class:  6
    Interface Protocol:   80
    Interface Index:      0

    Endpoint Descriptor: (端點描述符)
    Length:               7
    Descriptor Type:      5
    Endpoint Address:     
1 OUT endpoint
    Attributes:           Bulk
    Max Packet Size:      64
    Interval:             0

    Endpoint Descriptor: (端點描述符)
    Length:               7
    Descriptor Type:      5
    Endpoint Address:     
2 IN endpoint
    Attributes:           Bulk
    Max Packet Size:      64
    Interval:             0

    各種描述符的含義在以前的文章中介紹過了,或者去翻閱USB的specification,這里就不多說了,我們從接口描述符開始就一些關鍵點進行一下說明。
    首先看接口描述符,Interface Class = 8,表明是Mass Storage Device;Sub Class = 6,表明執行SCSI命令;Interface Protocol = 0x80,表明支持Bulk傳輸;另外,Number of Endpoints = 2,表明有兩個端點。
    兩個端點描述符要注意的是,Endpoint Address = 1的是OUT端點,Endpoint Address = 2的是IN端點,有些可能會不一樣;有些U盤可能還會有第三個端點,比如支持中斷傳輸的U盤還會有一個Interrupt端點,不過這都沒有關系。
    我大概看了我手頭有的5個U盤,都支持批量傳輸,且支持SCSI命令,所以,這可能是一個比較典型的例子,我們就以它為例。

二、CBW(Command Block Wrapper)和CSW(Command Status Wrapper)

    在《USB系列之一》中,我們安裝了一個DOSUSB,在《USB系列之二》中,我們利用USBDOS讀取了所有的描述表,掌握這些內容需要了解USB協議1.1(USB Specification Revision 1.1)即可,當然還要了解USBDOS,不過這個比較簡單。

    在系列一和系列二中,我們已經對DOSUSB的一個數據結構URB有所了解,本文中還要大量用到,我們還接觸了一個結構叫device_request,這個結構是在USB協議中定義的,用于向設備發送命令(Request),本文也會用到。

    與前面不同的是,前面的兩個系列可以針對任何USB設備,比如U盤、攝像頭、打印機等,而本文將只針對我們經常使用的USB設備----U盤,如果你打算嘗試本文所介紹的內容,請準備好一個U盤,什么樣子的都行,或者是一個USB讀卡器,不過要記得插一張卡進去,實際上本文所載范例就是使用一個USB的CF卡讀卡器完成的,不用擔心損害你的U盤中的數據,本文不會對U盤進行任何寫操作,僅僅做一些讀操作。

    這個系列中我們需要針對U盤讀更多的規范,如下:

     不用為規范發愁,實際上,前兩個規范都很短,其中第一個對實際編程沒有什么作用,但最好看一下;第二個規范連目錄一共22頁,其中13頁以前的內容可以跳過(很多和USB Specification中相同),第三個規范主要看第6章,第四個規范主要看第5章,后兩個規范在編程時需要經常翻閱,以便了解你正在實現的SCSI命令的具體格式和參數。

    本節我們主要介紹兩個新的數據結構,這兩個結構都是在第二個規范中定義的。

    第一個數據結構叫CBW(Command Block Wrapper)


    這個結構將承載具體的與設備有關的命令發送到設備上去,這個結構分成兩部分,第一部分從byte[0]--byte[14]共15個字節,第而部分從byte[15]--byte[30]共16個字節,整個數據結構為31個字節。規范中并沒有定義第二部分的內容,這是因為第二部分承載的具體的命令,既與命令集(SCSI命令集)有關,也與具體的命令有關,我們使用SCSI命令集,所以后16個字節的內容在前面提到的后面兩個規范中有定義。

    比如我們要向設備發出一個SCSI命令INQUIRY(我們姑且先不要管命令的含義),那么這個命令的結構在SPC-3的第142頁有定義,如下:


    對于SCSI INQUIRY這條命令而言,CBW的第二部分的定義就是上面的這六個字節,不同的命令,定義也會不同。

    好,我們回到CSW的結構上來,根據規范,dCBWSignature的值必須是0X43425355,其實就是USBC這幾個字母倒過來,這是因為CBW的字符順序是little endian(這個東東在以前有關網絡編程的文章中介紹過),而我們PC機中的字符順序是big endian,所以要顛倒一下,總之寫dCBWSignature = 0X43425355就OK了;dCBWTag僅僅是一個標志,你可以填任何值,這里要先說一下CSW(Command Status Wrapper),我們每發出一個命令,設備都會返回一個CSW(這個東東下面很快就要介紹了),以說明命令的執行狀態,這個結構中也有Signature和Tag這兩個字段,其中Tag字段和發出命令時CBW中的Tag字段相同,這樣就可以區分這個CSW是和那個CBW對應的了,至于Signature,下面再說。

    下一個字段是dCBWDataTransferLength,表示的是當這個命令發出后,我們希望設備返回數據的字符數或者我們要向設備傳輸的字符數,本文僅涉及從設備返回數據,不涉及向設備傳輸數據;舉例來說:我們發送INQIURY命令到設備,按照SPC-3第144頁的說明,該命令返回的數據至少為36個字節,所以,此時這個字節應該填36;再如:我們讀取U盤的一個扇區,如果扇區的長度是512個字節,那么這個字段就要填512。

    再下來是bmCBWFlags字段,這個字段只有bit 7有意義,為0表示要向設備傳輸數據,為1表示要從設備獲得數據。

    bCBWLUN字段總是填0,因為絕大多數的U盤都不支持多LUN(Logical Unit Number),只有一個邏輯單元自然好嗎就是0了。

    bCBWCBLength字段是只CBW第二部分的長度,像前面舉例的INQUIRY命令,長度為6個字節,則這個字段就應該填6,再如:READ(10)命令的長度是10個字節(SBC-2第42頁有定義),這個字段當然要填10了。

    第二個要說的數據結構是CSW,當host向device發送一個CBW后,接著就可以從device收到數據(或者發數據到device),當接受完所需的的數據后,就可以從device獲得一個CSW(Command Status Wrapper),CSW的結構如下:

     前面說過,在CBW中的dCBWSignature的值恒為:0x43425355,得到的CSW中的dCSWSignature的值為:0x53425355,dCSWTag與dCBWTag中的一致。

    在得到的CSW中,恒定有13個字節,bCSWStatus的定義如下:

 

三、發送命令和接收數據

    我們知道USB協議中定義了三種傳輸方式,控制傳輸、批量傳輸、中斷傳輸和實時傳輸,在《USB系列二》中我們一直都在使用控制傳輸,我們應該比較熟悉了,本文中將涉及批量傳輸。

    我們在使用控制傳輸時,我們設置好URB啟動傳輸事務,相應的結果將返回到制定得buffer中,批量傳輸沒有那么簡單,批量傳輸分為輸出事務和輸入事務,我們應該注意到,前面在看U盤的描述表時,在端點這一級有兩個端點,一個叫OUT端點,一個叫IN端點,當我們啟動一個輸出事務時,一定要發送給OUT端點,當我們啟動一個輸入事務時,一定要發送到輸入端點。下面我們簡單描述一下如何啟動批量傳輸事務。

    在使用控制傳輸時,我們應該閱讀過DOSUSB的說明,并且對URB結構比較熟悉,URB中有一個字段叫transation_type,當這個值為0x2d時為控制傳輸;當為0x69時為批量傳輸的IN事務;當為0xe1時為批量傳輸的OUT事務;當我們啟動一個傳輸時,一定要正確地設置這個值。

    我們以一個具體的例子來說明如何啟動一個傳輸,我們以SCSI INQUIRY命令為了,關于這個命令的定義在SPC-3的第142頁--157頁有說明,篇幅很長,但絕大多數篇幅用來解釋返回數據的含義,我們可以暫時不去理會。首先我們要填寫CBW結構,CBW結構的第一部分的填寫前面已經說的很明白了,第二部分的定義在SPC-3的第142頁,共有6個字節,我們要按照定義填寫好,實際上只要填兩個字段,一個是OPERATION CODE = 0X12,第二個就是ALLOCATION CODE = 36,表示需要返回36個字節的內容;CBW填好后,我們開始填寫URB,首先把CBW的偏移和段地址放到URB的buffer_off和buffer_seg中,把transation_type=0xe1,表示一個輸出事務,注意把end_point字段一定要放OUT endpoint的地址,從前面的描述符表中看,應該是1(2是IN endpoint的地址,你的機器可能不同),其它字段的填法在《USB系列二》中已經介紹過了,填完以后調用DOSUSB,這樣,一個承載著INQUIRY命令的輸出事務就發送到由URB中dev_add和end_point兩個字段指定的端點上去了。

    接下來我們要接收device返回的執行INQUIRY命令的結果,這要啟動一個輸入事務,相對容易一些,只要填寫URB就可以了,把transation_type=0x69,把end_point填上OUT endpoint的地址,本例中為2,buffer_off和buffer_seg指向緩沖區buffer,把buffer_length和actual_length均填為64,因為前面端點描述符表中寫明包的最大長度為64,其它字段按常規填寫,調用DOSUSB,在buffer中就可以得到返回的內容,按照SPC-3中對返回內容的解釋即可了解設備的一些情況。

    接收晚數據后,不要忘了接收CSW,方法也是啟動一個輸入事務,與接收數據完全相同,然后根據CSW的結構解釋其含義。至此一個命令執行完畢。

四、范例

    在本文的范例中,我們實現了如下內容:

  • 實現了Bulk-Only Mass Storage Reset
  • 實現了Get Max LUN
  • 實現了SCSI INQUIRY Command
  • 實現了SCSI READ CAPACITY (10) Command
  • 實現了SCSI REQUEST SENSE Command
  • 實現了SCSI TEST UNIT READY Command
  • 實現了SCSI READ (10) Command

    最后的一個命令,我將從你的U盤上讀出一個扇區。

    最前面的兩個命令,請翻閱《Universal Serial Bus Mass Storage Class - Bulk-Only Transport》第7頁;INQUIRY、REQUEST SENSE、TEST UNIT READY三個命令請翻閱SPC-3的第142、221和232頁;READ CAPACITY(10)和READ(10)命令,請翻閱SBC-2的第42和44頁。

    源代碼請在下面網址下載:

    http://blog.hengch.com/source/reader.rar

    各種概念在前面已經介紹過了,程序無非就是實現這些概念,幾乎所有的代碼都是圍繞著填寫數據結構和顯示返回結果的,所以代碼本身并不難,更重要的是理解數據結構中個字段的含義,這可能不得不閱讀一些規范,我想我不可能比規范說的更嚴謹更完整。要注意的是,你使用的U盤不可能和我的完全一致,一般情況下有可能有變化的是:設備地址devAddr、輸出端點地址outEndpoint和輸入端點地址inEndpoint,所以在編譯程序之前一定要使用《USB系列之二》中的方法仔細查看一下你的U盤的各種描述符表,如果這些值和我的U盤不同,請在主程序開始的地方,更改這幾個變量;另外,在主程序6th step中,scsiRead10(0),傳遞給scsiRead10的參數為0,含義是從LBA(Logical Block Address)為0的地方讀取一個扇區,如果你向讀取其它扇區,可以更改這個值,其最大值我們在實現 READ CAPACITY時已經讀出了,可以參考;此外,注意CBW的字符順序是little endian,所以我們在填寫LBA和讀取最大LBA時都做了相應的轉換。

    好了,應該沒有什么了!

    Enjoy it.

posted on 2010-11-24 14:09 wrh 閱讀(1412) 評論(1)  編輯 收藏 引用

評論

# re: USB系列之三:從你的U盤里讀出更多的內容 2012-07-17 17:53 王飛

請教個問題,傳輸數據塊時,可傳輸數據塊大小是由什么決定的呢?   回復  更多評論   

導航

<2010年7月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

統計

常用鏈接

留言簿(19)

隨筆檔案

文章檔案

收藏夾

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美日本韩国一区| 久久激情综合网| 欧美视频免费在线观看| 欧美激情在线有限公司| 欧美顶级大胆免费视频| 欧美成人精品激情在线观看| 免费在线看一区| 欧美日韩国产成人| 国产精品每日更新在线播放网址| 久久久91精品国产一区二区三区| 一区二区三区四区国产| 亚洲摸下面视频| 久久视频在线免费观看| 欧美日韩免费看| 国产精品视频成人| 亚洲电影自拍| 亚洲午夜羞羞片| 亚洲欧美日韩中文视频| 久久久亚洲欧洲日产国码αv| 久久久久久穴| 亚洲欧洲一区二区天堂久久| 亚洲国产精品成人一区二区| 亚洲视频狠狠| 久久免费国产精品| 欧美午夜在线观看| 亚洲大胆在线| 小黄鸭精品aⅴ导航网站入口 | 欧美午夜无遮挡| 黄网站免费久久| 亚洲一区日韩在线| 猛男gaygay欧美视频| 正在播放亚洲一区| 免费观看国产成人| 国产精品久久久久一区| 亚洲国产视频a| 欧美一区二区免费观在线| 亚洲二区视频| 久久久美女艺术照精彩视频福利播放| 午夜精品理论片| 男男成人高潮片免费网站| 国产嫩草影院久久久久| 国产精品99久久不卡二区| 久久躁日日躁aaaaxxxx| 午夜精品视频网站| 欧美视频观看一区| 亚洲狼人精品一区二区三区| 久热精品视频在线免费观看| 亚洲视频国产视频| 国产精品久久久久永久免费观看 | 久久久久久黄| 欧美视频免费看| 亚洲国产精品悠悠久久琪琪| 久久精品夜色噜噜亚洲a∨| 99国产精品视频免费观看| 欧美成人黄色小视频| 亚洲第一页在线| 免费观看成人www动漫视频| 欧美在线影院| 国产欧美在线看| 亚洲综合色在线| 99在线精品免费视频九九视| 欧美高清视频一区二区| 亚洲精品色婷婷福利天堂| 欧美电影免费观看| 猛男gaygay欧美视频| 在线观看日韩av先锋影音电影院| 欧美在线观看一区二区| 亚洲男人av电影| 国产伦精品一区| 久久久www免费人成黑人精品| 一区二区三区日韩| 国产精品羞羞答答xxdd| 久久精品1区| 欧美在线播放一区| 精品粉嫩aⅴ一区二区三区四区| 久久精品色图| 久久久久久久欧美精品| 亚洲国产综合在线| 亚洲精品日日夜夜| 国产精品黄视频| 久久久精品久久久久| 久久久久免费观看| 日韩午夜在线视频| 亚洲在线一区二区| 国产亚洲激情在线| 欧美激情视频网站| 欧美日韩国产综合视频在线| 亚洲欧美另类中文字幕| 久久精品国产99| 亚洲区欧美区| 国产精品99久久久久久久女警| 国产精品另类一区| 美女999久久久精品视频| 欧美女同在线视频| 性色av一区二区三区| 久久久夜精品| 亚洲视频在线一区| 欧美一区二区在线| 一本久道综合久久精品| 亚洲综合精品四区| 日韩午夜三级在线| 久久久久久久综合狠狠综合| 亚洲一区二区综合| 欧美99在线视频观看| 亚洲欧美日本另类| 欧美成年视频| 久久久久亚洲综合| 国产精品久久999| 亚洲国产天堂久久国产91| 在线观看欧美激情| 久久精品视频99| 亚洲少妇一区| 美女久久一区| 久久激情综合网| 国产精品激情av在线播放| 欧美高清自拍一区| 韩国一区二区三区美女美女秀| 欧美激情中文字幕在线| 国产精品一区在线播放| 亚洲日本黄色| 亚洲国产视频直播| 久久精品国产亚洲高清剧情介绍| 亚洲无玛一区| 欧美美女福利视频| 亚洲欧洲精品一区二区三区不卡 | 欧美a级片一区| 国产精品你懂得| 亚洲美女在线看| 亚洲国产另类久久精品| 久久精品亚洲一区二区三区浴池| 亚洲无亚洲人成网站77777 | 欧美视频一区二区三区四区| 免费观看成人www动漫视频| 国产日韩综合| 欧美一区二区黄| 欧美在线观看网站| 国产精品揄拍500视频| 午夜精品短视频| 久久久精品2019中文字幕神马| 国产精品亚洲综合一区在线观看| 亚洲理伦在线| 99热在线精品观看| 欧美精品三级| av成人黄色| 亚洲欧美日韩精品久久久久| 国产精品久久久久9999高清| 正在播放欧美一区| 欧美亚洲三区| 国内揄拍国内精品久久| 久久精品在线播放| 免费成人在线观看视频| 有码中文亚洲精品| 美女黄网久久| 夜夜嗨av色综合久久久综合网 | 欧美一级专区| 国产三区二区一区久久| 久久久久久久久久久成人| 欧美成人综合在线| 一区二区三区高清不卡| 国产精品剧情在线亚洲| 欧美一区二区免费| 欧美96在线丨欧| 亚洲婷婷综合久久一本伊一区| 欧美三级在线播放| 羞羞视频在线观看欧美| 老牛影视一区二区三区| 亚洲精品美女| 国产精品美女www爽爽爽| 亚洲一区二区三区四区视频 | 亚洲激情成人| 亚洲欧美成人一区二区三区| 国产亚洲精品7777| 欧美另类videos死尸| 亚洲免费在线视频| 国产精品wwwwww| 一区二区三区免费看| 一区二区三区四区五区在线 | 亚洲精品免费在线播放| 亚洲高清影视| 欧美日韩国产精品成人| 亚洲神马久久| 欧美不卡视频一区| 亚洲影音一区| 影音先锋欧美精品| 欧美区视频在线观看| 午夜精品国产更新| 亚洲国内自拍| 久久精品中文字幕一区二区三区| 精品91在线| 国产精品劲爆视频| 欧美成人黑人xx视频免费观看| 亚洲精品久久久久久久久久久久| 性久久久久久久久| av成人免费| 亚洲电影免费观看高清完整版在线观看| 欧美+日本+国产+在线a∨观看| 亚洲人体一区| 欧美成人黄色小视频| 欧美在线日韩精品| 日韩小视频在线观看专区|