搞明白IRP这个东东了

来源:互联网 发布:nba2konline数据库 编辑:程序博客网 时间:2024/04/29 07:02

按照ms的步骤走了一遍,搞明白了,整点笔记记录一下,别忘了。

IRP的结构:

1) Irp = IoAllocateIrp( IN CCHAR StackSize, IN BOOLEAN ChargeQuota); 

 分配一个IRP,看看ms是怎么做的吧:

 

  a. ) packetSize = IoSizeOfIrp(StackSize);

    

#define IoSizeOfIrp( StackSize ) /
    ((USHORT) (sizeof( IRP ) + ((StackSize) * (sizeof( IO_STACK_LOCATION )))))
计算 IRP的大小,看来一个IRP包括IRP头本身和stack location × StackSize,

  b.) irp = ExAllocatePoolWithTag(NonPagedPool, allocateSize, ' prI');

  分别空间,并且是分配在非分页内存池中。

c) IopInitializeIrp(irp, allocateSize, StackSize);

  初始化一个IRP。

#define IopInitializeIrp( Irp, PacketSize, StackSize ) {          /
    RtlZeroMemory( (Irp), (PacketSize) );                         /
    (Irp)->Type = (CSHORT) IO_TYPE_IRP;                           /
    (Irp)->Size = (USHORT) ((PacketSize));                        /
    (Irp)->StackCount = (CCHAR) ((StackSize));                    /
    (Irp)->CurrentLocation = (CCHAR) ((StackSize) + 1);           /
    (Irp)->ApcEnvironment = KeGetCurrentApcEnvironment();         /
    InitializeListHead (&(Irp)->ThreadListEntry);                 /
    (Irp)->Tail.Overlay.CurrentStackLocation =                    /
        ((PIO_STACK_LOCATION) ((UCHAR *) (Irp) +                  /
            sizeof( IRP ) +                                       /
            ( (StackSize) * sizeof( IO_STACK_LOCATION )))); }

 

 

一个IRP初始化是 当前栈要+1,然后指到分配空间的最后,一个IRP初始化之后,在内存中应该是这个样子:

----------------

|              |

|IRP头

|

|

|Tail.Overlay.CurrentStackLocation

|                                                   |

|

|------------

|

|             

|

|                                                  |

|

|

|

|                                                   |

|

|

----------------  <----------------------|

  2)  PIO_STACK_LOCATION irpSp = IoGetNextIrpStackLocation(Irp);

#define IoGetNextIrpStackLocation( Irp ) (/
    (Irp)->Tail.Overlay.CurrentStackLocation - 1 )

 

由于刚开始CurrentStackLocation  指向处于分配范围之外的地址,所以此处 -1 得到真正的第一个STACK_LOCATION

 

 3) IoCallDriver(DeviceObject, Irp);

 

将IRP发送到目的驱动

 

 

这是IoCallDriver的部分实现

 

可以看到当calldriver时候,IoCallDriver 会将当前栈-1 ,同时将下一个STACK_LOCATION  最为当前栈单元,通过设备对象找到其关联的驱动对象,调用MJ函数,IoCallDriver 返回。

 

 

 

原创粉丝点击