vipfengxiao
驱动牛犊
驱动牛犊
  • 注册日期2009-12-29
  • 最后登录2011-12-21
  • 粉丝1
  • 关注0
  • 积分79分
  • 威望681点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:3104回复:7

在内核线程中向上抛数据包调用NdisMIndicateReceivePacket蓝屏

楼主#
更多 发布于:2010-05-14 12:06
我在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);就蓝屏了
在线程里面蓝屏 在接收函数里面我也向上抛数据了正常  不知道为什么
vipfengxiao
驱动牛犊
驱动牛犊
  • 注册日期2009-12-29
  • 最后登录2011-12-21
  • 粉丝1
  • 关注0
  • 积分79分
  • 威望681点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2010-05-18 12:05
难道就没有人出来解答一下吗?帖子都发了N天了
jasic2002
驱动牛犊
驱动牛犊
  • 注册日期2003-10-26
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望37点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2010-05-20 22:21
有dump文件吗?看看BSOD发生在什么地方?
hyzimbtb
驱动牛犊
驱动牛犊
  • 注册日期2004-08-27
  • 最后登录2010-11-10
  • 粉丝2
  • 关注0
  • 积分387分
  • 威望216点
  • 贡献值0点
  • 好评度45点
  • 原创分0分
  • 专家分0分
地板#
发布于:2010-05-27 16:15
我也总是碰到这种蓝屏的事情!但是最后发现基本上都是自己在写程序时,某些问题考虑到不够好,导致一些指针为NULL导致
forxy
驱动牛犊
驱动牛犊
  • 注册日期2010-08-02
  • 最后登录2013-01-15
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望91点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于: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崩溃,上面的可能对你有帮助.
x1aon1ao
驱动牛犊
驱动牛犊
  • 注册日期2009-12-04
  • 最后登录2012-02-25
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望211点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2011-01-08 11:57
我和楼主碰到同样的问题,NdisMIndicateReceivePacket处蓝屏。

dump大致的意思是“在DISPATCH_LEVEL下访问了分页内存,或者该内存不可用。“

===================================================

这段内存应该是非分页内存,唯一的可能是内存不可用。但是内存也是在PtRecieve中自己new出来的,很奇怪哦。
哪位大人解释一下。
x1aon1ao
驱动牛犊
驱动牛犊
  • 注册日期2009-12-04
  • 最后登录2012-02-25
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望211点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2011-01-08 12:33
  貌似知道原因了,我去实验下,一会儿回来回复
iihacker
论坛版主
论坛版主
  • 注册日期2010-01-07
  • 最后登录2017-08-16
  • 粉丝5
  • 关注8
  • 积分377分
  • 威望1941点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
7楼#
发布于:2011-01-08 21:55
引用楼主vipfengxiao于2010-05-14 12:06发表的 在内核线程中向上抛数据包调用NdisMIndicateReceivePacket蓝屏 :
我在PtRecieve里面接收到数据包后放入队列 队列定义如下:
typedef struct _MYDATASTRUCT
{
 LIST_ENTRY ListEntry;
 PUCHAR pPacketList;//存放数据包
.......



如果你的PtReceivePackets 没有做处理,只是处理了解析的部分。NDIS是这样理解的,通知NDIS上层协议收包,并且小端口协议会在MPReturnPacket中释放包。 但是这个包是你自己生成的,并不是小端口层传下来的,小端口并不知道,释放蓝屏。



建议把PtReceivePackets /PtReceive张贴出来

NDIS 1群74755180 NDIS 2群182802097 交换机软硬件技术群 187471475 FPGA PCI PCIE 群187471817
游客

返回顶部