驱动程序开发学习(三)hello world
2012-05-08 09:23
281 查看
原帖地址:http://borland.mblogger.cn/doublefisher/posts/24513.aspx
驱动开发的例子里是没有所谓的“Hello World”程序的。这主要还是因为网络上的WDM资料太少造成的。但是程序的入口点呢?c语言有Main(),用Vc的常看见的是WinMain(),Delphi开发的是Program里的Begin,但是驱动开发呢?那也是应该有程序的入口点啊。后来我才明白了,那就是DriverEntry()函数。还有一个问题让我怀疑了老半天,那就是驱动开发的源程序中需不需要include头文件呀?为什么会怀疑呢?那是因为我看了半天的书都没有看到一个完整的驱动程序结构。真的是郁闷。下面是我看到的一个完整的结构,我先放上来,让大家看看驱动开发的结构吧。
驱动开发的例子里是没有所谓的“Hello World”程序的。这主要还是因为网络上的WDM资料太少造成的。但是程序的入口点呢?c语言有Main(),用Vc的常看见的是WinMain(),Delphi开发的是Program里的Begin,但是驱动开发呢?那也是应该有程序的入口点啊。后来我才明白了,那就是DriverEntry()函数。还有一个问题让我怀疑了老半天,那就是驱动开发的源程序中需不需要include头文件呀?为什么会怀疑呢?那是因为我看了半天的书都没有看到一个完整的驱动程序结构。真的是郁闷。下面是我看到的一个完整的结构,我先放上来,让大家看看驱动开发的结构吧。
/*************************************************************** 程序名称:Hello World for WDM 文件名称:HelloWDM.cpp 日期:2002-8-16 ***************************************************************/ //一定要的头文件,声明了函数模块和变量: #include "HelloWDM.h" /*************************************************************** 函数名称:DriverEntry() 功能描述:WDM程序入口(原来的WinMain被换成了DriverEntry,也是驱动程序的大门) 参数:IN PDRIVER_OBJECT DriverObject IN 是一个关键字表示这是一个输入参数,PDRIVER_OBJECT是一个数据结构的指针,就像PCHAR一样,这个数据结构是什么样子的,描述了一个驱动设备对象。 IN PUNICODE_STRING RegistryPath 指定了驱动程序注册表健的路径,因为驱动程序安装后总会在系统注册表里留下一点东西的。 返回值:NTSTATUS数据类型。上层的应用程序通过I/O请求包来告诉驱动程序,你要给我什么服务吧!IRP_MJ_PNP就是即插即用处理的请求。你发没发觉上面其实是在制造进入各个房间的“小门” ***************************************************************/ //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);
相关文章推荐
- 驱动程序开发学习(三)hello world
- <ARM嵌入式开发学习>我的第一个驱动程序-hello world
- Linux驱动开发学习 第一个驱动程序 hello world
- WinCE板级支持包开发学习之RTC驱动程序
- 驱动程序学习(一)从“hello world”开始
- 老手经验谈:Linux驱动程序开发学习步骤
- 从零开始学习Windows WDF驱动程序开发
- 驱动程序开发学习(四)编译
- Linux驱动程序开发学习步骤
- Windows驱动开发工具 WDK 学习笔记(1) 分类: windows驱动程序WDM 2013-08-01 11:08 566人阅读 评论(0) 收藏
- Linux设备驱动程序,个人学习,第一个模块hello world
- 跟着笨鸟一步一步学习spring开发(1 spring mvc 版hello world)
- 驱动程序开发学习-----20120414
- 【麦可网】Cocos2d-X跨平台游戏开发学习笔记---第五课:Hello World
- linux驱动学习(2)-第一个驱动程序hello world
- Windows驱动程序开发学习笔记(一) - 下载并安装WDK
- [转]MonoDroid学习之三:MonoDroid开发之Hello World
- [学习笔记]java基础Java8SE开发环境搭建、第一个Java Hello World、Java程序的编译与执行
- visual studio 2008 开发c++学习(二)--入门hello world程序
- 从零开始学习Windows WDF驱动程序开发