windows内核原理与实现笔记之IO请求包

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对象的设计特点:

  1. 所有的I/O请求都被抽象成针对文件对象的操作,OriginalFileObject 记录了该文件对象,代表一个I/O 请求的目标
  2. 栈单元。由于可能由多个驱动程序一次参与到一个I/O请求的处理过程中,所以,一个IRP对象出了以上列出的IRP数据结构,其后还有一个称为栈单元的数组。每个参与处理的驱动程序都可以有它自己的栈单元。
  3. 支持取消。线程可以指定一个取消例程,以便当I/O请求被取消时可以执行相关的动作。
  4. 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对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值