www.pudn.com > PPPOE.rar > packet.cpp
//********************************************************************
// ÈÕÆÚ: 2004/08/24 - 24:8:2004 20:37
// Ãûǰ: tiamo
// ÃèÊö: packet
//*********************************************************************
#include "Stdafx.h"
// for debug memory allocate
#define __ulFILE__ MAKE_SIG('P','A','K','T')
// pool
PACKET_POOL g_poolPacket;
BUFFER_POOL g_poolBuffer;
// ndis buffer pool
NDIS_HANDLE g_hNdisBufferPool;
// packet lookaside
NPAGED_LOOKASIDE_LIST g_lookasidePacket;
// init pool
NDIS_STATUS InitializePoolSystem()
{
// packet pool
g_poolPacket.m_ulSig = PACKET_POOL_SIG;
g_poolPacket.m_ulFreePackets = 0;
g_poolPacket.m_ulMaxFreeGuard = 100;
g_poolPacket.m_ulPacketsPerBlock = 16;
g_poolPacket.m_ulProtocolReservedLen = sizeof(PROTOCOL_RESERVED);
g_poolPacket.m_ulTotalPackets = 0;
NdisInitializeListHead(&g_poolPacket.m_ltPacketBlocksHead);
NdisInitializeListHead(&g_poolPacket.m_ltFreePacketsHead);
NdisAllocateSpinLock(&g_poolPacket.m_lockSelf);
g_poolBuffer.m_ulSig = BUFFER_POOL_SIG;
g_poolBuffer.m_ulBufferSize = PPPOE_MAX_ETH_FRAME_SIZE;
g_poolBuffer.m_ulBuffersPerBlock = 10;
g_poolBuffer.m_ulFreeBuffers = 0;
g_poolBuffer.m_ulMaxFreeGuard = 100;
g_poolBuffer.m_ulTotalBuffers = 0;
NdisAllocateSpinLock(&g_poolBuffer.m_lockSelf);
NdisInitializeListHead(&g_poolBuffer.m_ltBufferBlocksHead);
NdisInitializeListHead(&g_poolBuffer.m_ltFreeBuffersHead);
NdisInitializeNPagedLookasideList(&g_lookasidePacket,0,0,0,sizeof(PACKET),PACKET_SIG,0);
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
// for ndis buffer pool
NdisAllocateBufferPool(&status,&g_hNdisBufferPool,30);
if(status != NDIS_STATUS_SUCCESS)
{
DebugError(("can't allocate ndis buffer pool status = 0x%x.\n",status));
}
return status;
}
// shut down
VOID ShutdownPoolSystem()
{
ASSERT(g_poolBuffer.m_ulSig == BUFFER_POOL_SIG);
ASSERT(g_poolPacket.m_ulSig == PACKET_POOL_SIG);
// free buffer pool
NdisAcquireSpinLock(&g_poolBuffer.m_lockSelf);
FreeUnusedBufferBlock(&g_poolBuffer);
NdisReleaseSpinLock(&g_poolBuffer.m_lockSelf);
// free packet pool
NdisAcquireSpinLock(&g_poolPacket.m_lockSelf);
FreeUnusedPacketBlock(&g_poolPacket);
NdisReleaseSpinLock(&g_poolPacket.m_lockSelf);
// free npaged list
NdisDeleteNPagedLookasideList(&g_lookasidePacket);
// free ndis buffer pool
if(g_hNdisBufferPool)
{
NdisFreeBufferPool(g_hNdisBufferPool);
}
// dump packet leak
DumpPoolLeak();
NdisFreeSpinLock(&g_poolPacket.m_lockSelf);
NdisFreeSpinLock(&g_poolBuffer.m_lockSelf);
}
// reference packet
VOID ReferencePacket(PPACKET pPacket)
{
ASSERT(pPacket && pPacket->m_ulSig == PACKET_SIG);
InterlockedIncrement(&pPacket->m_lRefCount);
}
// dereference packet
VOID DereferencePacket(PPACKET pPacket)
{
ASSERT(pPacket && pPacket->m_lRefCount > 0 && pPacket->m_ulSig == PACKET_SIG);
LONG lCount = InterlockedDecrement(&pPacket->m_lRefCount);
// ref == 0
if(!lCount)
{
// header buffer chained
if(pPacket->m_ulFlags & PPPOE_PACKET_HEADER_BUFFER_CHAINED)
{
ASSERT(pPacket->m_pNdisPacket);
NdisUnchainBufferAtFront(pPacket->m_pNdisPacket,&pPacket->m_pNdisHeaderBuffer);
}
// data chained
if(pPacket->m_ulFlags & PPPOE_PACKET_DATA_BUFFER_CHAINED)
{
ASSERT(pPacket->m_pNdisPacket);
NdisUnchainBufferAtFront(pPacket->m_pNdisPacket,&pPacket->m_pNdisDataBuffer);
}
// allocated from our pool
if(pPacket->m_ulFlags & PPPOE_PACKET_BUFFER_FROM_POOL)
{
ASSERT(pPacket->m_pNdisDataBuffer && pPacket->m_pNdisHeaderBuffer && pPacket->m_pRealBuffer);
NdisAdjustBufferLength(pPacket->m_pNdisDataBuffer,g_poolBuffer.m_ulBufferSize - PPPOE_HEADER_LEN);
FreeNdisBufferToPool(&g_poolBuffer,pPacket->m_pRealBuffer);
}
// allocated from ndis pool
if(pPacket->m_ulFlags & PPPOE_PACKET_HEADER_BUFFER_FROM_NDIS)
{
ASSERT(pPacket->m_pNdisHeaderBuffer);
NdisFreeBuffer(pPacket->m_pNdisHeaderBuffer);
}
if(pPacket->m_ulFlags & PPPOE_PACKET_DATA_BUFFER_FROM_NDIS)
{
ASSERT(pPacket->m_pNdisDataBuffer);
NdisFreeBuffer(pPacket->m_pNdisDataBuffer);
}
// call send complete
if(pPacket->m_ulFlags & PPPOE_PACKET_NEED_CALL_SEND_COMPLETE)
{
ASSERT(pPacket->m_pNdisPacket && pPacket->m_pNdisDataBuffer);
PPROTOCOL_RESERVED pResv = reinterpret_cast(pPacket->m_pNdisPacket->ProtocolReserved);
ASSERT(pResv && pResv->m_pOrginalPacket && pResv->m_pOrginalPacket);
NdisChainBufferAtFront(pResv->m_pOrginalPacket,pPacket->m_pNdisDataBuffer);
ASSERT(pResv->m_pChannel && pResv->m_pChannel->m_hNdisVcHandle);
NdisMCoSendComplete(pPacket->m_status,pResv->m_pChannel->m_hNdisVcHandle,pResv->m_pOrginalPacket);
NdisInterlockedDecrement(&pResv->m_pChannel->m_lSendingPackets);
}
// free to pool
if(pPacket->m_ulFlags & PPPOE_PACKET_FROM_POOL)
{
ASSERT(pPacket->m_pNdisPacket);
FreeNdisPacketToPool(&g_poolPacket,pPacket->m_pPacketItem);
}
// return the packet
if(pPacket->m_ulFlags & PPPOE_PACKET_NEED_RETURN_PACKET)
{
ASSERT(pPacket->m_pNdisPacket && pPacket->m_pNdisReturnBuffer);
NdisChainBufferAtFront(pPacket->m_pNdisPacket,pPacket->m_pNdisReturnBuffer);
NdisReturnPackets(&pPacket->m_pNdisPacket,1);
ASSERT(pPacket->m_pBindContext);
NdisInterlockedDecrement(&pPacket->m_pBindContext->m_lPacketNeedReturn);
}
FreePacket(pPacket);
}
}
// get simple packet
PPACKET GetSimplePacket()
{
PPACKET pRetPacket = NULL;
__try
{
// allocate packet storage
pRetPacket = AllocPacket();
// get ndis packet
pRetPacket->m_pNdisPacket = GetNdisPacketFromPool(&g_poolPacket,&pRetPacket->m_pPacketItem);
// set pointer
reinterpret_cast(pRetPacket->m_pNdisPacket->ProtocolReserved)->m_pPacket = pRetPacket;
// got here packet pointer is not null,set flags
pRetPacket->m_ulFlags |= PPPOE_PACKET_FROM_POOL;
// get frame buffer and ndis buffers
pRetPacket->m_pFrame = GetNdisBufferFromPool(&g_poolBuffer,&pRetPacket->m_pNdisHeaderBuffer,&pRetPacket->m_pNdisDataBuffer);
// chain
NdisChainBufferAtFront(pRetPacket->m_pNdisPacket,pRetPacket->m_pNdisDataBuffer);
// set flags
pRetPacket->m_ulFlags |= PPPOE_PACKET_BUFFER_FROM_POOL;
pRetPacket->m_ulFlags |= PPPOE_PACKET_DATA_BUFFER_CHAINED;
NdisChainBufferAtFront(pRetPacket->m_pNdisPacket,pRetPacket->m_pNdisHeaderBuffer);
pRetPacket->m_ulFlags |= PPPOE_PACKET_HEADER_BUFFER_CHAINED;
// set pointer
pRetPacket->m_pucDataBuffer = pRetPacket->m_pucFrame + PPPOE_HEADER_LEN;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
if(pRetPacket)
{
DereferencePacket(pRetPacket);
pRetPacket = NULL;
}
}
return pRetPacket;
}
// clone packet
PPACKET ClonePacket(PPACKET pPacket)
{
PPACKET pRet = GetSimplePacket();
if(pRet)
{
NdisMoveMemory(pRet->m_pFrame,pPacket->m_pFrame,PPPOE_HEADER_LEN);
NdisMoveMemory(pRet->m_pucDataBuffer,pPacket->m_pucDataBuffer,PPPOE_MAX_DATA_SIZE);
NdisAdjustBufferLength(pRet->m_pNdisDataBuffer,ntohs(pPacket->m_pFrame->m_pppFrame.m_usLen));
}
return pRet;
}
// get packet from pool
PNDIS_PACKET GetNdisPacketFromPool(PPACKET_POOL pPacketPool,PPACKET_ITEM *ppItem)
{
PNDIS_PACKET pRet = NULL;
ASSERT(ppItem && pPacketPool && pPacketPool->m_ulSig == PACKET_POOL_SIG);
*ppItem = NULL;
NdisAcquireSpinLock(&pPacketPool->m_lockSelf);
// no free packets
if(IsListEmpty(&pPacketPool->m_ltFreePacketsHead))
{
// allocate a block
pRet = AddPacketBlockToPool(pPacketPool,ppItem);
}
else
{
PLIST_ENTRY pEntry = RemoveHeadList(&pPacketPool->m_ltFreePacketsHead);
PPACKET_ITEM pItem = CONTAINING_RECORD(pEntry,PACKET_ITEM,m_ltPacketItemAnchor);
pRet = pItem->m_pNdisPacket;
*ppItem = pItem;
pPacketPool->m_ulFreePackets --;
pItem->m_pPacketBlock->m_ulFreePacketItems --;
}
NdisReleaseSpinLock(&pPacketPool->m_lockSelf);
return pRet;
}
// get ndis buffer from pool
PPPPOE_FRAME GetNdisBufferFromPool(PBUFFER_POOL pBufferPool,PNDIS_BUFFER *ppHeaderBuffer,PNDIS_BUFFER *ppDataBuffer)
{
PPPPOE_FRAME pRet = NULL;
ASSERT(ppHeaderBuffer && ppDataBuffer && pBufferPool && pBufferPool->m_ulSig == BUFFER_POOL_SIG);
*ppHeaderBuffer = NULL;
*ppDataBuffer = NULL;
NdisAcquireSpinLock(&pBufferPool->m_lockSelf);
// no free packets
if(IsListEmpty(&pBufferPool->m_ltFreeBuffersHead))
{
// allocate a block
pRet = AddBufferBlockToPool(pBufferPool,ppHeaderBuffer,ppDataBuffer);
}
else
{
// get a free buffer
PLIST_ENTRY pEntry = RemoveHeadList(&pBufferPool->m_ltFreeBuffersHead);
PBUFFER_ITEM pItem = CONTAINING_RECORD(pEntry,BUFFER_ITEM,m_ltBufferItemAnchor);
pRet = reinterpret_cast(pItem->m_pStorage);
*ppHeaderBuffer = pItem->m_pNdisHeadBuffer;
*ppDataBuffer = pItem->m_pNdisDataBuffer;
pBufferPool->m_ulFreeBuffers --;
pItem->m_pBufferBlock->m_ulFreeBufferItems --;
}
NdisReleaseSpinLock(&pBufferPool->m_lockSelf);
return pRet;
}
// allocate packet
PPACKET AllocPacket()
{
PPACKET pRet = static_cast(NdisAllocateFromNPagedLookasideList(&g_lookasidePacket));
NdisZeroMemory(pRet,sizeof(PACKET));
pRet->m_lRefCount = 1;
pRet->m_ulSig = PACKET_SIG;
NdisInitializeListHead(&pRet->m_ltPacketAnchor);
return pRet;
}
// free buffers to pool
VOID FreeNdisBufferToPool(PBUFFER_POOL pPool,PVOID pRealBuffer)
{
ASSERT(pPool && pRealBuffer && pPool->m_ulSig == BUFFER_POOL_SIG);
NdisAcquireSpinLock(&pPool->m_lockSelf);
if(pPool->m_ulFreeBuffers > pPool->m_ulMaxFreeGuard)
FreeUnusedBufferBlock(pPool);
PBUFFER_ITEM pItem = CONTAINING_RECORD(pRealBuffer,BUFFER_ITEM,m_pStorage);
InsertHeadList(&pPool->m_ltFreeBuffersHead,&pItem->m_ltBufferItemAnchor);
pPool->m_ulFreeBuffers ++;
pItem->m_pBufferBlock->m_ulFreeBufferItems ++;
NdisReleaseSpinLock(&pPool->m_lockSelf);
}
// free packet to pool
VOID FreeNdisPacketToPool(PPACKET_POOL pPool,PPACKET_ITEM pItem)
{
ASSERT(pPool && pItem && pPool->m_ulSig == PACKET_POOL_SIG);
NdisAcquireSpinLock(&pPool->m_lockSelf);
if(pPool->m_ulFreePackets > pPool->m_ulMaxFreeGuard)
FreeUnusedPacketBlock(pPool);
InsertHeadList(&pPool->m_ltFreePacketsHead,&pItem->m_ltPacketItemAnchor);
pPool->m_ulFreePackets ++;
pItem->m_pPacketBlock->m_ulFreePacketItems ++;
NdisReleaseSpinLock(&pPool->m_lockSelf);
}
// free packet
VOID FreePacket(PPACKET pPacket)
{
ASSERT(pPacket && pPacket->m_lRefCount == 0 && pPacket->m_ulSig == PACKET_SIG);
NdisFreeToNPagedLookasideList(&g_lookasidePacket,pPacket);
}
// add packet block to pool
PNDIS_PACKET AddPacketBlockToPool(PPACKET_POOL pPacketPool,PPACKET_ITEM *ppItem)
{
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
ASSERT(pPacketPool && pPacketPool->m_ulSig == PACKET_POOL_SIG && ppItem);
PNDIS_PACKET pRetPacket = NULL;
ULONG ulSize = pPacketPool->m_ulPacketsPerBlock * sizeof(PACKET_ITEM) + sizeof(PACKET_BLOCK);
PPACKET_BLOCK pBlock;
// allocate block memory
NDIS_STATUS status = AllocateMemory((PVOID*)&pBlock,ulSize,PACKET_BLOCK_SIG);
if(status != NDIS_STATUS_SUCCESS)
return NULL;
pBlock->m_ulSig = PACKET_BLOCK_SIG;
// allocate packet pool
NdisAllocatePacketPool(&status,&pBlock->m_hPacketPool,pPacketPool->m_ulPacketsPerBlock,pPacketPool->m_ulProtocolReservedLen);
if(status != NDIS_STATUS_SUCCESS)
{
FreeMemory(pBlock,ulSize);
return NULL;
}
// set value
pBlock->m_ulTotalPacketItems = pPacketPool->m_ulPacketsPerBlock;
pBlock->m_ulFreePacketItems = pPacketPool->m_ulPacketsPerBlock - 1;
pBlock->m_pPacketPool = pPacketPool;
ULONG i;
for(i = 0; i < pBlock->m_ulTotalPacketItems; i ++)
{
// prepare item
PPACKET_ITEM pItem = pBlock->m_arrayItems + i;
pItem->m_pPacketBlock = pBlock;
pItem->m_ulSig = PACKET_ITEM_SIG;
NdisAllocatePacket(&status,&pItem->m_pNdisPacket,pBlock->m_hPacketPool);
if(status != NDIS_STATUS_SUCCESS)
{
break;
}
}
// unsuccessful
if(status != NDIS_STATUS_SUCCESS)
{
for(ULONG j = 0; j < i ; j ++)
{
// free it
PPACKET_ITEM pItem = pBlock->m_arrayItems + j;
NdisFreePacket(pItem->m_pNdisPacket);
}
// free block
FreeMemory(pBlock,ulSize);
}
else
{
// update pool value
pPacketPool->m_ulFreePackets += pBlock->m_ulFreePacketItems;
pPacketPool->m_ulTotalPackets += pPacketPool->m_ulPacketsPerBlock;
// link block
InsertHeadList(&pPacketPool->m_ltPacketBlocksHead,&pBlock->m_ltPacketBlockAnchor);
// link free packet
PPACKET_ITEM pItem;
for(i = 1; i < pBlock->m_ulTotalPacketItems; i ++)
{
pItem = pBlock->m_arrayItems + i;
InsertHeadList(&pPacketPool->m_ltFreePacketsHead,&pItem->m_ltPacketItemAnchor);
}
// return the first one
pItem = pBlock->m_arrayItems;
InitializeListHead(&pItem->m_ltPacketItemAnchor);
pRetPacket = pItem->m_pNdisPacket;
*ppItem = pItem;
}
return pRetPacket;
}
// add buffer block to pool
PPPPOE_FRAME AddBufferBlockToPool(PBUFFER_POOL pBufferPool,PNDIS_BUFFER *ppHeadBuffer,PNDIS_BUFFER *ppDataBuffer)
{
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
ASSERT(pBufferPool && pBufferPool->m_ulSig == BUFFER_POOL_SIG && ppHeadBuffer && ppDataBuffer);
PPPPOE_FRAME pRetFrame = NULL;
ULONG ulSize = pBufferPool->m_ulBuffersPerBlock *(pBufferPool->m_ulBufferSize + sizeof(BUFFER_ITEM)) + sizeof(BUFFER_BLOCK);
// round it
ulSize = (ulSize + 7) & 0xfffffff8;
PBUFFER_BLOCK pBlock;
// allocate block memory
NDIS_STATUS status = AllocateMemory((PVOID*)&pBlock,ulSize,BUFFER_POOL_SIG);
if(status != NDIS_STATUS_SUCCESS)
return NULL;
pBlock->m_ulSig = BUFFER_BLOCK_SIG;
// allocate buffer pool
NdisAllocateBufferPool(&status,&pBlock->m_hBufferPool,pBufferPool->m_ulBuffersPerBlock * 2);
if(status != NDIS_STATUS_SUCCESS)
{
FreeMemory(pBlock,ulSize);
return NULL;
}
// set value
pBlock->m_ulTotalBufferItems = pBufferPool->m_ulBuffersPerBlock;
pBlock->m_ulFreeBufferItems = pBufferPool->m_ulBuffersPerBlock - 1;
pBlock->m_pBufferPool = pBufferPool;
ULONG i;
for(i = 0; i < pBlock->m_ulTotalBufferItems; i ++)
{
// prepare item
PBUFFER_ITEM pItem = GET_ITEM_FROM_BLOCK_BY_INDEX(pBlock,i,pBufferPool->m_ulBufferSize);
pItem->m_pBufferBlock = pBlock;
pItem->m_ulSig = BUFFER_ITEM_SIG;
NdisAllocateBuffer(&status,&pItem->m_pNdisHeadBuffer,pBlock->m_hBufferPool,pItem->m_pStorage,PPPOE_HEADER_LEN);
if(status != NDIS_STATUS_SUCCESS)
{
break;
}
NdisAllocateBuffer(&status,&pItem->m_pNdisDataBuffer,pBlock->m_hBufferPool,pItem->m_pStorage + PPPOE_HEADER_LEN,
pBufferPool->m_ulBufferSize - PPPOE_HEADER_LEN);
if(status != NDIS_STATUS_SUCCESS)
{
NdisFreeBuffer(pItem->m_pNdisHeadBuffer);
break;
}
}
// unsuccessful
if(status != NDIS_STATUS_SUCCESS)
{
for(ULONG j = 0; j < i ; j ++)
{
// free it
PBUFFER_ITEM pItem = GET_ITEM_FROM_BLOCK_BY_INDEX(pBlock,i,pBufferPool->m_ulBufferSize);
NdisFreeBuffer(pItem->m_pNdisHeadBuffer);
NdisFreeBuffer(pItem->m_pNdisDataBuffer);
}
// free block
FreeMemory(pBlock,ulSize);
}
else
{
// update pool value
pBufferPool->m_ulFreeBuffers += pBlock->m_ulFreeBufferItems;
pBufferPool->m_ulTotalBuffers += pBufferPool->m_ulBuffersPerBlock;
// link block
InsertHeadList(&pBufferPool->m_ltBufferBlocksHead,&pBlock->m_ltBufferBlockAnchor);
// link free packet
PBUFFER_ITEM pItem;
for(i = 1; i < pBlock->m_ulTotalBufferItems; i ++)
{
PBUFFER_ITEM pItem = GET_ITEM_FROM_BLOCK_BY_INDEX(pBlock,i,pBufferPool->m_ulBufferSize);
InsertHeadList(&pBufferPool->m_ltFreeBuffersHead,&pItem->m_ltBufferItemAnchor);
}
// return the first one
pItem = pBlock->m_arrayItem;
InitializeListHead(&pItem->m_ltBufferItemAnchor);
*ppHeadBuffer = pItem->m_pNdisHeadBuffer;
*ppDataBuffer = pItem->m_pNdisDataBuffer;
pRetFrame = reinterpret_cast(pItem->m_pStorage);
}
return pRetFrame;
}
// free unused packet block
VOID FreeUnusedPacketBlock(PPACKET_POOL pPacketPool)
{
ASSERT(pPacketPool && pPacketPool->m_ulSig == PACKET_POOL_SIG);
ULONG ulSize = pPacketPool->m_ulPacketsPerBlock * sizeof(PACKET_ITEM) + sizeof(PACKET_BLOCK);
PLIST_ENTRY pEntry = pPacketPool->m_ltPacketBlocksHead.Flink;
while(pEntry != &pPacketPool->m_ltPacketBlocksHead)
{
PPACKET_BLOCK pBlock = CONTAINING_RECORD(pEntry,PACKET_BLOCK,m_ltPacketBlockAnchor);
ASSERT(pBlock && pBlock->m_ulSig == PACKET_BLOCK_SIG);
pEntry = pEntry->Flink;
if(pBlock->m_ulFreePacketItems == pBlock->m_ulTotalPacketItems)
{
for(ULONG j = 0; j < pBlock->m_ulTotalPacketItems ; j ++)
{
// free it
PPACKET_ITEM pItem = pBlock->m_arrayItems + j;
ASSERT(pItem && pItem->m_ulSig == PACKET_ITEM_SIG);
NdisFreePacket(pItem->m_pNdisPacket);
RemoveEntryList(&pItem->m_ltPacketItemAnchor);
}
pPacketPool->m_ulTotalPackets -= pBlock->m_ulTotalPacketItems;
pPacketPool->m_ulFreePackets -= pBlock->m_ulFreePacketItems;
RemoveEntryList(&pBlock->m_ltPacketBlockAnchor);
NdisFreePacketPool(pBlock->m_hPacketPool);
// free block
FreeMemory(pBlock,ulSize);
}
}
}
// free unused packet block
VOID FreeUnusedBufferBlock(PBUFFER_POOL pBufferPool)
{
ASSERT(pBufferPool && pBufferPool->m_ulSig == BUFFER_POOL_SIG);
ULONG ulSize = pBufferPool->m_ulBuffersPerBlock *(pBufferPool->m_ulBufferSize + sizeof(BUFFER_ITEM)) + sizeof(BUFFER_BLOCK);
ulSize = (ulSize + 7) & 0xfffffff8;
PLIST_ENTRY pEntry = pBufferPool->m_ltBufferBlocksHead.Flink;
while(pEntry != &pBufferPool->m_ltBufferBlocksHead)
{
PBUFFER_BLOCK pBlock = CONTAINING_RECORD(pEntry,BUFFER_BLOCK,m_ltBufferBlockAnchor);
ASSERT(pBlock && pBlock->m_ulSig == BUFFER_BLOCK_SIG);
pEntry = pEntry->Flink;
if(pBlock->m_ulFreeBufferItems == pBlock->m_ulTotalBufferItems)
{
for(ULONG j = 0; j < pBlock->m_ulTotalBufferItems ; j ++)
{
// free it
PBUFFER_ITEM pItem = GET_ITEM_FROM_BLOCK_BY_INDEX(pBlock,j,pBufferPool->m_ulBufferSize);
ASSERT(pItem && pItem->m_ulSig == BUFFER_ITEM_SIG && pItem->m_pNdisDataBuffer && pItem->m_pNdisHeadBuffer);
NdisFreeBuffer(pItem->m_pNdisHeadBuffer);
NdisFreeBuffer(pItem->m_pNdisDataBuffer);
RemoveEntryList(&pItem->m_ltBufferItemAnchor);
}
pBufferPool->m_ulTotalBuffers -= pBlock->m_ulTotalBufferItems;
pBufferPool->m_ulFreeBuffers -= pBlock->m_ulFreeBufferItems;
RemoveEntryList(&pBlock->m_ltBufferBlockAnchor);
NdisFreeBufferPool(pBlock->m_hBufferPool);
// free block
FreeMemory(pBlock,ulSize);
}
}
}
// dump packet leak
VOID DumpPoolLeak()
{
NdisAcquireSpinLock(&g_poolBuffer.m_lockSelf);
PLIST_ENTRY pEntry = g_poolBuffer.m_ltBufferBlocksHead.Flink;
while(pEntry != &g_poolBuffer.m_ltBufferBlocksHead)
{
PBUFFER_BLOCK pBlock = CONTAINING_RECORD(pEntry,BUFFER_BLOCK,m_ltBufferBlockAnchor);
ASSERT(pBlock && pBlock->m_ulSig == BUFFER_BLOCK_SIG);
pEntry = pEntry->Flink;
DebugError(("buffer block = 0x%x,unfree buffer items count = %d\n",
pBlock,pBlock->m_ulTotalBufferItems - pBlock->m_ulFreeBufferItems));
}
NdisReleaseSpinLock(&g_poolBuffer.m_lockSelf);
NdisAcquireSpinLock(&g_poolPacket.m_lockSelf);
pEntry = g_poolPacket.m_ltPacketBlocksHead.Flink;
while(pEntry != &g_poolPacket.m_ltPacketBlocksHead)
{
PPACKET_BLOCK pBlock = CONTAINING_RECORD(pEntry,PACKET_BLOCK,m_ltPacketBlockAnchor);
ASSERT(pBlock && pBlock->m_ulSig == PACKET_BLOCK_SIG);
pEntry = pEntry->Flink;
DebugError(("packet block = 0x%x,unfree packet items count = %d\n",
pBlock,pBlock->m_ulTotalPacketItems - pBlock->m_ulFreePacketItems));
}
NdisReleaseSpinLock(&g_poolPacket.m_lockSelf);
}