IRP和IO_STACK_LOCATION结构的关联

IRP结构中的IRP!StackCount--IRP!CurrentLocation--IRP!CurrentStackLocation三个字段关系错综,仅以此文已做备忘。

//IRP结构后面接一个IO_STACK_LOCATION数组
typedef struct _IRP {
  CSHORT  Type;
  USHORT  Size;
  struct _MDL  *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;
  //整个设备栈中从顶层到底层的栈深度(IO_STACK_LOCATION数组的长度)
  CHAR  StackCount;
  //当前设备栈深度,从1开始计数
  /*
   另外,IofCallDriver函数中一段代码:
   Irp->CurrentLocation--;
    if (Irp->CurrentLocation <= 0)
    {
        KeBugCheckEx(NO_MORE_IRP_STACK_LOCATIONS, (ULONG_PTR)Irp, 0, 0, 0);
    }
    在调用下一层设备之前,先对Irp->CurrentLocation减一,如果Irp->CurrentLocation==0就bugcheck了,
    从这里可以确定,CurrentLocation是从1开始计数的
    CurrentLocation就如同日常口语中第一层(对应数组元素0)第二层(数组元素1)的概念
   */
  CHAR  CurrentLocation;
BOOLEAN  Cancel;
  KIRQL  CancelIrql;
  CCHAR  ApcEnvironment;
  UCHAR  AllocationFlags;
  PIO_STATUS_BLOCK  UserIosb;
  //同步对象
  PKEVENT  UserEvent;
  union {
    struct {
      PIO_APC_ROUTINE  UserApcRoutine;
      PVOID  UserApcContext;
    } AsynchronousParameters;
    LARGE_INTEGER  AllocationSize;
  } Overlay;
  volatile PDRIVER_CANCEL  CancelRoutine;
  PVOID  UserBuffer;
  union {
    struct {
      _ANONYMOUS_UNION union {
        KDEVICE_QUEUE_ENTRY  DeviceQueueEntry;
        _ANONYMOUS_STRUCT struct {
          PVOID  DriverContext[4];
        } DUMMYSTRUCTNAME;
      } DUMMYUNIONNAME;
      //发出IRP的线程
      PETHREAD  Thread;
      PCHAR  AuxiliaryBuffer;
      _ANONYMOUS_STRUCT struct {
        LIST_ENTRY  ListEntry;
        _ANONYMOUS_UNION union {
            //当前使用的堆栈数组元素指针
            /*
            StackCount/CurrentLocation/CurrentStackLocation三者的关系还是得从IoSizeOfIrp和IoInitializeIrp确立
            */
          struct _IO_STACK_LOCATION  *CurrentStackLocation;
          ULONG  PacketType;
        } DUMMYUNIONNAME;
      } DUMMYSTRUCTNAME;
      //设备对象所关联的文件对象
      struct _FILE_OBJECT  *OriginalFileObject;
    } Overlay;
    //整个IRP异步返回时用到的APC对象
    KAPC  Apc;
    PVOID  CompletionKey;
  } Tail;
} IRP;

如同注释中说,

StackCount/CurrentLocation/CurrentStackLocation三者的关系还是得从IoSizeOfIrp和IoInitializeIrp确立

接下来看下IoSizeOfIrp和IoInitializeIrp对IRP中这些字段的操作

VOID
NTAPI
IoInitializeIrp(IN PIRP Irp,
                IN USHORT PacketSize,
                IN CCHAR StackSize)
{
    /* Clear it */
    IOTRACE(IO_IRP_DEBUG,
            "%s - Initializing IRP %p\n",
            __FUNCTION__,
            Irp);
    RtlZeroMemory(Irp, PacketSize);

    /* Set the Header and other data */
    Irp->Type = IO_TYPE_IRP;
    Irp->Size = PacketSize;
    Irp->StackCount = StackSize;
	//初始状态时当前堆栈深度为实际深度(StackSize)+1
	//因为此时的IRP还没有进入设备对象堆栈
    Irp->CurrentLocation = StackSize + 1;
    Irp->ApcEnvironment =  KeGetCurrentThread()->ApcStateIndex;
	//IO_STACK_LOCATION数组紧贴IRP后面,数组中一共只有StackSize个元素,
	//下标从0到StackSize-1,所以指针已经越界一个元素。
	//最重要的,调用IoCallDriver时会调用一次IoGetNextIrpStackLocation,把数组
	//指针拨动到正确的位置,然后再把irp传递下去
	/*
	还是以老式设备StackSize=1为例:
	Irp->CurrentLocation=2,设备栈中第二个设备(很可惜堆栈上一共只有1个设备),
	Irp->Tail.Overlay.CurrentStackLocation=&IO_STACK_LOCATION[1].数组中只有元素0,因此还是越界
	状态.
	调用IofCallDriver时,IoSetNextIrpStackLocation(Irp),因此Irp->CurrentLocation=1,意为取堆栈中
	第一个元素,Irp->Tail.Overlay.CurrentStackLocation--堆栈指针指向&IO_STACK_LOCATION[0],取
	堆栈元素0
	*/
    Irp->Tail.Overlay.CurrentStackLocation = (PIO_STACK_LOCATION)(Irp + 1) + StackSize;

    /* Initialize the Thread List */
    InitializeListHead(&Irp->ThreadListEntry);
}
 /*
 StackSize是设备栈中从顶层到底层设备数量,以老式设备为例StackSize=1.
 因此这个宏将在池中获得sizeof(IRP)和只有一个IO_STACK_LOCATION元素的数组,
 下标为0
 */
