阅读:9422回复:32
对胡老大的代码的注释,大家进来指导一下吧
下面是我对huyg的代码的注释,因为功底很浅,漏洞百出,希望各位高人能够指点一下,看的不爽大家只管骂,但是不要再让我回去查ddk了,上面很多在ddk中说的很是模棱两可的,抑或是我的E文太差实在是看不懂
第一部分 void CopyPacket2Buffer(IN PNDIS_PACKET pPacket,IN OUT PUCHAR pBuff,IN OUT PUINT pLength) { PNDIS_BUFFER BuffDT;// buffer指示符, PUCHAR BuffVA;//Buffer的虚拟地址 UINT BuffLen;//Buffer的长度 *pLength=0;//数据包内容的总长度,开始先置零 BuffLen=0;//Buffer的长度,开始先置零 NdisQueryPacket(pPacket,NULL,NULL,&BuffDT,NULL);//查询Packet的信息,这里查的是Packet的Buffer指示符的链表第一个的 while(BuffDT!=(PNDIS_BUFFER)NULL)//如果Buffer指示符不为NULL,则读取其中的内容 { NdisQueryBuffer(BuffDT,&BuffVA,&BuffLen);//得到BuffDT指向的那个Buffer的虚拟地BuffVA,和长度BuffLen NdisMoveMemory(pBuff,BuffVA,BuffLen);//将BuffVA其中的内容,移动到pBuff指向的那块区域 pBuff=pBuff+BuffLen;//pBuff指针后移,前BuffLen个字节已经填入数据 *pLength+=BuffLen;//记录pBuff中填入数据的总长度 NdisGetNextBuffer(BuffDT,&BuffDT);//获得Buffer指示符链表中的下一个Buffer指示符 } return; } //数据传输完备,如果调用了TransferData(),就必须要调用TransferDataComplete,因为Ndis必须遵守谁申请谁释放的原则 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;//得到ProtocolBind的信息 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的长度,应该是实际内容的长度吧 DBGPRINT(("In PtTransferDataCompleten")); // // Returning the Send on the Primary, will point to itself if there is no LBFO // pAdapt = pAdapt->pPrimaryAdapt;//得到第一设备,那为什么还要第一句“PADAPT pAdapt =(PADAPT)ProtocolBindingContext”呢? Rsvd =(PRSVD)(Packet->MiniportReserved);//不懂 pBakPacket=(PNDIS_PACKET)(Rsvd->OriginalPkt);//不懂,好像是从微端口获取,Packet的指针,看了后面,回头再写一点把 //这个pBakPacket是不是就是那些还在微端口中的数据啊?? if(pAdapt->MiniportHandle)//是否有微端口绑定,没有话,那也就是不可能有数据上传了 { if(pBakPacket==NULL)//如果没有,那是什么一种情况,不清楚,感觉是数据已经上传的意思吧,通知miniport释放资源 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); //Packet是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); //这个地方很奇怪了,这个指针好像指向的是Packet->MiniportReserved->OriginalPkt的内容,既然在这里释放,那它到底是属于谁的 //imd的还是miniport的 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); //释放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函数通知上层协议, NdisMIndicateReceivePacket(pAdapt->MiniportHandle,&Packet,1); if(NDIS_GET_PACKET_STATUS(Packet)!=NDIS_STATUS_PENDING)//返回后如果是NDIS_STATUS_PENDING(悬挂)则调用函数释放 { MPReturnPacket((NDIS_HANDLE)pAdapt,Packet); } } return; } 待续.... [编辑 - 4/3/04 by darkread] [编辑 - 4/3/04 by darkread] |
|
沙发#
发布于:2004-04-03 17:24
第二部分
NDIS_STATUS PtReceive( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE MacReceiveContext, IN PVOID HeaderBuffer, IN UINT HeaderBufferSize, IN PVOID LookAheadBuffer, IN UINT LookAheadBufferSize, IN UINT PacketSize ) /*++ Routine Description: LBFO - need to use primary for all receives Arguments: Return Value: --*/ { PADAPT OutAdapt,pAdapt =(PADAPT)ProtocolBindingContext; PNDIS_PACKET MyPacket, Packet,MyPacket1; NDIS_STATUS Status = NDIS_STATUS_SUCCESS; /* PUCHAR pEnetAddrDest=NULL; UINT nDataSize=0,i; PNDIS_BUFFER pNdisBuffer=NULL; UCHAR *BufferVa=NULL; PMACHEADER pMACHeader=NULL; PIPHEADER pIPHeader=NULL; PICMPHEADER pICMPHeader=NULL; PTCPHEADER pTCPHeader=NULL; PUDPHEADER pUDPHeader=NULL; */ PNDIS_BUFFER pPacketBuffer,pBakBuffer;//Buffer指示符,第一个是Packet的,第二个应该是在本函数生成的 PUCHAR pPacketContent,pBakContent;//把以太网帧的内容提取出来应该就放在这里了 UINT PacketLen;//包的长度把,暂时还不知道是Packet的,还是以太网帧的 UINT OffsetSize; //偏移量 UINT BytesTransferred;//已经传输的数据,好像后面写的是0 //以下三行是传说中的初始化了,为什么是传说中的呢?因为我对第一行实在是不了解 PRSVD Rsvd=NULL; PVOID MediaSpecificInfo=NULL; ULONG MediaSpecificSize=0; //如果MiniPort == NULL,那么就是说没有底层设备,当然就没有什么以太网帧啦,这个好理解 //但是TransferDataComplete()中的也有类似的一句就不是这么好理解了 if(!pAdapt->MiniportHandle) { Status = NDIS_STATUS_FAILURE; } else do { // // We should not be getting Receives on a Secondary, this is just specific to our LBFO driver // if(pAdapt->isSecondary) { DBGPRINT("PASSTHRU GETTING RECIEVES ON SECONDARY\n"); ASSERT(0); } // // If this was indicated by the miniport below as a packet, then get that packet pointer and indicate // it as a packet as well(with appropriate status). This way the OOB stuff is accessible to the // transport above us. // Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext); if(Packet != NULL)//如果能够不等于NULL就好办了 { // // Get a packet off the pool and indicate that up // NdisDprAllocatePacket(&Status, &MyPacket, pAdapt->RecvPacketPoolHandle); if(Status == NDIS_STATUS_SUCCESS) { MyPacket->Private.Head = Packet->Private.Head; MyPacket->Private.Tail = Packet->Private.Tail; // // Get the original packet(it could be the same packet as one received or a different one // based on # of layered MPs) and set it on the indicated packet so the OOB stuff is visible // correctly at the top. // NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet)); NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize); // // Set Packet Flags // NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet); // // Make sure the status is set to NDIS_STATUS_RESOURCES. // NDIS_SET_PACKET_STATUS(MyPacket, NDIS_STATUS_RESOURCES); NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1); ASSERT(NDIS_GET_PACKET_STATUS(MyPacket) == NDIS_STATUS_RESOURCES); NdisDprFreePacket(MyPacket); break; } } // // Fall through if the miniport below us has either not indicated a packet or we could not // allocate one // //说明Packet中的数据已经全部上来了,LookAheadBufferSize我猜测是属于IMD的,不知道对不对 //因为LookAheadBufferSize比PacketSize大,是不是就是说Packet的Buffer中的以太网帧的内容都在 //LookAheadBuffer中了呢? else if(PacketSize<=LookAheadBufferSize) { //给pPacketContent分配内存,HighestAcceptableMax必须=-1 Status=NdisAllocateMemory(&pPacketContent,BUFFER_SIZE,0,HighestAcceptableMax); if(Status!=NDIS_STATUS_SUCCESS) { DbgPrint("PTReceive:NdisAllocateMemory Failed\n"); return(NDIS_STATUS_NOT_ACCEPTED); } if(pPacketContent==NULL) { DbgPrint("PTReceive:pPacketContent==NULL\n"); return(NDIS_STATUS_NOT_ACCEPTED); } NdisZeroMemory(pPacketContent,BUFFER_SIZE);//将pPacketContent指向的内容置零,也即使刚分配的区域置零 //把HeaderBuffer(是不是叫以太网帧头部缓冲区)的内容放到pPacketContent中区 NdisMoveMemory(pPacketContent,HeaderBuffer,HeaderBufferSize); //把LookAheadBuffer中的数据放在pPacketContent指向的区域,而且是跟在HeaderBuffer的后面 //这样,一个以太网帧的数据就都有了,是吧???但是很奇怪,这里为什么不是PacketSize呢?? NdisMoveMemory(pPacketContent+HeaderBufferSize,LookAheadBuffer,LookAheadBufferSize); //这个以太网帧的长度, PacketLen=PacketSize+HeaderBufferSize; //下面部分莫非就是传说中的重新组包??,如果是就好了 //分配一个Packet指示符MyPacket,带Dpr的好像快一点 NdisDprAllocatePacket(&Status,&MyPacket,pAdapt->RecvPacketPoolHandle); if(Status==NDIS_STATUS_SUCCESS)//如果MyPacket分配成功,则继续 { //分配一个Buffer指示符,pPacketBuffer指向那个指示符 //并且将pPacketContent指向的地址传给那个分配的指示符,也就是所指示符所指向的真正的那块Buffer就是pPacketContent //指向的那块区域 NdisAllocateBuffer(&Status,&pPacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,PacketLen); //把这个指示符挂在MyPacket的指示符链表的第一个 NdisChainBufferAtFront(MyPacket,pPacketBuffer); //修整工作,只是不知道干什么的而已, MyPacket->Private.Head->Next=NULL; MyPacket->Private.Tail=NULL; //老问题了,这两句也不懂 Rsvd=(PRSVD)(MyPacket->MiniportReserved); Rsvd->OriginalPkt=NULL; //设置MyPacket的报头的大小,应该是重新组包了,因为它用的包头大小是HeaderBufferSize NDIS_SET_PACKET_HEADER_SIZE(MyPacket,HeaderBufferSize); //告诉上层协议驱动,有数据包,不过是我重新组包的了 NdisMIndicateReceivePacket(pAdapt->MiniportHandle,&MyPacket,1); //如果是NDIS_STATUS_PENDING(悬挂),在释放资源 //我想可能这里的悬挂就是完成的意思把 if(NDIS_GET_PACKET_STATUS(MyPacket)!=NDIS_STATUS_PENDING) { DBGPRINT(("In PtReceive And Free Memory\n")); NdisFreeBuffer(pPacketBuffer); NdisFreeMemory(pPacketContent,BUFFER_SIZE,0); NdisDprFreePacket(MyPacket); } } break; } else { //看着看着好像又不是huyg的程序了,就当是吧 //********这中情况,应该就是数据还没有完全上来的情况了*********// //这里是分配存放以太网帧的空间了 Status=NdisAllocateMemory(&pPacketContent,BUFFER_SIZE,0,HighestAcceptableMax); if(Status!=NDIS_STATUS_SUCCESS)//如果失败,则DbgPrint { DbgPrint("PtReceive:NdisAllocateMemory Failed.\n"); return(NDIS_STATUS_NOT_ACCEPTED); } if(pPacketContent==NULL)//如果失败,则DbgPrint,这里的失败应该是没有空间了吧 { DbgPrint("PTReceive:pPacketContent==NULL\n"); return(NDIS_STATUS_NOT_ACCEPTED); } //pPacketContent指向的空间置零 NdisZeroMemory(pPacketContent,BUFFER_SIZE); //获取Packet指示符 NdisDprAllocatePacket(&Status,&MyPacket,pAdapt->RecvPacketPoolHandle); //分配pBakContent指向的空间,我突然想到了,这里分配了两块空间,是不是 //一块是放已经上来的数据,而另一块放的是还在下面的数据 //分析下去看,但愿是这样的 Status=NdisAllocateMemory(&pBakContent,BUFFER_SIZE,0,HighestAcceptableMax); //下面两个if是显示分配空间出错的情况的 if(Status!=NDIS_STATUS_SUCCESS) { DbgPrint("PtReceive:NdisAllocateMemory Failed.\n"); return(NDIS_STATUS_NOT_ACCEPTED); } if(pBakContent==NULL) { DbgPrint("PTReceive:pPacketContent==NULL\n"); return(NDIS_STATUS_NOT_ACCEPTED); } //对pBakContent指向的那块空间置零 NdisZeroMemory(pBakContent,BUFFER_SIZE); //把HeaderBuffer中的数据放到pBakContent指向的那块空间中去 NdisMoveMemory(pBakContent,HeaderBuffer,HeaderBufferSize); //然后把LookAheadBuffer中的数据放在HeaderBuffer的后面 NdisMoveMemory(pBakContent+HeaderBufferSize,LookAheadBuffer,LookAheadBufferSize); //包的长度记录在PacketLen中,这里的包的意思应该是以太网帧 PacketLen=HeaderBufferSize+PacketSize; //分配一个Buffer指示符,用pPacketBuffer指向它,并把pPacketContent指向的那块空间中挂接上来 //这块Buffer指示符所指向的Buffer的大小是PacketSize-LookAheadBufferSize,看样子我是对的, //pPacketContent指向的那块空间中的数据是没有传上来的 NdisAllocateBuffer(&Status,&pPacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,PacketSize-LookAheadBufferSize); //把pPacketBuffer指向的Buffer指示符,挂接到MyPacket的Buffer指示符链表中 NdisChainBufferAtFront(MyPacket,pPacketBuffer); //不知道干什么的 MyPacket->Private.Head->Next=NULL; MyPacket->Private.Tail=NULL; //OffsetSize表示的是已经传上来的数据的大小吧, //又有问题了,请网上数10行,PacketSize-LookAheadBufferSize中的PacketSize中应该不包含HeadBufferSize的吧, OffsetSize=HeaderBufferSize+LookAheadBufferSize; //分配一个Packet指示符,叫用MyPacket1指向它 NdisDprAllocatePacket(&Status,&MyPacket1,pAdapt->RecvPacketPoolHandle); //再分配一个Buffer指示符,用pBakBuffer指向它,挂接的真正的空间(buffer)是pBakContent,大小OffsetSize NdisAllocateBuffer(&Status,&pBakBuffer,pAdapt->RecvBufferPoolHandle,pBakContent,OffsetSize); //将pBakBuffer指向的Buffer指示符挂接在MyPacket1的Buffer链表的第一个 NdisChainBufferAtFront(MyPacket1,pBakBuffer); //这两句 不懂!!!!!!!!!!!!!!! Rsvd=(PRSVD)(MyPacket->MiniportReserved); Rsvd->OriginalPkt=(PNDIS_PACKET)MyPacket1; //设置包头大小 NDIS_SET_PACKET_HEADER_SIZE(MyPacket,HeaderBufferSize); //调用NdisTransferData()把下面的数据调上来 NdisTransferData(&Status,pAdapt->BindingHandle,MacReceiveContext,LookAheadBufferSize,PacketSize-LookAheadBufferSize,MyPacket,&BytesTransferred); if(Status!=NDIS_STATUS_PENDING)//监察是否完成,完成则释放资源 { PtTransferDataComplete((NDIS_HANDLE)pAdapt,MyPacket,Status,BytesTransferred); } break; } pAdapt->IndicateRcvComplete = TRUE;//不懂 /* switch(pAdapt->Medium) { case NdisMedium802_3: { NdisMEthIndicateReceive(pAdapt->MiniportHandle, MacReceiveContext, HeaderBuffer, HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize, PacketSize); break; } case NdisMedium802_5: NdisMTrIndicateReceive(pAdapt->MiniportHandle, MacReceiveContext, HeaderBuffer, HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize, PacketSize); break; case NdisMediumFddi: NdisMFddiIndicateReceive(pAdapt->MiniportHandle, MacReceiveContext, HeaderBuffer, HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize, PacketSize); break; default: ASSERT(0); break; } */ } while(FALSE); DBGPRINT(("In PtReceive\n")); return Status; } 待续...... |
|
板凳#
发布于:2004-04-03 17:31
第三部分
VOID MPReturnPacket( IN NDIS_HANDLE MiniportAdapterContext, IN PNDIS_PACKET Packet ) /*++ Routine Description: Arguments: Return Value: --*/ { PADAPT pAdapt = (PADAPT)MiniportAdapterContext; PNDIS_PACKET MyPacket; PRSVD Resvd; PNDIS_BUFFER pNdisBuffer; PUCHAR pPacketContent; UINT BufferLen; Resvd = (PRSVD)(Packet->MiniportReserved); MyPacket = Resvd->OriginalPkt; if(MyPacket) { NdisFreePacket(Packet); NdisReturnPackets(&MyPacket, 1); } /*========================================================================= I Add This Code for NdisIndicateReceivePacket =========================================================================*/ else { DBGPRINT(("In MPReturnPacket And Free Memory\n")); //Packet的Buffer链表的第一个元素摘下,地址给pNdisBuffer NdisUnchainBufferAtFront(Packet,&pNdisBuffer); //查询这个Buffer指示符的信息,有Buffer的虚拟地址,长度,32是权限 NdisQueryBufferSafe(pNdisBuffer,(PVOID *)&pPacketContent,&BufferLen,32); //释放Buffer指示符 NdisFreeBuffer(pNdisBuffer); //释放Buffer空间 NdisFreeMemory(pPacketContent,BUFFER_SIZE,0); //释放Packet指示符 NdisFreePacket(Packet); DBGPRINT(("In MPReturnPacket And Free Memory\n")); } } 未完待续... |
|
地板#
发布于:2004-04-04 19:53
原始的代码哪里能弄到?
|
|
地下室#
发布于:2004-04-04 20:18
passthru代码是DDK的
贴的代码的胡老大的, 上面的英文注释也是胡老大的 中文注释是我的,因为是边看边写的,所以有前后不一致的地方,如果有错请题出来,骂出来也欢迎,只要别让我在去查DDK就好 |
|
5楼#
发布于:2004-04-06 17:57
大家都帮忙看看啊
版主asmsys,帮忙指点一下 |
|
6楼#
发布于:2004-04-06 18:02
//这两句 不懂!!!!!!!!!!!!!!!
Rsvd=(PRSVD)(MyPacket->MiniportReserved); Rsvd->OriginalPkt=(PNDIS_PACKET)MyPacket1; 就是说,这是半个包,等调用NdisTransferData取得后半部分时,就从MyPacket1中取出前半部分,然后合成一个完整的包。 鉴于此,以上关于pBakPacket和REVD的注解都应修改。 [编辑 - 4/6/04 by asmsys] |
|
7楼#
发布于:2004-04-06 18:05
//数据传输完备,如果调用了TransferData(),就必须要调用TransferDataComplete,因为Ndis必须遵守谁申请谁释放的原则
======================================================== 应该是NdisTransferData()吧。 如果返回的不是NDIS-STATUS-PENDING,PtTransferDataComplete就不被调用。这是应注意提前释放资源。 |
|
8楼#
发布于:2004-04-06 18:12
//安全的查询pBakBuffer(Buffer指示符)的情况,起始地址,内容长度,32是权限,等于哪个级别不清楚
======================================================= 32 别瞎说,看DDK: Priority Indicates the priority of the request as one of the following: LowPagePriority Specifies a low priority. It is acceptable for NdisQueryBufferSafe to fail if system resources are low. NormalPagePriority Specifies a normal priority. It is acceptable for NdisQueryBufferSafe to fail if system resources are low. HighPagePriority Specifies a high priority. It is not acceptable for NdisQueryBufferSafe to fail unless system resources are exhausted. |
|
9楼#
发布于:2004-04-06 20:26
asmsys
Rsvd=(PRSVD)(MyPacket->MiniportReserved); Rsvd->OriginalPkt=(PNDIS_PACKET)MyPacket1; 这两句还是有点小问题 如果是在PtReceive()中 Packet(也就是传入的那个Packet描述符)中的MiniportReserved中放的是什么啊 |
|
10楼#
发布于:2004-04-06 20:29
还有就是
MyPacket->Private.Head->Next=NULL; MyPacket->Private.Tail=NULL; 这两句是干什么的,应该是维护一个链表吧,具体是怎么样的,这两天看代码看的做梦都是Packet了,您就帮一下忙吧, |
|
11楼#
发布于:2004-04-07 08:31
还有就是 一个Packet中有一个指向一块buffer的指针,那块buffer又有指向一片内存(这里就是放包的内容的地方)的指针。一般来说,一个PACKET不止一块MEMORY,因为BUFFER和MEMORY之间是有对应关系的,所以只要将那些散开的BUFFER链到一起就能组成一个完整的包了。 但是我们自己分配包的时候,为了方便一次性就分配一个足够大的MEMORY,然后分配一个BUFFER链到PACKET上就足够了。 那么MyPacket->Private.Head就是这个BUFFER链的头指针,MyPacket->Private.Tail就是这个BUFFER链的尾指针,我们只有一块BUFFER,不然理解,一个链表只有头结点有内容,那么MyPacket->Private.Head就不为NULL,那么它的next结点无内容,所以指向NULL,同理尾结点也指向空。 |
|
12楼#
发布于:2004-04-07 08:52
asmsys Rsvd是供包的制造者用的,一般用来在开始时放入一些有用的数据供做回收处理。Rsvd的结构也是可以自己定义的,只有你制造的包,你才可以访问里边的东西,不是你的包,比如是下层发上来的包,你没有必要知道他是啥子东西。即使你知道下层放的是什么,对你来说一般也没什么用。 |
|
13楼#
发布于:2004-04-07 09:02
asmsys 今天起了个大早,发现有我知道的问题,多打点字说说,以前我也遇到同样的问题,摸了好半天才懂。 reserved为保留区,有两块,一个是ProtocolReserved,一个是MiniportReserved。顾名思意,一个是为协议层保留的,一个是为MINIPORT保留的。 在接收包的时候,IM接收到下面Miniport传上来的包描述符Packet(注意扣字眼),在PtReceive中你有两种处理方法: 1.什么都不做直接上指,先是分配一个新包描述符MyPacket,将得到的包描述符的相关信息拷贝到新的包描述符中,注意两个包描述符其实描述了同一块包内容。上指前将(MyPacket->MiniportReserved)->OriginalPkt = Packet 这有什么用呢?等下再说。 2.你要修改包内容,那你得将Packet所指向的内容CopyPacket2Buffer(这个函数你好像会用了),改完了再链到MyPacket上去,接着上指MyPacket,上指前将(MyPacket->MiniportReserved)->OriginalPkt = NULL 到重点了,为了很好地释放内存,这个保留区就派上用场了,我假设上指完后的状态不是NDIS_PENDING,那么要求马上释放资源: Resvd = (PRECV_RSVD)(MyPacket->MiniportReserved); OriginalPacket = Resvd->OriginalPkt; if(OriginalPacket != NULL) { FreePacket(MyPacket); NdisReturnPackets(&OriginalPacket, 1); } else { } 如果保留区的原始包不为空,那它就是指向原先Miniport上传上的的包描述符,那就是系统自已分配的Packet,直接调用NdisReturnPackets释放这个PACKET就行了。 如果为空,说明这个包是我们自己申请的,里面CHAIN的内存也是我们申请的,那么在这里就要调用一大堆FreePacket,FreeBuffer,FreeMemory等等一系列的动作了。 说了这么多,也不知讲清楚了没有。 :) :D |
|
14楼#
发布于:2004-04-07 09:38
讲的非常的好,我以前也摸索了好半天才搞懂
|
|
15楼#
发布于:2004-04-07 11:19
怎么XPDDK里面PassThru的ADAPT和2000DDK里面不一样呢?
|
|
16楼#
发布于:2004-04-09 09:19
楼主该散分了。 :D
|
|
17楼#
发布于:2004-04-09 09:28
9494
楼主写的不错!大家会给你分的! |
|
|
18楼#
发布于:2004-04-09 11:34
我不结帖的一个原因是我还在开发之中,我想把我在学习NDIS中碰到得我问题集合起来,为以后的初学者提供一个比较好的教材,因为我在学习之中碰到了许多问题,一个一个很分散,有时候找不到,心里非常着急,却又无能为力,很惨的
不知道大家同不同意我的想法,如果同意大家请多多帮忙,把经常碰到的问题和他的解决方案都放上来,好不好 |
|
19楼#
发布于:2004-04-10 08:48
支持,非常的支持,身边只有我一个人研究ndis真实辛苦呀,坚决的支持楼主
|
|
上一页
下一页