news 2026/10/6 12:29:55

Windows 驱动实例分析系列:libwdi 驱动分析 - libwdi 篇(七)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Windows 驱动实例分析系列:libwdi 驱动分析 - libwdi 篇(七)

子文档七:日志模块(logging.c)与 VID 数据库(vid_data.c)

日志模块(logging.c)

logging.c实现了 libwdi 的日志系统,它通过命名管道将日志消息从库内部传输到注册的窗口(或控制台)。

设计目标
  • 非侵入式:库内部调用wdi_dbg、wdi_info等宏即可记录日志,无需关心输出目标。
  • 异步通知:若窗口注册了日志消息,日志模块通过PostMessage异步通知窗口,避免阻塞。
  • 缓冲管理:日志管道大小为 8KB,当消息累积过多时,write_to_pipe会主动调用SendMessage强制刷新,防止管道溢出。
核心数据结构
  • logger_rd_handle和logger_wr_handle:日志管道的读端和写端句柄。
  • logger_dest和logger_msg:注册的窗口句柄和消息 ID。
  • log_messages_pending:待处理消息计数。
  • log_messages_pipe_size:管道中当前数据量。
关键函数
  • wdi_register_logger:创建一个命名管道\\.\pipe\libwdi-logger,并记录窗口句柄和消息 ID。
  • wdi_unregister_logger:关闭管道,清除注册信息。
  • wdi_read_logger:窗口在收到消息后调用此函数,从管道读取一条日志消息。
  • wdi_log:内部日志输出函数,根据是否注册窗口决定输出到管道还是控制台(console_wdi_log_v)。
  • wdi_set_log_level:设置全局日志级别,控制哪些级别的日志被输出。
管道同步

日志管道采用同步读写模式,但wdi_read_logger由窗口消息驱动,不会阻塞 UI。

使用示例

在 Zadig 中,主窗口通过wdi_register_logger(hMainDialog, UM_LOGGER_EVENT, 0)注册,当 libwdi 内部产生日志时,会向主窗口发送UM_LOGGER_EVENT消息,主窗口在消息处理中调用wdi_read_logger读取日志并显示到编辑框中。

VID 数据库(vid_data.c)

vid_data.c是一个自动生成的文件,它包含了一个从http://www.linux-usb.org/usb.ids转换而来的 VID 到厂商名称的映射表。该表在 libwdi 构建时通过脚本更新,因此库中的厂商名称数据与官方 USB ID 仓库保持同步。

数据结构

定义了一个静态结构体数组usb_vendor[],每个元素包含vid(16 位)和name(字符串指针)。数组按 VID 升序排列,便于二分查找(但代码中采用线性查找,因为数组大小约 2500 项,线性查找性能足够)。

查询函数

wdi_get_vendor_name接受 VID,返回对应的厂商名字符串,若未找到则返回 NULL。

用途

在 Zadig 中,当用户选择设备时,会调用此函数查询 VID 对应的厂商名称,并显示在工具提示中,帮助用户识别设备制造商。若 VID 未知,Zadig 会显示“提交厂商”按钮,引导用户向 USB ID 仓库提交新 VID。

数据来源

该文件在 libwdi 发布前通过make或脚本自动从网络下载usb.ids并转换生成,因此库的发布时间与 USB ID 仓库的版本对应。

其他辅助模块

  • msapi_utf8.h:提供所有 Windows API 的 UTF-8 版本封装,使核心代码无需显式转换字符串编码。例如,CreateFileU内部调用CreateFileW,并处理 UTF-8 到 UTF-16 的转换。这是 libwdi 保持编码一致性的关键。
  • stdfn.h:定义了safe_strcpy、safe_strcat、safe_sprintf等安全字符串操作函数,以及注册表读写辅助函数(ReadRegistryStr等),这些函数在整个库中被广泛使用。
  • resource.h:仅定义了进度条对话框的控件 ID,用于libwdi_dlg.c。

结语

libwdi 的核心库设计精巧,各模块职责明确,通过资源嵌入、令牌替换、自签名证书、进程隔离等多项技术,实现了跨平台的 USB 驱动自动化安装。其源码是学习 Windows 系统编程、驱动安装、PKI 操作和跨进程通信的优秀教材。深入理解这些模块的实现,不仅有助于正确使用 libwdi,也能为开发类似系统级工具提供宝贵的参考。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/6 12:29:29

4 步点亮画面与键鼠操控:QtScrcpy 投屏从连接到调优的实操路线

4 步点亮画面与键鼠操控:QtScrcpy 投屏从连接到调优的实操路线 【免费下载链接】QtScrcpy Android real-time display control software 项目地址: https://gitcode.com/GitHub_Trending/qt/QtScrcpy QtScrcpy 是跨平台的 Android 投屏工具:手机一…

作者头像 李华
网站建设 2026/10/6 12:12:58

SukiUI 主题系统实战:SukiTheme 单例的获取与运行时主题管理

UI组件桌面应用 【免费下载链接】SukiUI UI Theme for AvaloniaUI 项目地址: https://gitcode.com/gh_mirrors/su/SukiUI 点击查看 免费下载 SukiUI 是面向 AvaloniaUI 的界面主题库,其所有主题能力都收敛在 SukiTheme 这一个类上:明暗切换、…

作者头像 李华
网站建设 2026/10/6 12:07:03

手搓 main 函数+寄存器版控制GPIO输出

手搓 main 函数 第一步 加入头文件 #include <stm32f10x.h> 第二步 编写main 函数 第三步 while&#xff08;1&#xff09; 死循环 完整版本如何点亮一盏灯 1. 开启时钟 查找stm32中文手册56页系统时钟树2. 配置GPIO参数3. 输出高低电平2024.9.12更新 寄存器配置GPIOD输出…

作者头像 李华
网站建设 2026/10/6 12:05:55

数据结构排序算法精讲:插入、冒泡、选择排序与稳定性分析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华