阅读:2188回复:6
斑竹,胡老大的Passthru中的一个小问题,已经解决了,惭愧啊
在passthru.h中对
struct _Adapt是这样定义的 typedef struct _ADAPT { PADAPT Next; NDIS_HANDLE BindingHandle; // To the lower miniport NDIS_HANDLE MiniportHandle; // NDIS Handle to for miniport up-calls NDIS_HANDLE SendPacketPoolHandle; NDIS_HANDLE RecvPacketPoolHandle; NDIS_STATUS Status; // Open Status NDIS_EVENT Event; // Used by bind/halt for Open/Close Adapter synch. NDIS_MEDIUM Medium; NDIS_REQUEST Request; // This is used to wrap a request coming down // to us. This exploits the fact that requests // are serialized down to us. PULONG BytesNeeded; PULONG BytesReadOrWritten; BOOLEAN IndicateRcvComplete; BOOLEAN OutstandingRequests; //True - if a request has been passed to the miniport below the IM protocol BOOLEAN QueuedRequest; //True - if a request is queued with the IM miniport and needs to be either // failed or sent to the miniport below the IM Protocol BOOLEAN StandingBy; // True - When the miniport or protocol is transitioning from a D0 to Standby (>D0) State // False - At all other times, - Flag is cleared after a transition to D0 NDIS_DEVICE_POWER_STATE MPDeviceState; // Miniport's Device State NDIS_DEVICE_POWER_STATE PTDeviceState; // Protocol's Device State BOOLEAN isSecondary; // Set if miniport is secondary of a bundle NDIS_STRING BundleUniString; // Strores the bundleid PADAPT pPrimaryAdapt; // Pointer to the primary PADAPT pSecondaryAdapt; // Pointer to Secondary's structure KSPIN_LOCK SpinLock; // Spin Lock to protect the global list } ADAPT, *PADAPT; 没有一个叫RecvBufferPoolHandle的成员 再看胡老大的代码 在一下一段代码中有这样一句 NdisAllocateBuffer(&Status,&pPacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,PacketLen); 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; PUCHAR pPacketContent;//数据包的内容就提取出来后就放在这里,我想是从Packet的Buffer中提取出来的把吧 PRSVD Rsvd;//暂时还不知道干什么的 UINT OffsetSize,Result,PacketLen;//偏移量,结果,包的长度(应该是指以太网帧的长度吧) PNDIS_BUFFER pPacketBuffer;//Buffer指示符,我想它应该指向的是Packet中的Buffer PNDIS_PACKET pBakPacket;//Packet指示符,这个是在Ndis中新创建的Packet,感觉上向上层传送的应该就是这个了而不是Packet PNDIS_BUFFER pBakBuffer;//Buffer指示符,备份用的,作用还是有点模糊 PUCHAR pBakContent;//以太网帧的内容应该是放在这里的,pPacketContent已经有了,这里为什么还是要加一个,暂时还不清楚, UINT BufferLen;//Buffer的长度,应该是实际内容的长度吧 // // Returning the Send on the Primary, will point to itself if there is no LBFO // pAdapt = pAdapt->pPrimaryAdapt; //原来两个都是自己 Rsvd =(PRSVD)(Packet->MiniportReserved);//不懂 pBakPacket=(PNDIS_PACKET)(Rsvd->OriginalPkt);//不懂,好像是从微端口获取,Packet的指针,看了后面,回头再写一点把 //看了后面以后,感觉是TransferData把数据传上来之后既放在Packet->MiniportReserved->OriginalPkt里面了,放的就是已经传上来的数据的是pBakPacket if(pAdapt->MiniportHandle) { if(pBakPacket == NULL) { NdisMTransferDataComplete(pAdapt->MiniportHandle, Packet, Status, BytesTransferred); } else { Status=NdisAllocateMemory(&pPacketContent,BUFFER_SIZE,0,HighestAcceptableMax);//分配内存给pPacketContent, //BUFFER_SIZE的大小取决于MTU,比他大就行了,因为一个以太网帧不可能大于它的最大可传输单元(MTU)的,Huyg的值是2000 //上面有这样一句pBakPacket=(PNDIS_PACKET)(Rsvd->OriginalPkt),那么下面这句的意思就是把pBakPacket中的以太网帧的 //内容保存在pPacketContent中了,OffsetSize就是pPacketContent长度了 CopyPacket2Buffer(pBakPacket,pPacketContent,&OffsetSize); //同上,保存的是Packet的中的以太网帧的内容,放在pBakPacket的内容之后 CopyPacket2Buffer(Packet,pPacketContent+OffsetSize,&PacketLen); //PacketLen是pPacketContent的内容的长度 PacketLen+=OffsetSize; //从pBakPacket的Buffer链表中废除pBakBuffer NdisUnchainBufferAtFront(pBakPacket,&pBakBuffer); //安全的查询pBakBuffer(Buffer指示符)的情况,起始地址,内容长度,32是权限,等于哪个级别不清楚 //ddk上说运行NdisQueryBufferSafe在IRQL <= DISPATCH_LEVEL. 上,大概就是32了 NdisQueryBufferSafe(pBakBuffer,&pBakContent,&BufferLen,32); //释放pBakBuffer(释放的是指示符) NdisFreeBuffer(pBakBuffer); //释放pBakBuffer中所指向的缓冲区 NdisFreeMemory(pBakContent,BUFFER_SIZE,0); //释放pBakPacket,也就是已经上来的那个Packet,上数28行有注释的 NdisFreePacket(pBakPacket); //MiniportReserved的值置零,不指向任何地方 memset(Packet->MiniportReserved,0,sizeof(Packet->MiniportReserved)); //从Packet的Buffer链表中废除pPacketBuffer NdisUnchainBufferAtFront(Packet,&pPacketBuffer); //安全查询pPacketBuffer的虚拟地址,长度 NdisQueryBufferSafe(pPacketBuffer,&pBakContent,&BufferLen,32); //释放pPacketBuffer指向的Buffer指示符 NdisFreeBuffer(pPacketBuffer); //注意,这里没有free Packet,在下面重新组包的时候,就不用再分配一个新的Packet指示符了 //释放pPacketBuffer指向的Buffer指示符指向的那块缓冲区 NdisFreeMemory(pBakContent,BUFFER_SIZE,0); //请求分配Buffer指示符 NdisAllocateBuffer(&Status,&pPacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,PacketLen); //将它挂到Packet的Buffer指示符链表的最前端 NdisChainBufferAtFront(Packet,pPacketBuffer); //下面两句话不知道是什么意思,因为不知道Private是干什么的,ddk上有,看了也不明白 //猜测是在维护链表,哪个链表,不清楚了,作用也不清楚 Packet->Private.Head->Next=NULL; Packet->Private.Tail=NULL; //设置包头14个字节 NDIS_SET_PACKET_HEADER_SIZE(Packet,14); //调用和介质无关的Indicate函数通知上层协议, //pAdapt->MiniportHandle问题就在这里了,这个pAdapt指的应该是IMd Protocol了,他的MiniportHandle应该是谁呢?nic的还是IMD 的? NdisMIndicateReceivePacket(pAdapt->MiniportHandle,&Packet,1); if(NDIS_GET_PACKET_STATUS(Packet)!=NDIS_STATUS_PENDING)//返回后如果是NDIS_STATUS_PENDING(悬挂)则调用函数释放 { MPReturnPacket((NDIS_HANDLE)pAdapt,Packet); } } } } 这个怎么能够通的过呢,我想胡老大在前面初始化的时候应该是分配了一个BufferPool的东东的,而且修改了Adapt所以是可以的 可是好像别人照抄了这些代码,居然也没有问题,实在是奇怪极了,莫非是我的鱼木脑袋有问题?? [编辑 - 4/4/04 by darkread] |
|
最新喜欢:![]() |
沙发#
发布于:2004-04-04 20:35
刚才我修改了passthru.h 中的Adapt
添加了RecvBufferPoolHandle和SendBufferPoolHandle 编译通过了 安装后也没有出现异常情况,一切正常,呵呵,看样子是胡老大只贴了一个关键部分,我觉得奇怪的是为什么大家都没有碰到支歌问题呢?看来这里底子最烂的还是我,再次脸红 在我们实验室关门前,我做了最后一次实验,证明,那两个BufferPool是可以加上去的,胡老大是对的,原来我一开始对 IMD中pAdapt的认识完全是错误的,如果不写成Adapt写成PtBindingContext可能更好理解,它的作用应该是记录下所以对IMD不透明的句柄,状态。哎,看了那么些ddk,结果因为一个先入为主的错误观点,几乎全部的理解都错了,再再次脸红 [编辑 - 4/4/04 by darkread] |
|
板凳#
发布于:2004-04-05 10:45
能否给我一份你说的代码?谢谢
szyjb@hotmail.com |
|
地板#
发布于:2004-04-05 15:09
论坛里有下面这个帖子
对胡老大的代码的注释,大家进来指导一下吧 帖子是我写的,代码是胡老大的,很有参考价值的 |
|
地下室#
发布于:2004-12-27 11:17
哪个帖子?
|
|
5楼#
发布于:2005-02-03 11:56
能将代码共享一下吗?hugh_ham@126.com 谢谢啊!!!
|
|
6楼#
发布于:2005-02-04 10:52
就是这个帖子,呵呵
http://www.driverdevelop.com/forum/viewthread.php?tid=64174 |
|
|