阅读:3175回复:7
在内核线程中向上抛数据包调用NdisMIndicateReceivePacket蓝屏
我在PtRecieve里面接收到数据包后放入队列 队列定义如下:
typedef struct _MYDATASTRUCT { LIST_ENTRY ListEntry; PUCHAR pPacketList;//存放数据包 UINT Packetlenth;//数据包长度 PADAPT pAdapt;//这个参数主要是取绑定的上下文 PtRecieve的第一个参数 因为在线程中向上层抛数据的时候要用到 UINT HeaderBufferSize;//数据包头的长度 ULONG number;//列表计数 } MYDATASTRUCT, *PMYDATASTRUCT; 在PtRecieve函数里是将接收到得数据包放入队列 代码如下: PMYDATASTRUCT pData; 。。。。。。 Status = NdisAllocateMemoryWithTag((PVOID *)&pData->pPacketList, BUFFER_SIZE, 'maDN'); if(Status != NDIS_STATUS_SUCCESS) { return(NDIS_STATUS_NOT_ACCEPTED); } if(pData->pPacketList == NULL) { DbgPrint("PTReceive:pData->pPacketList==NULL\n"); return(NDIS_STATUS_NOT_ACCEPTED); } NdisMoveMemory(pData->pPacketList, pPacketContent, PacketLen); pData->pAdapt = pAdapt; pData->Packetlenth=PacketLen; pData->HeaderBufferSize = HeaderBufferSize; pData->number++; InsertTailList(&linkListHead,&pData->ListEntry); 然后是在内核线程里面的处理了: if (pData->pPacketList != NULL) { DBGPRINT(("列表不为空、。。。。。。。。。。。。")); --------------------------------------------------将队列中的包取出来 NdisMoveMemory(pPacketContent, pData->pPacketList, pData->Packetlenth); PacketLen = pData->Packetlenth; { --------------------------------------------------将包处理完后开始关联包 NdisDprAllocatePacket(&Status, &MyPacket, pData->pAdapt->RecvPacketPoolHandle); if(Status == NDIS_STATUS_SUCCESS) { DbgPrint("--------------------------------------------------------线程中分配包描述符成功.\n"); NdisAllocateBuffer(&Status, &pPacketBuffer, pData->pAdapt->RecvBufferPoolHandle, pPacketContentlast,PacketLenlast); NdisChainBufferAtFront(MyPacket, pPacketBuffer); MyPacket->Private.Head->Next = NULL; MyPacket->Private.Tail = NULL; RecvRsvd=(PRECV_RSVD)(MyPacket->MiniportReserved); RecvRsvd->OriginalPkt = NULL; NDIS_SET_PACKET_HEADER_SIZE(MyPacket, pData->HeaderBufferSize); NdisMIndicateReceivePacket((pData->pAdapt)->MiniportHandle, &MyPacket, 1); ///////////到这里就蓝屏了 if(NDIS_GET_PACKET_STATUS(MyPacket) != NDIS_STATUS_PENDING) { DBGPRINT(("In PtReceive And Free Memory\n")); NdisFreeBuffer(pPacketBuffer); // NdisFreeMemory(pPacketContent, BUFFER_SIZE, 0); // // NdisFreeMemory(pData->pPacketList, BUFFER_SIZE, 0); NdisFreeMemory(pPacketContentlast, BUFFER_SIZE, 0); NdisDprFreePacket(MyPacket); } } else { DbgPrint("--------------------------------------------------------线程中分配包描述符失败.\n"); } } pEntry = RemoveTailList(&linkListHead); pData = CONTAINING_RECORD(pEntry, MYDATASTRUCT, ListEntry); pData->number--; KdPrint(("%d\n",pData->number)); } MPReturnPacket函数也进行处理了 不知道为什么到了NdisMIndicateReceivePacket((pData->pAdapt)->MiniportHandle, &MyPacket, 1);就蓝屏了 在线程里面蓝屏 在接收函数里面我也向上抛数据了正常 不知道为什么 |
|
沙发#
发布于:2010-05-18 12:05
难道就没有人出来解答一下吗?帖子都发了N天了
|
|
板凳#
发布于:2010-05-20 22:21
有dump文件吗?看看BSOD发生在什么地方?
|
|
地板#
发布于:2010-05-27 16:15
我也总是碰到这种蓝屏的事情!但是最后发现基本上都是自己在写程序时,某些问题考虑到不够好,导致一些指针为NULL导致
|
|
地下室#
发布于:2010-09-01 18:47
如果你写中间层驱动遇到NdisReturnPackets+0x48处崩溃,原因在于:
底层提交给了的packet,而此包是不能被重用的;而你却又通过NdisReturnpackets返回给底层; 解决方法: 1)确认底层给你的包如果是不能被重用的,你不能通过NdisReturnpackets返回给他; 2)在MPReturnPackets中通过 PNDIS_PACKET_STACK NdisIMGetCurrentPacketStack( PNDIS_PACKET Packet, BOOLEAN* StacksRemaining );对提交给底层的packet进行进一步判断: PNDIS_PACKET_STACK stack; BOOLEAN StacksRemaining; stack=NdisIMGetCurrentPacketStack(oldPacket,&StacksRemaining); if(StacksRemaining) //must have!!! { NdisReturnPackets(&oldPacket,1); } { DbgPrint("we can not return the packet,becase the down layer maybe has Freed the packet,if you return the packet,it may be free twice!"); } 你用windbg分析下dump,如果NdisReturnPackets+0x48崩溃,上面的可能对你有帮助. |
|
5楼#
发布于:2011-01-08 11:57
我和楼主碰到同样的问题,NdisMIndicateReceivePacket处蓝屏。
dump大致的意思是“在DISPATCH_LEVEL下访问了分页内存,或者该内存不可用。“ =================================================== 这段内存应该是非分页内存,唯一的可能是内存不可用。但是内存也是在PtRecieve中自己new出来的,很奇怪哦。 哪位大人解释一下。 |
|
6楼#
发布于:2011-01-08 12:33
貌似知道原因了,我去实验下,一会儿回来回复
|
|