Windows驱动开发WDM (1) - 基本结构

驱动对象(DRIVER_OBJECT)

每个驱动程序会有唯一的驱动对象与之对应,并且这个驱动对象是在驱动加载的时候,被内核中的对象管理程序所创建的。

驱动对象用DRIVER_OBJECT来表示,内核对一个驱动只加载一个实例。对于DRIVER_OBJECT的说明,详见:http://msdn.microsoft.com/en-us/library/windows/hardware/ff544174(v=vs.85).aspx

说明一下其中的一个成员:DeviceObject。

MSDN上面是这么定义:

PDEVICE_OBJECT DeviceObject

Pointer to the device objects created by the driver. This member is automatically updated when the driver callsIoCreateDevice successfully. A driver can use this member and theNextDevice member ofDEVICE_OBJECT to step through a list of all the device objects that the driver created.

DeviceObject指向驱动对象的第一个设备对象。DeviceObject->NextDevice指向下一个设备对象,最后一个设备对象的NextDevice指向空。比如第一次调用IoCreateDevice的时候,DriverObject->DeviceObject指向第一个设备对象(DeviceObject->NextDevice=NULL),再调用一次IoCreateDevice创建第二个设备成功后,DriverObject->DeviceObject->NextDevice会指向第二个设备对象。

设备对象都是由驱动程序创建的,而非操作系统创建,当驱动被卸载的时候,需要遍历每个设备对象,并将其删除。

 

设备对象(DEVICE_OBJECT)

每个驱动会创建一个或者多个设备对象,用DEVICE_OBJECT表示。每个设备对象都有一个指针指向下一个设备对象,因此形成一个设备链。设备链的第一个设备是由DRIVER_OBJECT的DeviceObject指定。

参考:http://msdn.microsoft.com/en-us/library/windows/hardware/ff543147(v=vs.85).aspx

需要说明的是:

1. NextDevice,指向下一个设备对象,注意这里指的下一个对象是同属于一个驱动对象的设备。也就是说这个设备链是指同一个驱动对象的设备链。

2. AttachedDevice,这里指的是更高一层驱动的设备对象。比如另外一个驱动附加到本驱动,那么AttachedDevice指的是那个驱动里面的第一个设备对象。

 

设备扩展 (DEVICE_EXTENSION)

DEVICE_OBJECT里面记录一些通用信息,但是大多数情况下,驱动程序需要额外记录一些信息,这个时候就需要设备扩展了。

设备扩展是由程序员指定内容和大小,由I/O管理器创建的,并且保存在非分页内存中

在驱动程序中,尽量不要使用全局变量,数据可以保存在设备扩展里面。

 

WDM驱动的基本结构

从Windows2000以后,微软引入了新的驱动模型:WDM。WDM是建立在NT驱动模型之上的。

WDM驱动一般分为2种设备对象:

1. 物理设备对象(Physical Device Object,PDO)

2. 功能设备对象(Function Device Object,FDO)

比如:当用户插入USB盘的时候,总线驱动会创建PDO,然后提示用户加载FDO,如果操作系统已经提供了相应的驱动,那么操作系统会自动加载这个驱动。如果没有,则需要用户去安装相应的驱动。

在FDO和PDO之间,可以创建过滤驱动。

1. 位于FDO下面的,称之为下层过滤驱动;

2. 位于FDO上面的,称之为上层过滤驱动。

简单画了一个示意图:

过滤驱动不是必须的,在WDM中,基本上可以说PDO和FDO是必须的。AttachedDevice指向上层驱动的设备对象。

 

入口程序DriverEntry

跟NT驱动一样,WDM驱动的入口函数也是DriverEntry。WDM驱动需要额外设置2个派遣函数:

1. AddDevice

2. IRP_MJ_PNP

跟NT驱动不同,NT驱动一旦加载就创建设备,而WDM驱动是操作系统加载PDO以后,调用驱动的AddDevice例程,然后在AddDevice例程里面创建FDO,并且附加到PDO之上。

 

驱动程序的垂直层次结构

DeviceObject->AttachedDevice指向上层设备,如上面的图示。但是设备对象里面不能记录下一层驱动的设备对象(NextDevice指的是同一个驱动里面的下一个设备对象),这时就可以通过设备扩展来记录。

通过AttachedDevice和设备扩展,我们可以遍历整个设备对象堆栈,包括从上到下和从下到上。

 

驱动程序的水平层次结构

《windows驱动技术开发详解》里面将同一个驱动创建出来的设备对象的关系称之为水平层次,我觉得还是蛮形象的。

水平层次的第一个设备对象是由它的驱动对象所指定(DRIVER_OBJECT::DeviceObject)。每一个设备对象可以通过NextDevice找到水平层次(同一个驱动对象)的下一个设备对象。

比如插入2块同样型号的网卡。插入第一个网卡的时候,系统会创建一个PDO,并且加载相应的FDO,插入第二个网卡的时候,系统创建另外一个PDO,并且加载相应的FDO。那么这两个PDO之间就是同一个水平层次,这两个FDO也处于同一个水平层次。

 

第一章概述...........................................................................................................................6 1.1 本教程的规划:...............................................................................................................6 第二章WDM驱动程序的运行.................................................................................................7 2.1 WDM驱动程序的基本调用流程:.....................................................................................7 2.1.1驱动程序何时从何处开始执行?........................................................................7 2.1.1.1第一次安装好驱动程序:................................................................7 2.1.1.2驱动程序正常运行:........................................................................7 2.1.2 DriverEntry()大约做些什么?.........................................................................7 2.1.2.1 IRP主功能码(Major Function Code).......................................9 2.1.2.2 IRP_MJ_PNP次功能码(Minor Function Code).......................10 2.1.2.3 IRP_MJ_POWER次功能码(Minor Function Code)...................10 2.1.3驱动程序与应用程序相关的功能码如何调用?..............................................10 2.1.3.1 DriverEntry()中您必须要注册回调函数...................................10 2.1.3.2 在您的应用程序中正确调用CreateFile().............................11 2.1.3.3 应用层调用驱动的消息参照:.....................................................11 2.1.3.4 IoControl调用:...........................................................................11 第三章开始编写WDM驱动程序...........................................................................................13 3.1 得到一个Demo工程:.....................................................................................................13 3.2 在VC下配置DDK的开发环境...........................................................................................15 3.2.1 我的目录.............................................................................................15 3.2.1.1我们应该在系统环境变量里设置..................................................15 3.2.2安装VC6................................................................................................17 3.2.3 打开wdm1\sys\Wdm1.dsp工作区文件...............................................18 3.2.4 修改H:\driverDev\MakeDrvr.bat文件...........................................18 3.2.5 设置VC的环境.....................................................................................19 3.2.5.1前面的内容编译时出了错误(配置'MakeDrvr')......................19 3.2.5.1.1 在project -> settings中设置成如下:.......................19 3.2.5.1.2 还可以在Tools-> Options-〉directories中选择“Executable files”并添加MakeDrvr.bat的目录即可.................20 3.2.5.1.3 再按F7编译 有编译提示..................................................20 3.2.5.1.4 搞清楚 MakeDrvr.BAT文件的功能...................................21 3.2.5.2前面的内容编译时出了错误,让我们看看是什么原因..............22 第四章 安装DebugPrintMonitor驱动程序.................................................................................24 4.1 用控制面板安装DebugPrintMonitor...........................................................................24 4.2 检查DebugPrint driver的安装情况...........................................................................29 第五章 安装wdm1驱动程序..........................................................................................................30 5.1 INF 文件.........................................................................................................................30 5.1 全新安装驱动.................................................................................................................30 5.1.1 安装驱动WDM1.SYS.............................................................................................30 5.2 测试DebugPrintMonitor...............................................................................................30 第六章 执行应用程序...................................................................................................................32 6.1 打开Wdm1Test.dsp.........................................................................................................32 6.2 编译Wdm1Test 工程.......................................................................................................32 6.3 修改Wdm1Test .CPP文件的setupapi.h的路径...........................................................33 6.3 重新指定Wdm1Test 工程的setupapi.lib的路径.......................................................35 6.4 类型DWORD_PTR和ULONG_PTR没定义的错误.................................................................36 6.4 调试WdmTest工程...........................................................................................................37 6.4.1 设置断点.............................................................................................................37 6.4.2 单步执行.............................................................................................................38 6.4.3 SYS目录下驱动程序代码对照:.......................................................................40 6.4.4 EXE中继续往下执行ReadFile/WriteFile.......................................................40 6.4.4.1 执行ReadFile的情况.............................................................................40 6.4.4.2 执行WriteFile的情况...........................................................................42 6.4.5其他的请自己执行..............................................................................................43 第七章 启用wdm1驱动程序..........................................................................................................44 第八章 停用wdm1驱动程序..........................................................................................................45 8.1 点击“我的电脑” –〉“属性” –〉“硬件”.........................................................45 8.2 点击 “设备管理器”并展开其他设备.......................................................................45 第九章还有更好的DebugView.exe.............................................................................................47 9.1得到DebugView.exe.........................................................................................................47 9.2 原理..................................................................................................................................48 9.2.1 DBG.......................................................................................................................48 9.2.2 DbgPrint().........................................................................................................48 9.2.3 如何使用DbgPrint()........................................................................................48 9.2.4 修改wdm1工程的例子........................................................................................48 9.3 如何使用DebugView.......................................................................................................48
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值