您的位置:首页 > 移动开发 > IOS开发

IoGetCurrentIrpStackLocation和IoSkipCurrentIrpStackLocation和IoCopyCurrentIrpStackLocationToNext

2016-02-19 16:43 495 查看
IoGetCurrentIrpStackLocation
例程返回在给定的IRP的指针调用程序的堆栈位置
#define IoGetCurrentIrpStackLocation( Irp ) ( (Irp)->Tail.Overlay.CurrentStackLocation )

IoSkipCurrentIrpStackLocation
所述IoSkipCurrentIrpStackLocation宏修改系统的IO_STACK_LOCATION数组指针,所以,当电流驱动程序调用下一低级驱动程序,该驱动程序接收的电流驱动器接收到的相同IO_STACK_LOCATION结构
#define IoSkipCurrentIrpStackLocation( Irp ) { \
(Irp)->CurrentLocation++; \
(Irp)->Tail.Overlay.CurrentStackLocation++; }

有时候,当前设备堆栈不对IRP做任何处理。英雌,当时设备就不需要对应I/O堆栈。但是IoCallDriver已经将当前I/O堆栈向下移动了一个单位,所以DDK提供了内核宏IoSkipCurrentIrpStackLocation,
它的作用就是将当前I/O堆栈又往回(上)移动一个单位。
这样IoCallDriver和IoSkipCurrentIrpStackLocation对设备堆栈的移动就实现了平衡,也就是没有改变。这时IoCallDriver调用的低一层驱动所用的I/O堆栈,实际上和一层用到的是同一个。
因此,当本层驱动不需要用I/O堆栈时,可以做如下操作
//获取设备扩展
PDEVICE_EXTENSION pdx=(PDEVICE_EXTENSION)pDevObj->DeviceExtension;

//调用底层驱动
IoSkipCurrentIrpStackLocation(pIrp);

//调用下层驱动
ntStatus=IoCallDriver(pdx->TargetDevice,pIrp);

IoCopyCurrentIrpStackLocationToNext
该IoCopyCurrentIrpStackLocationToNext例行程序会将从当前的I / O堆栈位置到下一层的驱动的堆栈位置IRP栈参数
#define IoCopyCurrentIrpStackLocationToNext( Irp ) { \
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; }

在另外一种情况下,即当前IRP也参与操作时,就需要将当前I/O堆栈的参数复制到下一层,需要调用内核宏IoCopyCurrentIrpStackLocationToNext,也就是如下操作:
//获取设备扩展
PDEVICE_EXTENSION pdx=(PDEVICE_EXTENSION)pDevObj->DeviceExtension;

//调用底层驱动
IoCopyCurrentIrpStackLocationToNext(pIrp);
ntStatus=IoCallDriver(pdx->TargetDevice,pIrp);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: