KungFu
驱动大牛
驱动大牛
  • 注册日期2001-09-27
  • 最后登录2008-04-08
  • 粉丝0
  • 关注0
  • 积分221分
  • 威望24点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
阅读:4314回复:26

为什么得到的packet为空?

楼主#
更多 发布于:2002-03-03 14:06
在imd中,用NdisGetReceivedPacket得到的packet为null,但是,我可以正常上网。我用softice监视了很长时间,得到的全是null。此问题,有人提出过。但是没有合适的答案。

[编辑 -  3/3/02 作者: KungFu]
我不写驱动好多年
ysy
ysy
驱动中牛
驱动中牛
  • 注册日期2002-02-18
  • 最后登录2008-08-25
  • 粉丝0
  • 关注0
  • 积分201分
  • 威望29点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-03-03 17:28
是这样的,你可以搜艘网上的帖子,他们又对这些地解释,但是都不是很满意。尤其是huyg斑竹还贴出了一些代码,但没有实际意义,因为他的代码是在NdisGetPacket返回值不空的情况下处理的,如果返回值为空怎么处理,我也在实验,但是会出现page fault,不知哪位高手能提供些资料,code最好了。:)
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
板凳#
发布于:2002-03-04 09:13
是这样的,你可以搜搜网上的帖子,他们有对这些的解释,但是都不是很满意。尤其是huyg斑竹还贴出了一些代码,但没有实际意义,因为他的代码是在NdisGetReceivedPacket返回值不空的情况下处理的,如果返回值为空怎么处理,我也在实验,但是会出现page fault,不知哪位高手能提供些资料,code最好了。:)



对于ysy的污蔑( :-p ),我只好用source来说明问题了:-)。

首先何时会出现返回null,我不在这里做第n+1(n>2)次重复,
下面就直接贴source。其实我觉得原理比source要重要的多。

return null有两种情况:
1、不需要调用transferdata的
if(PacketSize <= LookAheadBufferSize) // 按照ddk的说法是当packetsize<=lookaheadbuffersize的时候就是所有的包都得到了
 // 但是我从来没有遇到过packetsize<lookaheadbuffersize的情况。
 // jim matteer的imd就从来没有处理<的情况,手头上没有nt4 ddk,不知道是jim处理
 // 的时候有个遗漏还是ndis5又作了什么变化。
{
Status = NdisAllocateMemory(
&pPacketContent,
2000,
0,
HighestAcceptableAddress);

if (Status != NDIS_STATUS_SUCCESS )
{
DbgPrint(\"ptreceive :ndisallocatememory failed\\n\");
return NDIS_STATUS_NOT_ACCEPTED ;
}

if(pPacketContent == NULL)
{
DbgPrint(\"prreceive:pPacketContent == NULL\\n\");
return NDIS_STATUS_NOT_ACCEPTED ;
}

RtlZeroMemory(pPacketContent,  2000  );

RtlCopyMemory(pPacketContent,HeaderBuffer,HeaderBufferSize);
RtlCopyMemory(pPacketContent+HeaderBufferSize,LookAheadBuffer,LookAheadBufferSize);
PacketLen = PacketSize+HeaderBufferSize;

// DbgPrint(\"Packet Size=%d\\n\",PacketLen);

result = RecvProcess( pAdapt,pPacketContent,&PacketLen);
if( result == PACKET_REFUSE )
{
DbgPrint(\"ptreceive :packet_refuse\\n\");
NdisFreeMemory(pPacketContent,2000,0);
return NDIS_STATUS_NOT_ACCEPTED;
}
NdisDprAllocatePacket(&Status,
 &MyPacket,
 pAdapt->RecvPacketPoolHandle);

if(Status == NDIS_STATUS_SUCCESS)
{
NdisAllocateBuffer(&Status,&PacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,PacketLen);
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 );
NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1); // 这个函数调用之后ndis就只能调用protocol的ptrecievepacket了。

if ( NDIS_GET_PACKET_STATUS( MyPacket ) != NDIS_STATUS_PENDING )
{
 NdisFreeBuffer(PacketBuffer);
 NdisFreeMemory(pPacketContent,2000,0);
 NdisDprFreePacket(MyPacket);
}
break;
}



2、
需要调用transferdata的。
Status = NdisAllocateMemory(
&pPacketContent,
2000,
0,
HighestAcceptableAddress);

if (Status != NDIS_STATUS_SUCCESS )
{
DbgPrint(\"ptreceive :ndisallocatememory failed\\n\");
return NDIS_STATUS_NOT_ACCEPTED ;
}

if(pPacketContent == NULL)
{
DbgPrint(\"prreceive:pPacketContent == NULL\\n\");
return NDIS_STATUS_NOT_ACCEPTED ;
}

RtlZeroMemory(pPacketContent,  2000  );
NdisDprAllocatePacket(&Status,
 &MyPacket,
 pAdapt->RecvPacketPoolHandle);


NdisAllocateMemory(
&pBakBuffer,
2000,
0,
HighestAcceptableAddress);
if(Status != NDIS_STATUS_SUCCESS)
{
DbgPrint(\"ptreceive:allcate bak buffer failed\\n\");
return NDIS_STATUS_NOT_ACCEPTED;
}

NdisMoveMemory(pBakBuffer,HeaderBuffer,HeaderBufferSize);
NdisMoveMemory(pBakBuffer+HeaderBufferSize,LookAheadBuffer,LookAheadBufferSize);
PacketLen = HeaderBufferSize + PacketSize;
NdisAllocateBuffer(&Status,&PacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,PacketSize-LookAheadBufferSize);
NdisChainBufferAtFront( MyPacket, PacketBuffer );
MyPacket->Private.Head->Next=NULL;
MyPacket->Private.Tail=NULL;

OffsetSize = HeaderBufferSize + LookAheadBufferSize;

NdisDprAllocatePacket(&Status,
&MyPacket2,
pAdapt->RecvPacketPoolHandle);
NdisAllocateBuffer(&Status,&OffsetBuffer,pAdapt->RecvBufferPoolHandle ,pBakBuffer,OffsetSize);
NdisChainBufferAtFront(MyPacket2,OffsetBuffer);

Resvd =(PRSVD)(MyPacket->MiniportReserved);
Resvd->OriginalPkt = (PNDIS_PACKET)MyPacket2;

NDIS_SET_PACKET_HEADER_SIZE( MyPacket, HeaderBufferSize );

NdisTransferData(&Status,
pAdapt->BindingHandle ,
MacReceiveContext,
LookAheadBufferSize,  
PacketSize-LookAheadBufferSize ,
MyPacket,
&BytesTransferred);

if ( Status != NDIS_STATUS_PENDING )
{

PtTransferDataComplete( (NDIS_HANDLE)pAdapt, MyPacket, Status, BytesTransferred );
}


不再回忆从前,我已经生活在幸福当中。
blue
驱动大牛
驱动大牛
  • 注册日期2001-04-25
  • 最后登录2010-10-15
  • 粉丝0
  • 关注0
  • 积分55分
  • 威望12点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-03-04 09:45
这个我也没有解决,我现在就是换成D-Link网卡了。
我原先问过一老外,他说这个是因为用的网卡接收方式较老,那封帽邮件我找不到了,大致意思是你自已将数据组包(数据在Buffer & LookBuffer),自己传输剩余数据。
ysy
ysy
驱动中牛
驱动中牛
  • 注册日期2002-02-18
  • 最后登录2008-08-25
  • 粉丝0
  • 关注0
  • 积分201分
  • 威望29点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-03-04 10:39
首先向huyg致歉,其实我并没有污蔑的意思。
再者,我觉得您说的理论固然重要,但是现在的状况是理论是基本上知道了一些,需要实践来证明,毕竟是水平有限,需要您的指导,但是这些问题对您来说又是小儿科,所以不免有些牢骚。
我纯粹自己在玩,等我能把包抓到之后,我肯定会把完整的代码贴出来,看看我的理解对不对。
谢谢huyg的大度和包涵!
KungFu
驱动大牛
驱动大牛
  • 注册日期2001-09-27
  • 最后登录2008-04-08
  • 粉丝0
  • 关注0
  • 积分221分
  • 威望24点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-03-04 11:29
首先向huyg致歉,其实我并没有污蔑的意思。
再者,我觉得您说的理论固然重要,但是现在的状况是理论是基本上知道了一些,需要实践来证明,毕竟是水平有限,需要您的指导,但是这些问题对您来说又是小儿科,所以不免有些牢骚。
我纯粹自己在玩,等我能把包抓到之后,我肯定会把完整的代码贴出来,看看我的理解对不对。
谢谢huyg的大度和包涵!


胡斑竹的大名在白云是很响的,我们公司的同事也都知道帝国空军有个做imd很高的牛人。但是,我们的水平不是太高,难免有些贻笑大方的问题,希望能给解答。也不是白帮忙的,如果空军牛人来青岛的话,qingdao beer和海鲜一定是少不了的:)

以上是题外话了。

1。你提供的source有个函数recvprocess不知道是做什么的?
2。如果你认为一些小儿科的问题不想重复,不妨告诉我,我愿意代劳,并且署名是胡大侠的:)
我不写驱动好多年
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
6楼#
发布于:2002-03-04 13:08
[quote]首先向huyg致歉,其实我并没有污蔑的意思。
再者,我觉得您说的理论固然重要,但是现在的状况是理论是基本上知道了一些,需要实践来证明,毕竟是水平有限,需要您的指导,但是这些问题对您来说又是小儿科,所以不免有些牢骚。
我纯粹自己在玩,等我能把包抓到之后,我肯定会把完整的代码贴出来,看看我的理解对不对。
谢谢huyg的大度和包涵!

我没有说你诬蔑我,为了防止你的误解,特意加了两个“:-)”,
就是表示我只是开个玩笑。我平时和朋友开玩笑,嬉笑怒骂太多
了,有的时候不免把这个习惯带到了网上,请各位兄弟谅解。在
军队那种环境中呆长了(10年军龄了啊),如果不自己找点排解
的方法必然会变态,这是我的经验和10年观察之后的结论:-)。


胡斑竹的大名在白云是很响的,我们公司的同事也都知道帝国空军有个做imd很高的牛人。但是,我们的水平不是太高,难免有些贻笑大方的问题,希望能给解答。也不是白帮忙的,如果空军牛人来青岛的话,qingdao beer和海鲜一定是少不了的:)

