本主题提供了一个示例,以说明如何使用 USB ETW 和 Netmon 对 Windows 无法识别 USB 设备进行故障排除。

对于此示例,我们插入了一个设备,该设备在设备管理器和其他用户界面 (UI) 部分中显示为未知设备。硬件 ID 为 USB\UNKNOWN。为了做进一步诊断,我们拔下了设备,开始 ETW 跟踪,并再次插入了设备。当设备显示为未知设备后,我们停止跟踪。

  • 关于未知设备问题
  • 启动事件跟踪分析
  • USB 设备摘要事件
  • 事件描述和数据负载
  • USB Netmon 筛选器
  • 了解错误事件和状态代码
  • 从问题事件向后读取
  • 相关主题

关于未知设备问题

为了调试未知 USB 设备问题,当用户将设备插入系统时,这有助于理解 USB 驱动程序堆栈枚举设备所执行的操作。有关 USB 枚举的信息,请参阅标题为 USB 堆栈如何枚举设备?的博客文章。

通常,如果 USB 驱动程序堆栈枚举设备失败,集线器驱动程序仍然会向 Windows 报告已插入设备,但是在设备管理器中会将设备标记为未知设备。设备的设备 ID 为 USB\VID_0000&PID_0000,硬件 ID 和兼容 ID 为 USB\UNKNOWN。以下事件会导致 USB 集线器驱动程序将 USB 设备枚举为未知设备:

  • 枚举过程中端口重置请求超时。
  • USB 设备的设置地址请求失败。
  • 对 USB 设备的设备描述符请求失败。
  • USB 设备描述符已损坏且验证失败。
  • 对配置描述符的请求失败。
  • USB 配置描述符已损坏且验证失败。

在 Windows 7 中,枚举失败的未知设备在设备管理器中标有故障代码 43。

如果设备在设备管理器中标有故障代码 28,则设备会枚举成功,但是仍然是未知设备。此故障代码表示设备在枚举过程中未提供产品产品 ID 字符串,Windows 无法找到设备的匹配 INF 来安装驱动程序。

启动事件跟踪分析

由于这是因设备故障而造成的,我们建议你将 Netmon 与 USB 分析器结合使用来分析日志文件。

查看事件跟踪日志

  1. 运行 Netmon,依次单击“文件”->“打开”->“捕获”,然后选择文件。
  2. 在“帧摘要”窗格中选择第一个事件,其中具有有关 SystemTrace 的说明。 此图像将显示在选择第一个事件后屏幕所呈现的外观。

  3. 若要自定义 Netmon 显示的列,请右键单击列名称并选择“选择列”。
  4. 第一个事件(标识为类型 SystemTrace)包含有关日志的常规信息。你可以通过在“帧详细信息”窗格中展开信息树,来查看诸如已丢失事件的数目和跟踪的开始时间等信息。

USB 设备摘要事件

事件 2 是日志中的第一个 USB 事件。此事件以及数个后续事件描述启动跟踪时连接到系统的 USB 主机控制器、集线器和设备。我们可将这一组事件称为设备摘要事件(或摘要事件)。如同第一个事件一样,摘要事件不描述驱动程序活动。摘要事件记录日志会话开始时的设备状态。其他事件表示总线上发生的活动、与客户端驱动程序或系统的交互,或是内部状态的变化。

USB 集线器和 USB 端口驱动程序都会记录摘要事件。记录事件的驱动程序在协议名称列中标识。例如,USB 端口驱动程序记录的事件具有 USBPort_MicrosoftWindowsUSBPORT 协议名称。USB 事件跟踪通常包含一系列端口摘要事件,后跟一系列集线器摘要事件。许多 USB 端口和 USB 集线器摘要事件的描述中具有“信息”或“属性等字词。

如何识别摘要事件的末尾?如果日志开头的 USB 集线器事件中时间戳模式包含一个明显的空白,该空白可能就是设备摘要的末尾。否则,任何 USB 集线器事件后的第一个 USB 端口事件可能是第一个非摘要事件。下一页上的图 3 显示此示例跟踪中的第一个非摘要事件。

在本例中,开始跟踪时,感兴趣的设备未连接到系统,因此,你可以暂时跳过设备摘要事件。

事件描述和数据负载

在示例日志中,设备摘要事件后的第一个事件是“USB 集线器等待唤醒 IRP 已完成”事件。我们已插入设备,且主机控制器或集线器被唤醒而进行响应。若要确定唤醒了哪一个组件,请查看事件的数据。该数据位于“帧详细信息”窗格中,大致采用以下形式在树结构中显示:

Frame information
ETW event header informationETW event descriptor (Constant information about the event ID suchas error level)
Event payload (Data logged at the time of the event)Name of a USB-specific structureStructure members and their values (Types: numbers, strings,or arrays)...

展开“USB 集线器等待唤醒 IRP 已完成”事件的负载数据,则会看到名为 fid_USBHUB_Hub 的 ETW 结构。该结构的名称包含下述部分:

术语 描述

fid_

USB ETW 结构的典型前缀。

USBHUB_

USB 集线器驱动程序记录事件的指示。

The rest of the string

结构的数据所描述对象的名称。对于此事件,即为集线器对象。

USB 集线器驱动程序使用 fid_USBHUB_Hub 结构来描述 USB 集线器。数据负载中具有此集线器结构的事件是指集线器,我们可使用该结构的内容来识别特定的集线器。图 4 显示“帧详细信息”窗格,其中展开了 fid_USBHUB_Hub 结构以显示其字段。

集线器结构与通常显示在 USB ETW 事件中的两个其他结构十分类似:fid_USBHUB_Device 和 fid_USBPORT_Device。以下重要字段在所有三种结构中都很常见:

fid_idVendor

设备的 USB 供应商 ID (VID)。

fid_idProduct

设备的 USB 产品 ID (PID)。

fid_PortPath

基于连接 USB 设备所通过的集线器端口号的列表。列表中端口号的数量包含在 PortPathDepth 字段中。对于根集线器设备,此列表全为零。对于直接连接到根集线器端口的 USB 设备,PortPath[0] 中的值是连接设备的端口的根集线器端口号。对于通过一个或多个附加 USB 集线器连接的 USB 设备,集线器端口号的列表以根集线器端口开头,然后是附加集线器(按照距根集线器的距离排序)。忽略零。 例如:

示例值 描述
[0, 0, 0, 0, 0, 0] 该事件是指根集线器(PC 上的端口,由 USB 主机控制器直接控制)。
[3, 0, 0, 0, 0, 0] 该事件是指插入根集线器端口号 3 中的集线器或设备。
[3, 1, 0, 0, 0, 0] 插入根集线器端口 3 中的集线器。该事件是指插入外部集线器端口 1 中的集线器或设备。

你应该监视感兴趣的任何设备的端口路径。枚举设备时,VID 和 PID 均未知,且记录为 0。VID 和 PID 在某些低级设备请求(如重置和暂停)中不会出现。这些请求将发送到插入设备的集线器。

在我们的示例日志中,等待唤醒完成事件的端口路径包括六个零。该事件表示根集线器上的等待唤醒操作。对于我们的操作,这是合乎逻辑的:我们将设备插入根集线器端口,因此,根集线器会唤醒。

USB Netmon 筛选器

如果有时间,你可以按照时间顺序检查日志中的每一个事件。即使经验丰富,也难以通过扫描事件描述列表快速识别重要事件。若要更快速地找出未知设备的原因,你可以使用 Netmon 筛选器功能。

USB 错误筛选器

若要在 Netmon 中激活 USB 错误筛选器,请依次单击“筛选器”->“显示筛选器”->“加载筛选器”->“标准筛选器”->“USB”->“USB 集线器错误”,然后单击“显示筛选器”窗格中的“应用”。

USB 错误筛选器会将事件列表的范围缩小到仅符合下表中所显示条件的事件。

筛选器文本 描述
(USBPort_MicrosoftWindowsUSBUSBPORT AND NetEvent.Header.Descriptor.Opcode == 34) 操作代码为 34 的 USB 端口事件是端口错误。
(USBHub_MicrosoftWindowsUSBUSBHUB AND NetEvent.Header.Descriptor.Opcode == 11) 操作代码为 11 的 USB 集线器事件是集线器错误。
(NetEvent.Header.Descriptor.Level == 0x2) 级别为 0x2 的事件是常见错误。
(USBHub_MicrosoftWindowsUSBUSBHUB AND NetEvent.Header.Descriptor.Id == 210) ID 为 210 的 USB 集线器事件是“记录的 USB 集线器异常”事件。有关详细信息,请参阅了解错误事件和状态代码。

下图显示将 USB 错误筛选器应用到示例跟踪日志后,在“帧摘要”窗格中显示较少的一组事件。

若要查看错误顺序的概述,可简要查看每个错误事件。要观察的重要字段包括 fid_NtStatusfid_UsbdStatus 和 fid_DebugText。有关详细信息,请参阅了解错误事件和状态代码。 若要关闭筛选器,请单击“显示筛选器”窗格中的“删除”按钮。

自定义 Netmon 筛选器

你可以在 Netmon 中创建自定义筛选器。最简单的方法是采用下述方法之一从屏幕上的数据创建筛选器:

  • 右键单击“帧详细信息”窗格中的字段并选择“将所选值添加到显示筛选器”。
  • 右键单击“帧摘要”窗格中的字段并选择“将 [字段名称] 添加到显示筛选器”。

你可以更改运算符(如 OR、AND 和 ==)和筛选器值,以便构建相应的筛选器表达式。

了解错误事件和状态代码

在我们的未知设备示例中,大多数 USB 集线器异常具有 CreateDeviceFailure 的 fid_DebugText 数据。异常的严重性并不清楚,但是调试文本可提供原因方面的提示:与新设备相关的操作失败。目前,假定邻近创建设备失败事件是冗余的。最后两个异常是 CreateDeviceFailure_Popup 和 GenErr_UserIoctlFailed。弹出异常的声音就像告诉用户产生了错误,但是任何及所有此类错误都与未知设备问题相关。

USB 错误事件以及其他事件的数据中都有状态值,用于提供关于问题的有用信息。你可以使用下表中的资源查找关于状态值的信息。

状态类型 资源
fid_NtStatus 参阅 NTSTATUS 值。
USB 请求块 (URB) 的状态字段或 fid_UsbdStatus 在 Windows 驱动程序工具包 (WDK) 中查找作为 inc\api\usb.h 中的 USBD_STATUS 的值。 你还可以使用 USBD_STATUS。本主题列出了符号名称和 USBD_STATUS 值的含义。

从问题事件向后读取

对于错误的原因,发生错误事件之前记录的事件可能提供重要的线索。你应该查看发生错误之前记录的事件,尝试确定未知设备的根本原因。在本示例中,从 CreateDeviceFailure_Popup 事件(倒数第二个异常)开始向后查看。当 USB 错误筛选器启用时选择此事件,然后单击“显示筛选器”窗格中的“删除”。USB 错误筛选器仍然显示在“显示筛选器”窗格中,你随后可以重新应用它。但是现在筛选器处于禁用状态,且“帧摘要”窗格显示所有事件,如下图所示。

恰好在 CreateDeviceFailure_Popup 事件之前记录的两个事件是“调度”和“完成 USB 控制传输”。两个事件的 fid_USBPORT_Device端口路径字段均为零,这表示传输的目标是根集线器。在完成事件的 fid_USBPORT_URB_CONTROL_TRANSFER 结构中,状态是零 (USBD_STATUS_SUCCESS),这表示传输已成功。继续检查前面的事件

前面接下来的两个事件是第四个(最终)“创建设备失败”事件和第四个(最终)CreateDeviceFailure 异常,即之前检查的事件。

前面接下来的一个事件是“端点关闭”事件。此事件表示端点不再可用。该事件数据描述该设备上的设备和端点。设备端口路径是 [1, 0, 0, 0, 0, 0]。我们运行跟踪的系统只有主机控制器(根集线器)和连接的设备,因此,该端口路径不描述集线器。关闭的端点必须位于插入的单个设备上,现在即可知道该设备的路径是 1。驱动程序使设备的端点不可访问的原因很可能是先前遇到的问题所导致的。继续检查前面的事件

