Go to My Blog
Go to Lin's Blog

Windows IRP

IRP(I/O Request Packet),是由IO manager发起的对device的IO请求。

当用户调用系统API,如createFile类似的函数,其实是会交给IO manager来做相应的处理。

首先IO Manager知道这次IO请求,涉及到的设备栈(Device Stack),每个Device都有相应的Driver。

IO Manager然后会组一个IRP的结构,包括IRP头,以及紧随其后的IO_STACK_LOCATION结构体数组。

相当于:

typedef struct _IRP{
 struct IRP_HEADER irpHeader;
 ...
 IO_STACK_LOCATION ioStack[];
 ...
}

irpHeader有不少有用的信息,如:SystemBuffer,StackCount,CurrentLocation,Flags...

其中成员StackCount指定IO_STACK_LOCATION数组的个数,其实就是Device Stack里面每个device都会被分配一个IO_STACK_LOCATION。

typedef struct _IO_STACK_LOCATION {
  UCHAR  MajorFunction;
  UCHAR  MinorFunction;
  UCHAR  Flags;
  UCHAR  Control;
  union {
        // Parameters for IRP_MJ_CREATE 
        struct {
            PIO_SECURITY_CONTEXT  SecurityContext;
            ULONG  Options;
            USHORT POINTER_ALIGNMENT  FileAttributes;
            USHORT  ShareAccess;
            ULONG POINTER_ALIGNMENT  EaLength;
        } Create;
        ...
    } Parameters;
  PDEVICE_OBJECT  DeviceObject;
  PFILE_OBJECT  FileObject;
  .
} IO_STACK_LOCATION, *PIO_STACK_LOCATION;

IO_STACK_LOCATON会有不少Input Parameter,如MajorFunction,MinorFunction...等,这些parameter是由上级device帮忙配置好的。

一般的流程就是,这级的device对应的driver根据上级帮忙配置的一些IO_STACK_LOCATION信息,完成相应的工作,然后配置好下一级的IO_STCAK_LOCATION.

调用IoCallDriver(NextDeviceObject,Irp),交给下一级的device.

事实上,如果某个device啥事都不想做,它可以直接skip原来分给它的IO_STACK_LOCATION,在IoCallDriver,只要相应调整下stackIndex类似的值,就可以让下一级的Device使用自己的IO_STACK_LOCATION内存了。

当然每个Device都可以配置IoSetCompletionRoutine,这样下一级完成的时候,会call自己设的completion routine,当然不设也没关系.

要理解IRP,其实首先需要理解device stack, IO Manager是怎么维护device stack的呢?

其实有相应的API, IoAttachDevice, IoDetachDevice。

NTSTATUS IoAttachDevice(
  _In_   PDEVICE_OBJECT SourceDevice,
  _In_   PUNICODE_STRING TargetDevice,
  _Out_  PDEVICE_OBJECT *AttachedDevice
);

The IoAttachDevice routine attaches the caller's device object to a named target device object, so that I/O requests bound for the target device are routed first to the caller.

VOID IoDetachDevice(
  _Inout_  PDEVICE_OBJECT TargetDevice
);

The IoDetachDevice routine releases an attachment between the caller's device object and a lower driver's device object.

在call这些API的时候,IO Manager就在做构建device stack的工作了。

posted @ 2013-10-12 13:49  一ke小小草  阅读(924)  评论(0编辑  收藏  举报