sbni
驱动牛犊
驱动牛犊
  • 注册日期2001-07-06
  • 最后登录2013-05-05
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望5点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
阅读:4860回复:12

部分源码,很精彩。

楼主#
更多 发布于:2002-04-24 12:59
这是我做的驱动中的一部分,希望对大家有益。

void CopyPacket2Buffer(IN PNDIS_PACKET pPacket,IN OUT PUCHAR pBuff,IN OUT PUINT pLength)
{
PNDIS_BUFFER BuffDT;
PUCHAR BuffVA;
UINT BuffLen;

*pLength=0;
BuffLen=0;

NdisQueryPacket(pPacket,NULL,NULL,&BuffDT,NULL);

while(BuffDT!=(PNDIS_BUFFER)NULL)
{
NdisQueryBuffer(BuffDT,&BuffVA,&BuffLen);
NdisMoveMemory(pBuff,BuffVA,BuffLen);
pBuff=pBuff+BuffLen;
*pLength+=BuffLen;
NdisGetNextBuffer(BuffDT,&BuffDT);
}
return;
}


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 Rsvd;
UINT OffsetSize,Result,PacketLen;

PNDIS_BUFFER pPacketBuffer;
PNDIS_PACKET pBakPacket;
PNDIS_BUFFER pBakBuffer;

PUCHAR pBakContent;
UINT BufferLen;

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

//
// Returning the Send on the Primary, will point to itself if there is no LBFO
//
pAdapt = pAdapt->pPrimaryAdapt;
Rsvd =(PRSVD)(Packet->MiniportReserved);
pBakPacket=(PNDIS_PACKET)(Rsvd->OriginalPkt);

if(pAdapt->MiniportHandle)
{
if(pBakPacket==NULL)
NdisMTransferDataComplete(pAdapt->MiniportHandle,Packet,Status,BytesTransferred);
else
{
Status=NdisAllocateMemory(&pPacketContent,BUFFER_SIZE,0,HighestAcceptableMax);
CopyPacket2Buffer(pBakPacket,pPacketContent,&OffsetSize);
CopyPacket2Buffer(Packet,pPacketContent+OffsetSize,&PacketLen);
PacketLen+=OffsetSize;

NdisUnchainBufferAtFront(pBakPacket,&pBakBuffer);
NdisQueryBufferSafe(pBakBuffer,&pBakContent,&BufferLen,32);
NdisFreeBuffer(pBakBuffer);
NdisFreeMemory(pBakContent,BUFFER_SIZE,0);
NdisFreePacket(pBakPacket);

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

NdisUnchainBufferAtFront(Packet,&pPacketBuffer);
NdisQueryBufferSafe(pPacketBuffer,&pBakContent,&BufferLen,32);
NdisFreeBuffer(pPacketBuffer);
NdisFreeMemory(pBakContent,BUFFER_SIZE,0);
NdisAllocateBuffer(&Status,&pPacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,PacketLen);
NdisChainBufferAtFront(Packet,pPacketBuffer);
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);
}
}
}
return;
}


