Windows驅動開發-IRP結構體


IRP的全名是I/O Request Package,即輸入輸出請求包,它是Windows內核中的一種非常重要的數據結構。

上層應用程序與底層驅動程序通信時,應用程序會發出I/O請求,操作系統將相應的I/O請求轉換成相應的IRP,不同的IRP會根據類型被分派到不同的派遣例程中進行處理。

IRP有兩個基本的屬性,即MajorFunctionMinorFunction,分別記錄IRP的主類型和子類型。

操作系統根據MajorFunction決定將IRP分發到哪個派遣例程,然后派遣例程根據MinorFunction進行細分處理。

沒有設置派遣函數的IRP,默認與IopInvalidDeviceRequest函數關聯

IRP結構體源碼

typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _IRP {
    CSHORT Type;
    USHORT Size;
    PMDL MdlAddress;
    ULONG Flags;
    union {
        struct _IRP *MasterIrp;
        __volatile LONG IrpCount;
        PVOID SystemBuffer;
    } AssociatedIrp;
    LIST_ENTRY ThreadListEntry;
    IO_STATUS_BLOCK IoStatus;
    KPROCESSOR_MODE RequestorMode;
    BOOLEAN PendingReturned;
    CHAR StackCount;
    CHAR CurrentLocation;
    BOOLEAN Cancel;
    KIRQL CancelIrql;
    CCHAR ApcEnvironment;
    UCHAR AllocationFlags;
    PIO_STATUS_BLOCK UserIosb;
    PKEVENT UserEvent;
    union {
        struct {
            union {
                PIO_APC_ROUTINE UserApcRoutine;
                PVOID IssuingProcess;
            };
            PVOID UserApcContext;
        } AsynchronousParameters;
        LARGE_INTEGER AllocationSize;
    } Overlay;
    __volatile PDRIVER_CANCEL CancelRoutine;
    PVOID UserBuffer;
    union {
        struct {
            union {
                KDEVICE_QUEUE_ENTRY DeviceQueueEntry;
                struct {
                    PVOID DriverContext[4];
                } ;
            } ;
            PETHREAD Thread;
            PCHAR AuxiliaryBuffer;
            struct {
                LIST_ENTRY ListEntry;
                union {
                    struct _IO_STACK_LOCATION *CurrentStackLocation;
                    ULONG PacketType;
                };
            };
            PFILE_OBJECT OriginalFileObject;
        } Overlay;
        KAPC Apc;
        PVOID CompletionKey;
    } Tail;

} IRP;

 驅動程序會創建一個個的設備對象,並將這些設備對象“疊”成一個垂直結構,這種垂直的結構很像棧,因此叫做“設備棧”
IRP會被操作系統發送到設備棧的頂層,如果頂層的設備對象的派遣函數結束了IRP的請求,則這次I/O請求結束,如果沒有
將IRP請求結束,那么操作系統將IRP轉發到設備棧的下一層設備處理,如果這個設備的派遣函數依然不能結束IRP請求,則
會繼續向更下層設備轉發,
因此,一個IRP請求可能被轉發多次,為了記錄IRP在每層設備中做的操作,IRP會有個IO_STACK_LOCATION數組,數組的元素個數
應該大於IRP穿過的設備數目,對於本層設備對應的IO_STACK_LOCATION,可以通過IoGetCurrentIrpStackLocation函數得到


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM