阅读:1036回复:1
帮助你理解代码:请看这个例子中的注释
这是我从别处搜索到罗聪先生的作品,对于那些读代码的朋友来说,这段代码的注释可以帮助你理解代码的作用:
转自老罗: WDM驱动程序入门(1)――HelloWDM 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”就介绍到这里,虽然实际上它什么都没有做,但是由于它包含了完整的框架,所以对于初学者来说还是很有参考价值的。至于怎么编译及安装,留待下次再讲,敬请留意。(不是我想卖关子啊,这些步骤实在是很麻烦的,要另外写一篇文章才说得清楚哦!) //************************************* |
|
最新喜欢:leavep... |
沙发#
发布于:2003-04-26 16:26
Good! :D
|
|
|