lucy_huiminz
驱动小牛
驱动小牛
  • 注册日期2002-06-18
  • 最后登录2009-02-11
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望6点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
阅读:2347回复:12

请教各位大侠,关于在ptreceive中调用NdisSend的问题

楼主#
更多 发布于:2003-08-13 14:51
搜索了论坛贴子,发现以前有类似的问题,不过还是没有搞明白:

我想在ptreceive中截获到感兴趣的包时,不向网卡指示,而直接组包向发包的机器回一个自定义的包:

在调用下面函数时:
ndissend(&Status,pAdapt->BindingHandle, MyPacket);

关于这个自定义包的内容已经写好,放在一个缓冲区中,第三个参数该如何填充呢?

麻烦指点!!
谢谢! :P
lucy_huiminz
驱动小牛
驱动小牛
  • 注册日期2002-06-18
  • 最后登录2009-02-11
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望6点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-08-19 13:14
我刚才做了一个实验,发现两种情况下,在ptsendcomplete中调用函数:NdisGetPacketFlags(Packet)得到的值是不一样的,好像一个是130,一个是128,不知这两个数值是偶然的还是有一定含义的呢?

不过我用这两个值作为上面两种情况的判断条件,机器会兰平.
lucy_huiminz
驱动小牛
驱动小牛
  • 注册日期2002-06-18
  • 最后登录2009-02-11
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望6点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-08-19 09:33
antspower:你说的有道理,这个是从论坛的贴子上看来的,不过问题可能就出在这里。

因为这个ptsendcomplete函数需要支持两种情况:
1、mpsend在调用ndissend后返回pending时;
2、自己构造的包发送调用ndissend后返回pending时;

对于情况1,直接调用我的ptsendcomplete中的if部分,对于情况2,调用else部分,现在就是如何判断是由哪种情况进入的ptsendcomplete函数呢?
antspower
驱动中牛
驱动中牛
  • 注册日期2002-10-17
  • 最后登录2010-08-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值2点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-08-19 08:29
Pkt = Rsvd->OriginalPkt;

通过这个来判断包时候是你不行.
//我以前试过.
放弃瘟草,现吃李草
xiaodai
驱动牛犊
驱动牛犊
  • 注册日期2002-10-22
  • 最后登录2004-06-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-08-18 17:36
发生错误情况很多,也许是你构造包内存问题!!
你还是仔细看看DDK Packet构造!
还有可能你释放内存太早驱动出错!!!
lucy_huiminz
驱动小牛
驱动小牛
  • 注册日期2002-06-18
  • 最后登录2009-02-11
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望6点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-08-18 13:23
bingjie:
我按照你的建议修改了程序,可是仍然会page fault,会不会是我的包有问题啊?
bingjie
驱动小牛
驱动小牛
  • 注册日期2001-08-15
  • 最后登录2007-11-29
  • 粉丝0
  • 关注0
  • 积分36分
  • 威望5点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-08-18 12:00
ndissend后如果返回非pending:
if (Status != NDIS_STATUS_PENDING)
{
NdisFreeBuffer(pPacketBuffer);
NdisFreeMemory(pPacketContent, BUFFER_SIZE, 0);
NdisDprFreePacket(MyPacket);
return NDIS_STATUS_SUCCESS;
}
...
这样不对么?
  

其实释放包的动作都可以放到PTSendComplete里,另外如果是PENDING,你不可以自己调用PTSendComplete,而是直接返回等待Ndis调用你的函数,否则必然PAGE_FAULT。
代码这样写就可以了
if (Status != NDIS_STATUS_PENDING)
{
  PTSendComplete( ... );
}
else
   return STATUS_SUCCESS;

lucy_huiminz
驱动小牛
驱动小牛
  • 注册日期2002-06-18
  • 最后登录2009-02-11
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望6点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
7楼#
发布于: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);
    }
}


这样不对么?
 
antspower
驱动中牛
驱动中牛
  • 注册日期2002-10-17
  • 最后登录2010-08-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值2点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于: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]
放弃瘟草,现吃李草
lucy_huiminz
驱动小牛
驱动小牛
  • 注册日期2002-06-18
  • 最后登录2009-02-11
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望6点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-08-15 14:19
我的自己组装的包放在一个缓冲区里面,如何把它组成一个ndis调用的packet?

我看了passthru中的mpsend函数,发现它利用传入的packet来组装自己的那个mypacket,对于我只有一个缓冲区,如何组装呢?

lucy_huiminz
驱动小牛
驱动小牛
  • 注册日期2002-06-18
  • 最后登录2009-02-11
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望6点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-08-15 14:19
我的自己组装的包放在一个缓冲区里面,如何把它组成一个ndis调用的packet?

我看了passthru中的mpsend函数,发现它利用传入的packet来组装自己的那个packet,对于我只有一个缓冲区,如何组装呢?

antspower
驱动中牛
驱动中牛
  • 注册日期2002-10-17
  • 最后登录2010-08-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值2点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2003-08-14 08:45
自己组装一个代替mypacket
放弃瘟草,现吃李草
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2003-08-13 14:58
就是你要发送的packet的指针吖
学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
游客

返回顶部