📄 memory.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/*****************************************************************************
*
*
* @doc EX_RAS
* memory.c NdisWan memory utilities
*
* Date: 4/26/99
*
*/
// Include Files
#include "windows.h"
#include "ndis.h"
#include "ras.h"
#include "raserror.h"
#include "cxport.h"
#include "protocol.h"
#include "ppp.h"
#include "macp.h"
#ifdef DEBUG
#define MAX_NODES 1000000
BOOLEAN
ListIsValid(
IN PLIST_ENTRY pListHead,
IN PNDIS_SPIN_LOCK SpinLock OPTIONAL)
{
PLIST_ENTRY pPred, pCurr;
DWORD dwNumNodes = 0;
BOOLEAN bValid = TRUE;
if (SpinLock)
NdisAcquireSpinLock(SpinLock);
pPred = pListHead;
while (TRUE)
{
pCurr = pPred->Flink;
if (pCurr->Blink != pPred)
{
DEBUGMSG(ZONE_ERROR, (TEXT("PPP: ERROR List %x Node %x Blink %x != pPred %x\n"), pListHead, pCurr, pCurr->Blink, pPred));
bValid = FALSE;
break;
}
if (pCurr == pListHead)
break;
if (dwNumNodes++ > MAX_NODES)
{
DEBUGMSG(ZONE_ERROR, (TEXT("PPP: ERROR List %x has more than %d nodes\n"), pListHead, MAX_NODES));
bValid = FALSE;
break;
}
pPred = pCurr;
}
if (SpinLock)
NdisReleaseSpinLock(SpinLock);
return bValid;
}
#endif
/*****************************************************************************
*
*
* @func BOOL | NdisWanAllocateSendResources
* Allocate the required send resources
*
* @rdesc TRUE if successful, FALSE for error.
*
* @parm PMAC_CONTEXT | pMac | Pointer to the Mac Context
*
* @comm
* This function will allocate the NDIS_WAN_PACKETs required for a
* connection
*
* @ex No Example
*
*/
NDIS_STATUS
NdisWanAllocateSendResources(
PMAC_CONTEXT pMac)
{
DWORD dwBufferSize;
DWORD cPackets, n;
DWORD dwPacketMemorySize;
PUCHAR PacketMemory = NULL;
PNDIS_WAN_PACKET pWanPacket;
// Allocate enough for the send window plus a spare for compression space
cPackets = pMac->WanInfo.MaxTransmit + 1;
// The compression code can actually wind up expanding the data size
// (though when the frame expands the original is sent, not the expanded one).
// The expansion can be up to 12.5% (1 extra bit per byte), so we reserve
// 12.5% of the max frame size bytes for this possible expansion.
//
// The 8 bytes cover the 5 bytes left out at the bottom as well as whatever
// bytes are lost to get DWORD alignment.
//
dwBufferSize = (pMac->WanInfo.MaxFrameSize * 9 + 7) / 8 +
pMac->WanInfo.HeaderPadding +
pMac->WanInfo.TailPadding +
8 +
sizeof(PVOID);
// Make size DWORD aligned
dwBufferSize &= ~(sizeof(PVOID) - 1);
dwPacketMemorySize = (dwBufferSize + sizeof(NDIS_WAN_PACKET)) * cPackets;
PacketMemory = pppAllocateMemory(dwPacketMemorySize);
if (NULL == PacketMemory)
{
DEBUGMSG(ZONE_ERROR, (TEXT("PPP: NdisWanAllocateSendResources: Allocation failed\r\n")));
return NDIS_STATUS_RESOURCES;
}
pMac->PacketMemory = PacketMemory;
pMac->PacketMemorySize = dwPacketMemorySize;
pMac->BufferSize = dwBufferSize;
NdisInitializeListHead (&pMac->PacketQueue);
// Now setup all of the WAN_PACKET's
for (n=0; n < cPackets; n++) {
pWanPacket = (PNDIS_WAN_PACKET)PacketMemory;
PacketMemory += sizeof(NDIS_WAN_PACKET);
pWanPacket->StartBuffer = PacketMemory;
PacketMemory += dwBufferSize;
// Leave a little extra at the end.
pWanPacket->EndBuffer = PacketMemory - 5;
// Add it to the list.
NdisInterlockedInsertHeadList (&pMac->PacketQueue, (PLIST_ENTRY)pWanPacket,
&pMac->PacketLock);
}
return NDIS_STATUS_SUCCESS;
}
NDIS_STATUS
NdisWanAllocatePacket (
IN OUT PMAC_CONTEXT pMac,
OUT PNDIS_WAN_PACKET *ppPacket)
//
// Get a free packet from the PacketQueue.
//
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
ASSERT(ListIsValid(&pMac->PacketQueue, &pMac->PacketLock));
*ppPacket = (PNDIS_WAN_PACKET)NdisInterlockedRemoveHeadList(&pMac->PacketQueue, &pMac->PacketLock);
ASSERT(ListIsValid(&pMac->PacketQueue, &pMac->PacketLock));
if (NULL == *ppPacket)
{
// If there are no transmit buffers left in the buffer pool maintained
// by PPP, the a deadlock can occur if the thread that is responsible
// for returning buffers to the pool blocks here.
//
// Currently this is known to happen when tcpstk "steals" the PPTP PacketWorkingThread
// to send some unrelated packets which are destined for the PPTP adapter.
//
// So, we don't want to take a chance blocking sending to the PPTP adapter.
//
DEBUGMSG(ZONE_ERROR, (TEXT("PPP: All Xmit Packets in use\n")));
Status = NDIS_STATUS_RESOURCES;
}
return Status;
}
NDIS_STATUS
NdisWanFreePacket (PMAC_CONTEXT pMac, PNDIS_WAN_PACKET pPacket)
//
// Return pPacket to the list of free packets.
//
{
ASSERT(ListIsValid(&pMac->PacketQueue, &pMac->PacketLock));
// Add it to the list.
NdisInterlockedInsertHeadList(&pMac->PacketQueue, (PLIST_ENTRY)pPacket, &pMac->PacketLock);
ASSERT(ListIsValid(&pMac->PacketQueue, &pMac->PacketLock));
return NDIS_STATUS_SUCCESS;
}
/*****************************************************************************
*
*
* @func PNDIS_WAN_PACKET | pppMac_GetPacket
* Get a packet to use internally
*
* @rdesc Pointer to the packet or NULL if error
*
* @parm PMAC_CONTEXT | pMac | Pointer to the Mac Context
*
* @comm
* This function will allocate the NDIS_WAN_PACKET's required for a
* connection
*
* @ex No Example
*
*/
PNDIS_WAN_PACKET
pppMac_GetPacket (PMAC_CONTEXT pMac)
{
PNDIS_WAN_PACKET pPacket;
NDIS_STATUS Status;
Status = NdisWanAllocatePacket(pMac, &pPacket);
if (NDIS_STATUS_SUCCESS != Status)
{
DEBUGMSG(ZONE_ERROR, (TEXT("pppMac_GetPacket: Error 0x%X from NdisWanAllocatePacket\n"), Status));
return NULL;
}
// Initialize the packet.
pPacket->CurrentBuffer = pPacket->StartBuffer + pMac->WanInfo.HeaderPadding;
pPacket->CurrentLength = pPacket->EndBuffer - pPacket->CurrentBuffer -
pMac->WanInfo.TailPadding;
DEBUGMSG (ZONE_MAC, (TEXT("pppMac_GetPacket: Have Packet Start=0x%X End=0x%X(%d) ")
TEXT("CBuf=0x%X CLen=%d HPad=%d TPad=%d\r\n"),
pPacket->StartBuffer, pPacket->EndBuffer,
pPacket->EndBuffer - pPacket->StartBuffer,
pPacket->CurrentBuffer, pPacket->CurrentLength,
pMac->WanInfo.HeaderPadding, pMac->WanInfo.TailPadding));
pPacket->ProtocolReserved1 = pMac;
pPacket->ProtocolReserved2 = pPacket->ProtocolReserved3 = pPacket->ProtocolReserved4 = NULL;
return pPacket;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -