找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3501|回復: 0
打印 上一主題 下一主題
收起左側(cè)

查找 USB 設(shè)備連接樹的方法

[復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:90014 發(fā)表于 2015-9-13 16:46 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
         由于 USB 只是一個設(shè)備接入到系統(tǒng)中的方式,對于大部分用戶來說,只要設(shè)備接入系統(tǒng)后能夠正常工作就可以了,不需要知道這個設(shè)備是連接在系統(tǒng)的哪一個端口上。但是如果一個系統(tǒng)中同時有多個具有相同的VID和PID的設(shè)備接入,要對其中的每一臺設(shè)備進行單獨的測試,就有必要研究這個設(shè)備的接入方式了。
一般的研究方法,應該是順藤摸瓜,或者相反。我在查找了相關(guān)的介紹后,很少能夠看到完整的例子,特別是對于U盤這樣的設(shè)備,很少有人直接將最終系統(tǒng)中顯示的文件卷與USB端口的連接關(guān)系做成樹狀的關(guān)系圖顯示出來。昨天看了那個設(shè)備的卸載過程示例后,覺得應該可以實現(xiàn)的。因為可以從一個文件卷查找到起對應的連接關(guān)系。即從 U 盤的文件卷找到其連接的HUB,然后從HUB的端口出發(fā),找到其所有的連接點(在設(shè)備管理器的資源中,顯示為總線關(guān)系)。后續(xù)應該可以繼續(xù)逆向?qū)ふ,一直找到主控制器。這樣就可以查清楚連接的脈絡(luò)。
看了微軟的 USB View 示例以及網(wǎng)友寫的 USB Port 示例,可以看出,查找USB設(shè)備,不一定非要從 USB 的設(shè)備接口類開始檢查,只要采用嘗試的方式,用 CreateFile 嘗試打開系統(tǒng)中名字為 HCD0, HCD1類似的名稱,就可以直接知道是不是有USB主控制器存在。此后通過 DeviceIoControl 函數(shù),給主控制器發(fā)送 IOCTL_USB_GET_ROOT_HUB_NAME 命令,獲取 Root Hub 的名字。此后再次使用 CreateFile 的方式,打開 RootHub,用DeviceIoControl 給RootHub發(fā)送 IOCTL_USB_GET_NODE_INFORMATION 命令,取得該 Hub上端口信息。在端口信息的 HubDescriptors 中,包含了 NumOfPorts,即該 Hub 上的端口數(shù)量。同時,這個端口信息中包含了指向端口連接關(guān)系的指針數(shù)組。通過循環(huán)檢查的方式,使用 DeviceIoControl 給端口發(fā)送 IOCTL_USB_GET_NODE_CONNECTION_INFORMATION 命令,獲取該端口的連接關(guān)系信息表,其中的一個bConnected 即標識了是否有設(shè)備連接在該端口上。并且有一個 ConnectedIsHub的標志,反映該端口連接是下一級 Hub還是一般的設(shè)備。通過 GetDriverKeyName 函數(shù),從 HubDevice 中獲得所連接的設(shè)備的驅(qū)動信息,包括了設(shè)備類Guid,設(shè)備的 PID,VID,連接速度等描述內(nèi)容。采用循環(huán)的方式可以逐一查找所有已連接的設(shè)備。
如果要進一步查找其中的Hub設(shè)備所連接的信息,必須采用遞歸方法逐步深入到每一個Hub的下層,才可以獲得完整的設(shè)備連接信息。
知道了設(shè)備名稱,并無法獲取對應的映射文件卷的關(guān)系。此時還需要回頭從文件系統(tǒng)著手,用循環(huán)的方法,檢查系統(tǒng)中已經(jīng)支持的文件卷多對應的設(shè)備,通過比對的方式與連接關(guān)系做對應。特別是對于一個連接口映射為多個文件卷的情形,可能有一部分是支持在文件系統(tǒng)中,而另一部分不一定顯示(如未分配驅(qū)動器符號或作為一個現(xiàn)有文件卷的連接等),則比較難于顯示了。

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表