以上是题外话了。

1。你提供的source有个函数recvprocess不知道是做什么的?
2。如果你认为一些小儿科的问题不想重复,不妨告诉我,我愿意代劳,并且署名是胡大侠的:) [/quote]

我考,几顶高帽子戴上来,我看我如果不贡献出所有知道的是说不
过去了 :-)。


1、recvprocess函数
这个和抓包无关,是做firewall和vpn等处理用的。里面就是判断
策略,如有必要,例如组包,我会把这个包放入一个队列,等待
以后处理。
2、再次重复一遍关于返回null的情况。当nic miniport调用
ndisethindicatepacket的时候,ndis就调用协议的ptrecieve,
这个时候会返回null。当nic miniport内存不够的时候,会
设置NDIS_PACKET的flag为ndis_resource然后indicatepacket,
这个时候也会使得ndis调用协议的ptrecieve,但是NdisGetPacket
不会返回null。返回了null说明一个问题,就是nic miniport
不支持或者不在这个包中提供oob data。因此,nic不需要把
一个ndis_packet提交给协议层,只需要提交一些raw data就
行了。这些raw data就在lookaheadbuffer和data里面。

对于返回null,还分2种情况:
一种是提交的数据都包含在ptreceive的入口参数中了,这个时候
协议层判断该包是否属于本协议,例如ip协议判断协议字段是否
是0x800。如果是,协议层负责拷贝这段数据,协议层不能直接
用这些指针构造packet,必须分配一块新内存。

还有一种情况是只有部分数据,协议层同样判断(判断方法同上)
如果协议发现这个包的确属于自己,那么它调用
miniport_transferdata来让nic miniport上传剩下的数据。

我贴的代码就是对这两种情况的处理。ptrecieve共有3种情况,
第一种是NdisGetPacket不返回null,这个passthru已经处理了。
剩下两种情况就是我贴的代码。

这里要说明一点的是,passthru用了一个让初学者郁闷的方法,
当它判断返回null的时候,它直接调用ndisXXXindicatepacket,
这样ip层会判断之后调用imd_transferdata,imd_transferdata
调用miniport_transferdata,对于上层(ip)来说,完美的仿真
了nic的行为,但是对于firewall之类的处理就加大了难度,
我猜想大多数人的郁闷都来源于此。

不再回忆从前,我已经生活在幸福当中。
ysy
ysy
驱动中牛
驱动中牛
  • 注册日期2002-02-18
  • 最后登录2008-08-25
  • 粉丝0
  • 关注0
  • 积分201分
  • 威望29点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-03-04 14:02
的确如此,您上面贴出的code是放在ndisXXXindicatepacket后面呢还是前面?
这些新分配的资源怎样free呢?应该是在PtTransferDataComplete里吧?
其实也不是戴高帽,古语说达者为师!
ysy
ysy
驱动中牛
驱动中牛
  • 注册日期2002-02-18
  • 最后登录2008-08-25
  • 粉丝0
  • 关注0
  • 积分201分
  • 威望29点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-03-04 17:28
huyg别见笑,这是我在PtTransferDataComplete里面做的工作。但是问题出在哪里呢?