前面接下来的事件是已完成 USB 控制传输。该事件数据显示传输的目标是该设备(端口路径是 1)。fid_USBPORT_Endpoint_Descriptor 结构表示端点的地址为 0,因此,这是 USB 定义的默认控制端点。URB 状态是 0xC0000004。由于该状态不是零,因此,传输可能未成功。有关此 USBD_STATUS 值的更多详细信息,请参阅 usb.h 和了解错误事件和状态代码。

#define USBD_STATUS_STALL_PID ((USBD_STATUS)0xC0000004L)

含义:设备返回停止数据包标识符。 端点停止了哪个请求?为事件记录的其他数据表示请求是标准的设备控制请求。下面是解析的请求:

  Frame: Number = 184, Captured Frame Length = 252, MediaType = NetEvent
+ NetEvent:
- MicrosoftWindowsUSBUSBPORT: Complete Internal URB_FUNCTION_CONTROL_TRANSFER - USBPORT_ETW_EVENT_COMPLETE_INTERNAL_URB_FUNCTION_CONTROL_TRANSFER: Complete Internal URB_FUNCTION_CONTROL_TRANSFER + fid_USBPORT_HC: + fid_USBPORT_Device: + fid_USBPORT_Endpoint: + fid_USBPORT_Endpoint_Descriptor: + fid_URB_Ptr: 0x84539008 - ControlTransfer: + Urb: Status = 0xc0000004, Flags 0x3, Length = 0 - SetupPacket: GET_DESCRIPTOR + bmRequestType: (Standard request) 0x80 bRequest: (6) GET_DESCRIPTOR Value_DescriptorIndex: 0 (0x0) Value_DescriptorType: (1) DEVICE _wIndex: 0 (0x0) wLength: 64 (0x40)

将 bRequest (GET_DESCRIPTOR) 与 Value_DescriptorType (DEVICE) 合并,你可以确定请求是获取设备描述符。

为了让 USB 枚举继续,设备本应已使用设备描述符响应此请求。但是,设备停止了请求,从而导致枚举失败。因此,设备描述符的停止请求导致了全部四个创建设备故障。你已确定设备未知的原因是枚举失败,而枚举失败的原因是设备未完成其设备描述符的请求。

相关主题

使用 USB ETWWindows 的 USB 事件跟踪

