IRP的理解
 
驱动程序与I/O管理器通信,使用的是IRP,即I/O请求包。IRP分为2部分:1)IRP首部;2)IRP堆栈。IRP首部信息如下:

IRP首部:
IO_STATUS_BLOCK IoStatus         包含I/O请求的状态
PVOID AssociatedIrp.SystemBuffer 如果执行缓冲区I/O,这个指针指向系统缓冲区
PMDL MdlAddress        如果直接I/O,这个指针指向用户缓冲区的存储器描述符表
PVOID UserBuffer        I/O缓冲区的用户空间地址

IRP堆栈:
UCHAR MajorFunction               指示IRP_MJ_XXX派遣例程
UCHAR MinorFunction               同上,一般文件系统和SCSI驱动程序使用它

union Parameters               MajorFunction的联合类型
{
struct Read                       IRP_MJ_READ的参数
ULONG Length
ULONG Key
LARGE_INTEGER ByteOffset

struct Write                      IRP_MJ_WRITE的参数
ULONG Length
ULONG Key
LARGE_INTEGER ByteOffset

struct DeviceIoControl            IRP_MJ_DEVICE_CONTROL参数
ULONG OutputBufferLength
ULONG InputBufferLength
ULONG IoControlCode
PVOID Type3InputBuffer

PDEVICE_OBJECT DeviceObject       请求的目标设备对象的指针
PFILE_OBJECT FileObject                请求的目标文件对象的指针,如果有的话
操作IRP。对于不同的IRP函数,操作也是不同的:有的只操作IRP首部;有的只操作IRP堆栈;还有操作IRP整体,下面是一些常用的函数:

IRP整体:

    名称                            描述                                   调用者
IoStartPacket             发送IRP到Start I/O例程              Dispatch
IoCompleteRequest     表示所有的处理完成                  DpcForIsr
IoStartNextPacket      发送下一个IRP到Start I/O例程     DpcForIsr
IoCallDriver                发送IRP请求                              Dispatch
IoAllocateIrp             请求另外的IRP                            Dispatch
IoFreeIrp                 释放驱动程序分配的IRP                I/O Completion

IRP堆栈:
    名称                                             描述                         调用者
IoGetCurrentIrpStackLocation   得到调用者堆栈的指针             Dispatch
IoMarkIrpPending              为进一步的处理标记调用者I/O堆栈  Dispatch
IoGetNextIrpStackLocation 得到下一个驱动程序的I/O堆栈的指针 Dispatch
IoSetNextIrpStackLocation      将I/O堆栈指针压入堆栈            Dispatc

在驱动程序,IRP派遣例程起着很重要的作用,每个IRP派遣例程,几乎都有对应的Win32函数,下面是几个常用的:

IRP派遣例程:

   名称                                      描述                           调用者
IRP_MJ_CREATE                   请求一个句柄                    CreateFile
IRP_MJ_CLEANUP            在关闭句柄时取消悬挂的IRP      CloseHandle
IRP_MJ_CLOSE                     关闭句柄                         CloseHandle
IRP_MJ_READ                      从设备得到数据                 ReadFile
IRP_MJ_WRITE                    传送数据到设备                 WriteFile
IRP_MJ_DEVICE_CONTROL    控制操作(利用IOCTL宏)   DeviceIoControl
IRP_MJ_INTERNAL_DEVICE_CONTROL  控制操作(只能被内核调用)       N/A
IRP_MJ_QUERY_INFORMATION    得到文件的长度             GetFileSize
IRP_MJ_SET_INFORMATION         设置文件的长度             SetFileSize
IRP_MJ_FLUSH_BUFFERS             写输出缓冲区或者丢弃输入缓冲区  FlushFileBuffers FlushConsoleInputBuffer PurgeComm
IRP_MJ_SHUTDOWN             系统关闭                     InitiateSystemShutdown