阅读:2670回复:16
中间层驱动,分段高速传海量数据
数据从应用程序到中间层驱动,然后发送,接收相反.现已经实现一次发一单包.但在应用程序里测试了不断发送就不行了 for(int k=0;k<100000;k++){writefile(...,...,...,NULL);} 会出错!!!?
我的目的是分段并快速传输海量数据(每段还是很大),请问怎么连续传输?需要所谓的startio例程(没学会)吗?我觉得应该不需要啊,因为我的writefile是同步的,发送的时候被阻塞,程序不往下运行,返回了说明写数据并发送已经处理完,这样一来,处理完一个writefile才轮到下一个不需要IRP排队吧?这样理解对吗?我该怎么做? |
|
沙发#
发布于:2005-06-25 10:39
1.不需要StartIo,ndis 架构不需要StartIo
2.你发送数据实际上调用的还是NdisSend,不是同步函数,PtSendComplete返回的时候,才表明 数据发送真正完成 |
|
板凳#
发布于:2005-06-25 11:15
PtSendComplete返回后,WriteFile才返回对吧?说明一切有关发送的东西都已经处理完毕,应用程序又可以调用执行下一个WriteFile ,就不会出现第一个WriteFile还没处理完就来第二个导致冲突的情况对吗?这样不需要对IRP串行处理就能实现分段多包发送了是吗?
for(int k=0;k<100000;k++){writefile(...,...,...,NULL);} 出错会是什么原因,而且k<100000出错,K<10就没错,是不是我内存没处理好。 |
|
地板#
发布于:2005-06-25 11:23
>>PtSendComplete返回后,WriteFile才返回对吧
需要你自己要写代码处理,系统不会替你这么做。你可以参考ddk\networks\ndis\ndisuio的例子 具体什么错误,描述一下. |
|
地下室#
发布于:2005-06-25 11:39
我是在PtSendComplete里面完成IRP这样没错吧,可以实现我说的功能吧?
for(int k=0;k<100000;k++){writefile(...,...,...,NULL);} 执行到一半,SOFTICE弹出来报错。是不是这样理论上是可以的,?因为一个一个WriteFile 的处理不冲突。 |
|
5楼#
发布于:2005-06-25 12:12
这样处理理论上没有问题
|
|
6楼#
发布于:2005-06-26 16:43
拿passthru来修改,我把中间层驱动当作协议层驱动来用,在分发历程的写函数里面仿照2000DDK的packet例子自己构造数据报然后ndissend发送出去,这样原来的MPSend()里面也有ndissend,他们共用一个PtSendcomplete(释放数据包时区别对待),这样会不会冲突,刚好某个时候都要调用它?因为我循环调用WriteFile 有时候会出错,有时候又不会,而且单个调用WriteFile的时候一般不会出错。有什么办法阻止接收上层下来的包?
|
|
7楼#
发布于:2005-06-26 22:02
不会冲突.驱动本来就是可重入的.现在你碰到的是什么错误?softice弹出来后,用stack看一下内容,记得把ntoskrnl,ndis的符号表都加载,试着分析一下问题出现在哪里,这也是做wndows驱动应该掌握的一种基本技能
|
|
8楼#
发布于:2005-06-26 22:39
弹出来SoftICE界面说page fault,全是汇编语言,我无从下手啊?加载XXX.sys变为原代码我倒会调试.
接收是没问题的,发送我也严格仿照packet 例子,(只是队列用全局变量(因为 我不会存open这个变量)) 所以我觉得没道理出错的,奇怪 |
|
9楼#
发布于:2005-07-27 20:49
guocaijian
我遇到了和你一样的问题! 一次发一单包没有问题,连续循环发送就蓝屏了, 我跟了一下,好象有时候连续两次调用了NDISSend后才两次调用PTsendcomplete, 会不会是这里的原因?我在NDISSend后等待Event, 在PTsendcomplete设置Event事件?应该没有问题的! |
|
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! |
|
11楼#
发布于:2005-07-28 20:39
1.装载对应的os symbols, 2.用ds中的symbols retriever 只下载ntoskrnl的symbol就可以了.
然后用symbol loader加载ntoskrnl的symbol, |
|
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); } |
|
13楼#
发布于:2005-08-05 11:10
除了没有使用事件机制外,大体看了以上代码,我的和LiuQF001的程序思想大体差不多,PtSendComplete释放包也是那样分两种情况。可是至今还没解决连续发送的问题,难在到第几个包出错有一定的随机性,对开发工具使用不熟啊,(1.装载对应的os symbols, 2.用ds中的symbols retriever 只下载ntoskrnl的symbol就可以了.然后用symbol loader加载ntoskrnl的symbol,)这些话没看懂,我得好好学习一下,丢脸了。
|
|
14楼#
发布于:2005-08-05 20:05
这个问题已经解决!
|
|
15楼#
发布于:2005-08-06 15:55
LiuQF001!请问是怎么解决的?是怎么回事?单个发送没错,循环连续发送为什么蓝屏?恳求指导啊!!!!!!!!!!
|
|
16楼#
发布于:2005-08-08 17:40
请问各位到底是怎么回事啊?郁闷中,等待中
|
|