VOID
PtTransferDataComplete(
IN  NDIS_HANDLE ProtocolBindingContext,
IN  PNDIS_PACKET Packet,
IN  NDIS_STATUS Status,
IN  UINT BytesTransferred
)
/*++

Routine Description:

Entry point called by NDIS to indicate completion of a call by us
to NdisTransferData.

See notes under SendComplete.

Arguments:

Return Value:

--*/
{
PADAPT  pAdapt =(PADAPT)ProtocolBindingContext;

DBGPRINT((\"Transfer complete\\n\"));

// if(pAdapt->MiniportHandle)
// {
// NdisMTransferDataComplete(pAdapt->MiniportHandle,
//  Packet,
//  Status,
//  BytesTransferred);
// }
do{
   PNDIS_PACKET            MyPacket, MyPacket2;
   PUCHAR                  pPacketContent, pBakBuffer;
   UINT                    BytesTransferred;
   PNDIS_BUFFER            PacketBuffer, OffsetBuffer;
   ULONG BufferLength, TotalLength;
   PRSVD Resvd;
   
   MyPacket = Packet;
Resvd =(PRSVD)(MyPacket->MiniportReserved);
MyPacket2 = (PNDIS_PACKET)Resvd->OriginalPkt;

        NdisGetFirstBufferFromPacket(
            MyPacket2,
            &OffsetBuffer,
            (PVOID *)&pBakBuffer,
            &BufferLength,
            &TotalLength);

if(pAdapt->MiniportHandle)
{
NdisMTransferDataComplete(pAdapt->MiniportHandle,
 MyPacket2,
 Status,
 BufferLength);
}
//        NdisFreePacket(MyPacket2);

//        NdisFreeBuffer(OffsetBuffer);

//        NdisFreeMemory(
//         pBakBuffer,
//         0,
//         0
//         );

        NdisGetFirstBufferFromPacket(
            MyPacket,
            &PacketBuffer,
            (PVOID *)&pPacketContent,
            &BufferLength,
            &TotalLength);

        NdisFreePacket(MyPacket);

        NdisFreeBuffer(PacketBuffer);

        NdisFreeMemory(
         pPacketContent,
         0,
         0
         );
//pAdapt->RecvPacketPoolHandle
    }while(0);
// PtTransferDataCompleteFreeMydata(
// ProtocolBindingContext,
// Packet,              
// Status,              
// BytesTransferred      
// );
}
ysy
ysy
驱动中牛
驱动中牛
  • 注册日期2002-02-18
  • 最后登录2008-08-25
  • 粉丝0
  • 关注0
  • 积分201分
  • 威望29点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-03-04 17:33
MPTransferData与在ptreceive里面调用NdisTransferData有关系吗?
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
10楼#
发布于:2002-03-04 18:16
的确如此,您上面贴出的code是放在ndisXXXindicatepacket后面呢还是前面?
这些新分配的资源怎样free呢?应该是在PtTransferDataComplete里吧?
其实也不是戴高帽,古语说达者为师!


忘掉那行ndisXXXindicatepacket吧。很简单,删掉它,以及那个
switch,因为我们不再需要它了。我们要对所有的medium做通用
处理,只需要用ndisindicatepacket。整个函数的结构如下:
if (ndisgetpacket!=null)
{
//第一种情况
ndisindicatepacket
}
else if (PacketSize <= LookAheadBufferSize)
{
//第二种情况

switch(medium)
{
case 802.3:
setpacketheadsize(14);
case fddi:
}
ndisindicatepacket
}
else
{
//第三种情况
case 802.3:
setpacketheadsize(14);
case fddi:

ndistransferdata();
if ( Status != NDIS_STATUS_PENDING )
{
PtTransferDataComplete( (NDIS_HANDLE)pAdapt, MyPacket, Status, BytesTransferred );
}

}

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;
PUCHAR pPacketContent;
PRSVD Resvd;
UINT OffsetSize;
UINT result;
UINT PacketLen;
PNDIS_BUFFER PacketBuffer;
PNDIS_PACKET OffsetPacket;
PNDIS_BUFFER OffsetBuffer;
PUCHAR pBakContent;
UINT bufLength;

NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress;

NDIS_STATUS status = NDIS_STATUS_SUCCESS;

DBGPRINT(\"in PtTransferDataComplete\\n\");

HighestAcceptableAddress.LowPart = -1;
HighestAcceptableAddress.HighPart = -1;

//
// Returning the Send on the Primary, will point to itself if there is no LBFO
//
pAdapt = pAdapt->pPrimaryAdapt;

Resvd = (PRSVD)(Packet->MiniportReserved);
OffsetPacket = (PNDIS_PACKET)Resvd->OriginalPkt;




if(pAdapt->MiniportHandle)
{
if (OffsetPacket==NULL)
{
 NdisMTransferDataComplete(pAdapt->MiniportHandle,
Packet,
Status,
BytesTransferred);
}
else
{
status = NdisAllocateMemory(
&pPacketContent,
2000,
0,
HighestAcceptableAddress);

CopyPacket2Buf(OffsetPacket,pPacketContent,&OffsetSize);
CopyPacket2Buf(Packet,pPacketContent+OffsetSize,&PacketLen);//packetlen == bytestransferred

PacketLen+=OffsetSize;
// 手动释放offsetpacket
NdisUnchainBufferAtFront( OffsetPacket,&OffsetBuffer );
NdisQueryBufferSafe(OffsetBuffer,&pBakContent,&bufLength, 32 );
NdisFreeBuffer(OffsetBuffer);
NdisFreeMemory(pBakContent,2000,0);
NdisFreePacket(OffsetPacket);

memset(Packet->MiniportReserved,0,sizeof(Packet->MiniportReserved));

result = RecvProcess(pAdapt,pPacketContent,&PacketLen);
if( result == PACKET_REFUSE )
{
MPReturnPacket((NDIS_HANDLE)pAdapt,Packet);
DbgPrint(\"recvprocess return packet_refuse\\n\");
return;
}
NdisUnchainBufferAtFront( Packet,&PacketBuffer );
NdisQueryBufferSafe(PacketBuffer,&pBakContent,&bufLength,32);
NdisFreeBuffer(PacketBuffer);
NdisFreeMemory(pBakContent,2000,0);
NdisAllocateBuffer(&status,&PacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,PacketLen);
NdisChainBufferAtFront(Packet,PacketBuffer);
Packet->Private.Head->Next =NULL;
Packet->Private.Tail=NULL;
NDIS_SET_PACKET_HEADER_SIZE(Packet,14);
NdisMIndicateReceivePacket(pAdapt->MiniportHandle ,&Packet,1);
if(NDIS_GET_PACKET_STATUS(Packet) != NDIS_STATUS_PENDING)
{
MPReturnPacket((NDIS_HANDLE)pAdapt,Packet);
}
}
}
}

不再回忆从前,我已经生活在幸福当中。
ysy
ysy
驱动中牛
驱动中牛
  • 注册日期2002-02-18
  • 最后登录2008-08-25
  • 粉丝0
  • 关注0
  • 积分201分
  • 威望29点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-03-05 13:22
我用的是xp ddk的passthru,在2k上编译通过。
这是ptreceive里的一段代码,是huyg斑竹给的:
ptreceive(...)
{
...
pAdapt->IndicateRcvComplete = TRUE;
switch (pAdapt->Medium)
{
 case NdisMedium802_3:
 case NdisMediumWan:
do{
   //PADAPT pOpenContext;
   PNDIS_PACKET            MyPacket, MyPacket2;
   PUCHAR                  pPacketContent, pBakBuffer;
   UINT                    BytesTransferred;
   PNDIS_BUFFER            PacketBuffer, OffsetBuffer;
   PRSVD Resvd;
   ULONG PacketLen, OffsetSize;
NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress;

HighestAcceptableAddress.LowPart = -1;
HighestAcceptableAddress.HighPart = -1;

   //pOpenContext = (PADAPT)ProtocolBindingContext;
   //NUIO_STRUCT_ASSERT(pOpenContext, oc);
   //pRcvPacket = NULL;
   //pRcvData = NULL;
   Status = NDIS_STATUS_SUCCESS;

if(PacketSize <= LookAheadBufferSize) {
DBGPRINT((\"pAdapt->Medium = %d\\n\", pAdapt->Medium));
NdisMEthIndicateReceive(pAdapt->MiniportHandle,
MacReceiveContext,
HeaderBuffer,
HeaderBufferSize,
LookAheadBuffer,
LookAheadBufferSize,
PacketSize);
break;
}

//
// fall here, the PacketSize > LookAhdeadBufferSize
//
Status = NdisAllocateMemory(
&pPacketContent,
2000,
0,
HighestAcceptableAddress);

if (Status != NDIS_STATUS_SUCCESS )
{
DbgPrint(\"ptreceive :ndisallocatememory failed\\n\");
Status = NDIS_STATUS_NOT_ACCEPTED;
break;
}

if(pPacketContent == NULL)
{
DbgPrint(\"prreceive:pPacketContent == NULL\\n\");
Status = NDIS_STATUS_NOT_ACCEPTED;
break;
}

RtlZeroMemory(
pPacketContent,
2000
);
NdisDprAllocatePacket(&Status,
&MyPacket,
pAdapt->RecvPacketPoolHandle);


NdisAllocateMemory(
&pBakBuffer,
2000,
0,
HighestAcceptableAddress);
if(Status != NDIS_STATUS_SUCCESS)
{
DbgPrint(\"ptreceive:allcate bak buffer failed\\n\");
Status = NDIS_STATUS_NOT_ACCEPTED;
break;
}

NdisMoveMemory(
pBakBuffer,
HeaderBuffer,
HeaderBufferSize
);
NdisMoveMemory(
pBakBuffer+HeaderBufferSize,
LookAheadBuffer,
LookAheadBufferSize
);
PacketLen = HeaderBufferSize + PacketSize;
NdisAllocateBuffer(
&Status,
&PacketBuffer,
pAdapt->RecvBufferPoolHandle,
pPacketContent,
PacketSize-LookAheadBufferSize
);
NdisChainBufferAtFront(
MyPacket,
PacketBuffer
);
MyPacket->Private.Head->Next=NULL;
MyPacket->Private.Tail=NULL;

OffsetSize = HeaderBufferSize + LookAheadBufferSize;

NdisDprAllocatePacket(
&Status,
&MyPacket2,
pAdapt->RecvPacketPoolHandle
);
NdisAllocateBuffer(
&Status,
&OffsetBuffer,
pAdapt->RecvBufferPoolHandle ,
pBakBuffer,
OffsetSize
);
NdisChainBufferAtFront(
MyPacket2,
OffsetBuffer
);

Resvd =(PRSVD)(MyPacket->MiniportReserved);
Resvd->OriginalPkt = (PNDIS_PACKET)MyPacket2;

NDIS_SET_PACKET_HEADER_SIZE( MyPacket, HeaderBufferSize );

NdisTransferData(
&Status,
pAdapt->BindingHandle ,
MacReceiveContext,
LookAheadBufferSize,
PacketSize-LookAheadBufferSize ,
MyPacket,
&BytesTransferred
);

if ( Status != NDIS_STATUS_PENDING )
{
PtTransferDataComplete(
(NDIS_HANDLE)pAdapt,
MyPacket,
Status,
BytesTransferred
);
}
}while(0);
break;
...
}

下面也是huyg斑竹给的,是pttransfercomplet,其中我注释掉了一部分。
VOID
PtTransferDataComplete(
IN  NDIS_HANDLE ProtocolBindingContext,
IN  PNDIS_PACKET Packet,
IN  NDIS_STATUS Status,
IN  UINT BytesTransferred
)
/*++

Routine Description:

Entry point called by NDIS to indicate completion of a call by us
to NdisTransferData.

See notes under SendComplete.

Arguments:

Return Value:

--*/
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
PUCHAR pPacketContent;
PRSVD Resvd;
UINT OffsetSize;
UINT result;
UINT PacketLen;
PNDIS_BUFFER PacketBuffer;
PNDIS_PACKET OffsetPacket;
PNDIS_BUFFER OffsetBuffer;
PUCHAR pBakContent;
UINT bufLength;

NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress;

NDIS_STATUS status = NDIS_STATUS_SUCCESS;

DBGPRINT((\"in PtTransferDataComplete\\n\"));

HighestAcceptableAddress.LowPart = -1;
HighestAcceptableAddress.HighPart = -1;

//
// Returning the Send on the Primary, will point to itself if there is no LBFO
//
// pAdapt = pAdapt->pPrimaryAdapt;

Resvd = (PRSVD)(Packet->MiniportReserved);
OffsetPacket = (PNDIS_PACKET)Resvd->OriginalPkt;




if(pAdapt->MiniportHandle)
{
if (OffsetPacket==NULL)
{
NdisMTransferDataComplete(pAdapt->MiniportHandle,
Packet,
Status,
BytesTransferred);
}
else
{
//status = NdisAllocateMemory(
// &pPacketContent,
// 2000,
// 0,
// HighestAcceptableAddress);

//CopyPacket2Buf(OffsetPacket,pPacketContent,&OffsetSize);
//CopyPacket2Buf(Packet,pPacketContent+OffsetSize,&PacketLen);//packetlen == bytestransferred

//PacketLen+=OffsetSize;
// 手动释放offsetpacket
NdisUnchainBufferAtFront( OffsetPacket,&OffsetBuffer );
NdisQueryBufferSafe(OffsetBuffer,&pBakContent,&bufLength, 32 );
NdisFreeBuffer(OffsetBuffer);
NdisFreeMemory(pBakContent,2000,0);
NdisFreePacket(OffsetPacket);

memset(Packet->MiniportReserved,0,sizeof(Packet->MiniportReserved));

MPReturnPacket((NDIS_HANDLE)pAdapt,Packet);
return;
//result = RecvProcess(pAdapt,pPacketContent,&PacketLen);
//if( result == PACKET_REFUSE )
//{
// MPReturnPacket((NDIS_HANDLE)pAdapt,Packet);
// DbgPrint(\"recvprocess return packet_refuse\\n\");
// return;
//}
NdisUnchainBufferAtFront( Packet,&PacketBuffer );
NdisQueryBufferSafe(PacketBuffer,&pBakContent,&bufLength,32);
NdisFreeBuffer(PacketBuffer);
NdisFreeMemory(pBakContent,2000,0);
NdisAllocateBuffer(&status,&PacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,PacketLen);
NdisChainBufferAtFront(Packet,PacketBuffer);
Packet->Private.Head->Next =NULL;
Packet->Private.Tail=NULL;
NDIS_SET_PACKET_HEADER_SIZE(Packet,14);
NdisMIndicateReceivePacket(pAdapt->MiniportHandle ,&Packet,1);
if(NDIS_GET_PACKET_STATUS(Packet) != NDIS_STATUS_PENDING)
{
MPReturnPacket((NDIS_HANDLE)pAdapt,Packet);
}
}
}

一旦加载这个驱动,page fault。还请hu大虾看看是怎么回事?谢谢!
blue
驱动大牛
驱动大牛
  • 注册日期2001-04-25
  • 最后登录2010-10-15
  • 粉丝0
  • 关注0
  • 积分55分
  • 威望12点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-03-05 16:07
Huyg: 我对你的敬仰有如江水,连绵不绝;又有如...
去年为解决这个问题,花了我一个月时间,但还是...,只好换卡。
受益非浅!!!
ysy
ysy
驱动中牛
驱动中牛
  • 注册日期2002-02-18
  • 最后登录2008-08-25
  • 粉丝0
  • 关注0
  • 积分201分
  • 威望29点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-03-06 10:14
blue老大,您说的是什么意思?是您也碰到了这问题吗?既然您已经解决了,能帮兄弟一把吗?谢谢!
blue
驱动大牛
驱动大牛
  • 注册日期2001-04-25
  • 最后登录2010-10-15
  • 粉丝0
  • 关注0
  • 积分55分
  • 威望12点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2002-03-06 16:18
非常简单:在产品说明书中注明:为保证本产品性能,请使用D-Link, 3COM等100M/10M自适应网卡。(请避免使用Realtek等品牌10M老式网卡)
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
15楼#
发布于:2002-03-06 19:06
非常简单:在产品说明书中注明:为保证本产品性能,请使用D-Link, 3COM等100M/10M自适应网卡。(请避免使用Realtek等品牌10M老式网卡)


这真是太有创意了,我简直受不了了。还有很多56k的moden
也用ndisxxxindicatepacket,那怎么办?
不再回忆从前,我已经生活在幸福当中。
ysy
ysy
驱动中牛
驱动中牛
  • 注册日期2002-02-18
  • 最后登录2008-08-25
  • 粉丝0
  • 关注0
  • 积分201分
  • 威望29点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2002-03-06 20:36
老大,不要拿兄弟们开涮好不好?如果我精于此道的话,我也就不问了!!唉,惨呀,这个如肉强食的世界!!!:(
xemexzj
驱动牛犊
驱动牛犊
  • 注册日期2001-11-07
  • 最后登录2006-03-15
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2002-03-07 14:56
请问版主,NdisMIndicateReceivePacket(...)中的Packet只能带一个buffer吗?
xeme
ysy
ysy
驱动中牛
驱动中牛
  • 注册日期2002-02-18
  • 最后登录2008-08-25
  • 粉丝0
  • 关注0
  • 积分201分
  • 威望29点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2002-03-11 11:05
老胡呀,诸位能决问题的大虾呀,你看看这个问题怎么解决...
代码就是上面老胡铁出来的那部分:
PtTransferDataComplete(...)
{
       ...
       Packet->Private.Tail=NULL;
       NDIS_SET_PACKET_HEADER_SIZE(Packet,14);
       NdisMIndicateReceivePacket(
                    pAdapt->MiniportHandle ,
                    &Packet,
                    1);
       ....
}
当执行NdisMIndicateReceivePacket时候,出现PageFault,你说该怎么办?
NdisMIndicateReceivePacket是不是就是执行((PNDIS_MINIPORT_BLOCK)(_H))->PacketIndicateHandler它呢?
blue
驱动大牛
驱动大牛
  • 注册日期2001-04-25
  • 最后登录2010-10-15
  • 粉丝0
  • 关注0
  • 积分55分
  • 威望12点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2002-03-11 12:03
to: ysy
对于Packet==NULL我就是没有解决呀!否则也不用敬仰别人了!
上一页
游客

返回顶部