NDIS_STATUS
PtReceive(
IN  NDIS_HANDLE ProtocolBindingContext,
IN  NDIS_HANDLE MacReceiveContext,
IN  PVOID HeaderBuffer,
IN  UINT HeaderBufferSize,
IN  PVOID LookAheadBuffer,
IN  UINT LookAheadBufferSize,
IN  UINT PacketSize
)
/*++

Routine Description:
LBFO - need to use primary for all receives

Arguments:


Return Value:

--*/
{
PADAPT OutAdapt,pAdapt =(PADAPT)ProtocolBindingContext;
PNDIS_PACKET MyPacket, Packet,MyPacket1;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;

/* PUCHAR pEnetAddrDest=NULL;
UINT nDataSize=0,i;
PNDIS_BUFFER pNdisBuffer=NULL;
UCHAR *BufferVa=NULL;

PMACHEADER pMACHeader=NULL;
PIPHEADER pIPHeader=NULL;
PICMPHEADER pICMPHeader=NULL;
PTCPHEADER pTCPHeader=NULL;
PUDPHEADER pUDPHeader=NULL;
*/

PNDIS_BUFFER pPacketBuffer,pBakBuffer;
PUCHAR pPacketContent,pBakContent;
UINT PacketLen;

UINT OffsetSize;
UINT BytesTransferred;

PRSVD Rsvd=NULL;
PVOID MediaSpecificInfo=NULL;
ULONG MediaSpecificSize=0;

if(!pAdapt->MiniportHandle)
{
Status = NDIS_STATUS_FAILURE;
}
else do
{
//
// We should not be getting Receives on a Secondary, this is just specific to our  LBFO driver
//

if(pAdapt->isSecondary)
{
DBGPRINT(\"PASSTHRU GETTING RECIEVES ON SECONDARY\\n\");
ASSERT(0);
}

//
// If this was indicated by the miniport below as a packet, then get that packet pointer and indicate
// it as a packet as well(with appropriate status). This way the OOB stuff is accessible to the
// transport above us.
//
Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext);
if(Packet != NULL)
{
//
// Get a packet off the pool and indicate that up
//
NdisDprAllocatePacket(&Status,
 &MyPacket,
 pAdapt->RecvPacketPoolHandle);

if(Status == NDIS_STATUS_SUCCESS)
{
 MyPacket->Private.Head = Packet->Private.Head;
 MyPacket->Private.Tail = Packet->Private.Tail;

 //
 // Get the original packet(it could be the same packet as one received or a different one
 // based on # of layered MPs) and set it on the indicated packet so the OOB stuff is visible
 // correctly at the top.
 //
 NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet));
 NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize);

 //
 // Set Packet Flags
 //
 NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);

 //
 // Make sure the status is set to NDIS_STATUS_RESOURCES.
 //
 NDIS_SET_PACKET_STATUS(MyPacket, NDIS_STATUS_RESOURCES);

 NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);

 ASSERT(NDIS_GET_PACKET_STATUS(MyPacket) == NDIS_STATUS_RESOURCES);
 NdisDprFreePacket(MyPacket);
 break;
}
}

