派遣函数收到irp怎么区分io的微信发起投票者

下次自动登录
现在的位置:
& 综合 & 正文
IRP与派遣函数
由于IRP与派遣函数这一个概念十分重要,很多历程中都会用到,所以先讲下这个概念。
派遣函数是windows驱动中的重要概念。驱动程序的主要功能是负责处理I/O请求,其中大部分I/O请求是在派遣函数中处理的
用户模式下所有对驱动程序的I/O请求,全部由操作系统转化为一个叫做IRP的数据结构。
不同的IRP数据会被“派遣”到不同的派遣函数
IRP的处理机制雷伊windows应用程序中的“消息处理”机制
驱动程序接收到不同的IRP后,会进入不同的派遣函数,在派遣函数中IRP得到处理
在windows内核中,有一种数据结构叫做IRP,即输入输出请求包。它是与输入输出相关的重要数据结构。
上层应用程序与底层驱动程序通信时,应用程序会发出I/O请求。
操作系统将I/O请求转化为相应的IRP数据,不同类型的IRP会根据类型传递到不同的派遣函数内
IRP是一个很复杂的数据结构。
在这里,先了解IRP的两个基本属性:MajorFunction,MinorFunction,分别记录IRP的主类型和子类型
操作系统根据MajorFunction将IRP“派遣”到不同的派遣函数中,在派遣函数中还可以继续判断这个IRP属于那种MinorFunction
一般来说,NT式驱动程序和WDM驱动程序都是在DriverEntry函数中注册派遣函数
以下是某DDK驱动中的DriverEntry片段
#pragma INITCODE
extern "C" NTSTATUS DriverEntry(
IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegistryPath )
KdPrint(("Enter DriverEntry\n"));
pDriverObject -& DriverUnload = HelloDDKU
pDriverObject -& MajorFunction[ IRP_MJ_CREATE ] = HelloDDKDispatchR
pDriverObject -& MajorFunction[ IRP_MJ_CLOSE ] = HelloDDKDispatchR
pDriverObject -& MajorFunction[ IRP_MJ_WRITE ] = HelloDDKDispatchR
pDriverObject -& MajorFunction[ IRP_MJ_READ ] = HelloDDKDispatchR
status = CreateDevice( pDriverObject );
KdPrint(("DriverEntry end\n"));
在DriverEntry的驱动对象pDriverObject中,有个函数指针数组MajorFunction。
函数指针数组是个数组,每个元素都记录着一个函数的地址
通过这个数据,可以将IRP的类型和派遣函数联系起来。
在上个例子中,只对四中类型的IRP设置了派遣函数,而IRP的类型不只四中。
对于其他没有设置的IRP类型 MajorFunction数组,系统默认这些IRP类型与_IopInvalidDeviceRequest函数关联
在进入DriverEntry之前,操作系统会将_IopInvalidDeviceRequest的地址填满整个MajorFunction数组
IRP的概念类似windows应用程序中“消息”的概念。在win32编程中,程序是由“消息”驱动的。不同的消息,会被分发到不同的消息处理函数中
如果没有对应的处理函数,它会进入到系统默认的新消息处理函数中
IRP的处理类似这种方式。文件I/O的相关函数,如CreateFile、ReadFile、WriteFile、CloseHandle等函数会使操作系统产生出IRP_MJ_CREATE
IRP_MJ_READ
IRP_MJ_WRITE
IRP_MJ_CLOSE等不同的IRP,这些IRP会被传送到驱动程序的派遣函数中
另外,内核中的文件I/O处理函数,如ZwCreateFile
ZwReadFile
ZwWriteFile
ZwClose,它们同样会创建相应的IRP_MJ_CREATE
IRP_MJ_READ
IRP_MJ_WRITE
IRP_MJ_CLOSE等IRP,并将IRP传送到相应驱动的派遣函数中
还有些IRP是由系统的某个组件创建的,比如IRP_MJ_SHUTDOWN是在windows的即插即用组件在即将关闭系统的时候发出的。
下面列出了一些IRP的类型,并对其产生的来源做了说明
IRP_MJ_CREATE
//创建设备,CraeteFile会产生此IRP
IRP_MJ_CLOSE
//关闭设备,CloseFile会产生此IRP
IRP_MJ_CLEANUP
//清除工作,CloseFile会产生此IRP
IRP_MJ_DIRECTORY_CONTROL
//DeviceControl函数会产生此IRP
IRP_MJ_PNP
//即插即用消息,NT驱动不支持此种IRP,WDM支持
IRP_MJ_POWER
//在操作系统处理电源消息时,产生此IRP
IRP_MJ_QUERY_INFORMATION
//获取文件长度,GetFileSize会产生此IRP
IRP_MJ_READ
//读取设备内容,ReadFile会产生此IRP
IRP_MJ_SET_INFORMATION
//设置文件长度,GetFileSize会产生此IRP
IRP_MJ_SHUTDOWN
//关闭系统前会产生此IRP
IRP_MJ_SYSTEM_CONTROL
//系统内部产生的控制信息,类似于内核调用DeviceIoControl
IRP_MJ_WRITE
//对设备进行WriteFile时产生此IRP
对派遣函数的简单处理
大部分的IRP都源于文件I/O处理Win32 API,如CreateFile、ReadFile等。
处理这些IRP最贱的方法是在相应的派遣函数中,将IRP的状态设置为成功,然后结束IRP请求,并让派遣函数返回成功。
结束IRP的请求使用IoCompleteRequest
下面的代码演示了一种最简单的处理IRP请求的派遣函数
#pragma PAGEDCODE
NTSTATUS HelloDDKDispatchRoutine( IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp )
KdPrint(("Enter HelloDDKDispatchRoutine\n"));
NTSTATUS status = STATUS_SUCCESS;
pIrp -& IoStatus.Status = //设置IRP的状态为成功
pIrp -& rmation = 0; //bytes xfered 设置操作的字节数为0,无实际意义
IoCompleteRequest( pIrp, IO_NO_INCREMENT ); //指示完成此IRP
KdPrint(("Leave HelloDDKDispatchRoutine\n"));
//成功返回
在本例中,派遣函数设置了IRP的完成状态为STATUS_SUCCESS
这样,发起I/O请求的Win32 API(如WriteFile)将会返回TRUE。
相反如果将IRP的完成状态设置为不成功,这是发起I/O请求的Win32 API(如WriteFile)将会返回FALSE
这种情况时,可以使用GetLastError Win32 API得到错误代码。所得的错误代码会和IRP设置的状态一样
除了设置IRP的完成状态,派遣函数还要设置这个IRP请求操作了多少字节。
在本例中,将做操字节数简单的设置为0.
若果是ReadFile产生的IRP,这个字节数代表从设备读取了多少字节。
若果是WriteFile产生的IRP,这个字节数代表对设备写了多少字节。
最后,派遣函数将IRP请求结束,这是通过IoCompeteRequest函数完成。
IoCompeteRequest声明如下:
VOID IoCompleteRequest( IN PIRO Irp, IN CCHAR PriorityBoost );
Irp:代表需要被结束的IRP
PriorityBoost:代表线程恢复时的优先级别
&&&&推荐文章:
【上篇】【下篇】内核(20)
1.派遣函数是WINDOWS驱动程序中的重要概念。驱动程序的主要功能是负责处理I/O请求,其中大部分I/O请求时在派遣函数中处理的。
2.用户模式下所有驱动程序的I/O请求,全部由操作系统化为一个叫做IRP的数据结构,不同的IRP数据会被“派遣”到不同的派遣函数(Dispatch Functin )中,这也是派遣函数名字的由来。
3.IRP的处理机制类似Windows应用程序的“消息处理”机制,驱动程序接收到不同的类型的IRP后,会进入不同的派遣函数,在派遣函数中IRP得到处理。
4.IRP是一个很复杂的数据结构,IRP两个基本的属性,一个是MajorFunction,另一个是MinorFunction,分别记录IRP的主类型和子类型。操作系统根据MajorFunction将IRP“派遣”到不同的派遣函数中,在派遣函数中还可以这个IRP属于哪种MinorFunction
5.DriverEntry有个函数指针数组MajorFunction.都是派遣函数地址。对于没有设置IRP类型,系统默认这些IRP类型与_IopInvalidDeviceRequest函数关联。还有些IRP是由系统的某个组件创建的。
6.下表列出了IRP的类型,并对其产生的来源做了说明。
7.应用程序和驱动程序有3中通信方式
1.DO_BUFFER_IO
2.DO_DIRECT_IO
8.在使用第3种读写设备时,派遣函数直接读写应用程序提供的缓冲区地址。ReadFile,WriteFile提供的缓冲区内存地址,可以在派遣函数中通过IRP的UserBuffer字段得到。
9.除了用ReadFile和WriteFile以外,应用程序还可以通过另外一个DeviceIoControl操作设备。DeviceIoControl内部会使用操作系统创建IRP_MJ_DEVICE_CONTROL类型的IRP,然后操作系统会将这个IRP转发到派遣函数中。它可以让应用程序和驱动程序进行通信。
10.通信必备参数:输入,输出地址,MDL结构(直接)
11.IO_STACK_LOCATION &即I/O堆栈,这个数据结构和IRP紧密相连。当IRP可能在设备栈中转发多次,为了记录IRP在每层设备中做的操作,IRP会有个IO_STACK_LOCATION数组。每个IO_STACK_LOCATION元素记录着对应设备中做的操作。对于本层可以通过IoGetCurrentIrpStackLocation函数得到。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:22301次
排名:千里之外
原创:51篇
转载:23篇
(1)(2)(3)(2)(1)(25)(27)(1)(3)(9)【图文】irp请求包_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
上传于||文档简介
&&驱​动​设​计​i​r​p​请​求​包​简​介
大小:80.00KB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢IRP 工作流程以及原理_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
IRP 工作流程以及原理
上传于||暂无简介
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
你可能喜欢}

我要回帖

更多关于 男子发起诚信挑战 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信