windows-nt/Source/XPSP1/NT/net/tcpip/driver/common/9x/mdlpool9x.c
2020-09-26 16:20:57 +08:00

237 lines
5.5 KiB
C

/*++
Copyright (c) 1999-2000 Microsoft Corporation
Module Name:
mdlpool9x.c
Abstract:
This file contains the implementation of an NDIS_BUFFER pool.
Author:
Shaun Cox (shaunco) 11-Nov-1999
--*/
#include "ndis.h"
#include "mdlpool.h"
// The pool structure itself is just a look aside list allocated out of
// non-paged pool.
//
// Each entry in the look aside list is an NDIS_BUFFER structure followed
// by the buffer itself. We initialize the NDIS_BUFFER structure each
// time we allocate from the look aside list. We need to do this in order
// to properly associate the NDIS_BUFFER with its owning pool. This is not
// possible to do with a custom allocate routine for the look aside list
// because their is no provision for an extra context parameter to the
// look aside allocate function.
//
// ---- Temporary Definitions until ndis.h is updated for Millennium -----
//
typedef struct _XNDIS_BUFFER {
struct _NDIS_BUFFER *Next;
PVOID VirtualAddress;
PVOID Pool;
UINT Length;
UINT Signature;
} XNDIS_BUFFER, *PXNDIS_BUFFER;
__inline
SIZE_T
NDIS_SIZEOF_NDIS_BUFFER(
VOID
)
{
return sizeof(XNDIS_BUFFER);
}
__inline
VOID
NdisInitializeNdisBuffer(
OUT PNDIS_BUFFER Buffer,
IN PVOID Pool,
IN PVOID VirtualAddress,
IN UINT Length
)
{
PXNDIS_BUFFER Internal = (PXNDIS_BUFFER)Buffer;
Internal->Next = 0;
Internal->Pool = Pool;
Internal->VirtualAddress = VirtualAddress;
Internal->Length = Length;
Internal->Signature = 0;
}
__inline
PVOID
NdisGetPoolFromNdisBuffer(
IN PNDIS_BUFFER Buffer
)
{
PXNDIS_BUFFER Internal = (PXNDIS_BUFFER)Buffer;
return Internal->Pool;
}
// ---- End temporary Definitions until ndis.h is updated for Millennium -----
UINT SizeOfNdisBufferStructure;
// Creates a pool of NDIS_BUFFERs built over non-paged pool. Each
// NDIS_BUFFER describes a buffer that is BufferSize bytes long.
// If NULL is not returned, MdpDestroyPool should be called at a later time
// to reclaim the resources used by the pool.
//
// Arguments:
// BufferSize - The size, in bytes, of the buffer that each MDL
// should describe.
// Tag - The pool tag to be used internally for calls to
// ExAllocatePoolWithTag. This allows callers to track
// memory consumption for different pools.
//
// Returns the handle used to identify the pool.
//
// Caller IRQL: [PASSIVE_LEVEL, DISPATCH_LEVEL]
//
HANDLE
MdpCreatePool(
IN USHORT BufferSize,
IN ULONG Tag
)
{
PNPAGED_LOOKASIDE_LIST Lookaside;
ASSERT(BufferSize);
// Cache the constant value of an NDIS_BUFFER structure size to
// avoid calling back into NDIS everytime we want a buffer.
//
if (0 == SizeOfNdisBufferStructure)
{
SizeOfNdisBufferStructure = NDIS_SIZEOF_NDIS_BUFFER();
}
ASSERT(SizeOfNdisBufferStructure);
// Allocate the pool header. This is a look aside list on Millenium.
//
Lookaside = ExAllocatePoolWithTag(
NonPagedPool,
sizeof(NPAGED_LOOKASIDE_LIST),
' pdM');
if (Lookaside)
{
// The size of the entries allocated by the look aside list are
// the NDIS_BUFFER structure size plus the buffer size requested by
// the caller.
//
ExInitializeNPagedLookasideList(
Lookaside,
NULL,
NULL,
0,
SizeOfNdisBufferStructure + BufferSize,
Tag,
0);
}
return Lookaside;
}
// Destroys a pool of NDIS_BUFFERs previously created by a call to
// MdpCreatePool.
//
// Arguments:
// PoolHandle - Handle which identifies the pool being destroyed.
//
// Caller IRQL: [PASSIVE_LEVEL, DISPATCH_LEVEL]
//
VOID
MdpDestroyPool(
IN HANDLE PoolHandle
)
{
ExDeleteNPagedLookasideList(PoolHandle);
}
// Returns an NDIS_BUFFER allocated from a pool. NULL is returned if the
// request could not be granted.
//
// Arguments:
// PoolHandle - Handle which identifies the pool being allocated from.
// Buffer - Address to receive the pointer to the underlying mapped buffer
// described by the MDL.
//
// Caller IRQL: [PASSIVE_LEVEL, DISPATCH_LEVEL]
//
PNDIS_BUFFER
MdpAllocate(
IN HANDLE PoolHandle,
OUT PVOID* Buffer
)
{
PNPAGED_LOOKASIDE_LIST Lookaside;
PNDIS_BUFFER NdisBuffer;
PUCHAR VirtualAddress;
ASSERT(PoolHandle);
Lookaside = (PNPAGED_LOOKASIDE_LIST)PoolHandle;
// Get an item from the look aside list.
//
NdisBuffer = ExAllocateFromNPagedLookasideList(Lookaside);
if (NdisBuffer)
{
// (Re)Initialize it to associate it with the pool handle so that
// we know which look aside list to return it to when it is freed.
//
VirtualAddress = (PUCHAR)NdisBuffer + SizeOfNdisBufferStructure;
NdisInitializeNdisBuffer(
NdisBuffer,
PoolHandle,
VirtualAddress,
Lookaside->L.Size - SizeOfNdisBufferStructure);
*Buffer = VirtualAddress;
}
return NdisBuffer;
}
// Free an NDIS_BUFFER to the pool from which it was allocated.
//
// Arguments:
// NdisBuffer - An NDIS_BUFFER returned from a prior call to MdpAllocate.
//
// Caller IRQL: [PASSIVE_LEVEL, DISPATCH_LEVEL]
//
VOID
MdpFree(
IN PNDIS_BUFFER NdisBuffer
)
{
PNPAGED_LOOKASIDE_LIST Lookaside;
// Locate the owning look aside list for this buffer and return it.
//
Lookaside = NdisGetPoolFromNdisBuffer(NdisBuffer);
ASSERT(Lookaside);
ExFreeToNPagedLookasideList(Lookaside, NdisBuffer);
}