//
// Fall through if the miniport below us has either not indicated a packet or we could not
// allocate one
//
else if(PacketSize<=LookAheadBufferSize)
{
Status=NdisAllocateMemory(&pPacketContent,BUFFER_SIZE,0,HighestAcceptableMax);
if(Status!=NDIS_STATUS_SUCCESS)
{
DbgPrint(\"PTReceive:NdisAllocateMemory Failed\\n\");
return(NDIS_STATUS_NOT_ACCEPTED);
}
if(pPacketContent==NULL)
{
DbgPrint(\"PTReceive:pPacketContent==NULL\\n\");
return(NDIS_STATUS_NOT_ACCEPTED);
}

NdisZeroMemory(pPacketContent,BUFFER_SIZE);
NdisMoveMemory(pPacketContent,HeaderBuffer,HeaderBufferSize);
NdisMoveMemory(pPacketContent+HeaderBufferSize,LookAheadBuffer,LookAheadBufferSize);
PacketLen=PacketSize+HeaderBufferSize;

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

if(Status==NDIS_STATUS_SUCCESS)
{
NdisAllocateBuffer(&Status,&pPacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,PacketLen);
NdisChainBufferAtFront(MyPacket,pPacketBuffer);
MyPacket->Private.Head->Next=NULL;
MyPacket->Private.Tail=NULL;
Rsvd=(PRSVD)(MyPacket->MiniportReserved);
Rsvd->OriginalPkt=NULL;
NDIS_SET_PACKET_HEADER_SIZE(MyPacket,HeaderBufferSize);
NdisMIndicateReceivePacket(pAdapt->MiniportHandle,&MyPacket,1);
if(NDIS_GET_PACKET_STATUS(MyPacket)!=NDIS_STATUS_PENDING)
{
DBGPRINT((\"In PtReceive And Free Memory\\n\"));
NdisFreeBuffer(pPacketBuffer);
NdisFreeMemory(pPacketContent,BUFFER_SIZE,0);
NdisDprFreePacket(MyPacket);
}
}
break;
}
else
{
Status=NdisAllocateMemory(&pPacketContent,BUFFER_SIZE,0,HighestAcceptableMax);
if(Status!=NDIS_STATUS_SUCCESS)
{
DbgPrint(\"PtReceive:NdisAllocateMemory Failed.\\n\");
return(NDIS_STATUS_NOT_ACCEPTED);
}
if(pPacketContent==NULL)
{
DbgPrint(\"PTReceive:pPacketContent==NULL\\n\");
return(NDIS_STATUS_NOT_ACCEPTED);
}
NdisZeroMemory(pPacketContent,BUFFER_SIZE);

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

Status=NdisAllocateMemory(&pBakContent,BUFFER_SIZE,0,HighestAcceptableMax);
if(Status!=NDIS_STATUS_SUCCESS)
{
DbgPrint(\"PtReceive:NdisAllocateMemory Failed.\\n\");
return(NDIS_STATUS_NOT_ACCEPTED);
}
if(pBakContent==NULL)
{
DbgPrint(\"PTReceive:pPacketContent==NULL\\n\");
return(NDIS_STATUS_NOT_ACCEPTED);
}
NdisZeroMemory(pBakContent,BUFFER_SIZE);
NdisMoveMemory(pBakContent,HeaderBuffer,HeaderBufferSize);
NdisMoveMemory(pBakContent+HeaderBufferSize,LookAheadBuffer,LookAheadBufferSize);
PacketLen=HeaderBufferSize+PacketSize;
NdisAllocateBuffer(&Status,&pPacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,PacketSize-LookAheadBufferSize);

NdisChainBufferAtFront(MyPacket,pPacketBuffer);
MyPacket->Private.Head->Next=NULL;
MyPacket->Private.Tail=NULL;

OffsetSize=HeaderBufferSize+LookAheadBufferSize;

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

Rsvd=(PRSVD)(MyPacket->MiniportReserved);
Rsvd->OriginalPkt=(PNDIS_PACKET)MyPacket1;

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);
}
break;

}
pAdapt->IndicateRcvComplete = TRUE;

/*
switch(pAdapt->Medium)
{
case NdisMedium802_3:
  {
NdisMEthIndicateReceive(pAdapt->MiniportHandle,
MacReceiveContext,
HeaderBuffer,
HeaderBufferSize,
LookAheadBuffer,
LookAheadBufferSize,
PacketSize);
break;
  }
 case NdisMedium802_5:
NdisMTrIndicateReceive(pAdapt->MiniportHandle,
MacReceiveContext,
HeaderBuffer,
HeaderBufferSize,
LookAheadBuffer,
LookAheadBufferSize,
PacketSize);
break;

 case NdisMediumFddi:
NdisMFddiIndicateReceive(pAdapt->MiniportHandle,
 MacReceiveContext,
 HeaderBuffer,
 HeaderBufferSize,
 LookAheadBuffer,
 LookAheadBufferSize,
 PacketSize);
break;

 default:
ASSERT(0);
break;
}
*/
} while(FALSE);

DBGPRINT((\"In PtReceive\\n\"));

return Status;
}

VOID
MPReturnPacket(
IN NDIS_HANDLE MiniportAdapterContext,
IN PNDIS_PACKET Packet
)
/*++

Routine Description:


Arguments:


Return Value:


--*/
{
PADAPT pAdapt = (PADAPT)MiniportAdapterContext;
PNDIS_PACKET MyPacket;
PRSVD Resvd;
PNDIS_BUFFER pNdisBuffer;
PUCHAR pPacketContent;
UINT BufferLen;

Resvd = (PRSVD)(Packet->MiniportReserved);
MyPacket = Resvd->OriginalPkt;

if(MyPacket)
{
NdisFreePacket(Packet);
NdisReturnPackets(&MyPacket, 1);
}
/*=========================================================================
I Add This Code for NdisIndicateReceivePacket
=========================================================================*/
else
{
DBGPRINT((\"In MPReturnPacket And Free Memory\\n\"));
NdisUnchainBufferAtFront(Packet,&pNdisBuffer);
NdisQueryBufferSafe(pNdisBuffer,(PVOID *)&pPacketContent,&BufferLen,32);
NdisFreeBuffer(pNdisBuffer);
NdisFreeMemory(pPacketContent,BUFFER_SIZE,0);
NdisFreePacket(Packet);
DBGPRINT((\"In MPReturnPacket And Free Memory\\n\"));
}
}

最新喜欢:

wuhpowuhpo ljmmaryljmmar... riririririri IammeIamme
Songzh
驱动牛犊
驱动牛犊
  • 注册日期2001-12-29
  • 最后登录2011-03-29
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-04-24 15:18
不错不错,多贴多贴。

我给你加分!!!
falwind
驱动牛犊
驱动牛犊
  • 注册日期2001-12-21
  • 最后登录2006-12-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-04-25 14:27
太好了!
这里太需要源代码了!

以前我对于OriginalPacket以及NdisBuffer等等的概念都不是很清楚,看了这段代码的具体操作之后明白了一些东西。原来OriginalPacket是用来存放HeaderBuffer+LookaHeadBuffer的,而新分配的Packet则用来存PacketSize-LookAheadBufferSize即需要Transfer的部分;NDIS_BUFFER其实只是一个Descriptor,还需要给它指定VirtualAddress,并且需要先实际地分配一块内存,而它仅仅用来描述这块内存。

给你加分。

[编辑 -  4/25/02 作者: falwind]
falwind
驱动牛犊
驱动牛犊
  • 注册日期2001-12-21
  • 最后登录2006-12-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-04-27 16:33
sbni老兄,我按照你写的试了一下,好像不行啊。
能不能把你的源码给我一份
rangzh@sina.com
sbni
驱动牛犊
驱动牛犊
  • 注册日期2001-07-06
  • 最后登录2013-05-05
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望5点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-04-30 22:17
我的程序还有一部分代码,主要是分配缓冲区池用的,比较简单,主要是在PtBindAdapter中做的,主要是调用NdisAllocateBufferPool。
再就是在MpHalt中调用NdisFreeBufferPool。比较简单,但是必须得做,如果不做一定会出问题。
lyabcd
驱动大牛
驱动大牛
  • 注册日期2001-08-09
  • 最后登录2015-10-01
  • 粉丝0
  • 关注0
  • 积分33分
  • 威望4点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-04-30 23:38
你的程序用在哪里
datongguandian@sina.com
falwind
驱动牛犊
驱动牛犊
  • 注册日期2001-12-21
  • 最后登录2006-12-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-05-01 11:26
BufferPool和PacketPool我都分配释放了,那没有问题。后来我找到问题了,原来是NdisFreeMemory。我的处理是那样的:在你的程序的思路基础上,在每个NdisMIndicateReceivePacket之前,调用一个自定义的ProcessPacket。后来我发现,在ProcessPacket中的一个NdisFreeMemory存在问题!文档里面明明说当free的是resident memory时,NdisFreeMemory可以在<=IRQL_DISPATCH_LEVEL调用。但是,我发现最好还是在IRQL_PASSIVE_LEVEL调用NdisFreeMemory比较安全。
另外一个问题是:驱动可以正常卸载,但是在PtUnload中设置断点似乎跟踪不到。
sirroom
驱动大牛
驱动大牛
  • 注册日期2001-07-30
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望11点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-05-05 16:57
怎么看着象是huyg原来贴过的代码,hoho
111
sbni
驱动牛犊
驱动牛犊
  • 注册日期2001-07-06
  • 最后登录2013-05-05
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望5点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-05-05 20:53
你说的很对,确实是huyg以前曾经贴过的,我只是按照它说的加以整理,同时把他没有说的部分补充而已。
jinyao
驱动牛犊
驱动牛犊
  • 注册日期2001-05-05
  • 最后登录2004-05-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-07-04 22:22
我想请问BUFFER_SIZE定义为多少?
fenger_li
驱动老牛
驱动老牛
  • 注册日期2002-03-26
  • 最后登录2005-04-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-07-04 22:45
如只作包过滤,则不小于mtu即可。

呵呵
有点意思。。。 呵呵!
ufo_online
驱动牛犊
驱动牛犊
  • 注册日期2002-04-26
  • 最后登录2004-03-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-07-15 12:30
NDIS_STATUS_NOT_ACCEPTED指示该包不是其要复制的。这段程序中,在分配资源出错时返回NDIS_STATUS_NOT_ACCEPTED,会不会对驱动程序的性能造成影响
jasic2002
驱动牛犊
驱动牛犊
  • 注册日期2003-10-26
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望37点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2003-11-14 11:28
关于上面的代码有点小疑惑。


当判断packetsizse<=lookaheadbuffer时,
为什么不直接调用indicatexxxx函数上去。

还有是关于错误处理的一个问题,
如果我在判断包的过程中发生错误,比如分配内存失败,那么这个包肯定是判断不了了。
这时我是应该把这个包提交上去,还是丢了。


谢谢!
游客

返回顶部