TDI过滤驱动 创建了自己的设备附加到 tcp udp rawip上面。
过滤后调用原来的IoCallDriver发送给下层驱动
NTSTATUS FilterDeviceDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION irps;
irps = IoGetCurrentIrpStackLocation(Irp);
//问题在这里
if (Irp->CurrentLocation <= 1)
{
DbgPrint("DeviceObject->stacksize=%d currentLocation=%d----%d\n", DeviceObject->StackSize, Irp->CurrentLocation\
,Irp->StackCount);
IoSkipCurrentIrpStackLocation(Irp);
DbgBreakPoint();
return IoCallDriver(GETORGDEVOBJ(DeviceObject), Irp);
}
IoCopyCurrentIrpStackLocationToNext(Irp);
return IoCallDriver(GETORGDEVOBJ(DeviceObject), Irp);
}
之前我并没有这个判断。
if (Irp->CurrentLocation <= 1)
直接调用
IoCopyCurrentIrpStackLocationToNext(Irp);
return IoCallDriver(GETORGDEVOBJ(DeviceObject), Irp);
(这里我没有设置完成例程,假设我有完成例程要设置 ,因此调用iocopy而不是ioskip)
在XP系统上浏览网页偶尔蓝屏 ,点击网络邻居查看网络连接之类的就会蓝屏几率更大。
蓝屏代码为NO_MORE_IRP_STACK_LOCATIONS
没有更多的IO栈
按理说,我的设备是附加上去的。 进入我的dispatch例程后。Irp->CurrentLocation至少为2为何会出现Irp->CurrentLocation==1的情况呢??
加上这个判断后的确也出现了Irp->CurrentLocation=1的情况。
查看寒江独钓tdifw源码
tdi_fw.c line 755
if (cr == NULL || irp->CurrentLocation <= 1)
{
/*
* we use _THIS_ way of sending IRP to old driver
* a) to avoid NO_MORE_STACK_LOCATIONS
* b) and if we haven't our completions - no need to copy stack locations!
*/
// stay on this location after IoCallDriver
IoSkipCurrentIrpStackLocation(irp);
}
这里也只是说明了
a避免 NO_MORE_STACK_LOCATIONS的错误
b没有完成例程,没必要copystacklocation 只需要skip就行。(假如我需要完成例程,是不是这个就漏过了)
并没有解释为何出现这个问题。
我自己跟踪了一下,发现流程是这样的
netbt.sys 创建的设备\Device\NetBt_tcpip_{xxxxxxxxxxxxx},stacksize为2
rdbss!RxTdiQueryInformation创建了一个IRP 发送到这个\Device\NetBt_tcpip_{xxxxxxxxxxxxx}
currentstacklocation值为stacksize+1=3;
随后调用IocallDriver currentstacklocation--变成2
进入netbt!NbtDispatchInternalCtrl
继续调用 netbt!NTQueryInformation
获取IoGetCurrentStackLocation获取irpsp
irpsp->fileobject
fileobject->fscontext
由于fscontext没法了解,总之再取了几次值以后
用IoGetRelatedDeviceObject获取到了我的过滤设备,FilterDevice。
然后IoCallDriver(FilterDevice,Irp)
currentstacklocation--变成1
就到了上面的情况。
源码很简单,希望哪位帮忙解释一下
希望高人指点一下为何会出现这个问题。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
上传的附件: