ruberman
驱动牛犊
驱动牛犊
  • 注册日期2003-04-08
  • 最后登录2011-04-06
  • 粉丝0
  • 关注0
  • 积分150分
  • 威望15点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
阅读:1821回复:9

刚才忘记设定分数,重新发一个MPSend自定义包的问题

楼主#
更多 发布于:2003-04-23 13:14
刚才忘记给分,不好意思,重新发一次。。管理员不要删除。。
=============================
我在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的时候如何处理?时间比较紧张,恳请各位大侠帮忙,
感谢!!

最新喜欢:

xiaojian521xiaoji...
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-04-23 14:42
你的整个的处理流程好像就有问题。
我没有仔细看:
对于你不象发送出去的packet,你是怎么通知上层协议的?
好像没有通知

程序里面的NdisSend是在什么情况下才调用的??

学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
michae1
驱动牛犊
驱动牛犊
  • 注册日期2003-04-23
  • 最后登录2003-04-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-04-23 15:04
passthru的MPSend函数只负责上层protocol driver往下发的数据报文。要想往上传收到的报文(或者是自己生成的报文)应该在别的函数里边实现吧?我也是刚刚接触passthru。昨天刚看。不过我的项目不急。hoho
ruberman
驱动牛犊
驱动牛犊
  • 注册日期2003-04-08
  • 最后登录2011-04-06
  • 粉丝0
  • 关注0
  • 积分150分
  • 威望15点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-04-23 16:15
我现在还没有做那么多,我想要想发包肯定要自己申请一块内存
容纳这个包吧。
我程序里申请了内存,拷贝了数据,然后释放掉了,然后还是发出原来的包,就是因为我在钻申请内存拷贝数据这一块。
但是安装以后兰屏,不知道为什么。
ruberman
驱动牛犊
驱动牛犊
  • 注册日期2003-04-08
  • 最后登录2011-04-06
  • 粉丝0
  • 关注0
  • 积分150分
  • 威望15点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-04-23 21:38
大侠帮忙啊!!呜呜。。
zuozi
驱动牛犊
驱动牛犊
  • 注册日期2003-03-24
  • 最后登录2004-09-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
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了,所以就没有在这里分配
ruberman
驱动牛犊
驱动牛犊
  • 注册日期2003-04-08
  • 最后登录2011-04-06
  • 粉丝0
  • 关注0
  • 积分150分
  • 威望15点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-04-24 10:28
NdisSetPacketFlags(MyPacket, NDIS_FLAGS_DONT_LOOPBACK);//自己定义的包

这句有什么作用?
zuozi
驱动牛犊
驱动牛犊
  • 注册日期2003-03-24
  • 最后登录2004-09-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-04-24 11:19
没什么用处,mpsend里面本来是给他自己的packet做了这项工作的,我顺手改了就是了
ruberman
驱动牛犊
驱动牛犊
  • 注册日期2003-04-08
  • 最后登录2011-04-06
  • 粉丝0
  • 关注0
  • 积分150分
  • 威望15点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-04-24 14:56
如果我这时遇到特定的包(如ARP)包,就不再发出,是不是要这样做?

1。NdisSend注释掉,然后返回给函数一个成功值,让系统以为包已经发出,从而释放掉内存。这个成功值应该怎么设定呢?
2。用NdisMIndicateReceive通知上层接收自己组建的数据包。此时
这个NdisMIndicateReceive的参数应该怎么写?
3。调用NdisMIndicateReceive如果返回不是Pending,,可以直接释放掉自己组建包用的内存。如果返回的是Pending,是不是要在ReturnPacket中释放内存呢?如何释放呢?

多谢大侠,上面给代码的仁兄,给你十分先。。
tsinghui
驱动牛犊
驱动牛犊
  • 注册日期2003-04-23
  • 最后登录2003-07-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-05-02 12:33
1。NdisSend() 返回一个状态值常量,找一下ddk 的文档就知道了。或者ndis.h 文件中也有定义。成功状态可能是ndis_packet_status_successful 吧。

游客

返回顶部