首页
社区
课程
招聘
[旧帖] [求助]在线求解答,NDIS驱动蓝屏问题 0.00雪花
发表于: 2012-8-21 16:43 2160

[旧帖] [求助]在线求解答,NDIS驱动蓝屏问题 0.00雪花

2012-8-21 16:43
2160
代码是基于Passthru的。
整体思想是这样的:一个有3个网卡的主机,我想让它作为网桥来使用。三个网卡在PtBindAdapter的时候都被设置成了混杂模式。在PtReceive里面,对数据包进行过滤,如果发现包的目的MAC和本网卡的MAC相同,则将它继续上传至上层协议,否则就转发,转发的时候,将MpInitialize保留的AdapterList链表的每一个adapter都转发,本adapter除外。每次到NdisSend的时候就会蓝屏。而如果我拔掉一根网线,并且将拔掉网线那个网卡禁用,那么不会蓝屏。转发关键代码如下:

//转发包的代码
VOID ForwardPacket( PNDIS_PACKET pPacket, PADAPT pAdaptIn)
{
	NDIS_STATUS Status;
	PADAPT pCursor;
	PADAPT Ifs[MAX_IF+1];
	ULONG IfNum, i;
	//
	// Remove the pAdapt from our global list
	//
	NdisAcquireSpinLock(&GlobalLock);
	for (pCursor=pAdaptList, IfNum=0; pCursor!=NULL; pCursor=pCursor->Next)
	{
		if (pCursor != pAdaptIn) {
			Ifs[IfNum++] = pCursor;
			REF_BINDING_CTXT( pCursor);
		}
	}
	NdisReleaseSpinLock (&GlobalLock);
	ASSERT(IfNum <= MAX_IF);
	// forward packets
	for ( i=0; i<IfNum; i++) 
	{
		REF_PACKET(pPacket);
		KdPrint(("Forward pkt %p from ADAPT %p\n", pPacket, Ifs[i]));
		NdisSetPacketFlags( pPacket, NDIS_FLAGS_DONT_LOOPBACK);
		NdisSend( &Status, Ifs[i]->BindingHandle, pPacket);//有3个网卡时此处蓝屏
		if ( Status != NDIS_STATUS_PENDING) {
			// send complete
			DEREF_PACKET(pPacket);
			DEREF_BINDING_CTXT(Ifs[i]);

			if ( Status != NDIS_STATUS_SUCCESS) {
				KdPrint(("Fail to send pkt, status# %08x\n", Status));
			} else {
				KdPrint(("Send pkt OK\n"));
				}
		}
	}	
	return;
}

//PtSendComplete的代码


VOID
PtSendComplete(
	IN	NDIS_HANDLE			ProtocolBindingContext,
	IN  PNDIS_PACKET		Packet,
	IN  NDIS_STATUS			Status
	)
/*++

Routine Description:

Interesting case:
	We wish to send all sends down the secondary NIC. But when we indicate to the protocol above,
	we need to revert back to the original miniport that Protocol wished to use for the Send

Arguments:

Return Value:

--*/
{
	PADAPT pAdapt = (PADAPT)ProtocolBindingContext;
	PNDIS_PACKET OriginalPkt;
	PRSVD Rsvd;

	Rsvd =(PRSVD)(Packet->ProtocolReserved);
	OriginalPkt = Rsvd->OriginalPkt;

	if ( NULL == OriginalPkt)
	{
		DEREF_PACKET(Packet);
		DEREF_BINDING_CTXT(pAdapt);
	} 
	else 
	{
		// Upper protocol's sending complete
		NdisIMCopySendCompletePerPacketInfo(OriginalPkt, Packet);
		NdisDprFreePacket(Packet);
		NdisMSendComplete(pAdapt->MiniportHandle, OriginalPkt, Status);
	}

	DBGPRINT(("pkt %p send complete, status# %08x\n", Packet, Status));
}


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (15)
雪    币: 67
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
很奇怪的问题,两个网卡就没事,三个就蓝屏
2012-8-21 16:49
0
雪    币: 67
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
调试发现,如果有两个网卡,IfNum=1,那么for循环只执行了一次。猜想是不是循环NdisSend导致的同步问题??
2012-8-21 18:25
0
雪    币: 85
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
蓝屏代码分析一下啊
2012-8-21 18:34
0
雪    币: 67
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
蓝屏: DRIVER-IRQL-NOT-LESS-OR-EQUAL
2012-8-21 19:00
0
雪    币: 67
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
如果是这样的话,该怎么改呢?
高手啊高手,你快出来吧~
2012-8-22 08:21
0
雪    币: 67
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
试着用NDIS_EVENT进行同步,结果蓝屏:
A wait operation,attach process,or yield was attempted from a DPC routine
我是这样同步的:
在ForwardPacket中
...........
...........
for ( i=0; i<IfNum; i++) 
  {
    REF_PACKET(pPacket);
    [COLOR="Red"]NdisInitializeEvent(&Ifs[i]->Event);//初始化Event[/COLOR]   
    KdPrint(("Forward pkt %p from ADAPT %p\n", pPacket, Ifs[i]));
    NdisSetPacketFlags( pPacket, NDIS_FLAGS_DONT_LOOPBACK);
    NdisSend( &Status, Ifs[i]->BindingHandle, pPacket);//有3个网卡时此处蓝屏
    if ( Status != NDIS_STATUS_PENDING) {
      // send complete
      DEREF_PACKET(pPacket);
      DEREF_BINDING_CTXT(Ifs[i]);

      if ( Status != NDIS_STATUS_SUCCESS) {
        KdPrint(("Fail to send pkt, status# %08x\n", Status));
      } else {
        KdPrint(("Send pkt OK\n"));
        }
    }
   [COLOR="red"]else{
        NdisWaitEvent(&Ifs[i]->Event);//如果没有处理完,就等待
    }[/COLOR]  
}  
...........
...........


