• 关于IoCallDriver


    通常我们所知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指针,就调用它。

  • 相关阅读:
    统计学习方法 学习笔记(八):k 近邻法
    统计学习方法 学习笔记(七):拉格朗日对偶性
    统计学习方法 学习笔记(六):序列最小最优化算法SMO
    统计学习方法 学习笔记(五):支持向量机(下)
    统计学习方法 学习笔记(四):支持向量机(中)
    统计学习方法 学习笔记(三):支持向量机(上)
    统计学习方法 学习笔记(二):感知机
    CUDA npp运动检测模块性能测试
    CUDA H624解码性能测试
    利用GPU改善程序性能的一点心得
  • 原文地址:https://www.cnblogs.com/foohack/p/3582291.html
Copyright © 2020-2023  润新知