分享
 
 
 

WDM驱动程序入门(1)——HelloWDM

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

WDM驱动程序是一种很新的东西,相信很多人都跟我一样,对它很感兴趣,但是又找不到学习的切入点。究其原因,还是因为WDM是一种非常“死板板”的程序,它一运行就是工作在系统的底层RING 0处,提供各种接口给应用程序调用。也正因为如此,它不像普通的应用程序一样,可以很快地上手——更多的时候,你是在阅读它的技术资料和各种接口信息,你还要非常地熟悉系统底层的工作原理,否则一个不小心,就“蓝屏”了,呵呵——话说回来,写驱动程序的时候,死机是家常便饭。

因此很多人都对WDM望而生畏了。回想一下,我刚开始学WDM的情形还历历在目——看书看了整整3天,但是看完之后好像跟没看也差不了多少,还是不知道怎么入门,甚至连怎么写一个“Hello World”都不知道——后来才知道其实WDM是没有所谓的“Hello World”程序的,唉,真是痛苦啊,这主要还是因为网络上的WDM资料太少造成的。为了不让大家重蹈我的覆辙并对WDM有个感性的认识,在此我给出一个最简单的完整的WDM框架,并附有注释,姑且可以算是一个入门的“Hello World”吧。

废话少说,让我们马上开始研究,要求读者已安装DDK 2000。(在Win98中我还没有测试过,不清楚是否能正常运行)

/***************************************************************

程序名称:Hello World for WDM

文件名称:HelloWDM.cpp

作者:罗聪

日期:2002-8-16

***************************************************************/

//一定要的头文件,声明了函数模块和变量:

#include "HelloWDM.h"

/***************************************************************

函数名称:DriverEntry()

功能描述:WDM程序入口

***************************************************************/

//extern "C"是必须的,表示“用C链接”。如果你的文件名是HelloWDM.c的话,这句可以省略。

extern "C"

NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject,

IN PUNICODE_STRING RegistryPath)

{

//指定“添加设备”消息由函数“HelloWDMAddDevice()”来处理:

DriverObject->DriverExtension->AddDevice = HelloWDMAddDevice;

//指定“即插即用”消息由函数“HelloWDMPnp()”来处理:

DriverObject->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp;

//返回一个NTSTATUS值STATUS_SUCCESS。几乎所有的驱动程序例程都必须返回一个NTSTATUS值,这些值在NTSTATUS.H DDK头文件中有详细的定义。

return STATUS_SUCCESS;

}

/***************************************************************

函数名称:HelloWDMAddDevice()

功能描述:处理“添加设备”消息

***************************************************************/

NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,

IN PDEVICE_OBJECT PhysicalDeviceObject)

{

//定义一个NTSTATUS类型的返回值:

NTSTATUS status;

//定义一个功能设备对象(Functional Device Object):

PDEVICE_OBJECT fdo;

//创建我们的功能设备对象,并储存到fdo中:

status = IoCreateDevice(

DriverObject, //驱动程序对象

sizeof(DEVICE_EXTENSION), //要求的设备扩展的大小

NULL, //设备名称,这里为NULL

FILE_DEVICE_UNKNOWN, //设备的类型,在标准头文件WDM.H或NTDDK.H中列出的FILE_DEVICE_xxx值之一

0, //各种常量用OR组合在一起,指示可删除介质、只读等。

FALSE, //如果一次只有一个线程可以访问该设备,为TRUE,否则为FALSE

&fdo); //返回的设备对象

//NT_SUCCESS宏用于测试IoCreateDevice内核是否成功完成。不要忘记检查对内核的所有调用是否成功。NT_ERROR宏不等同于!NT_SUCCESS,最好使用!NT_SUCCESS,因为除了错误外,它还截获警告信息。

if( !NT_SUCCESS(status))

return status;

//创建一个设备扩展对象dx,用于存储指向fdo的指针:

PDEVICE_EXTENSION dx = (PDEVICE_EXTENSION)fdo->DeviceExtension;

dx->fdo = fdo;

//用IoAttachDeviceToDeviceStack函数把HelloWDM设备挂接到设备栈:

dx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);

//设置fdo的flags。有两个“位”是必须改变的,一个是必须清除DO_DEVICE_INITIALIZING标志,如果在DriverEntry例程中调用IoCreateDevice(),就不需要清除这个标志位。还有一个是必须设置DO_BUFFER_IO标志位:

fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;

fdo->Flags &= ~DO_DEVICE_INITIALIZING;

//返回值:

return STATUS_SUCCESS;

}

/***************************************************************

函数名称:HelloWDMPnp()

功能描述:处理“即插即用”消息

***************************************************************/

NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,

IN PIRP Irp)

{

//创建一个设备扩展对象dx,用于存储指向fdo的指针:

PDEVICE_EXTENSION dx=(PDEVICE_EXTENSION)fdo->DeviceExtension;

//首先要通过函数IoGetCurrentIrpStackLocation()得到当前的IRP,并由此得到Minor Function:

PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);

ULONG MinorFunction = IrpStack->MinorFunction;

//然后把这个Minor Function传递给下一个设备栈:

IoSkipCurrentIrpStackLocation(Irp);

NTSTATUS status = IoCallDriver( dx->NextStackDevice, Irp);

//处理“即插即用”次功能代码:

//当Minor Function等于IRP_MN_REMOVE_DEVICE时,说明有设备被拔出或卸下,这时要取消资源分配并删除设备:

if( MinorFunction==IRP_MN_REMOVE_DEVICE)

{

//取消设备接口:

IoSetDeviceInterfaceState(&dx->ifSymLinkName, FALSE);

RtlFreeUnicodeString(&dx->ifSymLinkName);

//调用IoDetachDevice()把fdo从设备栈中脱开:

if (dx->NextStackDevice)

IoDetachDevice(dx->NextStackDevice);

//删除fdo:

IoDeleteDevice(fdo);

}

//返回值:

return status;

}

/***************************************************************

程序名称:Hello World for WDM

文件名称:HelloWDM.h

作者:罗聪

日期:2002-8-16

***************************************************************/

//头文件,只是声明一些函数和变量,比较简单就不多说了,请读者自行研究:

#ifdef __cplusplus

extern "C"

{

#endif

#include "ntddk.h"

#ifdef __cplusplus

}

#endif

typedef struct _DEVICE_EXTENSION

{

PDEVICE_OBJECT fdo;

PDEVICE_OBJECT NextStackDevice;

UNICODE_STRING ifSymLinkName;

} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,

IN PDEVICE_OBJECT PhysicalDeviceObject);

NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,

IN PIRP Irp);

好了,第一个WDM版的“Hello World”就介绍到这里,虽然实际上它什么都没有做,但是由于它包含了完整的框架,所以对于初学者来说还是很有参考价值的。至于怎么编译及安装,留待下次再讲,敬请留意。(不是我想卖关子啊,这些步骤实在是很麻烦的,要另外写一篇文章才说得清楚哦!)

(来源:http://laoluoc.yeah.net)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有