yellowzzp
驱动小牛
驱动小牛
  • 注册日期2007-07-16
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1015分
  • 威望131点
  • 贡献值0点
  • 好评度117点
  • 原创分0分
  • 专家分0分
阅读:2079回复:7

请教Passthru中间层 驱动 发包蓝屏问题

楼主#
更多 发布于:2007-08-09 18:09
代码如下:
VOID SendArpPacket(PARPHeader apPacket)
{
    PNDIS_PACKET  ArpPacket ;
    NDIS_STATUS        Status;
    PNDIS_BUFFER  buffer;
    
    //分配一段 长度为60的内存
    Status = NdisAllocateMemory( &pPacketContent, 60, 0,HighestAcceptableMax);
    if(Status!=NDIS_STATUS_SUCCESS )    
    {
        return ;
    }
    //对他进行清0操作
    NdisZeroMemory(pPacketContent,60);

    //把ARP头拷贝到 分配的内存中
    NdisMoveMemory(pPacketContent,apPacket,sizeof(PARPHeader));

    //从池中分配 包描述符 ArpPacket
    NdisDprAllocatePacket(&Status,&ArpPacket,hSendPool);
    
    //设置缓冲区描述符等
    NdisAllocateBuffer(&Status,&buffer,hSendPool,pPacketContent,60);
    //联接上
    NdisChainBufferAtFront( ArpPacket, buffer);

    ArpPacket->Private.Head->Next =NULL;
    ArpPacket->Private.Tail =NULL;
    NdisSetPacketFlags(ArpPacket, NDIS_FLAGS_DONT_LOOPBACK);

    NdisSend(&Status, pUnderAdapt->BindingHandle, ArpPacket);
    KdPrint(("发送Arp包完毕"));
}

按照ddk上面写的发包 步骤写的程序,,,谁帮忙看看为什么蓝屏

我程序是接到DeviceIoControl请求后,调用函数发送数据包。
上层应用程序一传递DeviceIoControl 请求这边就蓝屏了
问题肯定出在这个函数里
大家帮忙看看吧
yellowzzp
驱动小牛
驱动小牛
  • 注册日期2007-07-16
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1015分
  • 威望131点
  • 贡献值0点
  • 好评度117点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-08-09 23:22
就是按照ddk改的。.这个函数加上  发包就蓝屏..
ProPlayboy
驱动大牛
驱动大牛
  • 注册日期2005-07-07
  • 最后登录2022-02-15
  • 粉丝0
  • 关注0
  • 积分1016分
  • 威望811点
  • 贡献值0点
  • 好评度719点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2007-08-10 00:18
测试中,路过
人不靓仔心灵美,版头不正红花仔!
ProPlayboy
驱动大牛
驱动大牛
  • 注册日期2005-07-07
  • 最后登录2022-02-15
  • 粉丝0
  • 关注0
  • 积分1016分
  • 威望811点
  • 贡献值0点
  • 好评度719点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2007-08-10 00:19
调试靠猜?
人不靓仔心灵美,版头不正红花仔!
yellowzzp
驱动小牛
驱动小牛
  • 注册日期2007-07-16
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1015分
  • 威望131点
  • 贡献值0点
  • 好评度117点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-08-10 09:55
主要是不会调试 驱动。。只会用kdprint......感觉没问题了。。跟ddk里的例子差不多
yellowzzp
驱动小牛
驱动小牛
  • 注册日期2007-07-16
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1015分
  • 威望131点
  • 贡献值0点
  • 好评度117点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-08-10 12:04
NdisSetPacketFlags(ArpPacket, NDIS_FLAGS_DONT_LOOPBACK);

NdisSend(&Status, pUnderAdapt->BindingHandle, ArpPacket);
拿softice调试  就在这2句 出问题了

可是softice刚才又坏了。。一ctrl+d就蓝屏 显示模式改了半天也不成
newfire@163.com
驱动牛犊
驱动牛犊
  • 注册日期2008-01-29
  • 最后登录2011-07-18
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望133点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2008-11-11 11:23
新火(18089752)  10:57:08
经历2周 终于把passthru发包问题弄明白了现在把一点小小体会和大家分享一下
XXx(39034666)  10:57:56
passthru发包,是什么东西
新火(18089752)  10:58:23
//这是应用的接口不是重点
    case IOCTL_PTUSERIO_SENDPACKET:
        {
        if(uInSize>0)
            {
            if(PassthruSendPacket(pAdapt,pIoBuffer,uInSize))
                {
                status = STATUS_SUCCESS;
                }
            else
                status = STATUS_INVALID_DEVICE_REQUEST;
        
            }
        else
            status = STATUS_INVALID_PARAMETER;
        }
        break;
新火(18089752)  11:00:48
//这是PassthruSendPacket的代码 这个代码曾经蓝屏无数次
BOOLEAN  PassthruSendPacket(PADAPT pAdapt,UCHAR* pPacket,UINT uLength)
{
    PNDIS_PACKET            pNdisPacket;
    PNDIS_BUFFER            pNdisBuffer;
    PVOID                     pPacketContent = NULL;
    NDIS_PHYSICAL_ADDRESS    phyaddr = {-1};
    NDIS_STATUS                Status;
    
    //判断下层适配器是否可用
    if(pAdapt->MPDeviceState > NdisDeviceStateD0)
        {
        return FALSE;
        }
    
    //分配内存存放包内容
    Status = NdisAllocateMemory(&pPacketContent,uLength,0,phyaddr);
    if(Status!=NDIS_STATUS_SUCCESS )    
        {
        return FALSE;
        }
    //对他进行清0操作
    NdisZeroMemory(pPacketContent,uLength);

    //复制包内容到分配的内存中
    NdisMoveMemory(pPacketContent,pPacket,uLength);

    //从池中分配 包描述符 ArpPacket
    NdisDprAllocatePacket(&Status,&pNdisPacket,MySendPacketPool);
    if(NDIS_STATUS_SUCCESS != Status)
        {
        NdisFreeMemory(pPacketContent, uLength, 0);
        return FALSE;
        }

    //设置缓冲区
    NdisAllocateBuffer(&Status,&pNdisBuffer,MySendBufferPool,pPacketContent,uLength);
    if(NDIS_STATUS_SUCCESS != Status)
        {
        NdisDprFreePacket(pNdisPacket);
        NdisFreeMemory(pPacketContent, uLength, 0);
        return FALSE;
        }
    pNdisBuffer->Next = NULL;
    //联接上
    NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);
    //设置标志为自己定义的包
    NdisSetPacketFlags(pNdisPacket, NDIS_FLAGS_DONT_LOOPBACK);

    //发送自定义包 一直都卡在这里 一发包就蓝屏。
    NdisSend(&Status, pAdapt->BindingHandle, pNdisPacket);

    KdPrint(("发送自定义包完毕"));

    if (Status != NDIS_STATUS_PENDING)
        {
        NdisFreeBuffer(pNdisBuffer);
        NdisFreeMemory(pPacketContent,uLength,0);
        NdisDprFreePacket(pNdisPacket);
        }
    return TRUE;
}

新火(18089752)  11:07:38
//蓝屏的原因和解决办法
//蓝屏的原因是当我调用NdisSend 发包时 下层驱动发包后会调用PtSendComplete来通知上层驱动发送完毕需要释放包内存。而以前我一直没有在PtSendComplete里添加相关处理代码。只在PassthruSendPacket里找毛病自然不行。

//这是在PtSendComplete里添加的代码
  PoolHandle = NdisGetPoolFromPacket(Packet);
    //判断是否为自身发的包
    if (PoolHandle == MySendPacketPool)
        {
        NdisDprFreePacket(Packet);
        return;
        }

新火(18089752)  11:10:50
//注意到这里有两个全局变量是我新定义的一个是MySendPacketPool另一个是MySendBufferPool它们是在passthru.c里定义在DriverEntry里初始化的

//Myself send pools
NDIS_HANDLE MySendBufferPool = NULL;
NDIS_HANDLE MySendPacketPool = NULL;
新火(18089752)  11:11:13
    //
        //  Allocate myself packet pools.
        //
        NdisAllocatePacketPoolEx(
            &Status,
            &MySendPacketPool,
            MIN_PACKET_POOL_SIZE,
            MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,
            sizeof(SEND_RSVD));
      
        if (Status != NDIS_STATUS_SUCCESS)
            {
            DBGPRINT(("AllocatePacketPool fails!"));
            break;
            }
        //
        //    Allocate myself send buffer pools
        //
        NdisAllocateBufferPool(
                &Status,
                &MySendBufferPool,
                MAX_SEND_PACKET_POOL_SIZE);
        if (Status != NDIS_STATUS_SUCCESS)
            {
            DBGPRINT(("AllocateBufferPool fails!"));
            break;
            }

新火(18089752)  11:12:28
通过以上的修改就可以发送自定义数据包了。
netelife
驱动牛犊
驱动牛犊
  • 注册日期2006-07-26
  • 最后登录2012-10-27
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望33点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2008-11-11 18:04
//这是在PtSendComplete里添加的代码
  PoolHandle = NdisGetPoolFromPacket(Packet);
    //判断是否为自身发的包
    if (PoolHandle == MySendPacketPool)
        {
        NdisDprFreePacket(Packet);
        return;
        }
好像还有其它资源没有释放掉。例如:pNdisBuffer和pPacketContent。
游客

返回顶部