驱动程序打开别的驱动程序创建的Device的几种方法

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

驱动程序打开别的驱动程序创建的Device的几种方法
2010-09-03 20:44:40
标签:职场 程序 驱动 Device 休闲
1,最简单的也是最常用的应该是算ZwCreateFile,
跟应用程序API,CreateFile一样(其实CreateFile最终会调用ZwCreateFile,只不过一个事在应用层,一个是在内核层)来大打开一个设备,但是有一点不同,应用层当文件不存在时可以创建,但是ZwCreateFile仅仅是打开,不存在的时候就不创建(貌似跟这个名字不是很符合),打开方式有2中一种是同步打开,一种是异步打开!这个也跟应用层CreateFile一样不在累赘,打开设别后得到设备的句柄就可以读写该设备,也跟应用层读文件一样,ZwReadFile,或者ZwWriteFile,这2个函数会在目标设备创建相应的IRP,进行传递!同步打开的话没什么可以说的,会一直等到ZwReadFile/ZwWriteFile返回时才继续执行下去!异步打开的话就立即返回了,这里有2中方法来得到目标设备何时完成IRP,1是在跟应用程的ReadFile/WriteFile一样,他的其中一个参数是一个回调函数,当目标进程用IoCompleteRequest的时候会调用该回调函数,在回调函数设置事件,就可以得到何时结束IRP,比如:ZwReadFile(hDevice,NULL,CompleteRoutine,&event,&iostatus,NULL,0,&offset,NULL);再在次之前初始化event,事件为同步事件,CompleteRoutine是回调函数的地址,然后在回调函数中KeSetEvent((PKEVENT)context,IO_NO_INCREMENT,FALSE);就可以通知Read的Irp已经结束,WaitForSingleObject,阻塞消失!第二种方法是可以通过文件对象判断读取是否完成,打开一个设备会关联一个文件对象,利用ObReferenceObjectByHandle可以获得该文件对象指针。
2.通过符号链接打开设备,
符号链接是内核层与应用层的唯一识别路基。应用层想要打开设备,必须通过符号链接,同样内核层打开内核层设别也可以通过符号链接,可以利用ZwOpenSymbolicLinkObject函数得到符号链接句柄,然后使用ZwQuerySymbolicLinkObject得到设备名,有了设备名酒可以通过上面的方法打开设备。这里为什么要这样绕圈子呢,如果你是在应用层去控制一个驱动程序去打开另外一个驱动程序的时候,由于是应用层,是得不到那个驱动程序创建的设备名的,只能得到符号链接,这个时候就必须用这种方法。
3通过设备指针去调用其他驱动程序
可以用IoGetDeviceObjectPointer函数通过设别名获得文件对象,而不是设备句柄。调用IoGetDeviceObjectPointer会使文件对象引用计数增加1,用完后可以用ObDerefernceObject减少引用计数值。用这个函数打开的设备得到的是文件对象,所以不能再用ZwReadFile和ZwWriteFile函数去读写设备,这个时候需要自己创建IRP,创建Irp的函数大至有4个,IoBuildSynchronousFsdRequest,

IoBuildAsynchronousFsdRequest,IoBuildDeviceIoControlRequest,还有就是IoAllocateIrp!创建后调用IoGetNextIrpStackLocation,和IoCallDriver函数进行发送(这里有个问题,书上说IoCallDriver函数会使Irp堆栈向后移,必须用IoGetNextIrpStackLocation,IoSkipCurrentIrpStackLocation等函数使堆栈向前,我的理解是IoCallDriver函数需要的是下移个堆栈,因此需要这些函数)
4用ObReferenceObjectByName函数获得设备指针
ObReferenceObjectByName函数没有在DDK.h文件中声明,因此需要自己手动声明,同样用到的常量也学要手动声明,该函数可以得到设备对象的指针,他会增加设别对象的引用值,因此要用ObDereferenceObject减少引用值,

相关文档
最新文档