zoukankan      html  css  js  c++  java
  • 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的工作了。

  • 相关阅读:
    关于屏幕点亮和熄灭你所需要知道的
    关于handler的使用和理解
    关于Android Task的学习
    Android触摸屏幕事件总结
    Android工作问题总结
    Android生命周期总结
    Android中如何在子线程更新UI
    Eclipse中启动tomcat无效,而手动启动可以访问的原因
    使用Spring进行文件加载进内存
    spring集成quartz定时器的使用
  • 原文地址:https://www.cnblogs.com/zzSoftware/p/2908825.html
Copyright © 2011-2022 走看看