IRP 定義:
typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _IRP {
CSHORT Type;
USHORT Size;
PMDL MdlAddress;//該I/O請求的使用者緩沖區的MDL,僅用于“直接I/O”類型
ULONG Flags;//用于記錄各種标志
union {
struct _IRP *MasterIrp;//若這是一個關聯IRP,則指向主IRP
LONG IrpCount;//若這是一個主IRP,則必須先完成多少個關聯IRP
PVOID SystemBuffer;//該操作被緩沖起來,指向系統位址空間緩沖區的位址
} AssociatedIrp;
LIST_ENTRY ThreadListEntry;//連結清單向,可以加入到線程的未完成的I/O請求連結清單中
IO_STATUS_BLOCK IoStatus;//I/O操作的狀态
KPROCESSOR_MODE RequestorMode;//核心模式I/O請求或使用者模式I/O請求
BOOLEAN PendingReturned;//未完成傳回
CHAR StackCount;//棧單元計數
CHAR CurrentLocation;//目前棧單元位置
BOOLEAN Cancel;//該I/O請求是否已被取消
KIRQL CancelIrql;//取消自旋鎖在哪級IROQ上被擷取
CCHAR ApcEnvironment;//用于當該IRP被初始化時儲存APC環境
UCHAR AllocationFlags;//該IRP記憶體的配置設定控制狀态
PIO_STATUS_BLOCK UserIosb;//使用者的I/O狀态塊
PKEVENT UserEvent;//使用者事件對象
union {
struct {
PIO_APC_ROUTINE UserApcRoutine;//當I/O請求完成時指向的APC例程
PVOID UserApcContext;//傳遞UserApcRoutine的環境參數
} AsynchronousParameters;
LARGE_INTEGER AllocationSize;//配置設定塊的大小
} Overlay;
PDRIVER_CANCEL CancelRoutine;//若是可取消的I/O請求,該域包含了取消時調用的例程
PVOID UserBuffer;//調用者(即發起者)提供的輸出緩沖區的位址
//以下Tail聯合成員用于當I/O管理器處理該I/O請求時存放各種工作資訊
union {
struct {
union {
KDEVICE_QUEUE_ENTRY DeviceQueueEntry;//裝置隊列項
struct {
PVOID DriverContext[4];//由驅動程式解釋和使用
} ;
} ;
PETHREAD Thread;//指向發起者線程的ETHREAD
PCHAR AuxiliaryBuffer;//輔助緩沖區
struct {
LIST_ENTRY ListEntry;//存放到完成隊列中的連結清單項
union {
struct _IO_STACK_LOCATION *CurrentStackLocation;//指向目前棧單元,驅動程式不可直接通路
ULONG PacketType;//Minipacket 的類型
};
};
PFILE_OBJECT OriginalFileObject;//指向原始的檔案對象
} Overlay;
KAPC Apc;//特殊核心模式APC或發起者的APC
PVOID CompletionKey;//完成鍵,用于辨別在不同檔案句柄上的I/O請求
} Tail;
} IRP, *PIRP;
IRP對象從一個I/O請求被發起時開始存在,一直到該I/O請求被完成或者取消為止。
IRP對象的設計特點:
- 所有的I/O請求都被抽象成針對檔案對象的操作,OriginalFileObject 記錄了該檔案對象,代表一個I/O 請求的目标
- 棧單元。由于可能由多個驅動程式一次參與到一個I/O請求的處理過程中,是以,一個IRP對象出了以上列出的IRP資料結構,其後還有一個稱為棧單元的數組。每個參與處理的驅動程式都可以有它自己的棧單元。
- 支援取消。線程可以指定一個取消例程,以便當I/O請求被取消時可以執行相關的動作。
- I/O請求的完成。當一個驅動程式的分發例程認為它已經完成了該I/O請求時,會顯式的告訴I/O管理器,此I/O請求已完成。
棧單元IO_STACK_LOCATION 定義:
typedef struct _IO_STACK_LOCATION {
UCHAR MajorFunction;//在該裝置對象上的I/O請求主功能碼
UCHAR MinorFunction; //在該裝置對象上的I/O請求次功能碼
UCHAR Flags;
UCHAR Control;
union {
struct {...} Create; //NtCreateFile 的參數
struct {...} CreatePipe;// NtCreaeNamedPipeFile 的參數
struct {...} CreateMailslot;// NtCreateMailslotFile 的參數
struct {...} Read;// NtReadFile 的參數
struct {...} Write;// NtWriteFile 的參數
struct {...} QueryDirectory;// NtQueryDirectory 的參數
struct {...} NotifyDirectory;// NtNotifyChangeDirectroyFile的參數
struct {...} QueryFile;// NtQueryInformationFile 的參數
struct {...} SetFile;// NtSetInformationFile 的參數
struct {...} QueryEa;// NtQueryEaFile 的參數
struct {...} SetEa;//NtSetEaFile 的參數
struct {...} QueryVolume;// NtQueryvolumeInformationFile 的參數
struct {...} SetVolume;// NtSetvolumeInformationFile 的參數
struct {...} FileSystemControl;// NtFsControlFile 的參數
struct {...} LockControl;// NtLock/NtUnlockFile 的參數
//NtFlushBuffersFile的參數
//NtCancelIoFile的參數
struct {...} DeviceIoControl;//NtDeviceIoControFile的參數
struct {...} QuerySecurity;// NtQuerySecurityObject 的參數
struct {...} SetSecurity;// NtSetSecurityObject 的參數
struct {...} MountVolume;// MountVolume的參數
struct {...} VerifyVolume;// VerifyVolume的參數
struct {...} Scsi;//SCSI 内部裝置控制的參數
struct {...} QueryQuota;// NtQueryQuotaInformationFile 的參數
struct {...} SetQuota;//NtSetQuotaInformationFile 的參數
struct {...} QueryDeviceRelations;//IRP_MN_QUERY_DEVICE_RELATIONS的參數
struct {...} QueryInterface;//IRP_MN_QUERY_INTERFACE的參數
struct {...} DeviceCapabilities;//IRP_MN_QUERY_CAPABILITIES的參數
struct {...} FilterResourceRequirements;
//IRP_MN_FILTER_RESOURCE_REQUITEMENTS的參數
struct {...} ReadWriteConfig;//IRP_MN_READ_CONFIG和IRP_MN_WRITE_CONFIG的參數
struct {...} SetLock;//IRP_MN_SET_LOCK 的參數
struct {...} QueryId;//IRP_MN_QUERY_ID的參數
struct {...} QueryDeviceText;//IRP_MN_QUERY_DEVICE_TEXT的參數
struct {...} UsageNotification;//IRP_MN_DEVICE_USAGE_NOTIFICATION的參數
struct {...} WaitWake;//IRP_MN_WAIT_WAKE的參數
struct {...} PowerSequence;//IRP_MN_POWER_SEQUENCE的參數
struct {...} Power;//IRP_MN_SET_POWER、IRP_MN_QUERY_POWER的參數
struct {...} StartDevice;//StartDevice 的參數、Cleanup的參數
struct {...} WMI;//WMI IRP的參數
struct {...} Others;//其他,由驅動程式自己定義和解釋
} Parameters;
PDEVICE_OBJECT DeviceObject;
PFILE_OBJECT FileObject;
PIO_COMPLETION_ROUTINE CompletionRoutine;
PVOID Context;
} IO_STACK_LOCATION, *PIO_STACK_LOCATION;
Control 域包含了棧單元的控制标志,該域對驅動程式是隻讀的,請參考宏定義
#define SL_PENDING_RETURNED 0x01
#define SL_ERROR_RETURNED 0x02
#define SL_INVOKE_ON_CANCEL 0x20
#define SL_INVOKE_ON_SUCCESS 0x40
#define SL_INVOKE_ON_ERROR 0x80
DeviceObject :指向與該棧單元相對應的裝置對象
FileObject: 指向與DeviceObject相關聯的檔案對象
CompletionRoutine:是該棧單元對應的驅動程式通過IoSetCompletionRoutine設定的完成例程
Context :由驅動程式指定的、傳遞給CompletionRoutine 的參數
IRP與檔案對象、裝置對象和驅動程式之間的關系,如下圖:

IRP對象是通過IoAllocateIrp 配置設定的,IoAllocateIrp 轉發給pIoAllocateIrp 函數指針。pIoAllocateIrp 在初始化時指向IopAllocateIrpPrivate。是以,IRP對象實際是在IopAllocateIrpPrivate 完成的,通過IopFreeIrp 釋放IRP對象。