阅读:1773回复:19
我真的要睡了,PtTransferCompelte
已经记不清多少次蓝屏了,从昨天下午到今天凌晨5点.本来前天已经改好了的passthru,但我在 PtTransferDataComplete里没有调用MPReturnPacket,按照板上的几个号称很稳定的帖子改了之后确一发不可收拾.5点回去睡觉,睡梦里对代码进行了n次排序,想要将方便面整齐的排列在袋子里确怎么也办不到.一夜白头,夭寿.就象GJP,我真的要睡着了
|
|
沙发#
发布于:2003-12-16 15:35
先撇开代码不谈,谈论几个问题.首先我觉得原理性的东西,自己弄明白最好,让大拿们教你,很多地方不自己操作还是不明白.但编程中的问题,还是希望斑竹大侠们尽量一语道名,对我们初学者来说自己摸索就是白白耗尽生命,你们确可使我们事半功倍.
下面是我没明白的几个问题 1.为何PtReceive中要调用PtTransferDataComplete,PtTransferDataComplete中要调用MPReturnPacket,直接里面写代码不行么,比如PtReceive中直接释放packet. 2.packet中多个buffer是什么关系 3.释放packet时先QuerySafe,再FreeBuff,FreeMemory,FreePacket,合理吗? 含有多个buffer是否会出问题 4.NdisFreeMemory(pPacketConetent,BUFFER_SIZE,0);合理吗,万一memory小于Buffersize呢,应该按获得长度free,构造buffer按长度分配memory,对吗? 5,NDIS_SET_PACKET_STATUS(Packet,NDIS_STATUS_RESOURCES)什么作用 |
|
板凳#
发布于:2003-12-16 15:40
我的代码:
VOID PtTransferDataComplete( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet, IN NDIS_STATUS Status, IN UINT BytesTransferred ) /*++ Routine Description: Same as the Send above, all sends need to be completed on the Primary\'s MiniportHandle Arguments: Return Value: --*/ { PADAPT pAdapt =(PADAPT)ProtocolBindingContext; // // Returning the Send on the Primary, will point to itself if there is no LBFO // /*pAdapt = pAdapt->pPrimaryAdapt; if(pAdapt->MiniportHandle) { NdisMTransferDataComplete(pAdapt->MiniportHandle, Packet, Status, BytesTransferred); }*/ PUCHAR pPacketContent,pBakContent; PRSVD Resvd; UINT OffsetSize,TotalSize; UINT result,i; UINT PacketLen; PNDIS_BUFFER pPacketBuffer; PNDIS_PACKET OffsetPacket; PNDIS_BUFFER pOffsetBuffer; UINT BufLength1,BufLength2; PVOID first; NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress; NDIS_STATUS status = NDIS_STATUS_SUCCESS; HighestAcceptableAddress.LowPart = -1; HighestAcceptableAddress.HighPart = -1; // // Returning the Send on the Primary, will point to itself if there is no LBFO // pAdapt = pAdapt->pPrimaryAdapt; Resvd = (PRSVD)(Packet->MiniportReserved); OffsetPacket = (PNDIS_PACKET)Resvd->OriginalPkt; if(pAdapt->MiniportHandle){ if (OffsetPacket==NULL){ NdisMTransferDataComplete(pAdapt->MiniportHandle, Packet, Status, BytesTransferred); } else { status = NdisAllocateMemory( &pPacketContent, BUFFER_SIZE, 0, HighestAcceptableAddress); CopyPacket2Buffer(OffsetPacket,pPacketContent,&BufLength1); CopyPacket2Buffer(Packet,(unsigned char *)pPacketContent+BufLength1,&BufLength2); PacketLen=BufLength1+BufLength2; DbgPrint(\"PacketLen:%d,buf1:%d,buf2:%d\\n\",PacketLen,BufLength1,BufLength2); NdisUnchainBufferAtFront(OffsetPacket,&pOffsetBuffer); NdisQueryBufferSafe(pOffsetBuffer,&pBakContent,&BufLength1,32); NdisFreeBuffer(pOffsetBuffer); NdisFreeMemory(pBakContent,BUFFER_SIZE,0); NdisFreePacket(OffsetPacket); memset(Packet->MiniportReserved,0,sizeof(Packet->MiniportReserved)); NdisUnchainBufferAtFront(Packet,&pPacketBuffer); NdisQueryBufferSafe(pPacketBuffer,&pBakContent,&BufLength2,32); NdisFreeBuffer(pPacketBuffer); NdisFreeMemory(pBakContent,BUFFER_SIZE,0); NdisAllocateBuffer(&status,&pPacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,PacketLen); NdisChainBufferAtFront(Packet,pPacketBuffer); Packet->Private.Head->Next =NULL; Packet->Private.Tail=NULL; NDIS_SET_PACKET_HEADER_SIZE(Packet,14); //NDIS_SET_PACKET_STATUS(Packet,NDIS_STATUS_RESOURCES); DbgPrint(\"\\nIn777:%d\",pAdapt->MiniportHandle); NdisMIndicateReceivePacket(pAdapt->MiniportHandle ,&Packet,1); DbgPrint(\"\\nIn888\"); if(NDIS_GET_PACKET_STATUS(Packet) != NDIS_STATUS_PENDING) { MPReturnPacket((NDIS_HANDLE)pAdapt,Packet); } } } } 几乎和板上的一摸一样,但在NdisFreeBuffer处或Unchained处总出问题 |
|
地板#
发布于:2003-12-16 15:55
我正遇到类似的问题,当时可以回答你问题中的一些:
2,NDIS_PACKET是由一个或者多NDIS_BUFFER(其实就是一些MDL)组成的,是一个链表的形式吧,他们的地址不一定是连续的。要是想将整个packet作为整体处理最好是把他们放入到一个连续的内存空间中。 3,可以看ddk中有关ndisfreebuffer 从packet上解链下来的ndis_buffer也是需要被释放的。否则要溢出。 |
|
|
地下室#
发布于:2003-12-16 16:18
你觉得我的代码有什么问题么,
是否在资源低时会有问题 |
|
5楼#
发布于:2003-12-16 16:32
看代码?我头已经块炸了。呵呵
我还是问你个问题吧。 NdisFreeBuffer()释放的描述符,他所标记的那段内存空间是否也被释放完毕了呢? |
|
|
6楼#
发布于:2003-12-16 16:36
看前面人说得,没有.
还得FreeMemory.我QQ15954862 |
|
7楼#
发布于:2003-12-17 13:40
居然没人回答。你们也睡着了么
|
|
论坛版主
|
8楼#
发布于:2003-12-17 15:56
1.ptreceive中用的pttransferdatacomplete是在pttransferdata能同步完成的时候,这样返回的包处理需要在ptreive里面做,比如的包处理动作,还有就是返回下层包控制权,也就是returnpacket,这些动作可以直接写成代码在ptreceive里面,但和其他那两个函数代码大致相同,直接用了这两个函数
2.多个buffer指哪些?packet链的那些?如果是指这些他们只是一个单向链表,每个链表项指向一个缓冲区,用于放数据(注意链表项本身不是数据),给个图吧 ----------- | | ----------->| OOB | | | | --------------- | ----------- | |--------- | NDIS_PACKET | | |--------- --------------- | | | V --------------- | | | NDIS_PACKET | | _PRIVATE | --------------- (HEAD) | |-------------------------------------------- V V(TAIL) --------------- --------------- --------------- | | | | | | | NDIS_BUFFER |------>| NDIS_BUFFER |----> ... ... ---->| NDIS_BUFFER | | | | | | | --------------- --------------- --------------- | | | | | | V V V ----------- ----------- ----------- | | | | | | | 包数据 | | 包数据 | | 包数据 | | | | | | | ----------- ----------- ----------- 没办法,放上来就乱了:( 3.你认为有什么不合理?query是为了的到要是放的缓冲区的首地址,不的到首地址怎么释放?:)不过注意在query之前释放缓冲区描述符倒是不行,这个不用解释吧 4.它释放buffer_size是因为它分配的时候也用的这个宏,知道它就这么大,不知道这么大当然不对 |
|
9楼#
发布于:2003-12-17 21:34
谢谢。
6。我看hu的代码里有利用memory allocate buffer后,马上把meomery释放的语句,是错误吧? 7。NdisFreeMemory长度可设为0,msdn解释是ignored,不知这样行不? 8。我现在用softice调试会出NT... ResouceHalUsage异常错误,但不用softice就可以(并且没有网卡启动也有这个问题),是程序问题么 9。长时间运行后网络就不通了,是否在资源下降时的处理有问题? 10。recvbufferpoolhandle 应该在哪里是放? [编辑 - 12/18/03 by daweia] |
|
论坛版主
|
10楼#
发布于:2003-12-18 14:24
不是吧,我没看到说0表示忽略喔:
The parameters passed to NdisFreeMemory must be identical to those passed to NdisAllocateMemory when the block of memory was allocated. That is, a caller of NdisFreeMemory cannot release a subrange of the block that was allocated. Length Specifies the size in bytes of the memory block to be released. This parameter must be identical to the Length that was passed to NdisAllocateMemory. 这个应该没问题,释放长度肯定是分配长度。 长时间运行不通可能是你资源释放有问题,再查查 BUFFERPOOL的句柄不用释放,为什么你要释放它?它只是空闲资源的指针,没妨碍你吧:) |
|
11楼#
发布于:2003-12-18 17:03
我看的是msdn 2001-10里讲的
Length Specifies the size in bytes of the memory block to be released. This parameter must be identical to the Length that was passed to NdisAllocateMemory. However, if the MemoryFlags setting is zero, this parameter is ignored. |
|
论坛版主
|
12楼#
发布于:2003-12-19 14:49
我也看了,还是没有:)算了,不要纠缠这个问题了,就按照分配大小释放吧,你忽略这个参数系统如何知道你要是放的大小?有时间再研究这个问题,看看其他主要的地方有什么问题吧
|
|
13楼#
发布于:2003-12-19 23:59
目前的问题
1。装了softice后,即使不插网卡,boot启动出现 NT ...ReportHalResouceUsage异常,而不用softice我passthru没问题 2.在MPHal中我看有释放recvpacketpool和sendpacketpool的 我加了释放recvbufferpool的语句会有问题 3.好像处理包的方式比较慢.可不可以不用pttransferdatacomplete函数和mpreturn函数,直接在ptreceive里inidatecate 4.一个packet是否代表链路层一帧?它里面的origin packet呢其物理意义是什么? 5.packet里多个buffer的分界是否没有什么意义?也就是说每个buffer只代表帧的一部分? |
|
论坛版主
|
14楼#
发布于:2003-12-22 14:19
哈哈哈,兄弟,你娃问题多喔,PROBLEM BOY嗦
1.你的PASSTHRU怎么就确定没问题?你在其他机器上装上看看吧 2.你的recvbufferpool在什么地方分配的,做在PTBINDADAPT里面不?这个函数可能不是问题的关键,你弄清楚它什么时候调用没?是在停用PASSTHRU的时候,还是在卸载的时候,还是在SYSTEM SHUTDOWN的时候? 3.在PTRCEIVE里INDICATE没问题啊,你可以不自己做TRANSFERDATA,直接把包INDICATE到上层,让他决定做不做TRANSFERDATA,这样你就可以不要TRANSFERDATACOMPLETE了,但是MPTETURN还是要的,只不过你可以不动原来DDK的那个例子的,它的功能只是把上层的RETURN动作延续下去,告诉下层MINIPORT驱动释放资源,你没有分配资源就可以不在里面做释放动作。 4.你说的ORIGINAL PACKET是不是RSVD那里面的那个?这个东西用来保存包的一部分,主要是要用TRSFERDATA才能取完的那种长包,它是包的一部分,另外一种情况是整个包的描述符,我也觉得有点儿多余,不过这是例子,可能它想告诉大家怎么用这个域。 5.BUFFER的分界一般都是有意义的,但是平台不同不一样,你只能自己总结,一般都是完整的有意义字段,比如MAC帧头,IP头,TCP/UDP头 上述说法如有不对之处大家共同讨论 |
|
论坛版主
|
15楼#
发布于:2003-12-22 14:36
刚才看了看原来做的笔记,HOHO,保存ORIGINAL PACKET(完整的包的描述符)还可能是这样:
在MiniportSend函数内部,在分配了mypacket后,把上层来的包packet存在了mypacket的protocolreserved域,目的是如果ndissend返回pending,在下层实际发送完成后,ptsendcomplete调用ndissendcomplete的时候,要把mypacket保存的packet取出来,返回给上层,通知上层是哪个包发送完成了,这是原来我的理解,也不知道对不,特别是这样解释和IM总是自己分配包的描述符然后传到上下层去,而不用上下层自己的包描述符有点儿矛盾,DDK只说要这样做,就是不说WHY,原来我想了好久:)到现在也只是几种猜测,各位谁有想法的,大家讨论讨论 |
|
论坛版主
|
16楼#
发布于:2003-12-22 14:55
对了,刚才我说的TRANSFERDATACOMPLETE不要也是说你可以不动它哈,不是说连注册都不注册,这些函数全部都是连接上层TDI和项层MP的过渡函数,它不做你的动作也要传递上下层的动作,不要工作不起喔,你可以看看纯的DDK的例子的工作就知道。
|
|
17楼#
发布于:2003-12-22 14:59
wxl_50685330:
我把一个packet所有的buffer重新连接到一个新的连续的buffer中,再把这个buffer,chain到原来的packet上行么? |
|
|
论坛版主
|
18楼#
发布于:2003-12-22 16:07
可以可以:)完全没得问题
|
|
19楼#
发布于:2003-12-23 10:55
怎么散分啊
|
|