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选择 <Create test certificate...>
,则在编译时会自动生成测试签名证书。
生产环境
从Win10开始,驱动文件包不仅需要进行扩展验证 (EV) 代码签名,还需要提交到硬件开发中心仪表盘,具体操作指南可以参考此处,你可以在该文档上找到驱动签名所需的任何内容。
Windows驱动开发入门指引的更多相关文章
- windows 驱动开发入门——驱动中的数据结构
最近在学习驱动编程方面的内容,在这将自己的一些心得分享出来,供大家参考,与大家共同进步,本人学习驱动主要是通过两本书--<独钓寒江 windows安全编程> 和 <windows驱动 ...
- windows驱动开发推荐书籍
[作者] 猪头三 个人网站 :http://www.x86asm.com/ [序言] 很多人都对驱动开发有兴趣,但往往找不到正确的学习方式.当然这跟驱动开发的本土化资料少有关系.大多学的驱动开发资料都 ...
- Kinect for Windows SDK开发入门(15):进阶指引 下
Kinect for Windows SDK开发入门(十五):进阶指引 下 上一篇文章介绍了Kinect for Windows SDK进阶开发需要了解的一些内容,包括影像处理Coding4Fun K ...
- Windows内核驱动开发入门学习资料
声明:本文所描述的所有资料和源码均搜集自互联网,版权归原始作者所有,所以在引用资料时我尽量注明原始作者和出处:本文所搜集资料也仅供同学们学习之用,由于用作其他用途引起的责任纠纷,本人不负任何责任.(本 ...
- [Windows驱动开发](一)序言
笔者学习驱动编程是从两本书入门的.它们分别是<寒江独钓——内核安全编程>和<Windows驱动开发技术详解>.两本书分别从不同的角度介绍了驱动程序的制作方法. 在我理解,驱动程 ...
- Kinect for Windows SDK开发入门(一):开发环境配置
[译]Kinect for Windows SDK开发入门(一):开发环境配置 前几天无意中看到微软发布了Kinect for windows sensor,进去看了一下Kinect应用的例子,发现K ...
- Windows驱动开发(中间层)
Windows驱动开发 一.前言 依据<Windows内核安全与驱动开发>及MSDN等网络质料进行学习开发. 二.初步环境 1.下载安装WDK7.1.0(WinDDK\7600.16385 ...
- Windows 驱动开发 - 5
上篇<Windows 驱动开发 - 4>我们已经完毕了硬件准备. 可是我们还没有详细的数据操作,比如接收读写操作. 在WDF中进行此类操作前须要进行设备的IO控制,已保持数据的完整性. 我 ...
- Windows驱动——读书笔记《Windows驱动开发技术详解》
=================================版权声明================================= 版权声明:原创文章 谢绝转载 请通过右侧公告中的“联系邮 ...
随机推荐
- 网站开发进阶(二十五)js如何将html表格导出为excel文件
js如何将html表格导出为excel文件 赠人玫瑰,手留余香.若您感觉此篇博文对您有用,请花费2秒时间点个赞,您的鼓励是我不断前进的动力,共勉! jsp页面数据导出成excel的方法很 ...
- STL算法设计理念 - 函数对象和函数对象当参数和返回值
函数对象: 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象.一个类对象,表现出一个函数的特征,就是通过"对象名+(参数列表)&qu ...
- 【翻译】在Ext JS应用程序中使用自定义图标
原文:Using Custom Icons in Your Ext JS App 作者:Lee BoonstraLee is a technical trainer at Sencha. She's ...
- 【一天一道LeetCode】#14 Longest Common Prefix
一天一道LeetCode系列 (一)题目: Write a function to find the longest common prefix string amongst an array of ...
- Android群英传笔记——第六章:Android绘图机制与处理技巧
Android群英传笔记--第六章:Android绘图机制与处理技巧 一直在情调,时间都是可以自己调节的,不然世界上哪有这么多牛X的人 今天就开始读第六章了,算日子也刚好一个月了,一个月就读一半,这效 ...
- ROS探索总结(十四)——move_base(路径规划)
在上一篇的博客中,我们一起学习了ROS定位于导航的总体框架,这一篇我们主要研究其中最重要的move_base包. 在总体框架图中可以看到,move_base提供了ROS导航的配置.运行.交互接口,它主 ...
- android离线缓存技术
离线缓存是指在有网络的状态下将从服务器获取的网络数据,如Json 数据缓存到本地,在断网的状态下启动APP时读取本地缓存数据显示在界面上,常用的APP(网易新闻.知乎等等)都是支持离线缓存的,这样带来 ...
- 猴子吃桃问题---C实现
原题:猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了了一个.第二天早上又将剩下的桃子吃掉一半,又多吃了一个.以后每一天早上都吃前一天剩下桃子的一半零一个.到第十天早上想再吃时,发现 只剩下 ...
- linux中syscall调用号查看
可以用locate查找: locate unistd_32 //或者 locate unistd_64 以下是本猫在ubuntu下返回的结果: /usr/src/linux-headers-3.16. ...
- ## 分享一下Mac(苹果电脑)里面好用的软件!
该文章主要分享 Mac电脑常用的软件 文章来源于 github小弟调调™的仓库转载 说明 [Open-Source Software][OSS Icon] 表示 开源软件 ,点击进入 开源 仓库: ...