在PtSendComplete函数中这样修改:
............
............
if ( NULL == OriginalPkt)
  {
    DEREF_PACKET(Packet);
    DEREF_BINDING_CTXT(pAdapt);
   [COLOR="red"] NdisSetEvent(&pAdapt->Event);//处理完成,设置Event[/COLOR]  
 } 
...........
...........

结果还是蓝屏。

RefPacket代码如下:
ULONG RefPacket(
    IN PNDIS_PACKET	pPacket
)
{
        PRSVD pRsvd = (PRSVD)(pPacket->ProtocolReserved);
        pRsvd->OriginalPkt = NULL;
        return InterlockedIncrement(&pRsvd->RefCount);
}

DerefPacket代码如下:
ULONG DerefPacket(
    IN PNDIS_PACKET	pPacket
)
{
	PRSVD pRsvd = (PRSVD)(pPacket->ProtocolReserved);
	PNDIS_BUFFER pBuffer;
	PUCHAR pPktData;	
	ULONG Result, Len;
	KdPrint(("DerefPacket,pRsvd->RefCount=%d\n",pRsvd->RefCount));
	if ((Result = InterlockedDecrement(&pRsvd->RefCount)) == 0) {
		//
		// when refcount reaches 0, no one will use this packet any more, i.e., no one will 
		// increase refcount again. so i can here boldly release it.
		//
		NdisUnchainBufferAtFront( pPacket, &pBuffer);
		NdisQueryBufferSafe( pBuffer, &pPktData, &Len, NormalPagePriority)

		// free pkt resources
		NdisFreeToNPagedLookasideList( &PktDataLookasideList, pPktData);
		NdisFreeBuffer(pBuffer);
		NdisFreePacket(pPacket);
	}

	return Result;
}


RefBindingCtxt代码如下:
ULONG
RefBindingCtxt(
    IN PADAPT        pAdapt
)
{
	return InterlockedIncrement(&pAdapt->RefCount);
}

DerefBindingCtxt代码如下:
ULONG
DerefBindingCtxt(
    IN PADAPT        pAdapt
)
{
	return InterlockedDecrement(&pAdapt->RefCount);
}
2012-8-22 09:11
0
雪    币: 67
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
发现
http://bbs3.driverdevelop.com/simple/?t94163.html
有个人遇到了跟我类似的问题。我跟了一下发现确实,有时候会连续NdisSend两次之后,才收到PtSendComplete的回应。
2012-8-22 09:58
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
9
楼主写驱动不会调dmp吗?
2012-8-22 12:56
0
雪    币: 85
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
这是正常的嘛,完成例程本来就不确定什么时候被调用
2012-8-22 14:22
0
雪    币: 85
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
可能导致这个错误的原因太多了...
2012-8-22 14:34
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
请哦偶像剧去哦无关电影亲我恶搞美女
2012-8-22 15:27
0
雪    币: 67
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
没有用虚拟机,虚拟机上面模拟两个网卡不行。没有用windbg。唉
2012-8-22 19:03
0
雪    币: 85
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
那这如何是好,你本机调试?
2012-8-23 09:25
0
雪    币: 67
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
本机写程序,另外一机测试
2012-8-23 13:02
0
雪    币: 85
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
没单机调试过驱动,不懂了
2012-8-23 16:19
0
游客
登录 | 注册 方可回帖
返回
//