2024年8月22日发(作者:)

维普资讯

2007年7月 

第22卷第4期 

西安石油大学学报(自然科学版) 

Journal of Xi an Shiyou University(Natural Science Edition) 

Ju1.2007 

V01.22 No.4 

文章编号:1673—064X(2007)04—0113—03 

基于WDM的设备驱动程序开发 

宋新爱 ,余坤2 

(1.西安石油大学计算机学院,陕西西安710065;2.中国石油集团测井有限公司测井仪器厂,陕西西安710061) 

摘要:Windows驱动程序模型(WDM)是Microsoft公司新推出的设备驱动程序开发模型.分析了 

WDM驱动程序模型、结构和WDM程序的实现过程,并给出了使用DriverStudio3.2与VC++开 

发并1:7驱动程序的实例. 

关键词:设备驱动程序;体系结构;I/0请求包 

中图分类号:TP316.7 文献标识码:A 

设备驱动程序是连接计算机应用程序、硬件以 

及操作系统的桥梁,是硬件设备连接到计算机系统 

的软件接口.在Windows环境下开发应用系统经常 

WDM功能设备驱动程序通常由2个分离的执 

行文件组成.一个文件是类驱动程序,它了解如何处 

理操作系统使用的WDM协议,以及如何管理整个 

遇到对特定功能的硬件设备进行访问和控制的问 

题.由于Windows系统的CPU提供4种特权等级, 

通常称为Ring0,Ring1,Ring2,Ring3.Ring3特权级 

设备类的基本特征.另一个文件称为微小驱动程序 

(Minidriver),它包含类驱动程序,用于管理设备实 

例的厂商专有特征例程.只有二者结合在一起才成 

为一个完整的功能设备驱动程序.一个完整的功能 

设备驱动程序包含许多例程,结构如图1[2]所示.当 

操作系统遇到一个IRP(I/O request packet)时,它 

别最低,Ring0特权级别最高.操作系统和设备驱动 

程序运行在Ring0级 ̄J_kt ,可以执行任何有效的 

CPU指令;普通应用程序(包括DLL)运行在Ring3 

级别上,硬件I/0指令不能被执行,所以必须开发 

就调用驱动程序中的例程来执行该IRP的各种操 

作.有些例程是必需的,如DriverEntry和AddDe— 

vice,还有DispatchPnP,Dispatch_Power和Dispatch— 

设备驱动程序,以便使应用程序有效地控制计算机 

硬件设备. 

WMI派遣函数.需要对IRP排队的驱动程序一般 

1 Windows驱动程序模型(WDM) 

在Windows驱动程序模型(WDM,Windows 

都有一个Startlo例程,大部分能生成硬件中断的设 

备,其驱动程序都有一个中断服务例程和一个延迟 

过程调用例程,执行DMA传输的驱动程序应有一 

个AdapterControl例程. 

Driver Mode1)中,每个硬件设备至少有2个驱动程 

序.其中一个驱动程序称为功能(Function)设备驱 

动程序,负责初始化I/o操作、中断事件,为用户提 

供一种设备适合的控制方式.另一个驱动程序称为 

总线(BUS)设备驱动程序,它负责管理硬件与计算 

机的连接. 

2 WDM驱动程序结构 

WDM驱动程序采用分层的结构模型[3l,即设 

备驱动程序栈结构模型,如图2所示.在这个驱动程 

序设备栈中,总线驱动程序对总线上的设备进行控 

收稿日期:2006—10 11 

作者简介:宋新爱(1973一),女,讲师,工学硕士,主要从事计算机应用技术方面的研究 

维普资讯

114一 西安石油大学学报(自然科学版) 

制.驱动程序总是通过总线驱动程序创建的物理设 

备对象(PDO,Physics Device Object)对设备进行操 

作,PDO是总线驱动程序在枚举总线时,检测到实 

际设备,从而建立的表示实际物理设备对象.功能驱 

动程序是驱动程序完成控制设备操作功能最主要的 

部分,该层位于总线驱动程序上面.在单个硬件的驱 

动程序堆栈中,不同位置的驱动程序扮演了不同的 

角色.总线驱动程序管理计算机与PDO所代表的设 

备的连接.功能驱动程序管理功能设备对象(H)o, 

Function Device ojbect)所代表的设备.过滤驱动程 

序用于监视和修改IRP流. 

3 WDM驱动程序的实现 

3.1 DriverEntry例程 

在WDM驱动程序中,DriverEntry例程主要负 

责完成驱动程序的一些注册表信息和一些变量的初 

始化工作,不进行资源请求.所有的驱动程序都必须 

包含DriverEntry例程,它是驱动程序的一个入口 

点,当装载驱动程序时,PnP管理器为每个驱动程序 

调用一次DriverEntry例程,主要有以下3个功能. 

(1)设置AddDevice,Unload,Dispatch和其他例 

程的入口指针. 

NTSTATUS DriverEntry(IN PDRIVER— 

BJECT pDriverObject, 

IN PUNICoDE—STRING pRegistryPath) 

{ 

ULONG uleDviceNumber=0; 

NTSTATUS status; 

pDriverObject一>DriverUnlaod=DriverUn— 

laod; 

status=CreatDevice(pDriverObject,uleDvi— 

ceNumber); 

pDriverObject——>DriverStartIo:StartIo; 

pDriverObject 一 > MajorFunc— 

tion[IRP—MJ—CREAT]=DispatchCreat: 

pDriverObject——>MajorFunction[!Rp—MI_Close] 

=DispatchClose; 

pDriverObject一>MajorFunction[ 即一MJ—PnP] 

=DispatchPnp; 

return status; 

} 

(2)可以从注册表中获取一些需要的信息以初 

始化驱动程序. 

入121参数pRegistrypath指向一个枚举的Uni— 

code信息串,此Unicode信息串指定了驱动程序注 

册表键的路径.如果在驱动程序的其他地方需要用 

到它,就需要重新申请内存,备份该pRegistryPath 

串. 

(3)初始化其他的在驱动程序范围内的数据结 

构和资源. 

3.2 AddDevice例程 

操作系统找到一个新的设备以后,就从注册表 

中寻找它的驱动程序,然后就向驱动程序发送 

IRO一^ J—PNP qj IRP—MN—START—DEVI(’】 的 

请求,这样就进入了AddDevice例程,同时,操作系 

统还将硬件资源请求信息作为参数传递给AddDe— 

ivce,接下来AddDevice要从系统资源中分配出这些 

请求的资源,并且把资源信息保存起来,以便后面使 

用.在该例程中,驱动程序首先调用IoCreateDevice 

创建设备对象,并建立一个私有扩展设备对象,作为 

目标I/0设备;其次注册一个或多个设备接口,以 

便应用程序能知道设备对象的存在并创建符号连 

接;然后调用IoAttachDeviceToDeviceStack函数,把 

新设备对象放到设备堆栈上;最后初始化设备对象 

的标志成员,将设备对象附着到设备堆栈中. 

3.3 Unload例程 

个完整WDM驱动程序还应包含Unload例 

程,该例程负责删除DriverEntry例程所分配的驱动 

程序范围内的资源,如内存、事件等. 

4 基于WDM模型的并口驱动程序 

实例 

使用DriverStudio3.2与VC++开发工具针对 

820热敏绘图仪开发一个并口驱动程序,以下是对 

并口进行读写操作的部分程序代码. 

NTSrATUS Printer—Device::DeviceControI(KIrp 

I) 

{NTSTATUS status; 

switch(I.IoctlCode()) 

{case PRINTER—Write—Printer—Port: 

status:PRINTER—Write—Printer— 

Port—Handler(I);break; 

default: 

维普资讯

宋新爱等:基于WDM的设备驱动程序开发 一115一 

, nrecognized L request 

status=STA 兀 S—I卜『、,AI ID—PARAME— 

TER:break; 

} 

if(status=:SrATUS—PENDING)retum 

status; 

elseretum I.PnpComplete(thls,status); 

} 

Nr A]rI S Printer—Device::PRINTER—Write— 

Port—Handler(KIrp I) 

{ 

PI『CHAR pIOBuffer;//Pointer to transfer 

buffer 

UU NG InBufferSize://Amount of data 

avaiI.from caller. 

UL0NG OutBufferSize://Max data that 

caller can accept. 

UL0NG nPort://Port number to read or 

write. 

UCHAR value.status; 

hfl3ufferSize=.IoctllnputBufferSize(CUR— 

RENT); 

OutBufferSize = I. IoctlOutputBufferSize 

(CURRENT);//OutputBufferLength; 

pIOBuffer=(PI『CHAR)I.IoctIBuffer(); 

I.Information()=0; 

nPort=Ox378: 

WRITE—P0RT—UCHAR((PUCHAR)(nPort 

+2),0xCC);//写并口状态控制字 

//并口状态查询 

do{ 

status =READ—PORT— UCHAR 

((PUCHAR)(n_Port+1)); 

status=status&0x80: 

}while((!status)); 

value=*((PUCHAR)pIOBuffer); 

WRITE—PORT—UCHAR((PUCHAR) 

(nPort),value); 

KeStlalExecutionProcessor(1);/艇时等待 

WRITE—PORT—UCHAR((PUCHAR)(nPort 

+2),0xCD); 

KeStal1ExecutionProcessor(1); 

WRITE—PORT—UCHAR((PUCHAR)(nPort 

+2),0xCC); 

do{ 

status =READ—PORT— I『CHAR 

((PUCHAR)(nPort+1)); 

status=status&0x80: 

}while((!status)); 

retum STATUS—SUCCESS; 

5 结束语 

基于WDM驱动模型设计的驱动程序支持即插 

即用功能,可以很好地在Windows系统中运行, 

WDM定义了一个基本模型,处理所有类型的数据. 

通过这种共同的核心模型驱动程序开发者可以很容 

易从一种类型的设备转移到另一种类型的设备. 

WDM提供的总线驱动程序和类驱动程序是其关键 

部分,这也使得开发驱动程序由复杂变得相对简单. 

WDM是跨平台的驱动程序模型,在编写时尽量不 

要使用汇编,而且要分别在不同的平台下编译,开发 

驱动程序的工具一般使用DriverStudio 3.2和VC 

++. 

参考文献: 

[1]郭四稳.WDM驱动程序的开发与实现[J].电脑与信 

息技术,2006,14(4):47—50. 

[2]张惠娟.Windows环境下的设备驱动程序设计[M].西 

安:西安电子科技大学出版社,2002. 

[3]武安河.Windows 2000/XP WDM设备驱动程序开发 

[M].2版.北京:电子工业出版社,2005. 

编辑:张新宝