#define IoSizeOfIrp(_StackSize)   ((USHORT) (sizeof(IRP) + ((_StackSize) * (sizeof(IO_STACK_LOCATION)))))
时间: 2024-10-08 20:50:35

IRP和IO_STACK_LOCATION结构的关联的相关文章

比较结构的关联词(二)

一.比较结构的关联词(二) 11. nothing but = nothing else than = nothing less than 不是别的...正是...;完全是:无异于 Genius is nothing else but labor and diligence. 译文:天才不过是劳动加勤奋而已 12.much less = still less 更不,更无 I could not agree to ,much less participate in such proceedings

IO_STACK_LOCATION与IRP的一点笔记

IO_STACK_LOCATION和IRP算是驱动中两个很基础的东西,为了理解这两个东西,找了一点资料. 1. IRP可以看成是Win32窗口程序中的消息(Message),DEVICE_OBJECT可以看成是Win32窗口程序中的窗口(Window) 2. 任何内核模式程序在创建一个IRP时,同时还创建了一个与之关联的IO_STACK_LOCATION结构数组:数组中的每个堆栈单元都对应一个将处理该IRP的驱动程序.IRP的头部有一个当前IO_STACK_LOCATION的数组索引,同时也有一

[转&amp;精]IO_STACK_LOCATION与IRP的一点笔记

IO_STACK_LOCATION和IRP算是驱动中两个很基础的东西,为了理解这两个东西,找了一点资料. 1. IRP可以看成是Win32窗口程序中的消息(Message),DEVICE_OBJECT可以看成是Win32窗口程序中的窗口(Window) 2. 任何内核模式程序在创建一个IRP时,同时还创建了一个与之关联的IO_STACK_LOCATION结构数组:数组中的每个堆栈单元都对应一个将处理该IRP的驱动程序. IRP的头部有一个当前IO_STACK_LOCATION的数组索引,同时也有

从IRP说起(转)

原文链接:http://www.cnblogs.com/zhuyp1015/archive/2012/03/14/2396595.html IRP(I/O request package)是操作系统内核的一个数据结构.应用程序与驱动程序进行通信需要通过IRP包.当上层应用程序需要与驱动通信的时候,通过调用一定的 API函数,IO管理器针对不同的API产生不同的IRP,IRP被传递到驱动内部不同的分发函数进行处理.对于不会处理的IRP包需要提供一个默认的分 发函数来处理. 现在我们来看一下IRP的

HTML5新增的结构元素

HTML5的结构 一:新增的主体结构元素 在HTML5中,为了使文档的结构更加清晰明确,追加了几个与页眉,页脚内容区块等文档结构相关联的结构元素. 1.1article元素 article元素代表文档,页面或应用程序中独立的完整的,可以独自被外部引用的内容,<article> 标签定义外部的内容.article元素是可以嵌套使用的,内层的内容在原则上需要与外层的内容相关联, 另外article元素也可以用来表示一个插件. <time> 标签定义日期或时间,或者两者.pubdate

单文档程序结构

创建过程 下面展示建一个单文档程序的过程,在MFC Application Wizard中第一步做如下选择 不妨Project style选择MFC stardard,Visual style and colors选择Windows Native/Default,其他的选项将创建不同样式的界面. 下一步Compound document support按默认选择None: 下一步是Document Template String文档模板字符串的设置,用于设置文档视结构的一些属性,如下 各选项的意

OVERLAPPED结构与GetOverlappedResult函数

异步I/O调用时,我们会用到OVERLAPPED结构和函数GetOverlappedResult.以前一直对GetOverlappedResult比较困惑,这两天看书和代码才知道这个函数的主要作用不过是将Overlapped返回的结果进行一次简单的分析而已. 下面是OVERLAPPED的结构定义:typedef struct _OVERLAPPED {     DWORD  Internal;     DWORD  InternalHigh;     DWORD  Offset;     DWO

《Web前端笔记2.10-2.11》 HTML5 新增的结构元素

课程背景: 在 HTML5 中,为了使文档的结构更加清晰明确,追加了几个与页眉.页脚.内容区块等文档结构相关联的元素. 核心内容:1.Article2.Section3.Nav4.Aside5.Time6.Pubdate 7. header 元素8. footer 元素9. hgroup 元素10. address 元素 article 元素 article 元素代表文档,页面或应用程序中独立的.完整的.可以独自被外部引用的内容. section 元素 本课时讲解 HMTL5 新增的主体结构元素

关联分析:FP-Growth算法

关联分析又称关联挖掘,就是在交易数据.关系数据或其他信息载体中,查找存在于项目集合或对象集合之间的频繁模式.关联.相关性或因果结构.关联分析的一个典型例子是购物篮分析.通过发现顾客放入购物篮中不同商品之间的联系,分析顾客的购买习惯.比如,67%的顾客在购买尿布的同时也会购买啤酒.通过了解哪些商品频繁地被顾客同时购买,可以帮助零售商制定营销策略.关联分析也可以应用于其他领域,如生物信息学.医疗诊断.网页挖掘和科学数据分析等. 1. 问题定义 图1 购物篮数据的二元表示 图1表示顾客的购物篮数据,其