USB 用CreateFile()打开usb设备时,如何填写devicepath这个值?

springsun_xu 2018-09-20 11:53:53
问题由来:
https://bbs.csdn.net/topics/390907217?page=1#post-403471959
这位兄弟在很多年前使用USB时有个问题:用CreateFile()打开usb设备时,如何填写devicepath这个值?
他的描述为:
想通过ReadFile()和WriteFile()这两个接口来访问usb设备,看文档说在调用这两个接口前需要先调用CreateFile()来获取handle,而调用CreateFile()需要指定portname+端点索引号,问题是,这个portname是如何获得的?查询msdn发现需要使用IStiDeviceControl::GetMyDevicePortName()来获取,头文件为:Stiusd.h 。这个接口是在应用层调用的吗?
我看了很多回复,都没有说到关键点上去,尤其是那些不负责任的人胡乱贴一些代码根本就运行不了。垃圾!

此前本人并没有涉及WINDOW下的USB编程,USB是老玩意了吧!但为啥没有成熟的回复呢? 为了解决这个问题,本人做了一些研究,最终解决了问题,由于在那个帖子中回复只能回复5次,所以我这里集中把解决问题的经历写在这里:

先正面回答问题:CreateFile函数用到的devicepath就是通过设备GUID获取的devicepath,这个设备GUID是具体到如果有子设备的话是子设备的设备GUID,当获取到具有子设备GUID的devicepath时就可以直接使用,无需再找什么portname+端点索引号,或许根据具体设备的GUID获取设备的devicepath就包含所谓的“portname+端点索引号"了吧(这个我没弄清楚),以下是我的心路历程,认真看完应该可以解决问题。

为了便于问题解决,强烈建议下载 工具软件 UsbTreeView 和 BusHound

4年过去了,楼主及其他人有解决方案么?
我的计算机上有个U盘,盘符是H, 利用 UsbTreeView 知道该U盘 VID= 0x090c, pid= 0x1000,

利用 GUID_DEVINTERFACE_USB_DEVICE 这个GUID 结合 VID= 0x090c, pid= 0x1000
以及以下几个主要函数 SetupDiGetClassDevs,SetupDiEnumDeviceInterfaces,SetupDiGetDeviceInterfaceDetail 获取 设备路径DevicePath为 "\\\\?\\usb#vid_090c&pid_1000#5&8b518d6&0&3#{a5dcbf10-6530-11d2-901f-00c04fb951ed}"; (注意,这个字符串中某些数字会变动,可能跟插的不同USB口有关),
利用这个DevicePath 执行 CreateFile函数并配置相应的参数能够获取句柄,但是获取的句柄与使用 strDeviceName = "\\\\.\\H:"; 这个字符串(盘符名)获取的句柄值是不一样的,后续利用DeviceIoControl来读写设备结果也是不同的,用前一种方法获得的句柄读写失败,后一种直接利用盘符获取的句柄执行DeviceIoControl就可以成功读取数据。 不知道什么原因!!!!!!

另外,当使用 GUID_DEVINTERFACE_USB_DEVICE 这个GUID 时 , HidD_GetAttributes 函数不能使用,我这里测试这个函数只能用于HID设备。

我的问题是一个普通非U盘设备如何获取类似"\\\\.\\H:"这样的“文件”名来提供给CreateFile的????

尊敬的楼主及所有关心该帖的同道们,虽然该帖4年过去了,但是仍有人关注和关心这个帖子,不能不让人不感动!

入正题,上一个回复中提到的Device Path我利用工具 UsbTreeView,查看发现有两处一处与我用函数获取的相同,另一个为:
\\?\usbstor#disk&ven_usb&prod_flash_disk&rev_1100#6&ef43437&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b},
这一次我用这个代入CreateFile函数获取句柄,虽然与用"\\\\.\\H:"获得的句柄值不同,但后续也能成功读取。
我惊讶发现这个DevicePath是 Child Device 1 的DevicePath !!!!

那么我现在初步回答楼主的问题(用CreateFile()打开usb设备时,如何填写devicepath这个值? ),通常利用我上一个回复里的方法可以获取devicepath,如果没有子设备,那么就直接用这个devicepath配合CreateFile获取句柄,如果有子设备,暂时我还没有办法自己获取其子设备的devicepath, 但利用工具UsbTreeView可以查到,(UsbTreeView这个工具可以在网上下载到),希望能够帮到你。

问题: 如何通过编程获取子设备的devicepath?

以下是利用UsbTreeView获取的U盘部分信息描述


