一、所用接口总结
整个工程里,只用了如下几种与USB驱动相关的接口:
1、DeviceIoControl

HANDLE hHCDev = CreateFile("\\.\HCD0", , , , OPEN_EXISTING, 0, NULL);
DeviceIoControl(hHCDev, IOCTL_USB_GET_xxx,,,struct, sizeof(struct),);
CloseHandle(hHCDev);

它们定义在系统头文件<WinBase.h>中:
(c:\program files\microsoft sdks\windows\v7.0a\include)
(c:\winddk\7600.16385.1\inc\api)

2、CM_***

CM_Locate_DevNode(&devInst, NULL, 0)
CM_Get_Child(&devInstNext, devInst, 0)
CM_Get_Sibling(&devInstNext, devInst, 0)
CM_Get_Parent(&devInstNext, devInst, 0)
CM_Get_Device_ID(devInst, buf, len, 0);
CM_Get_DevNode_Registry_Property(devInst,CM_DRP_DRIVER, NULL, buf, &len, 0);
CM_Get_DevNode_Registry_Property(devInst, CM_DRP_DEVICEDESC, NULL, buf, &len, 0);

它们定义在系统头文件<CfgMgr32.h>中:
(c:\program files\microsoft sdks\windows\v7.0a\include)
(c:\winddk\7600.16385.1\inc\api)

3、SetupDi***

HDEVINFO hDevInfo = SetupDiGetClassDevs((LPGUID)&GUID_CLASS_USB_HOST_CONTROLLER,,,,);
SetupDiEnumDeviceInterfaces(hDevInfo,,,,&devIntfData);
SetupDiGetDeviceInterfaceDetail(hDevInfo, &devIntfData, devIntfDetailData,,);
SetupDiDestroyDeviceInfoList(hDevInfo);

它们定义在系统头文件<SetupAPI.h>中:
(c:\program files\microsoft sdks\windows\v7.0a\include)
(c:\winddk\7600.16385.1\inc\api)

二、基本过程分析

