ARTICLE DETAIL

资讯详情

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

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

Windows 驱动实例分析系列:libwdi 驱动分析 - libwdi 篇(七) 子文档七日志模块logging.c与 VID 数据库vid_data.c日志模块logging.clogging.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.cvid_data.c是一个自动生成的文件它包含了一个从http://www.linux-usb.org/usb.ids转换而来的 VID 到厂商名称的映射表。该表在 libwdi 构建时通过脚本更新因此库中的厂商名称数据与官方 USB ID 仓库保持同步。数据结构定义了一个静态结构体数组usb_vendor[]每个元素包含vid16 位和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也能为开发类似系统级工具提供宝贵的参考。
返回列表