IRP是I/O request packet的缩写,即I/O请求包。驱动与驱动之间通过IRP进行通信。而使用驱动的应用层调用的CreatFile,ReadFile,WriteFile,DeviceIoControl等函数,说到底也是使用IRP和驱动进行通信。
一个IRP由两部分组成。首先是头部或者叫包的固定部分,是一个IRP结构。紧跟在这个头部之后的是I/O stack locations ,这是一个IO_STACK_LOCATION结构的数组,这个数组中元素的个数是根据情况而定的,由IoAllocateIrp( IN CCHAR StackSize , IN BOOLEAN ChargeQuota ) 时的参数StackSize决定。而StackSize通常由IRP发往的目标DEVICE_OBJECT的 +30 char StackSize决定。而这个StackSize是由设备对象连入所在的设备栈时,根据在设备栈中位置决定的。我们先看看IRP结构和IO_STACK_LOCATION结构的定义。
IRP结构定义如下
struct _IRP (sizeof=112)
+00 int16 Type
+02 uint16 Size
+04 struct _MDL *MdlAddress
+08 uint32 Flags
+0c union __unnamed14 AssociatedIrp
+0c struct _IRP *MasterIrp
+0c int32 IrpCount
+0c void *SystemBuffer
+10 struct _LIST_ENTRY ThreadListEntry
+10 struct _LIST_ENTRY *Flink
+14 struct _LIST_ENTRY *Blink
+18 struct _IO_STATUS_BLOCK IoStatus
+18 int32 Status
+18 void *Pointer
+1c uint32 Information
+20 char RequestorMode
+21 byte PendingReturned
+22 char StackCount
+23 char CurrentLocation
+24 byte Cancel
+25 byte CancelIrql
+26 char ApcEnvironment
+27 byte AllocationFlags
+28 struct _IO_STATUS_BLOCK *UserIosb
+2c struct _KEVENT *UserEvent
+30 union __unnamed15 Overlay
+30 struct __unnamed16 AsynchronousParameters
+30 function *UserApcRoutine
+34 void *UserApcContext
+30 union _LARGE_INTEGER AllocationSize
+30 uint32 LowPart
+34 int32 HighPart
+30 struct __unnamed3 u
+30 uint32 LowPart
+34 int32 HighPart
+30 int64 QuadPart
+38 function *CancelRoutine
+3c void *UserBuffer
+40 union __unnamed17 Tail
+40 struct __unnamed18 Overlay
+40 struct _KDEVICE_QUEUE_ENTRY DeviceQueueEntry
+40 struct _LIST_ENTRY DeviceListEntry
+40 struct _LIST_ENTRY *Flink
+44 struct _LIST_ENTRY *Blink
+48 uint32 SortKey
+4c byte Inserted
+40 void *DriverContext[4]
+50 struct _ETHREAD *Thread
+54 char *AuxiliaryBuffer
+58 struct _LIST_ENTRY ListEntry
+58 struct _LIST_ENTRY *Flink
+5c struct _LIST_ENTRY *Blink
+60 struct _IO_STACK_LOCATION *CurrentStackLocation
+60 uint32 PacketType
+64 struct _FILE_OBJECT *OriginalFileObject
+40 struct _KAPC Apc
一个IRP由两部分组成。首先是头部或者叫包的固定部分,是一个IRP结构。紧跟在这个头部之后的是I/O stack locations ,这是一个IO_STACK_LOCATION结构的数组,这个数组中元素的个数是根据情况而定的,由IoAllocateIrp( IN CCHAR StackSize , IN BOOLEAN ChargeQuota ) 时的参数StackSize决定。而StackSize通常由IRP发往的目标DEVICE_OBJECT的 +30 char StackSize决定。而这个StackSize是由设备对象连入所在的设备栈时,根据在设备栈中位置决定的。我们先看看IRP结构和IO_STACK_LOCATION结构的定义。
IRP结构定义如下
struct _IRP (sizeof=112)
+00 int16 Type
+02 uint16 Size
+04 struct _MDL *MdlAddress
+08 uint32 Flags
+0c union __unnamed14 AssociatedIrp
+0c struct _IRP *MasterIrp
+0c int32 IrpCount
+0c void *SystemBuffer
+10 struct _LIST_ENTRY ThreadListEntry
+10 struct _LIST_ENTRY *Flink
+14 struct _LIST_ENTRY *Blink
+18 struct _IO_STATUS_BLOCK IoStatus
+18 int32 Status
+18 void *Pointer
+1c uint32 Information
+20 char RequestorMode
+21 byte PendingReturned
+22 char StackCount
+23 char CurrentLocation
+24 byte Cancel
+25 byte CancelIrql
+26 char ApcEnvironment
+27 byte AllocationFlags
+28 struct _IO_STATUS_BLOCK *UserIosb
+2c struct _KEVENT *UserEvent
+30 union __unnamed15 Overlay
+30 struct __unnamed16 AsynchronousParameters
+30 function *UserApcRoutine
+34 void *UserApcContext
+30 union _LARGE_INTEGER AllocationSize
+30 uint32 LowPart
+34 int32 HighPart
+30 struct __unnamed3 u
+30 uint32 LowPart
+34 int32 HighPart
+30 int64 QuadPart
+38 function *CancelRoutine
+3c void *UserBuffer
+40 union __unnamed17 Tail
+40 struct __unnamed18 Overlay
+40 struct _KDEVICE_QUEUE_ENTRY DeviceQueueEntry
+40 struct _LIST_ENTRY DeviceListEntry
+40 struct _LIST_ENTRY *Flink
+44 struct _LIST_ENTRY *Blink
+48 uint32 SortKey
+4c byte Inserted
+40 void *DriverContext[4]
+50 struct _ETHREAD *Thread
+54 char *AuxiliaryBuffer
+58 struct _LIST_ENTRY ListEntry
+58 struct _LIST_ENTRY *Flink
+5c struct _LIST_ENTRY *Blink
+60 struct _IO_STACK_LOCATION *CurrentStackLocation
+60 uint32 PacketType
+64 struct _FILE_OBJECT *OriginalFileObject
+40 struct _KAPC Apc