+++++++++++++++++ Device Information ++++++++++++++++++
Device Description : USB 大容量存储设备
Device Path : \\?\usb#vid_090c&pid_1000#5&8b518d6&0&3#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
Device ID : USB\VID_090C&PID_1000\5&8B518D6&0&3
Hardware IDs : USB\VID_090C&PID_1000&REV_1100 USB\VID_090C&PID_1000
Driver KeyName : {36fc9e60-c465-11cf-8056-444553540000}\0070 (GUID_DEVCLASS_USB)
Driver : system32\DRIVERS\USBSTOR.SYS (Version: 6.1.7600.16385 Date: 2009-07-14)
Driver Inf : C:\Windows\inf\usbstor.inf
Legacy BusType : PNPBus
Class : USB
Class GUID : {36fc9e60-c465-11cf-8056-444553540000} (GUID_DEVCLASS_USB)
Interface GUID : {a5dcbf10-6530-11d2-901f-00c04fb951ed} (GUID_DEVINTERFACE_USB_DEVICE)
Service : USBSTOR
Enumerator : USB
Location Info : Port_#0003.Hub_#0001
Location IDs : PCIROOT(0)#PCI(1400)#USBROOT(0)#USB(3)
Container ID : {b577a458-b617-11e8-a8c8-28e3472d3289}
Manufacturer Info : 兼容 USB 存储设备
Capabilities : 0xC4 (Removable, RawDeviceOK, SurpriseRemovalOK)
Status : 0x0180600A (DN_DRIVER_LOADED, DN_STARTED, DN_DISABLEABLE, DN_REMOVABLE, DN_NT_ENUMERATOR, DN_NT_DRIVER)
Problem Code : 0
Address : 3
Power State : D0 (supported: D0, D3, wake from D0)
Child Device 1 : USB Flash Disk USB Device (磁盘驱动器) (Disk1)
DevicePath : \\?\usbstor#disk&ven_usb&prod_flash_disk&rev_1100#6&ef43437&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
Device ID : USBSTOR\DISK&VEN_USB&PROD_FLASH_DISK&REV_1100\6&EF43437&0
Class : DiskDrive
Volume : \\?\Volume{b577a45b-b617-11e8-a8c8-28e3472d3289}\
Kernel Name : \Device\HarddiskVolume7
Mountpoint : H:\

---------------------------
问题延伸,当我们获取Child Device 的DevicePath后把U盘插入另外一个USB口发现这个DevicePath是变得例如我这里两次不同USB口获取的值为:
strDeviceName = "\\\\?\\usbstor#disk&ven_usb&prod_flash_disk&rev_1100#6&ef43437&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}";
strDeviceName = "\\\\?\\usbstor#disk&ven_usb&prod_flash_disk&rev_1100#6&b867c1f&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}";

所以我们迫切需要编程自动获取该值。

如何编程获取Child Device 的DevicePath呢?????


问题进一步解决:
上回书说到利用UsbTreeView可以获取Child Device的DevicePath,但如果更换USB口这个DevicePath会改变,所以如果这样的程序交给客户用显然不行的,我们最终要摆脱UsbTreeView,要让程序自我自动查找到Child Device的DevicePath,那为什之前找到的总是父设备的DevicePath呢?
重新研究了一下 父设备与子设备的DevicePath猛然发现,父设备与子设备的GUID不同
父设备DevicePath = "\\\\?\\usb#vid_090c&pid_1000#5&8b518d6&0&3#{a5dcbf10-6530-11d2-901f-00c04fb951ed}"
//子设备DevicePath = "\\\\?\\usbstor#disk&ven_usb&prod_flash_disk&rev_1100#6&b867c1f&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}";
想到之前用一通函数SetupDiGetClassDevs,SetupDiEnumDeviceInterfaces,SetupDiGetDeviceInterfaceDetail 获取设备路径DevicePath时用的
GUID 不就是DevicePath后面“尾巴”么???灵光一闪,说时迟那时快,赶紧把程序头部的GUID换成子设备的GUID,尝试一下,
就是把 父设备 Interface GUID : {a5dcbf10-6530-11d2-901f-00c04fb951ed}
换成子设备 Interface GUID :{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
也就是在代码里把它们写成结构体形式为:
static GUID GUID_DEVINTERFACE_USB_DEVICE ={ 0xA5DCBF10L, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } };//父
变为
static GUID GUID_DEVINTERFACE_USB_DEVICE ={ 0x53f56307L, 0xb6bf, 0x11d0, {0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b } };//子

使用子设备的GUID重新查找!果不其然!!!找到了!!!!
不过还是出了点小问题:
程序找到了两个,我这里的情况列举如下:
\\?\scsi#disk&ven_hgst&prod_hts541010a9e6800#4&f50782b&0&040000#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
\\?\usbstor#disk&ven_usb&prod_flash_disk&rev_1100#6&b867c1f&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}

后一个就是我要的东西,前一个不知道是什么,不过我直接用“usb”字符串比对把前一个或略掉,留下后一个解决当前项目。

给所有朋友留一个问题:
前一个\\?\scsi#disk&ven_hgst&prod_hts541010a9e6800#4&f50782b&0&040000#{53f56307-b6bf-11d0-94f2-00a0c91efb8b} 是什么东西?干嘛用的呢?

...全文
3406 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
窝米逗佛~ 2019-06-04
  • 打赏
  • 举报
回复 1
?这个很难?

DEFINE_GUID( GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, \
	0xC0, 0x4F, 0xB9, 0x51, 0xED ); // USB specific GUIDs
DEFINE_GUID(GUID_DEVINTERFACE_DISK,                   0x53f56307L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); // ioctlguid

Wenpupil 2019-03-31
  • 打赏
  • 举报
回复
感谢大佬 ,这几天查了一堆资料,都看不太懂 ,看到这篇突然茅舍顿开
赵4老师 2018-09-20
  • 打赏
  • 举报
回复
百度搜“devcon”

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