quarkfc
驱动牛犊
驱动牛犊
  • 注册日期2001-07-13
  • 最后登录2006-07-26
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望3点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
阅读:2675回复:18

Passthru:胡大侠的代码为撒当PacketSize>LookAheadBufferSize,在PtTransferDataComplete中重新组装Indicate网络不通(附代码)?

楼主#
更多 发布于:2003-01-13 10:32
参考胡大侠的代码,我已经搞定了mpSend(屏蔽掉sendPacket),接收时候的ptRecv(屏蔽掉ptRecvPacket)在Packet = NdisGetReceivedPacket时候,Packet!=空也可以,
当Packet==NULL,当PacketSize <= LookAheadBufferSize也通了,
就是当PacketSize > LookAheadBufferSize时候(如果ping包大于128,就会走这条路),因为只是返回了一部分Packet数据,需要在PtTransferDataComplete中重新组装新的数据报,我跟踪了所有函数,返回都是成功,但是网络就是不通,因为indicate上去的数据报是两个Packet组装起来的,我开始用的PTRecv中返回的OOB数据,后来换成PtTransferDataComplete中返回的Packet的OOB数据,依然不通,哪位前辈帮我看看下面的代码,谢谢了,或者哪位有已经通过的PtTransferDataComplete给我参考参考。stand_fucai@163.com。

VOID
PtTransferDataComplete(
IN  NDIS_HANDLE ProtocolBindingContext,
IN  PNDIS_PACKET Packet,
IN  NDIS_STATUS Status,
IN  UINT BytesTransferred
)
/*++

Routine Description:

Entry point called by NDIS to indicate completion of a call by us
to NdisTransferData.

See notes under SendComplete.

Arguments:

Return Value:

--*/
{
PADAPT  pAdapt =(PADAPT)ProtocolBindingContext;
PUCHAR pPacketContent;
PRECV_RSVD Resvd;
UINT OffsetSize;
UINT result;
UINT PacketLen;
PVOID MediaSpecificInfo = NULL;
ULONG MediaSpecificInfoSize = 0;
PNDIS_BUFFER PacketBuffer;
PNDIS_PACKET OffsetPacket;
PNDIS_BUFFER OffsetBuffer;
PUCHAR pBakContent;
UINT bufLength;
NDIS_STATUS status;
NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress;
HighestAcceptableAddress.LowPart = -1;
HighestAcceptableAddress.HighPart = -1;


Resvd = (PRECV_RSVD)(Packet->MiniportReserved);
OffsetPacket = (PNDIS_PACKET)Resvd->OriginalPkt;

if(pAdapt->MiniportHandle)
{
//NdisMTransferDataComplete(pAdapt->MiniportHandle,Packet,Status,BytesTransferred);
DbgPrint(\"PtTransferDataComplete(BytesTransferred:%d)! OffsetPacket:%x Packet:%x\\n\",BytesTransferred,OffsetPacket,Packet);
if (OffsetPacket==NULL){//如果为空,则说明不是自己请求的传输动作,直接调用结束即可
NdisMTransferDataComplete(pAdapt->MiniportHandle,Packet,Status,BytesTransferred);
}else{
status = NdisAllocateMemory(&pPacketContent,2000,0,HighestAcceptableAddress);
CopyPacket2Buffer(OffsetPacket,pPacketContent,&OffsetSize);
CopyPacket2Buffer(Packet,pPacketContent+OffsetSize,&PacketLen);//packetlen == bytestransferred
PacketLen+=OffsetSize;


//result = RecvProcess(pAdapt,pPacketContent,&PacketLen);
//if( result == PACKET_REFUSE ){
// MPReturnPacket((NDIS_HANDLE)pAdapt,Packet);
// DbgPrint(\"recvprocess return packet_refuse\\n\");
// return;
//}
NdisUnchainBufferAtFront( Packet,&PacketBuffer );
NdisQueryBufferSafe(PacketBuffer,&pBakContent,&bufLength,32);
NdisFreeBuffer(PacketBuffer);
NdisFreeMemory(pBakContent,2000,0);
//重新构造完整数据报对应的Packet!
//add@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@没有下面代码,还是不通
NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(Packet),
  NDIS_OOB_DATA_FROM_PACKET(OffsetPacket),
  sizeof(NDIS_PACKET_OOB_DATA));
NdisIMCopySendPerPacketInfo(Packet, OffsetPacket);
NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(OffsetPacket,
&MediaSpecificInfo,
&MediaSpecificInfoSize);

if (MediaSpecificInfo || MediaSpecificInfoSize){
NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(Packet,
MediaSpecificInfo,
MediaSpecificInfoSize);
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// 手动释放原来的offsetpacket
NdisUnchainBufferAtFront( OffsetPacket,&OffsetBuffer );
NdisQueryBufferSafe(OffsetBuffer,&pBakContent,&bufLength, 32 );
NdisFreeBuffer(OffsetBuffer);
NdisFreeMemory(pBakContent,2000,0);
NdisFreePacket(OffsetPacket);

memset(Packet->MiniportReserved,0,sizeof(Packet->MiniportReserved));

NdisAllocateBuffer(&status,&PacketBuffer,pAdapt->RecvPacketPoolHandle,pPacketContent,PacketLen);
NdisChainBufferAtFront(Packet,PacketBuffer);
Packet->Private.Head->Next =NULL;
Packet->Private.Tail=NULL;
NDIS_SET_PACKET_HEADER_SIZE(Packet,14);
DbgPrint(\"PtTransferDataComplete:Will NdisMIndicateReceivePacket: Packet:%x\\n\",Packet);
NdisMIndicateReceivePacket(pAdapt->MiniportHandle ,&Packet,1);
status=NDIS_GET_PACKET_STATUS(Packet);
DbgPrint(\"PtTransferDataComplete:NdisMIndicateReceivePacket return Code:%d\\n\",status);
if(status!= NDIS_STATUS_PENDING)
{
DbgPrint(\"PtTransferDataComplete:NdisMIndicateReceivePacket Not Pending Will MPReturnPacket:Packet:%x\\n\",Packet);
MPReturnPacket((NDIS_HANDLE)pAdapt,Packet);
}else{
DbgPrint(\"PtTransferDataComplete:NdisMIndicateReceivePacket Pending Packet:%x\\n\",Packet);
}
}//offsetPacket!=NULL
}
}
附件名称/大小 下载次数 最后更新
2003-01-13_PtTransferDataComplete.cpp (4KB)  37

最新喜欢:

peralperal
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-01-13 10:48
重新组包算校验和了么?
还有,packet是你导致分片的么?如果不是你为什么要组包?
学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-01-13 10:55
ndistransferdata并不需要组包,本来就是一个packet里面的东西,你为什么说是两个packet?难道你是用两个pacekt接收的?如果你是用了两个packet估计肯定用问题了。
学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
quarkfc
驱动牛犊
驱动牛犊
  • 注册日期2001-07-13
  • 最后登录2006-07-26
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望3点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-01-13 11:21
是要组包压,因为在ptReve中只是接收到一个完整数据报的一部分,
另外部分在TransdataComplete中得到,那么不是在TransdataComplete中将原来的数据与现在的数据一起合成一个数据报,应该不需要算CheckSum,因为是一个原始数据报在不通地方得到不通部分而已,我看了几个贴出来的代码,都没有算CheckSum,不知道为什么我的不通,他们贴出来的就通了。还恳请大侠指教!

注意:在PtRecv中先申请了一个Packet,将已经得到的数据放在此Packet中,也就是TransdataComplete中的OffsetPacket,
Resvd = (PRECV_RSVD)(Packet->MiniportReserved);
OffsetPacket = (PNDIS_PACKET)Resvd->OriginalPkt;
再又生成一个Packet,用此Packet来调用NdisTransData,
NdisTransferData(&Status,pAdapt->BindingHandle ,MacReceiveContext,LookAheadBufferSize, PacketSize-LookAheadBufferSize ,MyPacket,&BytesTransferred);
以得到剩余的数据,
在TransdataComlete中也就是将这两个Packet数据组合到一个Packet中,可参见代码,为什么不通呢?
普通的ping包因为PacketSize <= LookAheadBufferSize所以不需要调用NDISTRansdata,可以Ping通,当ping X.X.X.X -l 129(大于128),
走的是TransData,就是不通。
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-01-13 11:47
 
再又生成一个Packet,用此Packet来调用NdisTransData

不用在生成一个packet,如果你方才申请的buffer不够用,那就在申请一个buffer,然后把这个buffer链到原先的packet上去就可以了。
不过ndistransferdata只会向第一个buffer里面copy数据,所以这时候你有两个选择,或者直接从lookaheardbuffer里面copy出来packetsize大小的内容来,如果你不放心,那就让ndistransferdata从0开始传递数据,这样就可以了,不要再分配一个packet,
然后要别忘了OOB数据。
学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
quarkfc
驱动牛犊
驱动牛犊
  • 注册日期2001-07-13
  • 最后登录2006-07-26
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望3点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-01-13 15:08
我现在就是对自己生成Packet的OOB数据不知道怎么处理。
对于自己生成的Packet,OOB数据怎么设置呢?
另外,如果不用再申请Packet,那么,是不是就在PTRecv中直接生成Packet,Indicate上去?但是如果Ndistransdata pending怎么办?
恳请大侠指教!
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-01-13 15:40
首先你分配的buffer 的size应该是packetsize大小,然后如果lookaheadbuffersize<packetsize,你传给ndistransferdata这个packet,如果是pending,那就在transfercomeplete里面处理好了,这时候你还是能得到这个packet吖。

至于oob数据,可以用ddk里面的宏来得到,然后在对你分配的packet进行设置。如果调用了ndistransferdata,应该就不用在特意设置这些数据了。
学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-01-13 15:47
实际的packet的大小应该是packetsize+headbuffersize。
不过如果你调用ndistransferdata从offet 0开始传递数据,这时候是没有headbuffer的,在向上交包时要特别处理一下
学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-01-13 15:51
在很多lookaheadbuffersize<packetsize的情况下,你直接从lookaheadbuffer里面copy出来packetsize大小的内容来就可以了。因为都在那里放着呢
学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
quarkfc
驱动牛犊
驱动牛犊
  • 注册日期2001-07-13
  • 最后登录2006-07-26
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望3点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-01-13 16:17
谢谢楼上大侠指教,我直接从lookaheadbuffer里面copy出来packetsize大小的内容,重新生成新的数据报,没有调用Tranferdata,居然通了。不过我大为不解压,如果是这样,
NDIS把lookaheadbuffer设置为PacketSize不就可以了吗?为什么还要别人去NdisTransferData,还有,是不是所有的网卡都是这样直接copy PacketSize也可以呢?比如在拨号网卡情况下,行的通吗?
谢谢!
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-01-13 16:24
设计这样的方式是在以前使用的,现在的网卡一般都是把所有数据一次交上来的。拨号我没有试过,你可以试一下,看看是什么结果。我是用ndistransferdata从0开始取数据的:)
学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
quarkfc
驱动牛犊
驱动牛犊
  • 注册日期2001-07-13
  • 最后登录2006-07-26
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望3点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2003-01-13 16:38
听说现在的网卡大部分都是直接调用PtRecvPacket,而不是PtRecv,
为了处理简单一点,我将PtRecvPacketHandle=NULL,让NDIS只是调用PtRecv,不知道行缶?由于我试验了几台机器,在我屏蔽RecvPacket之前,都只是调用了RecvPacket,因此,只好询问大侠了。
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2003-01-13 16:40
注册的时候PtRecvPacketHandle=NULL就可以了,就只会调用receive 了。

其实你在receivepacket里面处理不是更好么?收到的都是完整的packet了。
学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
quarkfc
驱动牛犊
驱动牛犊
  • 注册日期2001-07-13
  • 最后登录2006-07-26
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望3点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2003-01-13 22:27
按照您的方法,直接从LookaheaderBuffer中拷贝PacketSize字节,在实验室的机器上可以通,但是寝室的机器就不行了,估计还是不是标准做法,导致兼容性不够,我寝室是老式Realtek RTL8029网卡,我想还是按照老胡的代码,在NdisTRansData中处理完整数据报,也就是我提问题贴出来的代码,
烦大侠再帮我看看,好吗?谢谢,我可以再开贴子给分。
quarkfc
驱动牛犊
驱动牛犊
  • 注册日期2001-07-13
  • 最后登录2006-07-26
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望3点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2003-01-17 16:07
到底有没有在TransDataComplete中重新组装数据报Indicate上去成功的?我试验了XPPassthru与2KPassthru,照胡大侠代码改的,
就是当数据报大于一定数值网络就不通。

恳请已经调通了这条路的大侠们指教!
quarkfc
驱动牛犊
驱动牛犊
  • 注册日期2001-07-13
  • 最后登录2006-07-26
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望3点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2003-01-17 20:59
FT,还是自己发现了其中的Bug.
胡大侠的代码没错。是我自己用错了一个变量。

今天用SoftICE总算发现了。

不靠天,不靠地,还是只能靠自己亚!
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2003-01-17 21:51
你会帮别人去改这种程序错误么?
学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
quarkfc
驱动牛犊
驱动牛犊
  • 注册日期2001-07-13
  • 最后登录2006-07-26
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望3点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2003-01-17 23:34
确实。这种错误很花时间与精力。
关键还是靠自己的细心调试与检查。
我总是抱着一丝幻想,也许别人会指出来。结果,耽误了时间。
不过,通过这次错误的查找,也学会了核心太调试的一些技巧。

呵呵,今后我会尽量帮别人的啦。
也谢谢楼上的大侠给我的帮助。
chili
驱动牛犊
驱动牛犊
  • 注册日期2004-03-31
  • 最后登录2011-03-29
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2004-05-31 10:50
我现在遇到和你一样的问题,我是把包收下后保存在自己的队列中(队列映射了包的信息),然后经过处理后再发送,也是当包大于某一值的时候有你说的那个问题。可以告诉我怎么解决的吗?谢谢了!
游客

返回顶部