阅读:2346回复:12
请教各位大侠,关于在ptreceive中调用NdisSend的问题
搜索了论坛贴子,发现以前有类似的问题,不过还是没有搞明白:
我想在ptreceive中截获到感兴趣的包时,不向网卡指示,而直接组包向发包的机器回一个自定义的包: 在调用下面函数时: ndissend(&Status,pAdapt->BindingHandle, MyPacket); 关于这个自定义包的内容已经写好,放在一个缓冲区中,第三个参数该如何填充呢? 麻烦指点!! 谢谢! :P |
|
沙发#
发布于:2003-08-13 14:58
就是你要发送的packet的指针吖
|
|
|
板凳#
发布于:2003-08-14 08:45
自己组装一个代替mypacket
|
|
|
地板#
发布于:2003-08-15 14:19
我的自己组装的包放在一个缓冲区里面,如何把它组成一个ndis调用的packet?
我看了passthru中的mpsend函数,发现它利用传入的packet来组装自己的那个packet,对于我只有一个缓冲区,如何组装呢? |
|
地下室#
发布于:2003-08-15 14:19
我的自己组装的包放在一个缓冲区里面,如何把它组成一个ndis调用的packet?
我看了passthru中的mpsend函数,发现它利用传入的packet来组装自己的那个mypacket,对于我只有一个缓冲区,如何组装呢? |
|
5楼#
发布于:2003-08-16 21:40
Status = NdisAllocateMemory(
&pPacketContent, 2000, 0, HighestAcceptableAddress); ASSERT(Status==NDIS_STATUS_SUCCESS); ASSERT(pPacketContent != NULL) RtlZeroMemory(pPacketContent, 2000 ); //copy你构造的数据包 RtlCopyMemory(pPacketContent,yourdata!!!,yourdataleng); NdisAllocateBuffer(&Status,&PacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,yourdatalen); NdisDprAllocatePacket(&Status, &MyPacket, pAdapt->RecvPacketPoolHandle); NdisChainBufferAtFront( MyPacket, PacketBuffer ); MyPacket->Private.Head->Next=NULL; MyPacket->Private.Tail=NULL; Resvd =(PRSVD)(MyPacket->MiniportReserved); Resvd->OriginalPkt = NULL; NDIS_SET_PACKET_HEADER_SIZE( MyPacket, HeaderBufferSize ); NDIS―SET―PACKET―DONTLOOKBACK Status = ndissend(); if(status!=NDIS_STATUS_PENDING) { 释放你申请的所有资源 RETURN STATUS―SUCCESS } //否则在ptsendcomplete中释放你的资源 这下你还不明白? [编辑 - 8/16/03 by antspower] |
|
|
6楼#
发布于:2003-08-18 11:02
谢谢你,antspower,我后来也是按照你说的流程作的,现在的问题是:
程序几乎每次发送status都是pending,然后调用ptsendcomplete,然后就会出现page fault,系统重启下面是我的代码: ndissend后如果返回非pending: if (Status != NDIS_STATUS_PENDING) { NdisFreeBuffer(pPacketBuffer); NdisFreeMemory(pPacketContent, BUFFER_SIZE, 0); NdisDprFreePacket(MyPacket); return NDIS_STATUS_SUCCESS; } ptsendcomplete: VOID PtSendComplete( IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET Packet, IN NDIS_STATUS Status ) { PADAPT pAdapt =(PADAPT)ProtocolBindingContext; PNDIS_PACKET Pkt; PRSVD Rsvd; PNDIS_BUFFER pNdisBuffer; PUCHAR pPacketContent; UINT BufferLen; pAdapt = pAdapt->pPrimaryAdapt; Rsvd =(PRSVD)(Packet->ProtocolReserved); Pkt = Rsvd->OriginalPkt; if(Pkt) { NdisIMCopySendCompletePerPacketInfo (Pkt, Packet); NdisDprFreePacket(Packet); NdisMSendComplete(pAdapt->MiniportHandle, Pkt, Status); } else { NdisUnchainBufferAtFront(Packet,&pNdisBuffer); NdisQueryBufferSafe(pNdisBuffer,(PVOID *) &pPacketContent,&BufferLen,32); NdisFreeBuffer(pNdisBuffer); NdisFreeMemory(pPacketContent,BUFFER_SIZE,0); NdisDprFreePacket(Packet); } } 这样不对么? |
|
7楼#
发布于:2003-08-18 12:00
ndissend后如果返回非pending: 其实释放包的动作都可以放到PTSendComplete里,另外如果是PENDING,你不可以自己调用PTSendComplete,而是直接返回等待Ndis调用你的函数,否则必然PAGE_FAULT。 代码这样写就可以了 if (Status != NDIS_STATUS_PENDING) { PTSendComplete( ... ); } else return STATUS_SUCCESS; |
|
8楼#
发布于:2003-08-18 13:23
bingjie:
我按照你的建议修改了程序,可是仍然会page fault,会不会是我的包有问题啊? |
|
9楼#
发布于:2003-08-18 17:36
发生错误情况很多,也许是你构造包内存问题!!
你还是仔细看看DDK Packet构造! 还有可能你释放内存太早驱动出错!!! |
|
10楼#
发布于:2003-08-19 08:29
Pkt = Rsvd->OriginalPkt;
通过这个来判断包时候是你不行. //我以前试过. |
|
|
11楼#
发布于:2003-08-19 09:33
antspower:你说的有道理,这个是从论坛的贴子上看来的,不过问题可能就出在这里。
因为这个ptsendcomplete函数需要支持两种情况: 1、mpsend在调用ndissend后返回pending时; 2、自己构造的包发送调用ndissend后返回pending时; 对于情况1,直接调用我的ptsendcomplete中的if部分,对于情况2,调用else部分,现在就是如何判断是由哪种情况进入的ptsendcomplete函数呢? |
|
12楼#
发布于:2003-08-19 13:14
我刚才做了一个实验,发现两种情况下,在ptsendcomplete中调用函数:NdisGetPacketFlags(Packet)得到的值是不一样的,好像一个是130,一个是128,不知这两个数值是偶然的还是有一定含义的呢?
不过我用这两个值作为上面两种情况的判断条件,机器会兰平. |
|