ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

windows 驱动实例分析系列: libusb驱动分析-test篇

windows 驱动实例分析系列: libusb驱动分析-test篇 tests 目录代码解读文档 —— testlibusb 与 testlibusb_win1. 概述tests 目录包含两个测试程序testlibusb.c控制台版本和 testlibusb_win.cWindows GUI 版本。它们的主要功能是枚举系统中所有 USB 设备并输出详细的设备信息包括设备描述符、配置描述符、接口描述符、端点描述符以及字符串描述符制造商、产品、序列号。这两个程序是 libusb-win32 库的标准验证工具用于检查驱动是否正确安装、设备是否可访问以及描述符解析是否正常。2. testlibusb.c —— 控制台版本2.1 代码结构该程序是经典的 C 命令行工具流程清晰- 解析命令行参数支持 -v 启用详细模式。- 调用 usb_init()、usb_find_busses()、usb_find_devices() 初始化库并扫描设备。- 遍历所有总线上的设备对每个设备调用 print_device 输出信息。- print_device 函数尝试打开设备获取字符串描述符然后根据 verbose 标志决定是否输出详细的描述符层级。2.2 功能特性- 基础模式仅显示设备编号、VID/PID以及如果打开成功制造商和产品名称。- 详细模式-v额外输出完整的设备描述符、所有配置描述符、接口描述符及其端点信息并以缩进层级呈现。- 对于根集线器设备root_dev除非详细模式否则递归打印其子设备。2.3 实现技术- 使用 usb_get_string_simple 获取字符串描述符该函数自动处理语言 ID 和 Unicode 转换。- 描述符打印函数print_device_descriptor、print_configuration 等直接访问结构体成员并按照 USB 规范格式化输出十六进制和十进制。- 对每个设备先尝试 usb_open若成功则读取字符串然后立即 usb_close避免占用句柄。- 所有打印使用标准 printf适合重定向到文件或管道。2.4 典型用途- 验证驱动是否识别设备。- 检查设备描述符是否正确如 VID/PID、类别码。- 调试 USB 协议栈查看端点配置。- 作为库 API 调用的示例初始化、扫描、打开、关闭、获取描述符。3. testlibusb_win.c —— Windows GUI 版本3.1 代码结构这是一个标准的 Win32 GUI 应用程序入口为 WinMain主要组件- 一个主窗口带编辑框和两个按钮Exit 和 Refresh。- 编辑框用于显示设备信息使用等宽字体 Courier。- 消息循环处理窗口大小变化、按钮点击、设备插拔通知WM_DEVICECHANGE。- 核心刷新函数 on_refresh 执行设备扫描并填充编辑框。3.2 功能特性- 显示 DLL 和驱动版本号通过 usb_get_version。- 以表格形式列出每个设备的 bus/device 名称、VID/PID。- 对于每个设备尝试打开并获取制造商、产品、序列号字符串若失败则提示。- 始终输出完整的设备描述符与 testlibusb 的 -v 模式类似以及所有配置、接口、端点描述符。- 支持动态刷新点击 Refresh 按钮或设备插入/拔出时自动重新枚举并更新显示。3.3 实现技术- 使用 Windows 编辑框控件作为输出终端通过 EM_REPLACESEL 追加文本并自动滚动到底部。- 动态内存管理使用 edit_buffer 存储所有输出文本一次性设置到编辑框提高性能。- 注册设备通知RegisterDeviceNotification以监听 USB 设备接口的到达和移除事件GUID_DEVINTERFACE_USB_HUB 和 GUID_DEVINTERFACE_USB_DEVICE。- 消息处理中响应 WM_SIZE 调整控件布局响应 WM_DEVICECHANGE 触发刷新。- 调用 usb_set_debug(4) 启用库的调试日志但输出到调试器而非界面。3.4 交互优势- 实时反映设备状态变化无需手动重新运行程序。- 可视化布局便于观察大量设备信息。- 适合开发者在调试过程中持续监控设备枚举情况。4. 两者对比- 运行环境testlibusb 在控制台运行适合脚本或远程执行testlibusb_win 需要图形界面适合桌面交互。- 功能完整性GUI 版本始终显示详细描述符而控制台版本通过 -v 开关控制。- 动态性GUI 版本支持热插拔通知控制台版本一次运行后退出。- 输出格式控制台使用普通文本GUI 使用富文本编辑框但仅纯文本并采用 \r\n 换行。5. 关键技术点解析5.1 设备枚举流程两个程序都遵循相同步骤1. usb_init() —— 初始化库内部状态。2. usb_find_busses() —— 扫描系统总线在 Windows 下实际是创建虚拟总线。3. usb_find_devices() —— 扫描所有设备填充 usb_device 结构链表。4. usb_get_busses() —— 获取总线链表头遍历每个总线及其 devices 链表。5.2 描述符解析与打印- libusb-win32 在 usb_find_devices 时已自动获取并解析了设备描述符和配置描述符通过 usb_fetch_and_parse_descriptors因此可直接访问 dev-descriptor 和 dev-config 数组。- 打印函数按照 USB 规范定义的结构体成员逐项输出包括 bLength、bDescriptorType、bcdUSB、idVendor、idProduct 等。- 对于端点还输出 bEndpointAddress、bmAttributes、wMaxPacketSize 等。5.3 字符串获取- 使用 usb_get_string_simple 简化操作该函数内部调用 usb_get_string 并处理 Unicode 到 ASCII 的转换非 ASCII 字符替换为 ?。- 若字符串索引为 0 或获取失败则显示 VID/PID 替代。5.4 Windows GUI 特有的技术- 使用 DEFINE_GUID 定义设备接口 GUID用于注册设备通知。- RegisterDeviceNotification 与窗口句柄关联当设备事件发生时窗口过程收到 WM_DEVICECHANGE 消息。- 编辑框设置为只读、多行、自动垂直滚动通过 SendMessage(EM_SETSEL) 和 EM_REPLACESEL 追加文本。- 动态分配输出缓冲区使用 vsnprintf 格式化避免频繁的窗口刷新。6. 编译与使用- 两个程序均需链接 libusb0.lib或动态加载 libusb0.dll并包含 lusb0_usb.h。- 控制台版本可直接在命令行编译gcc -o testlibusb testlibusb.c -lusb。- GUI 版本需链接 user32、gdi32、comctl32 等 Windows 库并使用 -mwindows 选项MinGW或相应项目设置VS。- 运行时需要 libusb0.sys 驱动已安装且设备已绑定该驱动或过滤驱动。7. 错误处理与健壮性- 程序对 usb_open 失败有处理不会崩溃而是显示 VID/PID 组合。- 描述符获取失败时dev-config 为 NULL打印提示信息并跳过详细输出。- GUI 版本在设备移除时自动刷新避免显示过时信息。8. 总结tests 目录下的两个程序是 libusb-win32 库最直接的功能验证工具。它们不仅展示了库的基本使用模式还提供了完善的描述符解析和可视化输出是开发人员调试 USB 设备不可或缺的助手。控制台版本适合自动化测试和日志记录GUI 版本适合交互式开发和实时监控。两者共同覆盖了常见的使用场景代码简洁清晰是学习 libusb-win32 编程的良好起点。
返回列表