阅读:1821回复:9
刚才忘记设定分数,重新发一个MPSend自定义包的问题
刚才忘记给分,不好意思,重新发一次。。管理员不要删除。。
============================= 我在PassThru基础上做一个中间层驱动。现在遇到一些问题。当上层发出一个Arp数据报时,我要禁止它发出 然后自己构造一个相应的回应包,通知上层接收。在MpSend中调用NdisSend之前我加入了如下代码: UINT PhysicalBufferCount; UINT BufferCount,k; UINT TotalPacketLength; PNDIS_BUFFER CurrentBuffer,NextBuffer,pArpBuffer; UINT CurrentBufferLength; PVOID CurrentBufferVA; NDIS_HANDLE PacketCopy=NULL; PNDIS_STATUS Sts=NDIS_STATUS_SUCCESS; PETHHDR DownEthhdr;//,UpEthhdr; PARPHDR DownArphdr;//,UpArphdr; //PIPHDR DownIphdr; PUCHAR pArpContent; UINT PacketLen; //×××以上是原PassThru中NdisSend之前的代码,主要是构造MyPacket.. NdisQueryPacket(MyPacket , &PhysicalBufferCount , &BufferCount , &CurrentBuffer , &TotalPacketLength ); DbgPrint(\"BufferCount:%u.\\n\",BufferCount); DbgPrint(\"TotalPacketLength:%u.\\n\",TotalPacketLength); /*if(!BufferCount) { // Output debug information DbgPrint(\" Debug Report @ MPSend: BufferCount of Packet is 0,\\n\"); DbgPrint(\"and MPSend will return NDIS_STATUS_FAILURE\\n\"); return (NDIS_STATUS_FAILURE); }*/ NdisQueryBuffer(CurrentBuffer, &CurrentBufferVA, &CurrentBufferLength); DbgPrint(\"CurrentBufferLength: %u \\n\",CurrentBufferLength); DownEthhdr=(PETHHDR)CurrentBufferVA; if(DownEthhdr->ProtocolType==ARP_PROTOCOL) { //this is an arp packet... DbgPrint(\"This is an arp packet...\\n\"); //修改包内容,通知上层接收 DownArphdr=(PARPHDR)((UINT)CurrentBufferVA+14); //申请内存 Status=NdisAllocateMemory(&pArpContent,100,0,HighestAcceptableMax); if(Status==NDIS_STATUS_SUCCESS) { DbgPrint(\"In MPSend:NdisAllocatePacketPool Successed.\\n\"); if(pArpContent!=NULL) { DbgPrint(\"In MPSend:pPacketContent!=NULL\\n\"); //NdisZeroMemory(pArpContent,2000); //拷贝内容数据 DbgPrint(\"In MPSend:Begin copy packet to mybuffer.\\n\"); CopyPacket2Buffer(MyPacket,pArpContent,&TotalPacketLength); PacketLen=TotalPacketLength; NdisAllocatePacketPool(Sts,PacketCopy,1,0); if (*Sts== NDIS_STATUS_SUCCESS) { DbgPrint(\"In MPSend:NdisAllocatePacketPool successed\\n\"); NdisAllocatePacket(&Status,&MyArpPacket,&PacketCopy); if(Status=NDIS_STATUS_SUCCESS) { DbgPrint(\"In MPSend:NdisAllocatePacket successed\\n\"); NdisAllocateBuffer(&Status,&pArpBuffer,pAdapt->SendBufferPoolHandle,pArpContent,PacketLen); NdisChainBufferAtFront(MyArpPacket,pArpBuffer); MyArpPacket->Private.Head->Next=NULL; MyArpPacket->Private.Tail=NULL; NDIS_SET_PACKET_HEADER_SIZE(MyArpPacket,14); DbgPrint(\"In MPSendacket copy down,begin query new arp packet.\\n\"); NdisQueryPacket(MyArpPacket, &PhysicalBufferCount, &BufferCount, &CurrentBuffer, &TotalPacketLength); DbgPrint(\"BufferCount:%u.\\n\",BufferCount); DbgPrint(\"TotalPacketLength:%u.\\n\",TotalPacketLength); NdisQueryBuffer(CurrentBuffer, &CurrentBufferVA, &CurrentBufferLength); DbgPrint(\"CurrentBufferLength: %u \\n\",CurrentBufferLength); DBGPRINT(\"In Mpsend,Free Memory\\n\"); NdisFreeBuffer(pArpBuffer); NdisFreePacket(MyArpPacket); } NdisFreePacketPool(PacketCopy); } } NdisFreeMemory(pArpContent,100,0); } } NdisSend(&Status, pAdapt->BindingHandle, MyPacket); if (Status != NDIS_STATUS_PENDING) { NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket); NdisFreePacket(MyPacket); } 现在没有修改数据报,只是申请内存,复制了一个数据报,然后释放掉。安装时兰屏,错误代码是 Xmode_exception_not_handled. 我的问题是我的代码问题出在什么地方?下一步我要修改我申请的内存,我应该怎么做呢?如何通知上层 接收我构造的数据报?如何解决返回的问题?Pending的时候如何处理?时间比较紧张,恳请各位大侠帮忙, 感谢!! |
|
最新喜欢:xiaoji... |
沙发#
发布于:2003-04-23 14:42
你的整个的处理流程好像就有问题。
我没有仔细看: 对于你不象发送出去的packet,你是怎么通知上层协议的? 好像没有通知 程序里面的NdisSend是在什么情况下才调用的?? |
|
|
板凳#
发布于:2003-04-23 15:04
passthru的MPSend函数只负责上层protocol driver往下发的数据报文。要想往上传收到的报文(或者是自己生成的报文)应该在别的函数里边实现吧?我也是刚刚接触passthru。昨天刚看。不过我的项目不急。hoho
|
|
地板#
发布于:2003-04-23 16:15
我现在还没有做那么多,我想要想发包肯定要自己申请一块内存
容纳这个包吧。 我程序里申请了内存,拷贝了数据,然后释放掉了,然后还是发出原来的包,就是因为我在钻申请内存拷贝数据这一块。 但是安装以后兰屏,不知道为什么。 |
|
地下室#
发布于:2003-04-23 21:38
大侠帮忙啊!!呜呜。。
|
|
5楼#
发布于:2003-04-23 23:18
呵呵,贴一段我得代码给你吧,是仿照receive那边大家都做的那种方法,重新分配一个包,拷贝内容,然后发送自己分配的包最后释放。都是调试好没问题的,我想也许对你有帮助。^_^
注意你改mpsend的同时要改ptsendcomplete,否则会蓝屏 NDIS_STATUS MPSend( IN NDIS_HANDLE MiniportAdapterContext, PNDIS_PACKET Packet, UINT Flags ) { PADAPT pAdapt = (PADAPT)MiniportAdapterContext; NDIS_STATUS Status; PNDIS_PACKET MyPacket; PUCHAR pPacketContent; PNDIS_BUFFER PacketBuffer; UINT PacketLen; UINT bufLength; PRSVD Rsvd; PVOID MediaSpecificInfo = NULL; ULONG MediaSpecificInfoSize = 0; UINT headersize; NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress; HighestAcceptableAddress.LowPart = -1; HighestAcceptableAddress.HighPart = -1; ASSERT (pAdapt->pSecondaryAdapt); pAdapt = pAdapt->pSecondaryAdapt; if (IsIMDeviceStateOn (pAdapt) == FALSE) { return NDIS_STATUS_FAILURE; } Status = NdisAllocateMemory(&pPacketContent,2000,0,HighestAcceptableAddress);//分配内存 if (Status != NDIS_STATUS_SUCCESS ) { DbgPrint(\"mpsend: ndisallocatememory failed\\n\"); return NDIS_STATUS_FAILURE ; } if(pPacketContent == NULL) { DbgPrint(\"mpsend: pPacketContent == NULL\\n\"); return NDIS_STATUS_FAILURE ; } RtlZeroMemory(pPacketContent, 2000 ); CopyPacket2Buf(Packet,pPacketContent,&PacketLen);//拷贝包内容 NdisAllocatePacket(&Status,&MyPacket,pAdapt->SendPacketPoolHandle);//分配包,失败的话要把分配的内存释放掉 if (Status == NDIS_STATUS_SUCCESS) { NdisAllocateBuffer(&Status,&PacketBuffer,pAdapt->SendBufferPoolHandle,pPacketContent,PacketLen);//分配buffer NdisChainBufferAtFront( MyPacket, PacketBuffer); Rsvd = (PRSVD)(MyPacket->ProtocolReserved); Rsvd->OriginalPkt = Packet; MyPacket->Private.Head->Next=NULL; MyPacket->Private.Tail=NULL; NdisSetPacketFlags(MyPacket, NDIS_FLAGS_DONT_LOOPBACK);//自己定义的包 NdisSend(&Status, pAdapt->BindingHandle, MyPacket);//发送 if (Status != NDIS_STATUS_PENDING)//返回pending的话自己分配的东西要在PtSendComplete里面释放 { NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket); NdisUnchainBufferAtFront(MyPacket ,&PacketBuffer); NdisQueryBufferSafe(PacketBuffer,(PVOID *)&pPacketContent,&bufLength,32); NdisFreeBuffer(PacketBuffer); NdisFreeMemory(pPacketContent,2000,0); NdisDprFreePacket(MyPacket); } } else NdisFreeMemory(pPacketContent,2000,0); //没分配到包的时候释放内存 return(Status); } VOID PtSendComplete( NDIS_HANDLE ProtocolBindingContext , PNDIS_PACKET Packet , NDIS_STATUS Status) { PADAPT pAdapt =(PADAPT)ProtocolBindingContext; PNDIS_PACKET Pkt; P_IP_PACKET p_ip; UINT i; PUCHAR pPacketContent; PNDIS_BUFFER PacketBuffer; PRSVD Rsvd; UINT PacketLen; UINT bufLength; NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress; HighestAcceptableAddress.LowPart = -1; HighestAcceptableAddress.HighPart = -1; pAdapt = pAdapt->pPrimaryAdapt; Rsvd =(PRSVD)(Packet->ProtocolReserved); Pkt = Rsvd->OriginalPkt;//自己分配包的时候已经把原来的包放在这里面了 if(Pkt) NdisIMCopySendCompletePerPacketInfo (Pkt, Packet); NdisUnchainBufferAtFront(Packet,&PacketBuffer); NdisQueryBufferSafe(PacketBuffer,(PVOID *)&pPacketContent,&bufLength,32); NdisFreeBuffer(PacketBuffer); NdisFreeMemory(pPacketContent,2000,0); NdisDprFreePacket(Packet); //释放 if(pAdapt->MiniportHandle) { if(Pkt) { NdisMSendComplete(pAdapt->MiniportHandle, Pkt, Status); } } } 对了,我自己事先分配好pool了,所以就没有在这里分配 |
|
6楼#
发布于:2003-04-24 10:28
NdisSetPacketFlags(MyPacket, NDIS_FLAGS_DONT_LOOPBACK);//自己定义的包
这句有什么作用? |
|
7楼#
发布于:2003-04-24 11:19
没什么用处,mpsend里面本来是给他自己的packet做了这项工作的,我顺手改了就是了
|
|
8楼#
发布于:2003-04-24 14:56
如果我这时遇到特定的包(如ARP)包,就不再发出,是不是要这样做?
1。NdisSend注释掉,然后返回给函数一个成功值,让系统以为包已经发出,从而释放掉内存。这个成功值应该怎么设定呢? 2。用NdisMIndicateReceive通知上层接收自己组建的数据包。此时 这个NdisMIndicateReceive的参数应该怎么写? 3。调用NdisMIndicateReceive如果返回不是Pending,,可以直接释放掉自己组建包用的内存。如果返回的是Pending,是不是要在ReturnPacket中释放内存呢?如何释放呢? 多谢大侠,上面给代码的仁兄,给你十分先。。 |
|
9楼#
发布于:2003-05-02 12:33
1。NdisSend() 返回一个状态值常量,找一下ddk 的文档就知道了。或者ndis.h 文件中也有定义。成功状态可能是ndis_packet_status_successful 吧。
|
|