EnumerateHostControllers()//主入口,枚举系统所有USB Host Controller
for(i = 0; i < 10; i++){
HANDLE hHCDev = CreateFile("\\.\HCD0", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
EnumerateHostController(hHCDev)//枚举一个具体的USB Host Controller
USB_HCD_DRIVERKEY_NAME  drvKeyName = {0};
BOOL bRet = DeviceIoControl(hHCDev, IOCTL_GET_HCD_DRIVERKEY_NAME,,,drvKeyName, sizeof(drvKeyName),);
drvKeyNameA: "{36FC9E60-C465-11CF-8056-444553540000}\0000"
PTSTR deviceID/deviceDesc = DriverNameToDeviceDesc(drvKeyNameA, *);
DEVINST devInst = 0;
CONFIGRET cRet = CM_Locate_DevNode(&devInst, NULL, 0);
cRet = CM_Get_Child(&devInstNext, devInst, 0); devInst = devInstNext;
cRet = CM_Get_Sibling(&devInstNext, devInst, 0); devInst = devInstNext;
cRet = CM_Get_Parent(&devInstNext, devInst, 0); devInst = devInstNext;
cRet = CM_Get_DevNode_Registry_Property(devInst,CM_DRP_DRIVER, NULL, buf, &len, 0);
buf: "{4D36E966-E325-11CE-BFC1-08002BE10318}\0000"
cRet = CM_Get_Device_ID(devInst, buf, len, 0);
buf: "PCI\VEN_8086&DEV_3B3C&SUBSYS_04401028&REV_06\3&11583659&0&D0"
deviceID: buf
cRet = CM_Get_DevNode_Registry_Property(devInst, CM_DRP_DEVICEDESC, NULL, buf, &len, 0);
buf: "Intel(R) 5 Series/3400 Series Chipset Family USB Enhanced Host Controller - 3B3C"
deviceDesc: buf
USB_ROOT_HUB_NAME rootHubName;
BOOL bRet = DeviceIoControl(hHCDev, IOCTL_USB_GET_ROOT_HUB_NAME,,,rootHubName, sizeof(rootHubName),);
rootHubNameA: "USB#ROOT_HUB20#4&8985dfa&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}"
EnumerateHub(rootHubNameA)//获取一个具体的USB Hub的信息
HANDLE hHubDevice =CreateFile("\\.\USB#ROOT_HUB20#4&8985dfa&0#{f18a0e88-c30c-11d0-8815-00a0c906bed8}",...);
USB_HUB_CAPABILITIES_EX  hubCapsEx = {0};
BOOL bRet = DeviceIoControl(hHubDevice, IOCTL_USB_GET_HUB_CAPABILITIES_EX,,,hubCapsEx, sizeof(hubCapsEx),);
USB_HUB_CAPABILITIES  hubCaps = {0};
BOOL bRet = DeviceIoControl(hHubDevice, IOCTL_USB_GET_HUB_CAPABILITIES,,,hubCaps, sizeof(hubCaps),);
hubCaps.HubIs2xCapable: 1
USB_NODE_INFORMATION  hubInfo = {0};
BOOL bRet = DeviceIoControl(hHubDevice, IOCTL_USB_GET_NODE_INFORMATION,,,hubInfo, sizeof(hubInfo),);
hubInfo.u.HubInformation.HubDescriptor.bNumberOfPorts: 2
EnumerateHubPorts(hHubDevice, bNumberOfPorts)//枚举一个具体的USB Hub的所有端口
for(index = 1; index <= bNumberOfPorts; index++){
USB_NODE_CONNECTION_INFORMATION_EX connInfoEx; = {0};
BOOL bRet = DeviceIoControl(hHubDevice, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX,,,connInfoEx, sizeof(connInfoEx),);
USB_NODE_CONNECTION_INFORMATION connInfo; = {0};
BOOL bRet = DeviceIoControl(hHubDevice, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION,,,connInfo, sizeof(connInfo),);
connInfoEx.DeviceDescriptor
USB_NODE_CONNECTION_DRIVERKEY_NAME  drvKeyName = {0};
BOOL bRet = DeviceIoControl(hHubDevice, IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME,,,drvKeyName, sizeof(drvKeyName),);
drvKeyNameA: "{36FC9E60-C465-11CF-8056-444553540000}\0005"
PTSTR deviceDesc = DriverNameToDeviceDesc(drvKeyNameA, *);
deviceDesc: "Generic USB Hub"
USB_DESCRIPTOR_REQUEST  configDescReq = {0};
BOOL bRet = DeviceIoControl(hHubDevice, IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,,,configDescReq, nBytes,);
if(connInfoEx.DeviceIsHub)//如果是USB Hub,递归调用EnumerateHub()
USB_NODE_CONNECTION_NAME extHubName;
BOOL bRet = DeviceIoControl(hHubDevice, IOCTL_USB_GET_NODE_CONNECTION_NAME,,,extHubName, sizeof(extHubName
extHubNameA: "USB#Vid_8087&Pid_0020#5&2fd74a1d&0&1#{f18a0e88-c30c-11d0-8815-00a0c906bed8}"
EnumerateHub()//递归枚举一个具体的USB Hub
HubInformation.HubDescriptor.bNumberOfPorts: 6
EnumerateHubPorts()//递归枚举一个具体的USB Hub的所有端口
for(index = 1; index <= bNumberOfPorts; index++)
{
if(connInfoEx1.DeviceIsHub)//如果是USB Hub,递归调用EnumerateHub()
extHubNameA: "USB#Vid_0a5c&Pid_4500#6&2cd76888&0&1#{f18a0e88-c30c-11d0-8815-00a0c906bed8}
EnumerateHub()//获取一个具体的USB Hub的信息
HubInformation.HubDescriptor.bNumberOfPorts: 3
EnumerateHubPorts()//枚举一个具体的USB Hub的所有端口
for(index = 1; index <= bNumberOfPorts; index++)
{
//如果不是USB Hub,可能没连设备,或没配置
connInfoEx1.CurrentConfigurationValue: 0
connInfoEx2.CurrentConfigurationValue: 0
connInfoEx3.ConnectionStatus: NoDeviceConnected
}
connInfoEx2.ConnectionStatus: NoDeviceConnected
connInfoEx3.CurrentConfigurationValue: NoDeviceConnected
//如果有连设备,则获取设备的具体信息
connInfoEx4:
drvKeyNameA: "{53D29EF7-377C-4D14-864B-EB3A85769359}\0001"
deviceDesc: "Validity Sensor (VFS300)"
}

三、疑点难点问题
1、如何获取设备描述符?
各种描述符都是用DeviceIoControl()接口获取的。
USB_NODE_INFORMATION里包含有USB_HUB_DESCRIPTOR;
USB_NODE_CONNECTION_INFORMATION里包含有USB_DEVICE_DESCRIPTOR。

2、如何获取接口描述符和端点描述符?
答:接口描述符和端点描述符,是紧跟在配置描述符后面的。
具体实现是在GetConfigDescriptor()里完成的,都保存在configDescReq中。

3、如何获取字符串描述符中的字符串是否支持国际化?
答:是的,获取字符串描述符时,可以指定LangID;
而LangNum和LangIDs在所有字符串描述符的起始位置(index=0),可以首先获取到。
LangIDs参见:http://www.usb.org/developers/docs/USB_LANGIDs.pdf

usbview源码阅读与总结相关推荐

  1. 应用监控CAT之cat-client源码阅读(一)

    CAT 由大众点评开发的,基于 Java 的实时应用监控平台,包括实时应用监控,业务监控.对于及时发现线上问题非常有用.(不知道大家有没有在用) 应用自然是最初级的,用完之后,还想了解下其背后的原理, ...

  2. centos下将vim配置为强大的源码阅读器

    每日杂事缠身,让自己在不断得烦扰之后终于有了自己的清静时光来熟悉一下我的工具,每次熟悉源码都需要先在windows端改好,拖到linux端,再编译.出现问题,还得重新回到windows端,这个过程太耗 ...

  3. 源码阅读:AFNetworking(十六)——UIWebView+AFNetworking

    该文章阅读的AFNetworking的版本为3.2.0. 这个分类提供了对请求周期进行控制的方法,包括进度监控.成功和失败的回调. 1.接口文件 1.1.属性 /**网络会话管理者对象*/ @prop ...

  4. 源码阅读:SDWebImage(六)——SDWebImageCoderHelper

    该文章阅读的SDWebImage的版本为4.3.3. 这个类提供了四个方法,这四个方法可分为两类,一类是动图处理,一类是图像方向处理. 1.私有函数 先来看一下这个类里的两个函数 /**这个函数是计算 ...

  5. mybatis源码阅读

    说下mybatis执行一个sql语句的流程 执行语句,事务等SqlSession都交给了excutor,excutor又委托给statementHandler SimpleExecutor:每执行一次 ...

  6. 24 UsageEnvironment使用环境抽象基类——Live555源码阅读(三)UsageEnvironment

    24 UsageEnvironment使用环境抽象基类--Live555源码阅读(三)UsageEnvironment 24 UsageEnvironment使用环境抽象基类--Live555源码阅读 ...

  7. Transformers包tokenizer.encode()方法源码阅读笔记

    Transformers包tokenizer.encode()方法源码阅读笔记_天才小呵呵的博客-CSDN博客_tokenizer.encode

  8. 源码阅读笔记 BiLSTM+CRF做NER任务 流程图

    源码阅读笔记 BiLSTM+CRF做NER任务(二) 源码地址:https://github.com/ZhixiuYe/NER-pytorch 本篇正式进入源码的阅读,按照流程顺序,一一解剖. 一.流 ...

  9. 源码阅读:AFNetworking(八)——AFAutoPurgingImageCache

    该文章阅读的AFNetworking的版本为3.2.0. AFAutoPurgingImageCache该类是用来管理内存中图片的缓存. 1.接口文件 1.1.AFImageCache协议 这个协议定 ...

最新文章

  1. 计算机英语四六级对调剂有影响吗,英语四六级对考研有什么影响?不过会被歧视吗?...
  2. VTK:图表之LabelVerticesAndEdges
  3. C# 的 Console类
  4. linux 更改文件和目录权限
  5. c语言程序设计实践教程编程题8.3,C语言程序设计教程(21世纪计算机科学与技术实践型教程)...
  6. 中国连续纤维毡行业市场供需与战略研究报告
  7. 可视化修改SQL服务器名字,修改sql server服务器名称
  8. 启明星系统字体的演变
  9. weblogic10.3.6安装漏洞补丁
  10. 菲尼克斯馈电隔离器 - MINI MCR-SL-RPS-I-I
  11. Greenplum性能优化analyze
  12. springBoot接入阿里云oss
  13. 一步步教你搭建自己的云服务器,(鉴于网上一大堆文章,看这一篇就够了)
  14. 百度旋转验证码识别平台接口文档
  15. 群晖Synology DS918+使用笔记-基础篇
  16. 经典伴读_GOF设计模式_结构型模式
  17. RSA加密解密DES加密解密AES
  18. Wireshark lua插件
  19. 【ZCMU1930】帽子戏法(并查集)
  20. Docker快速部署Yearning

热门文章

  1. ION-DTN网络设计思想(一)
  2. eclipse jee mars linux,【创建maven-web项目-eclipse-jee-mars-2-win32-x86_64-jdk1.8】
  3. 公众号菜单 点击推送图片素材_微信公众平台常用图片素材分享(点击关注、阅读原文、分享朋友圈)...
  4. 哈佛大学最受欢迎的幸福课——幸福的方法
  5. HTML5前端开发实战06-幸福表单
  6. 算法设计与分析复习笔记(上)
  7. \begin{itemize} \item如何让每个item顶格
  8. Deformable ConvNets v2 原理与代码解析
  9. 进程调度-时间片轮转算法
  10. 数字式竞赛抢答器(基于Quartus的原理图设计)FPGA