在微软的Windows 操作系统家族中,都通过发送I/O 请求包(IRP, I/o Request Packets)来进行
和驱动程序的通讯。用来封装IRP 的数据结构不仅仅用来描述一个I/O 操作的请求本身的内
容,还要用来维护这一请求在一系列驱动程序中传递的过程中的相关状态信息.。实现这一数
据结构其实是为了两重目的,也就是说IRP 可以被定义[理解]为:
一个放置I/O请求的容器
一个与线程无关的调用栈
操作系统以IRP 的形式进行绝大多数发给驱动程序的I/O 操作请求。因为下列特点,使得IRP
非常适合于这一目的:
IRP 设计来可以被异步操作
IRP 可以被在完成前取消
IRP 设计来适合于需要多驱动协同完成的输入输出操作
IRP数据结构封装了一个被请求的驱动所需要的,用来回复这一请求的“全部”信息,而请求则可能来自于用户模式或者内核模式,队友被请求的驱动程序,所需要的信息是一样的。
所有的IRP都包含有
一个用来描述主要I/O请求的头部 头部的数据尺寸是固定的,且所有IRP都相同
一组用来描述下级请求的参数 而下级请求数组的尺寸则依赖于会有多少个驱动要来操作这一请求。
IRP Header |
Parameters for sub-request |
Parameters for sub-request |
.. |
IRP头部的内容
一个IRP通常会被某个由一些驱动程序组成的栈来执行,每个IRP的头部信息,都各自包含着每个要操作这个IRP的驱动程序会使用的数据,当一个给定的驱动程序正在处理一个IRP时,这个驱动就被定义为此IRP的当前拥有者。
每一个IRP的头部,当包含有以下指针
指向针对这一IRP的用以读写输入以及写回输出的缓冲区,
指向当前拥有这一IRP的驱动程序的内存区域
指向一个由当前拥有这一IRP的驱动提供的例程,这一例程将由系统在IRP被取消后调用
指向当前子请求的参数