Winoows内核设计思想之IRP
+ -

IRP调用IoSkipCurrentIrpStackLocation与IoCopyCurrentIrpStackLocationToNext的区别

2022-08-01 146 20

当IPR需要传递给下层设备时,一般的操作有两种。
第一种是直接下传:

 IoCopyCurrentIrpStackLocationToNext(irp);
 status = IoCallDriver(parentFdoExt->fdo, irp);

这种情况下是保留当前驱动栈对该IRP的IO_STACK_LOCATION,这是因为:


FORCEINLINE
VOID
IoCopyCurrentIrpStackLocationToNext(
    _Inout_ PIRP Irp
)
/*--

Routine Description:

    This routine is invoked to copy the IRP stack arguments and file
    pointer from the current IrpStackLocation to the next
    in an I/O Request Packet (IRP).

    If the caller wants to call IoCallDriver with a completion routine
    but does not wish to change the arguments otherwise,
    the caller first calls IoCopyCurrentIrpStackLocationToNext,
    then IoSetCompletionRoutine, then IoCallDriver.

Arguments:

    Irp - Pointer to the I/O Request Packet.

Return Value:

    None.

--*/
{
    PIO_STACK_LOCATION irpSp;
    PIO_STACK_LOCATION nextIrpSp;
    irpSp = IoGetCurrentIrpStackLocation(Irp);
    nextIrpSp = IoGetNextIrpStackLocation(Irp);
    RtlCopyMemory( nextIrpSp, irpSp, FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine));
    nextIrpSp->Control = 0;
}

可以以看到IoCopyCurrentIrpStackLocationToNext只是将当前的栈信息复制到下一层中(不包括完成例程)

而第二种是:

 IoSkipCurrentIrpStackLocation(irp);
 status = IoCallDriver(parentFdoExt->topDevObj, irp);

跳过当前栈,让下层驱动使用当前的驱动栈。所以使用IoSkipCurrentIrpStackLocation函数先使IRP的IO_STACK_LOCATION上移,上移Irp->Tail.Overlay.CurrentStackLocation指针的上移和当前位置层位置CurrentLocation的上移:

ORCEINLINE
VOID
IoSkipCurrentIrpStackLocation (
    _Inout_ PIRP Irp
)
/*--
Routine Description:

    This routine is invoked to increment the current stack location of
    a given IRP.

    If the caller wishes to call the next driver in a stack, and does not
    wish to change the arguments, nor does he wish to set a completion
    routine, then the caller first calls IoSkipCurrentIrpStackLocation
    and the calls IoCallDriver.

Arguments:

    Irp - Pointer to the I/O Request Packet.

Return Value:

    None
--*/
{
    NT_ASSERT(Irp->CurrentLocation <= Irp->StackCount);
    Irp->CurrentLocation++;
    Irp->Tail.Overlay.CurrentStackLocation++;
}

最终它们都是调用的是IoCalldriver函数:http://www.pnpon.com/article/detail-361.html
从源代码可以看到:
其仅是检查当前位直CurrentLocation。然后获取下一层的IO_STACK_LOCATION并赋于Irp->Tail.Overlay.CurrentStackLocation,然后执行DeviceObject对应的DriverObject对应的函数。

其实从这里也可以看出,IoCallDriver这个函数的调用是需要一些准备工作的,而且比较重要。这些准备工作是根据用户的需求而设置不同。所以IoCallDriver函数有点像半个函数。

0 篇笔记 写笔记

IoCopyCurrentIrpStackLocationToNextIoSkipCurrentIrpStackLocation操作的IO_STACK_LOCATION有什么区别
在Windows驱动中,传递IPR一般有两种操作:一种是调用IoSkipCurrentIrpStackLocation,表示跳过本层驱动的操作,直接转发至下层: IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(FDODeviceEx......
IoCallDriver函数源代码
#define IoCallDriver IofCallDriverNTSTATUS FASTCALL IofCallDriver ( IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp ) { PDRI......
IRP调用IoSkipCurrentIrpStackLocationIoCopyCurrentIrpStackLocationToNext的区别
当IPR需要传递给下层设备时,一般的操作有两种。第一种是直接下传: IoCopyCurrentIrpStackLocationToNext(irp); status = IoCallDriver(parentFdoExt->fdo, irp);这种情况下是保留当前驱动栈对该IRP的IO_......
作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!