IRP Structure

发布时间:2014-5-9 19:11
分类名称:Driver


typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _IRP {

CSHORT Type;    // 一般为IO_TYPE_IRP(0x00000006)

USHORT Size;    // IRP + 和其对应的I/0堆栈的总大小,分配IRP的时候,它们就是一起在堆上分配的空间,所以IRP下面就是I/O堆栈

 

//

// Define the common fields used to control the IRP.

//

 

//

// Define a pointer to the Memory Descriptor List (MDL) for this I/O

// request. This field is only used if the I/O is "direct I/O".

//

 

PMDL MdlAddress;

 

//

// Flags word - used to remember various flags.

//

 

ULONG Flags;

 

//

// The following union is used for one of three purposes:

//

// 1. This IRP is an associated IRP. The field is a pointer to a master

// IRP.

//

// 2. This is the master IRP. The field is the count of the number of

// IRPs which must complete (associated IRPs) before the master can

// complete.

//

// 3. This operation is being buffered and the field is the address of

// the system space buffer.

//

 

union {

struct _IRP *MasterIrp;

__volatile LONG IrpCount;

PVOID SystemBuffer;

} AssociatedIrp;

 

//

// Thread list entry - allows queueing the IRP to the thread pending I/O

// request packet list.

//

 

LIST_ENTRY ThreadListEntry;

 

//

// I/O status - final status of operation.

//

 

IO_STATUS_BLOCK IoStatus;

 

//

// Requestor mode - mode of the original requestor of this operation.

//

 

KPROCESSOR_MODE RequestorMode;

 

//

// Pending returned - TRUE if pending was initially returned as the

// status for this packet.

//

 

// 在IoComplateRequest函数中,有一句:Irp->PendingReturned = stackPointer->Control & SL_PENDING_RETURNED;

// 在回弹完成函数时,如果stackPointer->Control(IoMarkIrpPending可设置)有SL_PENDING_RETURNED,会将其保存到Irp->PendingReturned

// 在完成函数中判断Irp->PendingReturned,继续调用IoMarkIrpPending,向上传递。

BOOLEAN PendingReturned;    

 

//

// Stack state information.

//

 

CHAR StackCount;        // 和 Device->StackSize 大小一样

CHAR CurrentLocation;    // 当前Location,初始值为StackCount大小加1,用来和StackCount+1对比,是否到达最上层

 

//

// Cancel - packet has been canceled.

//

// 当IRP被取消时,会被设置为FALSE。如在,IoCancelIrp中被设置为TRUE。

BOOLEAN Cancel;

 

//

// Cancel Irql - Irql at which the cancel spinlock was acquired.

//

// IoAcquireCancelSpinLock得到锁后的IRQL

KIRQL CancelIrql;

 

//

// ApcEnvironment - Used to save the APC environment at the time that the

// packet was initialized.

//

 

CCHAR ApcEnvironment;

 

//

// Allocation control flags.

//

 

UCHAR AllocationFlags;

 

//

// User parameters.

//

 

PIO_STATUS_BLOCK UserIosb;

PKEVENT UserEvent;            // 保存用户层传递的Evnet(如ReadFile异步调用时)

union {

struct {

union {

PIO_APC_ROUTINE UserApcRoutine;    // 用户层传递的,APC 异步调用函数

PVOID IssuingProcess;

};

PVOID UserApcContext;                // APC 参数

} AsynchronousParameters;    // APC异步调用参数

LARGE_INTEGER AllocationSize;

} Overlay;    //通过名字可以和用户层对应起来,都是Overlay。

 

//

// CancelRoutine - Used to contain the address of a cancel routine supplied

// by a device driver when the IRP is in a cancelable state.

//

// IRP取消的时候会被调用

__volatile PDRIVER_CANCEL CancelRoutine;

 

//

// Note that the UserBuffer parameter is outside of the stack so that I/O

// completion can copy data back into the user's address space without

// having to know exactly which service was being invoked. The length

// of the copy is stored in the second half of the I/O status block. If

// the UserBuffer field is NULL, then no copy is performed.

//

 

PVOID UserBuffer;

 

//

// Kernel structures

//

// The following section contains kernel structures which the IRP needs

// in order to place various work information in kernel controller system

// queues. Because the size and alignment cannot be controlled, they are

// placed here at the end so they just hang off and do not affect the

// alignment of other fields in the IRP.

//

 

union {

 

struct {

 

union {

 

//

// DeviceQueueEntry - The device queue entry field is used to

// queue the IRP to the device driver device queue.

//

// KeInsertDeviceQueue( &DeviceObject->DeviceQueue, &Irp->Tail.Overlay.DeviceQueueEntry );

// 将IRP和DeviceObject连接起来,使用在StartIO串行方式中。

KDEVICE_QUEUE_ENTRY DeviceQueueEntry;

 

struct {

 

//

// The following are available to the driver to use in

// whatever manner is desired, while the driver owns the

// packet.

//

 

PVOID DriverContext[4];

 

} ;

 

} ;

 

//

// Thread - pointer to caller's Thread Control Block.

//

// PsGetCurrentThread

PETHREAD Thread;

 

//

// Auxiliary buffer - pointer to any auxiliary buffer that is

// required to pass information to a driver that is not contained

// in a normal buffer.

//

 

PCHAR AuxiliaryBuffer;

 

//

// The following unnamed structure must be exactly identical

// to the unnamed structure used in the minipacket header used

// for completion queue entries.

//

 

struct {

 

//

// List entry - used to queue the packet to completion queue, among

// others.

//

 

LIST_ENTRY ListEntry;

 

union {

 

//

// Current stack location - contains a pointer to the current

// IO_STACK_LOCATION structure in the IRP stack. This field

// should never be directly accessed by drivers. They should

// use the standard functions.

//

 

struct _IO_STACK_LOCATION *CurrentStackLocation;

 

//

// Minipacket type.

//

 

ULONG PacketType;

};

};

 

//

// Original file object - pointer to the original file object

// that was used to open the file. This field is owned by the

// I/O system and should not be used by any other drivers.

//

 

PFILE_OBJECT OriginalFileObject;

 

} Overlay;

 

//

// APC - This APC control block is used for the special kernel APC as

// well as for the caller's APC, if one was specified in the original

// argument list. If so, then the APC is reused for the normal APC for

// whatever mode the caller was in and the "special" routine that is

// invoked before the APC gets control simply deallocates the IRP.

//

 

KAPC Apc;

 

//

// CompletionKey - This is the key that is used to distinguish

// individual I/O operations initiated on a single file handle.

//

 

PVOID CompletionKey;

 

} Tail;

 

} IRP;