guocaijian
驱动牛犊
驱动牛犊
  • 注册日期2005-04-06
  • 最后登录2006-02-15
  • 粉丝0
  • 关注0
  • 积分137分
  • 威望21点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
阅读:2670回复:16

中间层驱动,分段高速传海量数据

楼主#
更多 发布于:2005-06-25 00:25
    数据从应用程序到中间层驱动,然后发送,接收相反.现已经实现一次发一单包.但在应用程序里测试了不断发送就不行了 for(int k=0;k<100000;k++){writefile(...,...,...,NULL);} 会出错!!!?
我的目的是分段并快速传输海量数据(每段还是很大),请问怎么连续传输?需要所谓的startio例程(没学会)吗?我觉得应该不需要啊,因为我的writefile是同步的,发送的时候被阻塞,程序不往下运行,返回了说明写数据并发送已经处理完,这样一来,处理完一个writefile才轮到下一个不需要IRP排队吧?这样理解对吗?我该怎么做?
zhaock
驱动太牛
驱动太牛
  • 注册日期2002-01-26
  • 最后登录2018-06-02
  • 粉丝3
  • 关注2
  • 积分73328分
  • 威望362317点
  • 贡献值1点
  • 好评度226点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2005-06-25 10:39
1.不需要StartIo,ndis 架构不需要StartIo
2.你发送数据实际上调用的还是NdisSend,不是同步函数,PtSendComplete返回的时候,才表明
数据发送真正完成
guocaijian
驱动牛犊
驱动牛犊
  • 注册日期2005-04-06
  • 最后登录2006-02-15
  • 粉丝0
  • 关注0
  • 积分137分
  • 威望21点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-06-25 11:15
PtSendComplete返回后,WriteFile才返回对吧?说明一切有关发送的东西都已经处理完毕,应用程序又可以调用执行下一个WriteFile ,就不会出现第一个WriteFile还没处理完就来第二个导致冲突的情况对吗?这样不需要对IRP串行处理就能实现分段多包发送了是吗?
for(int k=0;k<100000;k++){writefile(...,...,...,NULL);} 出错会是什么原因,而且k<100000出错,K<10就没错,是不是我内存没处理好。
zhaock
驱动太牛
驱动太牛
  • 注册日期2002-01-26
  • 最后登录2018-06-02
  • 粉丝3
  • 关注2
  • 积分73328分
  • 威望362317点
  • 贡献值1点
  • 好评度226点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2005-06-25 11:23
>>PtSendComplete返回后,WriteFile才返回对吧
需要你自己要写代码处理,系统不会替你这么做。你可以参考ddk\networks\ndis\ndisuio的例子

具体什么错误,描述一下.
guocaijian
驱动牛犊
驱动牛犊
  • 注册日期2005-04-06
  • 最后登录2006-02-15
  • 粉丝0
  • 关注0
  • 积分137分
  • 威望21点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2005-06-25 11:39
我是在PtSendComplete里面完成IRP这样没错吧,可以实现我说的功能吧?
for(int k=0;k<100000;k++){writefile(...,...,...,NULL);} 执行到一半,SOFTICE弹出来报错。是不是这样理论上是可以的,?因为一个一个WriteFile 的处理不冲突。
zhaock
驱动太牛
驱动太牛
  • 注册日期2002-01-26
  • 最后登录2018-06-02
  • 粉丝3
  • 关注2
  • 积分73328分
  • 威望362317点
  • 贡献值1点
  • 好评度226点
  • 原创分0分
  • 专家分0分
  • 社区居民
5楼#
发布于:2005-06-25 12:12
这样处理理论上没有问题
guocaijian
驱动牛犊
驱动牛犊
  • 注册日期2005-04-06
  • 最后登录2006-02-15
  • 粉丝0
  • 关注0
  • 积分137分
  • 威望21点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2005-06-26 16:43
拿passthru来修改,我把中间层驱动当作协议层驱动来用,在分发历程的写函数里面仿照2000DDK的packet例子自己构造数据报然后ndissend发送出去,这样原来的MPSend()里面也有ndissend,他们共用一个PtSendcomplete(释放数据包时区别对待),这样会不会冲突,刚好某个时候都要调用它?因为我循环调用WriteFile 有时候会出错,有时候又不会,而且单个调用WriteFile的时候一般不会出错。有什么办法阻止接收上层下来的包?
zhaock
驱动太牛
驱动太牛
  • 注册日期2002-01-26
  • 最后登录2018-06-02
  • 粉丝3
  • 关注2
  • 积分73328分
  • 威望362317点
  • 贡献值1点
  • 好评度226点
  • 原创分0分
  • 专家分0分
  • 社区居民
7楼#
发布于:2005-06-26 22:02
不会冲突.驱动本来就是可重入的.现在你碰到的是什么错误?softice弹出来后,用stack看一下内容,记得把ntoskrnl,ndis的符号表都加载,试着分析一下问题出现在哪里,这也是做wndows驱动应该掌握的一种基本技能
guocaijian
驱动牛犊
驱动牛犊
  • 注册日期2005-04-06
  • 最后登录2006-02-15
  • 粉丝0
  • 关注0
  • 积分137分
  • 威望21点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2005-06-26 22:39
弹出来SoftICE界面说page fault,全是汇编语言,我无从下手啊?加载XXX.sys变为原代码我倒会调试.
接收是没问题的,发送我也严格仿照packet 例子,(只是队列用全局变量(因为 我不会存open这个变量))
所以我觉得没道理出错的,奇怪
LiuQF001
驱动牛犊
驱动牛犊
  • 注册日期2005-07-13
  • 最后登录2005-09-29
  • 粉丝0
  • 关注0
  • 积分24分
  • 威望5点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2005-07-27 20:49
guocaijian
 
我遇到了和你一样的问题!
一次发一单包没有问题,连续循环发送就蓝屏了,
我跟了一下,好象有时候连续两次调用了NDISSend后才两次调用PTsendcomplete,
会不会是这里的原因?我在NDISSend后等待Event,
在PTsendcomplete设置Event事件?应该没有问题的!
LiuQF001
驱动牛犊
驱动牛犊
  • 注册日期2005-07-13
  • 最后登录2005-09-29
  • 粉丝0
  • 关注0
  • 积分24分
  • 威望5点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2005-07-28 19:35
今天又跟踪了一下,发现把网卡线拔出就没有问题,插上就死!
现象为:
Beak due to KebugcheckEx(Unhandle kernel mode exception)
Error =A(IRQL_Not_LESS_OR_EQUAL) P1=1E p2=2 p3=0 p4=BFEF5D11

我用stack命令查看到的是: ntoskenl!kebugcheckEx+001
我看到的是汇编啊,还说我的ntoskenl的符号表没有加载!如何加载啊?HElp!
zhaock
驱动太牛
驱动太牛
  • 注册日期2002-01-26
  • 最后登录2018-06-02
  • 粉丝3
  • 关注2
  • 积分73328分
  • 威望362317点
  • 贡献值1点
  • 好评度226点
  • 原创分0分
  • 专家分0分
  • 社区居民
11楼#
发布于:2005-07-28 20:39
1.装载对应的os symbols, 2.用ds中的symbols retriever 只下载ntoskrnl的symbol就可以了.
然后用symbol loader加载ntoskrnl的symbol,
LiuQF001
驱动牛犊
驱动牛犊
  • 注册日期2005-07-13
  • 最后登录2005-09-29
  • 粉丝0
  • 关注0
  • 积分24分
  • 威望5点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2005-07-28 21:10
这是我的自己的发包函数,单个发没有问题的!
NDIS_STATUS
MPSendMyPacket(
       IN       NDIS_HANDLE                            MiniportAdapterContext       //,
       )
{
       PADAPT                     pAdapt = (PADAPT)MiniportAdapterContext;
       NDIS_STATUS              Status;
       PNDIS_PACKET       MyPacket;
       PRSVD                     Rsvd;
       PVOID                     MediaSpecificInfo = NULL;
       ULONG                     MediaSpecificInfoSize = 0;
       PUCHAR          pPacketLiuQF , ppLiuQF  ;
       int                            r=0 ;
    UINT                     BufLength;
       UINT                     PacketLen = 999 ;
       UINT                     bufLength;
       UINT                     rTT;
       PNDIS_BUFFER       PacketBuffer;
       PUCHAR                     pSndPacketContent;
       //lqf
      
       //       DbgPrint("==>MPSend(...)\n");
       //
       //  According to our LBFO design, all sends will be performed on the secondary miniport
       //       However, the must be completed on the primary's miniport handle
       //
      
       ASSERT (pAdapt->pSecondaryAdapt);      
       pAdapt = pAdapt->pSecondaryAdapt;      
      
       if (IsIMDeviceStateOn (pAdapt) == FALSE)
       {
              return NDIS_STATUS_FAILURE;
       }
      
       ///lqflqf      
//       if(pSndPacketContent==NULL)
       {
              Status = NdisAllocateMemory(&pSndPacketContent,2000,0, HighestAcceptableMax);//分配内存
              if (Status != NDIS_STATUS_SUCCESS )
              {
                     DbgPrint("mpsend: ndisallocatememory failed\n");
                     return NDIS_STATUS_FAILURE ;
              }
       }
       if(pSndPacketContent == NULL)
       {
              DbgPrint("mpsend: pSndPacketContent == NULL\n");
              return NDIS_STATUS_FAILURE ;
       }
      
       *(pSndPacketContent+00) = 0x00 ;
       *(pSndPacketContent+01) = 0x04 ;
       *(pSndPacketContent+02) = 0x76 ;
       *(pSndPacketContent+03) = 0xce ;
       *(pSndPacketContent+04) = 0x1f ;
       *(pSndPacketContent+05) = 0xc3 ; // DEll PC MAC Address

       rTT = 0 ;
       //              if(*((ULONG*)(pSndPacketContent))!=0xffffffff)
       {
              for( r=0 ; r<24 ; r++)
              {
                     *(pSndPacketContent+14+rTT) = 0 ;//(UCHAR)rTT ;
                     DbgPrint("%02X " , *(pSndPacketContent+rTT) );
                     rTT++ ;
                     //                                   if( rTT>=BufLength ) break ;
              }
              DbgPrint(" SND XY %04d ZXX %04d \n" , PacketLen , m_MyPacketCount);
       }      
      
       ///lqflqf      
       NdisAllocatePacket(&Status,
                                      &MyPacket,
                                      pAdapt->SendPacketPoolHandle);
       if(Status != NDIS_STATUS_SUCCESS)  //lqflqf
       {
              DbgPrint("nNdisAllocatePacket() failed\n");
              NdisFreeMemory(pSndPacketContent,2000,0); //没分配到包的时候释放内存
              return Status;
       }
      
       //              PNDIS_PACKET_EXTENSION       Old, New;
      
       NdisAllocateBuffer(&Status,&PacketBuffer,pAdapt->SendPacketPoolHandle, pSndPacketContent ,PacketLen);// 600 );//分配buffer
       //              NdisAllocateBuffer(&Status,&PacketBuffer,pAdapt->SendPacketPoolHandle, pSndPacketContent , 99 );//分配buffer
       NdisChainBufferAtFront( MyPacket, PacketBuffer);
      
       Rsvd = (PRSVD)(MyPacket->ProtocolReserved);
       Rsvd->OriginalPkt = NULL ; //Packet;
       Rsvd->PktMemory   = pSndPacketContent ;
       //              MyPacket->Private.Flags = Flags;
       MyPacket->Private.Head->Next = NULL;
       MyPacket->Private.Tail       = NULL;
       NdisSetPacketFlags(MyPacket, NDIS_FLAGS_DONT_LOOPBACK);
       //              NDIS_SET_PACKET_HEADER_SIZE(MyPacket,14);
       DbgPrint("PASSTHRU NdisSend002 \n");
      
       m_NdisSendpktFlag = 1 ;
       NdisSend(&Status,
              pAdapt->BindingHandle,
              MyPacket);
      
       //lqf
       if (Status != NDIS_STATUS_PENDING)
       {
              //                     NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket);
              NdisUnchainBufferAtFront(MyPacket ,&PacketBuffer);
              //                     NdisQueryBufferSafe(PacketBuffer,(PVOID *)&pPacketContent,&bufLength,32);
              if(PacketBuffer)
                     NdisFreeBuffer(PacketBuffer);
              if(pSndPacketContent)
                     NdisFreeMemory(pSndPacketContent,2000,0);
              PacketBuffer = NULL ;
              pSndPacketContent = NULL ;
              //              NdisDprFreePacket(MyPacket);
              NdisFreePacket(MyPacket);
              
       }
       else
       {
              NdisWaitEvent(&pAdapt->Event, 0);
       }
       NdisResetEvent(&pAdapt->Event);
       //       DbgPrint("<==MPSendMyPacket(...)\n");
       return(Status);
}

PtSendComplete()中我是这么处理的

                mPiont = Rsvd->PktMemory ;
       if(1==m_NdisSendpktFlag) ///myself packet
       {
              NdisUnchainBufferAtFront(Packet ,&PacketBuffer);
              if(PacketBuffer)
                     NdisFreeBuffer(PacketBuffer);        
              if(mPiont)
                     NdisFreeMemory(mPiont,2000,0);
              mPiont = NULL ;
              PacketBuffer = NULL ;
              NdisDprFreePacket(Packet);
              m_NdisSendpktFlag = 0 ;
              NdisSetEvent(&pAdapt->Event);
              //NdisMSendComplete(pAdapt->MiniportHandle, Pkt,Status);
       }      
       else       //lqflqf
       {
              NdisIMCopySendCompletePerPacketInfo (Pkt, Packet);
              NdisDprFreePacket(Packet);
              NdisMSendComplete(pAdapt->MiniportHandle,
                     Pkt,
                     Status);
       }
guocaijian
驱动牛犊
驱动牛犊
  • 注册日期2005-04-06
  • 最后登录2006-02-15
  • 粉丝0
  • 关注0
  • 积分137分
  • 威望21点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2005-08-05 11:10
除了没有使用事件机制外,大体看了以上代码,我的和LiuQF001的程序思想大体差不多,PtSendComplete释放包也是那样分两种情况。可是至今还没解决连续发送的问题,难在到第几个包出错有一定的随机性,对开发工具使用不熟啊,(1.装载对应的os symbols, 2.用ds中的symbols retriever 只下载ntoskrnl的symbol就可以了.然后用symbol loader加载ntoskrnl的symbol,)这些话没看懂,我得好好学习一下,丢脸了。
LiuQF001
驱动牛犊
驱动牛犊
  • 注册日期2005-07-13
  • 最后登录2005-09-29
  • 粉丝0
  • 关注0
  • 积分24分
  • 威望5点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2005-08-05 20:05
这个问题已经解决!
guocaijian
驱动牛犊
驱动牛犊
  • 注册日期2005-04-06
  • 最后登录2006-02-15
  • 粉丝0
  • 关注0
  • 积分137分
  • 威望21点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2005-08-06 15:55
LiuQF001!请问是怎么解决的?是怎么回事?单个发送没错,循环连续发送为什么蓝屏?恳求指导啊!!!!!!!!!!
guocaijian
驱动牛犊
驱动牛犊
  • 注册日期2005-04-06
  • 最后登录2006-02-15
  • 粉丝0
  • 关注0
  • 积分137分
  • 威望21点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2005-08-08 17:40
请问各位到底是怎么回事啊?郁闷中,等待中
游客

返回顶部