首页 > 代码库 > 白话IoSkipCurrentIrpStackLocation
白话IoSkipCurrentIrpStackLocation
我们在IRP的Passthrough例程中会这样处理放过的IRP
<pre name="code" class="cpp">IoSkipCurrentIrpStackLocation( Irp ); return IoCallDriver( ...->AttachedToDeviceObject, Irp );
那么这两个函数内在本质是什么呢?
WDK的wdm.h 中有关于 IoSkipCurrentIrpStackLocation 的源码
<pre name="code" class="cpp"><pre name="code" class="cpp">FORCEINLINE VOID IoSkipCurrentIrpStackLocation ( __inout PIRP Irp ) { ASSERT(Irp->CurrentLocation <= Irp->StackCount); Irp->CurrentLocation++; Irp->Tail.Overlay.CurrentStackLocation++; }
WRK源码base\ntos\io\iomgr.h 下有IopfCallDriver 源码
NTSTATUS FORCEINLINE IopfCallDriver( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ) { 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; }
其中IoGetNextIrpStackLocation( Irp );
#define IoGetNextIrpStackLocation( Irp ) ( (Irp)->Tail.Overlay.CurrentStackLocation - 1 )
IoSkipCurrentIrpStackLocation()做了两件事
1 Irp->CurrentLocation++;
2 Irp->Tail.Overlay.CurrentStackLocation++;
而 IopfCallDriver 中1 Irp->CurrentLocation--;
2 Irp->Tail.Overlay.CurrentStackLocation = Irp->Tail.Overlay.CurrentStackLocation - 1
这时候 driverObject->MajorFunction[irpSp->MajorFunction]( DeviceObject, Irp );中的IRP没有改变,还是原来的IRP。也就是说, 下层驱动处理的IRP就是上层传递下来的IRP。
再回头看 MSDN 中 关于 IoSkipCurrentIrpStackLocation 写到
The IoSkipCurrentIrpStackLocation macro modifies the system‘s IO_STACK_LOCATION array pointer, so that when the current driver calls the next-lower driver, that driver receives the same IO_STACK_LOCATION structure that the current driver received.
下层驱动接收到 same IO_STACK_LOCATION structure 。白话IoSkipCurrentIrpStackLocation