Windows驱动开发入门指引
|
1. 前言 |
因工作上项目的需要,笔者需要做驱动相关的开发,之前并没有接触过相关的知识,折腾一段时间下来,功能如需实现了,也积累了一些经验和看法,所以在此做番总结。
对于驱动开发的开发指引,微软官方文档网站已经提供了很详细的教程文档,并且在Github上提供了一系列典型的例程源码用于开发人员参考。开发人员在具备一定的驱动概念知识后,通过参考官方例程可以很容易实现拥有特定功能的驱动应用程序。
Windows驱动程序入门: https://docs.microsoft.com/zh-cn/windows-hardware/drivers/gettingstarted/
Github: https://github.com/Microsoft/Windows-driver-samples
|
2. 驱动类型 |
驱动分为如下几种类型:
- 设备函数驱动程序
- 设备筛选器驱动程序
- 软件驱动程序
- 文件系统筛选器驱动程序
- 文件系统驱动程序
驱动程序不是一定需要与硬件通讯,如果需要访问操作系统核心数据,往往应用程序没有足够的权限,这种情况则需要在内核模式下进行访问。就上面5种驱动类型,笔者参考着微软的驱动例子开发过 鼠标键盘设备过滤驱动 和 网络过滤软件驱动程序,所以对驱动开发的理解仍在浅水区,如在阅读过程中发现有误的地方,还请不吝指出。
采用的驱动类型关乎到代码的实现(需不需要考虑PNP和电源管理)和驱动的安装( NT式驱动程序以 service 的形式运行,其他驱动需要采用通用的INF文件安装),微软的官方文档这样提到:
有关软件驱动程序,你的两个选项为 KMDF 和内核模式 Windows NT 驱动程序模型。 使用 KMDF 和内核模式 Windows NT 模型,你可以编写驱动程序,而无需考虑即插即用 (PnP) 和电源管理。 你可以改为专心于驱动程序的首要任务上。 使用 KMDF,你不必考虑 PnP 和电源,因为框架会为你处理 PnP 和电源。 使用内核模式 Windows NT 模型,你不必考虑 PnP 和电源,因为内核模式服务在与 PnP 和电源管理完全无关的环境中运行。
|
3. 开发环境 |
Visual Studio + WDK(Windows Driver Kit)
其中WDK需要自己手动下载安装
笔者是在Windows平台上开发,使用的开发环境为 Visual Studio 2013 + WDK 8.1
|
4. 实现方式 |
WDM vs WDF
对于刚接触驱动开发的新手来说,笔者不建议采用WDM(Windows 驱动程序模型)进行开发。目前在网上能找到的关于驱动开发的中文书籍基本上都是围绕WDM模式进行讲述的,而关于WDF(Windows 驱动框架)开发的书籍寥寥无几,《竹林溪径——深入浅出Window驱动开发》和《Developing Drivers with the Windows Driver Foundation》算是两本讲述基于WDF开发驱动的书籍,两者都能在网上找到电子书资源。
基于WDF的驱动开发
WDF的开发需要遵循一定的规则,开发实现时需要考虑较多的细节,由于篇幅有限,笔者凭着自己的经验暂且稍做列举,后续将写一篇针对WDF驱动开发的文章。
- PNP和电源管理(WDF已经帮忙封装了大部分的接口);
- 各种对象:驱动对象,设备对象,WDF对象,文件对象,队列对象;
- 驱动上下文:有时称为设备扩展,用于存储特定设备对象的相关信息的数据结构;
- 对象的释放:需要考虑不同性质对象释放的时机;
- 中断请求级别:处理不当易导致蓝屏;
- 分页与非分页内存;
- 同步锁:回调同步锁、框架等待锁、自旋锁、中断锁等;
- 日志跟踪记录: 调试的必备,可以采用
WPP(Windows软件追踪预处理器)或简单的DebugPrint输出 - 与应用程序的通讯:控制代码、IRQ,请求队列
|
5. 驱动安装 |
测试环境下安装驱动前
开发的驱动程序没有进行签名或者采用测试签名,则需要在设备上开启测试模式,具体操作为:打开控制台,输入:
bcdedit /set testsigning on
回车,会提示:操作成功完成。 然后重启设备,开机后会在电脑桌面右下方显示有“测试模式”字样内容的水印。
如果要关闭测试模式,则需在控制台输入:
bcdedit /set testsigning off
回车,同样会提示:操作成功完成。 重启设备后则会发现桌面右下角的水印消失。
以服务的形式运行
NT式的驱动程序允许以 service 的形式运行, 服务安装的例程可以参考 WDF Sample 中的 Eventdrv 工程,或者参考我写的关于进程网络监控的驱动例程的开源代码
使用INF文件安装
设备相关的驱动安装可以选择INF进行安装,INF安装文件的编写建议从 WDF Sample 中找到合适的INF文件进行修改,如果你想了解INF的语法,可以参考这里
- 通过设备管理器手工安装
打开控制台,输入 devmgmt 回车,这是打开设备管理器的其中一种方式,其他方式比如右键系统菜单栏图标均可以打开任务管理器,只是使用命令行的方式比较少见,这里特意记录一下。找到感兴趣的 设备节点,右键 属性(或更新驱动程序软件),切换到 驱动程序,可以进行感兴趣的操作。这里所看到所提供的选项,后续等你熟悉了驱动安装的接口后,你会发现都有对应的接口对应每个功能选项。
- 通过程序实现自动安装
可以参考 WDF Sample 中的Driver Install Frameworks API (DIFxAPI) Sample 和Device Console (DevCon) Tool 两个工程,分别提供了不同调用接口的驱动安装方式,Device Console (DevCon) Tool 生成的devcon.exe 是一个功能强大的工具,不仅可用于驱动(包)的安装和卸载,还可以获取设备的硬件ID,描述符以及设备所安装的驱动列表等信息,开发人员可以从中一窥究竟。
在驱动的安装过程中,系统会自动记录安装的日志,在INF目录(路径一般在 C:\Windows\inf下)下可以找到两个日志文件 setupapi.app.log 和 Setupapi.dev.log ,查看这两个日志文件有利于理解驱动安装的执行过程,同时也有利于排查驱动安装过程中出现的异常。
驱动的安装涉及到驱动文件的校验(保证驱动文件的完整性和合法性),驱动的优先级计算(选择最优的驱动去匹配当前识别到的新的设备),驱动的放置目录(Driver Store)等内容。开发人员熟悉驱动安装逻辑有利于驱动的开发,感兴趣可以通过此处进行了解。
|
6. 驱动签名 |
测试环境
通过VS集成开发环境创建 Driver 解决方案后会生成两个项目,右键属性打开 XXX Package,左侧选中 Driver Signing ,在右侧栏 Sign Mode 选择 Test Sign,在 Test Certificate选择 ,则在编译时会自动生成测试签名证书。
生产环境
从Win10开始,驱动文件包不仅需要进行扩展验证 (EV) 代码签名,还需要提交到硬件开发中心仪表盘,具体操作指南可以参考此处,你可以在该文档上找到驱动签名所需的任何内容。