案例研究:使用 ETW 和 Netmon 解决未知 USB 设备的问题相关推荐

  1. 案例研究 | 运用设计冲刺,解决俄罗斯家庭暴力问题

    问题 家庭暴力是一个困扰全球的问题,运用设计冲刺能帮我们解决它吗? 在俄罗斯,每5名妇女就有1名遭受到丈夫或伴侣的虐待,而这种情况在2017年国家将家庭虐待定为非刑事罪后更是急剧恶化. 于是,俄罗斯的 ...

  2. 未知USB设备(设备描述符请求失败)终于解决。网上查到的所有方法我都试过了,全部失败。我的成功方法就是调整“电源选项”

    我试过了网上所说的所有方法,卸载usb设备再扫描.bios.开启服务.除静电重启.更新驱动--没有一个成功. 今天无意中解决了问题,一句话就说清楚:调一下电池的"电源选项"--设置 ...

  3. 设备管理器出现“未知USB设备”同时蓝牙不可用的解决方法

      很莫名其妙地,刚才还在使用蓝牙鼠标和蓝牙键盘,离开一会儿后重新解锁进入桌面,蓝牙就彻底不见了.打开设备管理器,里面的蓝牙图标不见了,同时通用串行总线控制器中出现了一个未知USB设备.   查阅后找 ...

  4. 未知USB设备(设备描述符请求失败)解决方法之一

    前言 网上很多帖子讲述了出现未知USB设备的处理情况.这里给大家提供一种其他的可能性,这是大部分帖子里都没讲到的. 解决方案 将线插到电脑上其他USB口上,先排除是不是电脑USB口的问题(如果电脑是台 ...

  5. 未知USB设备(设备描述符请求失败)

    出现该问题时先确定以下问题: 1.当前环境是否有产生静电的可能? 2.出现该问题的设备是什么类型的设备(鼠标.U盘.无线网卡等)? 3.是否是驱动问题(可以使用驱动检测软件检测下)? 解决方法一: 注 ...

  6. 未知USB设备(设备描述符请求失败)是什么?

    未知USB 设备(设备描述符请求失败)是什么? 参考解决方案:Win10一个USB设备描述符请求失败解决方法 恕我直言,对我们没有什么用,我们需要的是不用插拔usb也能让错误消失

  7. STM32F103调试笔记(1)——microusb接入电脑后显示未知USB设备(代码43)

    这真的是一个很傻的错误- 由于我最近刚接触stm32,就在b站搜stm32的视频来看,现学现卖现烧程序.终于烧好了,想要用串口调试助手的时候却用不了,设备管理器显示未知USB设备(设备描述符请求失败) ...

  8. win10升级后蓝牙不见了,设备管理器里没有,多了个串行控制器里的未知USB设备?...

    win10更新后,蓝牙功能不见了,也没有打开的选项,设备管理器里也没有,多了个未知USB设备,重启无效,重装蓝牙驱动无效,BIOS中的Bluetooth是开的. 试了网上能找到的所有方法,包括更新wi ...

  9. 未知USB设备(设备描述符请求失败)伴随笔记本蓝牙消失

    本人使用的笔记本电脑已经两次遇到这种情况了,第一次遇到的时候是因为发现电脑开机之后蓝牙消失了.第二次也是一样的结果,当然第二次有经验了,很快就解决了. 首先呢,蓝牙消失的同时,设备管理器中会出黄色感叹 ...

最新文章

  1. 力特usb转232驱动程序下载_毕亚兹 USB转RJ45网线接口USB扩充口,特殊时期在家办公更轻松...
  2. CICC科普栏目|神经网络浅讲:从神经元到深度学习
  3. Qt Creator指定项目属性
  4. Spring新注解详解
  5. linux之readelf命令
  6. 如何修改emcp的sn号_百家号领域选择错误怎么办?百家号怎么更改领域?
  7. GIF动画解析RNN,LSTM,GRU
  8. 如何删除集合(数组)中指定的元素
  9. 物理、化学实验仪器与设备
  10. dbeaver 修改数据_GitHub 上 5 款超好用的数据库 GUI 带你玩转 MongoDB、Redis、SQL 数据库...
  11. photoshop插件开发
  12. at android.widget.Toast$TN.handleShow(Toast.java:501)自定义布局异常
  13. 基于随机森林实现特征选择降维及回归预测(Matlab代码实现)
  14. 【01】制作第一个zblog模板第一期,第一步首先我们创建我们的模板基础信息以及申请成为zblog开发者
  15. SQL server 数据库查询语句的基本实现
  16. Win7文件夹怎么加密
  17. 大小写字母c语言,C语言 大小写字母转换
  18. cc1101初始化c语言程序,STC89C52单片机驱动CC1101无线模块的接收C语言程序
  19. 360智能摄像机:超市防盗安全员
  20. OpenStack八大核心组件精讲之---swift

热门文章

  1. 大家保险发布“早下班一小时”倡议,呼吁“重阳节,不脱节”
  2. 第九周 作业管理系统成本估算
  3. PCIe数据卡设计资料第611篇:基于VU9P的双路5Gsps AD 双路6Gsps DA PCIe数据卡
  4. 防火墙阻止tftp_H3C防火墙常见问题汇总
  5. SyntaxError: Non-UTF-8 code starting with ‘\xe6‘ in file C:/Users/0moyi0/Desktop/DeepLearningExample
  6. Linux bridge hairpin mode
  7. 【小白米日志】树莓派3b+四位共阴数码管的连接和驱动
  8. Python爬虫实战 | 利用多线程爬取 LOL 高清壁纸
  9. 应用程序操作word文件报“RPC服务器不可用,HRESULT:0x800706BA”
  10. Leetcode 368. Largest Divisible Subset