阅读:3343回复:10
诚心求救, NdisSend 蓝屏数周未能解决!
我HOOK了ReceivePacket,SendComplet.
并且在ReceivePacket里使用NdisSend发送一个已经组合好的MyPacket. 但是该句代码导致蓝屏.调试发现NdisSend并没有进入到SendComplet中.所以也没办法进一步确认是否在区分自己的包和系统的包的处理上出了问题. 代码如下: ReceivePacket INT MyReceivePackets( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet ) { int BufLength; PADAPT pAdapt = (PADAPT)ProtocolBindingContext; //这里我非常怀疑可能有问题,大部分人都是PADAPT pAdapt = (PADAPT)MiniportAdapterContext,我不知道这两者有何不同,但是这里只有ProtocolBindingContext可以用.所以只能用这个. NDIS_STATUS Status; PRECV_RSVD RsvdTemp = (PRECV_RSVD)(MyPacket->ProtocolReserved); NdisSend(&Status,pAdapt->BindingHandle,MyPacket); //MYPACKET已经组合好了,应该没有问题. if (Status != NDIS_STATUS_PENDING){ NdisUnchainBufferAtFront(MyPacket, &(RsvdTemp->pMyBuffer)); NdisQueryBufferSafe(RsvdTemp->pMyBuffer, &(RsvdTemp->pMyContent), &BufLength, NormalPagePriority); NdisFreeBuffer(RsvdTemp->pMyBuffer); NdisFreeMemory(RsvdTemp->pMyContent,BufLength,0); NdisDprFreePacket(MyPacket); } else //本来我以为NDISSEND完了如果是PENDING,会自动去调用SendComplete,但是查看调试器,并没有进入到SendComplete里就蓝屏了.所以我自己调用了. { MySendComplete(ProtocolBindingContext,MyPacket,Status); } MySendComplet void MySendComplete( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet, IN NDIS_STATUS Status ) { UINT BufLength; PRECV_RSVD RsvdTemp = (PRECV_RSVD)(Packet->ProtocolReserved); DbgPrint("In the sendComplet\n"); if(RsvdTemp->Mine==TRUE){ //如果是自己做的包 DbgPrint("Its My Packet!!!!\n"); //这句没出现前就蓝屏了 NdisUnchainBufferAtFront(Packet, &(RsvdTemp->pMyBuffer)); NdisQueryBufferSafe(RsvdTemp->pMyBuffer, &(RsvdTemp->pMyContent), &BufLength, NormalPagePriority); NdisFreeBuffer(RsvdTemp->pMyBuffer); NdisFreeMemory(RsvdTemp->pMyContent,BufLength,0); NdisDprFreePacket(Packet); return; } else{ //如果是系统的包 m_pSendComplete(ProtocolBindingContext,Packet,Status); //这里保存了系统原来的SendCompletHandler } } 已经困了很久了,实在没有办法,论坛的帖,基本相关的都搜索和看过了..大家帮帮忙吧. |
|
沙发#
发布于:2009-12-26 01:29
typedef struct _RECV_RSVD //Packet->ProtocolReserved 结构
{ PNDIS_PACKET OriginalPkt; PNDIS_BUFFER pMyBuffer; PUCHAR pMyContent; BOOLEAN Mien; } RECV_RSVD, *PRECV_RSVD; |
|
板凳#
发布于:2009-12-26 13:18
www.drivercoding.com 可以提供技术支持,欢迎联系!
|
|
|
地板#
发布于:2009-12-26 23:16
PADAPT pAdapt = (PADAPT)ProtocolBindingContext; 这句是没错的。
其他的就是 你要理解,pSendComplete 是 异步发送的回调函数,你不能手工去调用。 看你上面的代码找不到问题,关键的地方你也没给出代码。。。大家无法帮你分析。。 NdisSend(&Status,pAdapt->BindingHandle,MyPacket); //MYPACKET已经组合好了,应该没有问题. 这里的 MyPacket 是你自己分配的包描述符,。但是怎么分配的,那些协议头怎么填充和计算的,内存怎么分配的 你都没给出代码, 往往自己发包 蓝屏的原因一般只有两个地方。 1、NDISSEND 之前内存方面的 没分配好。。 2、发送回调中错误的回收资源。 |
|
地下室#
发布于:2009-12-27 11:16
回 3楼(webqy) 的帖子
是不是环回导致的?你发送了一个包,自己又收到了这个包... |
|
|
5楼#
发布于:2009-12-28 01:30
谢谢LS两位兄弟帮忙.我来补充一下信息:
如果 PADAPT pAdapt = (PADAPT)ProtocolBindingContext;没问题, 那么会不会是_ADAPT结构的问题,网上这个结构有很多种,包括passthru里的这个结构都很多不同的版本,但是NDIS_HANDLE BindingHandle;都是处于第二位. pSendComplete 是 异步发送的回调函数,你不能手工去调用.这个我之前是没有手工调用的,但是发现连SendComplete里的DbgPrint都没有显示出来就蓝屏了,所以怀疑是没有进入SENDCOMPLETE.如果连SendComplete里的都没有执行,那是否说明要么MYPACKET出了问题,要么NDISSEND的pAdapt->BindingHandle出了问题?我尝试过显示pAdapt结构里的LowerDeviceName,DeviceName,但是都是乱码或者问号.所以也没办法证实是否调用了没有连上网络的网卡去发导致的?(因为本机有两个网卡,有线和无线.只有一个连接网络). 协议头怎么填充和计算我觉得应该没有问题,因为我是COPY了一个收到的正常包,然后互换发送IP和接收IP地址,重新算了CHECKSUM,重新算了TCP头的序列号确认序列号.这个MYPACKET也是可以通过 NdisBuffer=MyPacket->Private.Head; NdisQueryBufferSafe(NdisBuffer,&tembuffer2,©size,NormalPagePriority); 从而得到tembuffer2里的数据段内容的.就算其中CHECKSUM或者序列号计算错误,也只应该收不到包,而不是蓝屏吧? 发送回调中错误的回收资源。 我的回收资源方法和自己的包辨认代码都在上面给出来了,是自己的包,就 NdisUnchainBufferAtFront(Packet, &(RsvdTemp->pMyBuffer)); NdisQueryBufferSafe(RsvdTemp->pMyBuffer, &(RsvdTemp->pMyContent), &BufLength, NormalPagePriority); NdisFreeBuffer(RsvdTemp->pMyBuffer); NdisFreeMemory(RsvdTemp->pMyContent,BufLength,0); NdisDprFreePacket(Packet); return; 不是自己的包就 m_pSendComplete(ProtocolBindingContext,Packet,Status); //这里保存了系统原来的SendCompletHandler 还是希望大家指点一下~~谢谢 |
|
6楼#
发布于:2009-12-28 20:59
另外,分配MYPACKET的相关三个变量,我是以全局来保存的.
extern PNDIS_PACKET MyPacket = NULL; extern PNDIS_BUFFER ndisBuffer = NULL; extern PUCHAR sendBuffer = NULL; |
|
7楼#
发布于:2010-01-03 00:15
调试下吧,看看蓝屏的滞后的显示的code 0xxxx开头的,然后找出代码对应的蓝屏原因。
|
|
8楼#
发布于:2010-01-09 00:52
。。。windbg源码调试一下,设置一下崩溃内存转储,再用windbg分析转储的.dmp文件 能看到蓝屏时的代码位置,加上蓝屏时的bug check号码,就知道原因了。
|
|
9楼#
发布于:2010-01-18 20:43
你的驱动是中间层驱动?包的来源是包池吗?我觉得不需要使用free释放,直接管理起来或者退回到包池就行了。我认为蓝屏是错误的资源释放导致的。尤其是在Pending状态下,这时微端口驱动还没完成数据的交换。
|
|
10楼#
发布于:2010-02-06 00:28
顶一下,不知道你解决了没有,我也碰到同样的问题,不知道有没有解决思路,我看到一个人在http://topic.csdn.net/u/20090507/16/30c1c01d-af94-42c4-83eb-ab22f25d40ce.html?seed=1788001109&r=63303041#r_63303041上面写了一个文章,但是好像也会蓝。不知道具体解决办法。
|
|