Windows 驱动实例分析系列libwdi 驱动分析 - 实现篇一、总体实现概览libwdi 的实现遵循“分层解耦、资源内置、进程隔离”的总体策略。整个项目的源代码分布在libwdi/核心目录、examples/示例目录以及msvc/构建配置目录中共涉及约 40 个源文件。从实现视角看libwdi 可以划分为7 个逻辑组件模块每个组件承担明确的职责模块间通过定义良好的接口API 或 IPC进行协作。模块定位实现文件资源嵌入模块构建时工具embedder.c,embedder_files.h核心 API 模块运行时入口libwdi.c,libwdi.h,libwdi_i.h驱动准备模块INF/CAT 生成tokenizer.c,pki.c,mssign32.h安装执行模块提权安装器installer.c,installer.h日志诊断模块调试与反馈logging.c,logging.h应用示例模块API 使用参考zadig.c,wdi-simple.c,profile.c等系统适配模块跨版本/编码适配msapi_utf8.h,stdfn.h,config.h下文逐个分析各组件的内部实现机制。二、资源嵌入模块构建时组件资源嵌入模块是一个构建时工具解决了静态库无法直接嵌入二进制资源的难题。其实现原理如下开发者在embedder_files.h中声明需要嵌入的文件路径如 WDK 目录下的winusbcoinstaller2.dll、libusb0 驱动文件、INF 模板等embedder.c作为独立可执行程序在编译前运行。它遍历所有声明的文件读取每个文件的二进制内容将其转换为 C 数组字面量const unsigned char file_XXX[] { 0x01, 0x02, ... }同时记录每个文件的提取子目录、大小和创建时间戳生成一个资源索引表struct res resource[]最终输出embedded.h头文件供libwdi.c包含该模块的设计巧妙之处在于将文件系统依赖转化为编译期数据依赖。生成的embedded.h体积虽大包含所有驱动二进制但完全自包含使得 libwdi 库无需任何外部资源文件即可独立工作。三、核心 API 模块运行时入口核心 API 模块是 libwdi 对外的门面实现了三个主要函数wdi_create_list、wdi_prepare_driver、wdi_install_driver。其内部实现要点如下设备枚举wdi_create_list使用SetupDiGetClassDevs枚举所有 USB 类设备GUID_DEVINTERFACE_USB_DEVICE通过SetupDiGetDeviceRegistryProperty读取SPDRP_HARDWAREID、SPDRP_SERVICE、SPDRP_DRIVER等属性从硬件 ID 字符串中通过strtok解析 VID/PID/MI例如USB\VID_045EPID_0289通过DEVPKEY_Device_BusReportedDeviceDesc读取设备描述Windows 8 及以上回退到SPDRP_DEVICEDESC所有字符串在返回前转换为 UTF-8 编码保持 API 层字符串编码统一并发控制每个 API 函数入口处通过CreateMutex以函数名为互斥体名称防止多个线程同时调用 libwdi 的敏感操作如设备枚举和驱动安装避免资源竞争。Windows 版本检测通过GetVersionEx结合VerifyVersionInfo规避 Windows 8.1 及之后版本的版本号伪装问题确保库能准确识别 Windows 7 到 Windows 11 各版本以决定是否支持某些特性如 SHA-256 签名。四、驱动准备模块INF/CAT 生成驱动准备模块是 libwdi 实现“零手动编写 INF”的核心由两个子组件构成令牌生成器tokenizer和 PKI 签名器pki。令牌生成器tokenizer.c该组件实现了一个轻量级模板引擎其设计极简却足够有效模板文件如winusb.inf.in中使用#TOKEN_NAME#格式的占位符调用方提供一个token_entity_t数组每个元素包含匹配字符串和替换字符串tokenize_string函数采用单次扫描方式定位#前缀标记匹配令牌表执行替换支持递归替换recursive参数但默认只执行一轮避免死循环替换后的内容以 UTF-16 编码写入.inf文件并添加 BOM0xFEFF确保非英文系统下的兼容性PKI 签名器pki.cPKI 模块负责生成 CAT 目录文件并自签名其实现依赖 Windows CryptoAPI 和 MSSign32证书生成调用CertCreateSelfSignCertificate创建自签名证书配置代码签名 EKU1.3.6.1.5.5.7.3.3设置 CPS 策略指向http://libwdi-cps.akeo.ie有效期至 2029 年证书安装将证书添加到本地机器的Root和TrustedPublisher存储区CertAddCertificateContextToStoreCAT 文件创建使用CryptCATOpen创建目录文件通过CryptCATPutMemberInfo为每个驱动文件.sys、.dll、.inf计算 SHA-1 哈希并加入目录签名调用SignerSignEx对 CAT 文件进行 Authenticode 签名密钥清理签名完成后立即调用CryptAcquireContext配合CRYPT_DELETEKEYSET删除私钥容器防止私钥被恶意重用该设计的关键权衡是“以安全性换取便利性”——私钥被销毁意味着证书无法用于签署其他文件但这也防止了证书被滥用。五、安装执行模块提权安装器安装执行模块是 libwdi 中唯一需要管理员权限的部分被设计为独立进程installer.exe以嵌入式资源的形式存在。其实现包含以下核心机制命名管道通信主进程调用方在启动安装器前先创建服务端命名管道\\.\pipe\libwdi-installer管道采用消息模式PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE支持双向消息传递主进程通过ShellExecuteEx配合runas动词启动安装器若需要 UAC 提权或直接CreateProcess若已提权消息协议安装器与主进程之间定义了 9 种消息类型installer_code枚举IC_GET_DEVICE_ID/IC_GET_HARDWARE_ID安装器请求设备标识IC_PRINT_MESSAGE/IC_SYSLOG_MESSAGE安装器向主进程回传日志IC_SET_STATUS安装器报告最终状态码IC_SET_TIMEOUT_INFINITE/IC_SET_TIMEOUT_DEFAULT动态调整超时实际驱动安装安装器通过UpdateDriverForPlugAndPlayDevices执行驱动安装。若设备当前已连接该 API 会立即触发安装若设备未连接则调用SetupCopyOEMInf将 INF 复制到系统目录等待设备插入时由 PnP 管理器自动安装安装器还启动一个后台线程实时读取setupapi.dev.log系统日志通过管道将日志流式回传给主进程实现安装进度的可视化系统保护安装器在执行安装前通过IGroupPolicyObjectCOM 接口临时禁用系统还原点创建DisableSystemRestore安装完成后恢复避免长时间安装过程中的额外开销。六、日志诊断模块日志模块logging.c的实现采用了与安装器类似的命名管道机制但独立于安装器管道日志管道命名为\\.\pipe\libwdi-logger采用同步读写模式主进程调用wdi_register_logger注册一个窗口句柄和消息 ID日志模块会通过PostMessage异步通知该窗口有新日志到达窗口收到通知后调用wdi_read_logger读取日志缓冲区内容日志缓冲区固定为 8KB当管道即将溢出时write_to_pipe会主动调用SendMessage强制刷新避免阻塞该设计实现了日志的生产者-消费者解耦libwdi 内部任意位置调用wdi_dbg/wdi_info/wdi_err宏即可写入日志而无需关心日志的最终去向控制台或 GUI 窗口。七、应用示例模块ZadigZadig 是 libwdi 最完整的应用示例其实现展示了 libwdi API 的完整使用方式zadig.c实现了完整的 GUI 主循环使用 Windows 原生 Dialog 和控件zadig_net.c实现了基于 WinINet 的在线更新检查支持 HTTP/2 和 gzip 解码zadig_parser.c实现了 UTF-16 配置文件的键值对解析用于.cfg预设文件profile.c是从 Kerberos 项目移植的 INI 风格解析器用于读取zadig.ini启动配置zadig_stdlg.c封装了文件夹浏览、文件对话框、关于对话框等标准 UI 组件Zadig 不仅是一个工具更是 libwdi API 的“活文档”——开发者可通过阅读 Zadig 源码理解如何在实际项目中集成 libwdi。八、系统适配模块msapi_utf8.h是 libwdi 的“系统胶水层”其设计意图非常明确将 Windows 原生使用的 UTF-16 编码 API 全部封装为 UTF-8 版本。每个封装函数如CreateFileU、GetWindowTextU、MessageBoxU内部先通过MultiByteToWideChar将 UTF-8 输入转换为 UTF-16调用对应的 W 版本 API再将输出通过WideCharToMultiByte转回 UTF-8对于结构体参数如OPENFILENAMEA封装函数会将其转换为 W 版本结构体调用 W API 后再复制回 A 结构体该层使得 libwdi 的核心代码可以全部使用 UTF-8 字符串处理无需在源码中频繁进行编码转换极大提升了代码的可读性和可维护性九、模块间协作总览从宏观执行流程看各模块的协作关系如下构建时资源嵌入模块扫描文件 → 生成embedded.h运行时准备阶段核心 API 接收设备信息 → 令牌生成器填充 INF 模板 → PKI 模块生成并自签名 CAT → 资源嵌入模块提取驱动二进制到目标目录运行时安装阶段核心 API 创建命名管道 → 启动安装执行模块提权→ 安装器通过管道获取设备 ID → 调用 Windows Setup API 安装驱动 → 日志模块实时回传安装进度运行时UI 展示应用示例模块Zadig通过核心 API 枚举设备 → 驱动准备模块生成文件 → 安装执行模块完成安装 → 日志模块在 UI 中显示过程信息libwdi 的实现充分体现了“高内聚、低耦合”的设计原则各模块职责单一、边界清晰通过 API 接口和 IPC 管道完成协作使得整个库在约 1.5 万行 C 代码的规模下依然保持了良好的可维护性和可扩展性。
企业数字化 ERP 产品动态
相关推荐
嵌入式硬件调试全解析:从JTAG/SWD到示波器实战 1. 为什么嵌入式开发离不开硬件调试1.1 嵌入式系统“看不见摸不着”的特性决定了调试方式搞嵌入式开发的人都有这种体验:写PC端程序,代码崩溃了IDE会直接告诉你崩在哪一行,变量值可以随时hover查看,异常堆栈清清楚楚。但到了单片机… · 2026/9/27 11:15:27
网站详情页用什么软件做?资深老手教你3步选出最划算方案 网站详情页用什么软件做?资深老手教你3步选出最划算方案 找建站公司怕被坑高价,这是很多老板和运营人员最头疼的事。很多公司一上来就报价几万块,说什么“高端定制”、“动态交互”,结果做出来的页面加载慢得像蜗牛,后期改个价格还得再掏钱。其实,… · 2026/9/27 11:15:27
windows 驱动实例分析系列: libwdi驱动分析-设计篇 一、项目概述
libwdi(Library for Windows Driver Installation)是一个开源的Windows USB驱动安装库,由Pete Batard开发并维护,主要用于简化USB设备在Windows系统上的驱动程序安装流程。该库的核心价值在于:将原本复杂… · 2026/9/27 11:15:21
AI高效修Bug:5步搞定代码难题,TaoToken统一Key接入实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 11:57:29
避坑指南:网络推广方案策划报告怎么写才不翻车?5个注意事项 避坑指南:网络推广方案策划报告怎么写才不翻车?5个注意事项 做建站和运维的兄弟,是不是经常被老板或客户怼:“这网站怎么这么丑?模板改改就能用,还要我花大钱?” 模板网站太丑不够用 ,这是咱们这行最真实的痛。… · 2026/9/27 11:57:23
Prompt提示词与代码项目结构图:用TaoToken统一Key优化学习路径,提高学习效率 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 11:57:17
2026年老师都在用的英语听力平台,实测这5个 核心要点:英语听力平台到2026年,老师挑工具的逻辑变了:素材多不多只是基础,能不能分层放音、能不能把错题自动收上来、能不能生成可读的学情报告,才是每天要面对的。统一语速和手动错题本,是听力训练里最耗… · 2026/9/27 11:57:17
Vercel Eve 快速入门:用 eve init 构建你的第一个 Agent 并接入 TaoToken /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 11:56:46
网站建设sql语句留言板速查手册:3步搞定低成本留言功能 网站建设sql语句留言板速查手册:3步搞定低成本留言功能 网站上线了三个月,后台数据冷得发指,除了蜘蛛偶尔来爬两下,连个访客评论都没有。很多甲方朋友问我,是不是SEO没做好,还是推广没到位?其实,很多时候不是流量不行,而是你的网站缺乏一个低… · 2026/9/27 11:56:46
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现 简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01
汕头网站建设制作厂家避坑指南:5大注意事项救急 汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习 简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现 简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01
汕头网站建设制作厂家避坑指南:5大注意事项救急 汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习 简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01