通常我们所知IoCallDriver是把irp传递给下一层设备,传递到底是什么意思呢?
IoCallDriver中实际调用了IopfCallDriver,其代码如下:
NTSTATUS
FORCEINLINE
IopfCallDriver(
    IN PDEVICE_OBJECT DeviceObject,
    IN OUT PIRP Irp
    )

/*++

Routine Description:

This routine is invoked to pass an I/O Request Packet (IRP) to another
    driver at its dispatch routine.

Arguments:

DeviceObject - Pointer to device object to which the IRP should be passed.

Irp - Pointer to IRP for request.

Return Value:

Return status from driver's dispatch routine.

--*/

{
    PIO_STACK_LOCATION irpSp;
    PDRIVER_OBJECT driverObject;
    NTSTATUS status;

//
    // Ensure that this is really an I/O Request Packet.
    //

ASSERT( Irp->Type == IO_TYPE_IRP );

//
    // Update the IRP stack to point to the next location.
    //
    Irp->CurrentLocation--;

if (Irp->CurrentLocation <= 0) {
        KiBugCheck3( NO_MORE_IRP_STACK_LOCATIONS, (ULONG_PTR) Irp, 0, 0 );
    }

irpSp = IoGetNextIrpStackLocation( Irp );
    Irp->Tail.Overlay.CurrentStackLocation = irpSp;

//
    // Save a pointer to the device object for this request so that it can
    // be used later in completion.
    //

irpSp->DeviceObject = DeviceObject;

//
    // Invoke the driver at its dispatch routine entry point.
    //

driverObject = DeviceObject->DriverObject;

//
    // Prevent the driver from unloading.
    //

status = driverObject->MajorFunction[irpSp->MajorFunction]( DeviceObject,
                                                              Irp );

return status;
}

可以看到,IopfCallDriver首先将irp的当前位置减一,即得到下一个位置。而IoGetNextIrpStackLocation是一个宏,得到下一个irp堆栈的指针,并将这一指针身为当前irp堆栈指针。实际上就是irp->Tail.Overlay.CurrentStackLocation - 1。然后从该irp堆栈中取出它所对应的device object,从而得到driver object。最后,传递irp实际上就是调用对应这次请求的例程。这个请求或者从irp堆栈中取出一些参数,或者干些其他什么事,这我们就不管了。
 
再有就是有关于完成例程IoCompletionRoutine,它是如何被调用的?当完成一个irp时,我们会呼叫IoCompleteRequest。这个函数遍历一遍irp堆栈,如果发现堆栈中设置了IoCompletionRoutine指针,就调用它。

关于IoCallDriver的更多相关文章

  1. 关于IoCallDriver使用的疑惑

    #pragma PAGEDCODE NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) { KdPrint(("Dr ...

  2. [转]C/C++ 实现文件透明加解密

    今日遇见一个开超市的朋友,真没想到在高校开超市一个月可以达到月净利润50K,相比起我们程序员的工资,真是不可同日而语,这个世道啊,真是做程序员不如经商开超市, 我们高科技的从业者,真是造原子弹不如卖茶 ...

  3. I/O 请求数据包

    MSDN原文:https://msdn.microsoft.com/zh-cn/library/windows/hardware/hh439638(v=vs.85).aspx 发送到设备驱动程序的大部 ...

  4. Windows内核 WDM驱动程序的基本结构和实例

    WDM驱动的基本结构: WDM驱动模型是建立在NT式驱动程序模型基础之上的.对于WDM驱动程序来说,一般都是基于分层的,即完成一个设备的操作,至少要由两个驱动设备共同完成. 1)物理设备对象和功能设备 ...

  5. IRP IO_STACK_LOCATION 《寒江独钓》内核学习笔记(1)

    在学习内核过滤驱动的过程中,遇到了大量的涉及IRP操作的代码,这里有必要对IRP的数据结构和与之相关的API函数做一下笔记. 1. 相关阅读资料 <深入解析 windows 操作系统(第4版,中 ...

  6. [windows驱动]基本概念

    https://msdn.microsoft.com/zh-cn/library/windows/hardware/ff554721 1.设备节点和设备堆栈 在windows中,设备通过即插即用设备树 ...

  7. Windows xp 重载内核(使用Irp进行文件操作)

    一.前言 最近在阅读A盾代码A盾电脑防护(原名 3600safe)anti-rootkit开放源代码,有兴趣的可以去看雪论坛下载,本文代码摘自其中的重载内核. 二.实现步骤 1.ZwQuerySyst ...

  8. 从IRP说起(转)

    原文链接:http://www.cnblogs.com/zhuyp1015/archive/2012/03/14/2396595.html IRP(I/O request package)是操作系统内 ...

  9. IoSkipCurrentIrpStackLocation .(转)

    原文链接:http://m.blog.csdn.net/blog/ruanben/19758769# 当驱动被分层以后,他们被注册到一个chain中,IRP会在这个chain中传递,从最上面,到最下面 ...

随机推荐

  1. 护肤品总结 Skin Care (2)

    接护肤品总结(1) 面膜篇 个人不太喜欢片状面膜,所以用膏状面膜比较多. 1. Origins Drink Up-Intensive Overnight Mask 悦木之源补水睡眠面膜 牛油果油油的质 ...

  2. Java 8 默认方法和多继承深入解析

    以前经常谈论的Java对比c++的一个优势是Java中没有多继承的问题. 因为Java中子类只能继承(extends)单个父类, 尽管可以实现(implements)多个接口,但是接口中只有抽象方法, ...

  3. Android笔记(二):从savedIndstanceState发散

    savedIndstanceState savedIndstanceState位于ActivityonCreate(Bundle savedInstanceState)方法的参数中.对这个参数的理解要 ...

  4. Python模拟登录实战(二)

    目标:1.模拟登录豆瓣,2.自动更改签名和发表说说. 代码如下: #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'ziv·chan ...

  5. openfire连接登陆优化方案

    client登陆openfire,大概总共须要9个来回才完毕登录. 在2G情况下.就表现为client登录特别慢,所以,为解决问题,对openfire进行了例如以下优化 openfire的连接.登陆过 ...

  6. 《Java虚拟机原理图解》1.4 class文件里的字段表集合--field字段在class文件里是如何组织的

    0.前言 了解JVM虚拟机原理是每个Java程序猿修炼的必经之路.可是因为JVM虚拟机中有非常多的东西讲述的比較宽泛.在当前接触到的关于JVM虚拟机原理的教程或者博客中,绝大部分都是充斥的文字性的描写 ...

  7. javascript eval和JSON之间的联系(转)

    eval函数的工作原理 eval函数会评估一个给定的含有JavaScript代码的字符串,并且试图去执行包含在字符串里的表达式或者一系列的合法的JavaScript语句.eval函数将把最后一个表达式 ...

  8. PHP页面之间跳转方法总结

    编程中,在页面之间进行跳转是必须的.这里列出了三种办法,供参考. 一.用HTTP头信息 也就是用PHP的HEADER函数.PHP里的HEADER函数的作用就是向浏览器发出由HTTP协议规定的本来应该通 ...

  9. Velocity 语法示例

    一.简介: 1)它允许任何人使用简单而强大的模板语言来引用定义在 java 代码中的对象" 2)Velocity是一个基于java的模板引擎,简称VTL(Velocity Template ...

  10. mybati之day02

    今天开始讲解mybatis的第二天内容  一,拼接sql 在mapper.xml中,会多次使用到同一条sql片段,这时为了简便书写,将其定义出来 <sql id="base_sql&q ...