More stuff moved out of ip lib.

svn path=/trunk/; revision=11207
This commit is contained in:
Art Yerkes 2004-10-06 04:40:34 +00:00
parent 91447e78e2
commit 4368f11574
2 changed files with 771 additions and 21 deletions

View file

@ -1,9 +1,16 @@
struct _NDIS_BUFFER;
#define __NTDRIVER__
#include <ndissys.h>
#include <buffer.h>
#undef __NTDRIVER__
#include <ndishack.h>
typedef VOID (*PLOOKASIDE_MINMAX_ROUTINE)(
POOL_TYPE PoolType,
ULONG Size,
PUSHORT MinimumDepth,
PUSHORT MaximumDepth);
/* global list and lock of Miniports NDIS has registered */
LIST_ENTRY MiniportListHead;
KSPIN_LOCK MiniportListLock;
@ -18,6 +25,19 @@ KSPIN_LOCK OrphanAdapterListLock;
static KSPIN_LOCK ExpGlobalListLock = { 0, };
PNDIS_BUFFER_POOL GlobalBufferPool;
PNDIS_PACKET_POOL GlobalPacketPool;
LIST_ENTRY ExpNonPagedLookasideListHead;
KSPIN_LOCK ExpNonPagedLookasideListLock;
LIST_ENTRY ExpPagedLookasideListHead;
KSPIN_LOCK ExpPagedLookasideListLock;
PLOOKASIDE_MINMAX_ROUTINE ExpMinMaxRoutine;
//#define InitializeListHead(PL) { (PL)->Flink = (PL); (PL)->Blink = (PL); }
/*
* @implemented
*/
@ -52,19 +72,285 @@ ExInterlockedInsertTailList(PLIST_ENTRY ListHead,
return(Old);
}
VOID STDCALL ExInitializeNPagedLookasideList
( PNPAGED_LOOKASIDE_LIST Lookaside,
PALLOCATE_FUNCTION Allocate,
PFREE_FUNCTION Free,
ULONG Flags,
ULONG Size,
ULONG Tag,
USHORT Depth ) {
Lookaside->Allocate = Allocate;
Lookaside->Free = Free;
Lookaside->Size = Size;
static
inline
PSINGLE_LIST_ENTRY
PopEntrySList(
PSLIST_HEADER ListHead
)
{
PSINGLE_LIST_ENTRY ListEntry;
ListEntry = ListHead->Next.Next;
if (ListEntry!=NULL)
{
ListHead->Next.Next = ListEntry->Next;
ListHead->Depth++;
ListHead->Sequence++;
}
return ListEntry;
}
static
inline
VOID
PushEntrySList (
PSLIST_HEADER ListHead,
PSINGLE_LIST_ENTRY Entry
)
{
Entry->Next = ListHead->Next.Next;
ListHead->Next.Next = Entry;
ListHead->Depth++;
ListHead->Sequence++;
}
VOID ExpDefaultMinMax(
POOL_TYPE PoolType,
ULONG Size,
PUSHORT MinimumDepth,
PUSHORT MaximumDepth)
/*
* FUNCTION: Determines the minimum and maximum depth of a new lookaside list
* ARGUMENTS:
* Type = Type of executive pool
* Size = Size in bytes of each element in the new lookaside list
* MinimumDepth = Buffer to store minimum depth of the new lookaside list in
* MaximumDepth = Buffer to store maximum depth of the new lookaside list in
*/
{
/* FIXME: Could probably do some serious computing here */
if ((PoolType == NonPagedPool) ||
(PoolType == NonPagedPoolMustSucceed))
{
*MinimumDepth = 10;
*MaximumDepth = 100;
}
else
{
*MinimumDepth = 20;
*MaximumDepth = 200;
}
}
PVOID STDCALL
ExpDefaultAllocate(POOL_TYPE PoolType,
ULONG NumberOfBytes,
ULONG Tag)
/*
* FUNCTION: Default allocate function for lookaside lists
* ARGUMENTS:
* Type = Type of executive pool
* NumberOfBytes = Number of bytes to allocate
* Tag = Tag to use
* RETURNS:
* Pointer to allocated memory, or NULL if there is not enough free resources
*/
{
return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag);
}
VOID STDCALL
ExpDefaultFree(PVOID Buffer)
/*
* FUNCTION: Default free function for lookaside lists
* ARGUMENTS:
* Buffer = Pointer to memory to free
*/
{
ExFreePool(Buffer);
}
#define INIT_FUNCTION
VOID INIT_FUNCTION
ExpInitLookasideLists()
{
InitializeListHead(&ExpNonPagedLookasideListHead);
KeInitializeSpinLock(&ExpNonPagedLookasideListLock);
InitializeListHead(&ExpPagedLookasideListHead);
KeInitializeSpinLock(&ExpPagedLookasideListLock);
/* FIXME: Possibly configure the algorithm using the registry */
ExpMinMaxRoutine = ExpDefaultMinMax;
}
PVOID
FASTCALL
ExiAllocateFromPagedLookasideList (
PPAGED_LOOKASIDE_LIST Lookaside
)
{
PVOID Entry;
/* Try to obtain an entry from the lookaside list. If that fails, try to
allocate a new entry with the allocate method for the lookaside list */
Lookaside->TotalAllocates++;
// ExAcquireFastMutex(LookasideListLock(Lookaside));
Entry = PopEntrySList(&Lookaside->ListHead);
// ExReleaseFastMutex(LookasideListLock(Lookaside));
if (Entry)
return Entry;
Lookaside->AllocateMisses++;
Entry = (*Lookaside->Allocate)(Lookaside->Type,
Lookaside->Size,
Lookaside->Tag);
return Entry;
}
#define LookasideListLock(l)(&(l->Obsoleted))
/*
* @implemented
*/
VOID
STDCALL
ExDeleteNPagedLookasideList (
PNPAGED_LOOKASIDE_LIST Lookaside
)
{
KIRQL OldIrql;
PVOID Entry;
/* Pop all entries off the stack and release the resources allocated
for them */
while ((Entry = ExInterlockedPopEntrySList(
&Lookaside->ListHead,
LookasideListLock(Lookaside))) != NULL)
{
(*Lookaside->Free)(Entry);
}
KeAcquireSpinLock(&ExpNonPagedLookasideListLock, &OldIrql);
RemoveEntryList(&Lookaside->ListEntry);
KeReleaseSpinLock(&ExpNonPagedLookasideListLock, OldIrql);
}
/*
* @implemented
*/
VOID
STDCALL
ExDeletePagedLookasideList (
PPAGED_LOOKASIDE_LIST Lookaside
)
{
KIRQL OldIrql;
PVOID Entry;
/* Pop all entries off the stack and release the resources allocated
for them */
for (;;)
{
// ExAcquireFastMutex(LookasideListLock(Lookaside));
Entry = PopEntrySList(&Lookaside->ListHead);
if (!Entry)
break;
// ExReleaseFastMutex(LookasideListLock(Lookaside));
(*Lookaside->Free)(Entry);
}
KeAcquireSpinLock(&ExpPagedLookasideListLock, &OldIrql);
RemoveEntryList(&Lookaside->ListEntry);
KeReleaseSpinLock(&ExpPagedLookasideListLock, OldIrql);
}
VOID
STDCALL
ExiFreeToPagedLookasideList (
PPAGED_LOOKASIDE_LIST Lookaside,
PVOID Entry
)
{
Lookaside->TotalFrees++;
if (ExQueryDepthSList(&Lookaside->ListHead) >= Lookaside->Depth)
{
Lookaside->FreeMisses++;
(*Lookaside->Free)(Entry);
}
else
{
// ExAcquireFastMutex(LookasideListLock(Lookaside));
PushEntrySList(&Lookaside->ListHead, (PSINGLE_LIST_ENTRY)Entry);
// ExReleaseFastMutex(LookasideListLock(Lookaside));
}
}
/*
* @implemented
*/
VOID
STDCALL
ExInitializeNPagedLookasideList (
PNPAGED_LOOKASIDE_LIST Lookaside,
PALLOCATE_FUNCTION Allocate,
PFREE_FUNCTION Free,
ULONG Flags,
ULONG Size,
ULONG Tag,
USHORT Depth)
{
DbgPrint("Initializing nonpaged lookaside list at 0x%X\n", Lookaside);
Lookaside->TotalAllocates = 0;
Lookaside->AllocateMisses = 0;
Lookaside->TotalFrees = 0;
Lookaside->FreeMisses = 0;
Lookaside->Type = NonPagedPool;
Lookaside->Tag = Tag;
Lookaside->Depth = Depth;
/* We use a field of type SINGLE_LIST_ENTRY as a link to the next entry in
the lookaside list so we must allocate at least sizeof(SINGLE_LIST_ENTRY) */
if (Size < sizeof(SINGLE_LIST_ENTRY))
Lookaside->Size = sizeof(SINGLE_LIST_ENTRY);
else
Lookaside->Size = Size;
if (Allocate)
Lookaside->Allocate = Allocate;
else
Lookaside->Allocate = ExpDefaultAllocate;
if (Free)
Lookaside->Free = Free;
else
Lookaside->Free = ExpDefaultFree;
ExInitializeSListHead(&Lookaside->ListHead);
KeInitializeSpinLock(LookasideListLock(Lookaside));
/* Determine minimum and maximum number of entries on the lookaside list
using the configured algorithm */
(*ExpMinMaxRoutine)(
NonPagedPool,
Lookaside->Size,
&Lookaside->Depth,
&Lookaside->MaximumDepth);
ExInterlockedInsertTailList(
&ExpNonPagedLookasideListHead,
&Lookaside->ListEntry,
&ExpNonPagedLookasideListLock);
}
#define NTOSAPI
@ -168,8 +454,6 @@ VOID STDCALL KeAcquireSpinLock( PKSPIN_LOCK Lock, PKIRQL Irql ) { }
VOID STDCALL KeReleaseSpinLock( PKSPIN_LOCK Lock, KIRQL Irql ) { }
VOID STDCALL KeAcquireSpinLockAtDpcLevel( PKSPIN_LOCK Lock ) { }
VOID STDCALL KeReleaseSpinLockFromDpcLevel( PKSPIN_LOCK Lock ) { }
VOID STDCALL KeRaiseIrql( KIRQL NewIrql, PKIRQL OldIrql ) { }
VOID STDCALL KeLowerIrql( KIRQL OldIrql ) { }
VOID FASTCALL ExAcquireFastMutex( PFAST_MUTEX Mutex ) { }
VOID FASTCALL ExReleaseFastMutex( PFAST_MUTEX Mutex ) { }
VOID STDCALL KeInitializeEvent( PKEVENT Event,
@ -265,9 +549,6 @@ PWORK_QUEUE_ITEM GetWorkQueueItem() {
return NULL;
}
VOID STDCALL ExDeleteNPagedLookasideList(PNPAGED_LOOKASIDE_LIST Lookaside) {
}
NTSTATUS STDCALL KeWaitForSingleObject
( PVOID Object,
KWAIT_REASON WaitReason,
@ -867,3 +1148,468 @@ VOID DDKAPI NdisFreePacket(IN PNDIS_PACKET Packet)
PVOID DDKAPI MmMapLockedPages( PMDL Mdl, KPROCESSOR_MODE Mode ) {
return Mdl->MappedSystemVa;
}
__inline INT SkipToOffset(
PNDIS_BUFFER Buffer,
UINT Offset,
PCHAR *Data,
PUINT Size)
/*
* FUNCTION: Skip Offset bytes into a buffer chain
* ARGUMENTS:
* Buffer = Pointer to NDIS buffer
* Offset = Number of bytes to skip
* Data = Address of a pointer that on return will contain the
* address of the offset in the buffer
* Size = Address of a pointer that on return will contain the
* size of the destination buffer
* RETURNS:
* Offset into buffer, -1 if buffer chain was smaller than Offset bytes
* NOTES:
* Buffer may be NULL
*/
{
for (;;) {
if (!Buffer)
return -1;
NdisQueryBuffer(Buffer, (PVOID)Data, Size);
if (Offset < *Size) {
*Data = (PCHAR)((ULONG_PTR) *Data + Offset);
*Size -= Offset;
break;
}
Offset -= *Size;
NdisGetNextBuffer(Buffer, &Buffer);
}
return Offset;
}
UINT CopyBufferToBufferChain(
PNDIS_BUFFER DstBuffer,
UINT DstOffset,
PUCHAR SrcData,
UINT Length)
/*
* FUNCTION: Copies data from a buffer to an NDIS buffer chain
* ARGUMENTS:
* DstBuffer = Pointer to destination NDIS buffer
* DstOffset = Destination start offset
* SrcData = Pointer to source buffer
* Length = Number of bytes to copy
* RETURNS:
* Number of bytes copied to destination buffer
* NOTES:
* The number of bytes copied may be limited by the destination
* buffer size
*/
{
UINT BytesCopied, BytesToCopy, DstSize;
PCHAR DstData;
DbgPrint("DstBuffer (0x%X) DstOffset (0x%X) SrcData (0x%X) "
"Length (%d)\n", DstBuffer, DstOffset, SrcData, Length);
/* Skip DstOffset bytes in the destination buffer chain */
if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == -1)
return 0;
/* Start copying the data */
BytesCopied = 0;
for (;;) {
BytesToCopy = MIN(DstSize, Length);
RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy);
BytesCopied += BytesToCopy;
SrcData = (PCHAR)((ULONG_PTR)SrcData + BytesToCopy);
Length -= BytesToCopy;
if (Length == 0)
break;
DstSize -= BytesToCopy;
if (DstSize == 0) {
/* No more bytes in desination buffer. Proceed to
the next buffer in the destination buffer chain */
NdisGetNextBuffer(DstBuffer, &DstBuffer);
if (!DstBuffer)
break;
NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
}
}
return BytesCopied;
}
UINT CopyBufferChainToBuffer(
PUCHAR DstData,
PNDIS_BUFFER SrcBuffer,
UINT SrcOffset,
UINT Length)
/*
* FUNCTION: Copies data from an NDIS buffer chain to a buffer
* ARGUMENTS:
* DstData = Pointer to destination buffer
* SrcBuffer = Pointer to source NDIS buffer
* SrcOffset = Source start offset
* Length = Number of bytes to copy
* RETURNS:
* Number of bytes copied to destination buffer
* NOTES:
* The number of bytes copied may be limited by the source
* buffer size
*/
{
UINT BytesCopied, BytesToCopy, SrcSize;
PCHAR SrcData;
DbgPrint("DstData 0x%X SrcBuffer 0x%X SrcOffset 0x%X Length %d\n",
DstData,SrcBuffer, SrcOffset, Length);
/* Skip SrcOffset bytes in the source buffer chain */
if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == -1)
return 0;
/* Start copying the data */
BytesCopied = 0;
for (;;) {
BytesToCopy = MIN(SrcSize, Length);
DbgPrint("Copying (%d) bytes from 0x%X to 0x%X\n",
BytesToCopy, SrcData, DstData);
RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy);
BytesCopied += BytesToCopy;
DstData = (PCHAR)((ULONG_PTR)DstData + BytesToCopy);
Length -= BytesToCopy;
if (Length == 0)
break;
SrcSize -= BytesToCopy;
if (SrcSize == 0) {
/* No more bytes in source buffer. Proceed to
the next buffer in the source buffer chain */
NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
if (!SrcBuffer)
break;
NdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize);
}
}
return BytesCopied;
}
UINT CopyPacketToBuffer(
PUCHAR DstData,
PNDIS_PACKET SrcPacket,
UINT SrcOffset,
UINT Length)
/*
* FUNCTION: Copies data from an NDIS packet to a buffer
* ARGUMENTS:
* DstData = Pointer to destination buffer
* SrcPacket = Pointer to source NDIS packet
* SrcOffset = Source start offset
* Length = Number of bytes to copy
* RETURNS:
* Number of bytes copied to destination buffer
* NOTES:
* The number of bytes copied may be limited by the source
* buffer size
*/
{
PNDIS_BUFFER FirstBuffer;
UINT FirstLength;
UINT TotalLength;
DbgPrint("DstData (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) "
"Length (%d)\n", DstData, SrcPacket, SrcOffset, Length);
NdisQueryPacket( SrcPacket, &FirstBuffer, 0, &FirstLength, &TotalLength );
#if 0
NdisGetFirstBufferFromPacket(SrcPacket,
&FirstBuffer,
&Address,
&FirstLength,
&TotalLength);
#endif
return CopyBufferChainToBuffer(DstData, FirstBuffer, SrcOffset, Length);
}
/*
* @implemented
*/
VOID
EXPORT
NdisQueryBufferOffset(
IN PNDIS_BUFFER Buffer,
OUT PUINT Offset,
OUT PUINT Length)
{
*((PUINT)Offset) = MmGetMdlByteOffset(Buffer);
*((PUINT)Length) = MmGetMdlByteCount(Buffer);
}
UINT CopyPacketToBufferChain(
PNDIS_BUFFER DstBuffer,
UINT DstOffset,
PNDIS_PACKET SrcPacket,
UINT SrcOffset,
UINT Length)
/*
* FUNCTION: Copies data from an NDIS packet to an NDIS buffer chain
* ARGUMENTS:
* DstBuffer = Pointer to destination NDIS buffer
* DstOffset = Destination start offset
* SrcPacket = Pointer to source NDIS packet
* SrcOffset = Source start offset
* Length = Number of bytes to copy
* RETURNS:
* Number of bytes copied to destination buffer
* NOTES:
* The number of bytes copied may be limited by the source and
* destination buffer sizes
*/
{
PNDIS_BUFFER SrcBuffer;
PCHAR DstData, SrcData;
UINT DstSize, SrcSize;
UINT Count, Total;
DbgPrint("DstBuffer (0x%X) DstOffset (0x%X) SrcPacket (0x%X) "
"SrcOffset (0x%X) Length (%d)\n",
DstBuffer, DstOffset, SrcPacket, SrcOffset, Length);
/* Skip DstOffset bytes in the destination buffer chain */
NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == -1)
return 0;
/* Skip SrcOffset bytes in the source packet */
NdisQueryPacket( SrcPacket, &SrcBuffer, 0, &SrcSize, &Total );
NdisQueryBuffer( SrcBuffer, (PVOID *)&SrcData, &SrcSize );
#if 0
NdisGetFirstBufferFromPacket(SrcPacket, &SrcBuffer, (PVOID *)&SrcData,
&SrcSize, &Total);
#endif
if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == -1)
return 0;
/* Copy the data */
for (Total = 0;;) {
/* Find out how many bytes we can copy at one time */
if (Length < SrcSize)
Count = Length;
else
Count = SrcSize;
if (DstSize < Count)
Count = DstSize;
RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, Count);
Total += Count;
Length -= Count;
if (Length == 0)
break;
DstSize -= Count;
if (DstSize == 0) {
/* No more bytes in destination buffer. Proceed to
the next buffer in the destination buffer chain */
NdisGetNextBuffer(DstBuffer, &DstBuffer);
if (!DstBuffer)
break;
NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
}
SrcSize -= Count;
if (SrcSize == 0) {
/* No more bytes in source buffer. Proceed to
the next buffer in the source buffer chain */
NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
if (!SrcBuffer)
break;
NdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize);
}
}
return Total;
}
PVOID AdjustPacket(
PNDIS_PACKET Packet,
UINT Available,
UINT Needed)
/*
* FUNCTION: Adjusts the amount of unused space at the beginning of the packet
* ARGUMENTS:
* Packet = Pointer to packet
* Available = Number of bytes available at start of first buffer
* Needed = Number of bytes needed for the header
* RETURNS:
* Pointer to start of packet
*/
{
PNDIS_BUFFER NdisBuffer;
INT Adjust;
DbgPrint("Available = %d, Needed = %d.\n", Available, Needed);
Adjust = Available - Needed;
NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, NULL);
/* If Adjust is zero there is no need to adjust this packet as
there is no additional space at start the of first buffer */
if (Adjust != 0) {
NdisBuffer->MappedSystemVa = (PVOID) ((ULONG_PTR)(NdisBuffer->MappedSystemVa) + Adjust);
NdisBuffer->ByteOffset += Adjust;
NdisBuffer->ByteCount -= Adjust;
}
return NdisBuffer->MappedSystemVa;
}
UINT ResizePacket(
PNDIS_PACKET Packet,
UINT Size)
/*
* FUNCTION: Resizes an NDIS packet
* ARGUMENTS:
* Packet = Pointer to packet
* Size = Number of bytes in first buffer
* RETURNS:
* Previous size of first buffer
*/
{
PNDIS_BUFFER NdisBuffer;
UINT OldSize;
NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, NULL);
OldSize = NdisBuffer->ByteCount;
if (Size != OldSize)
NdisBuffer->ByteCount = Size;
return OldSize;
}
NDIS_STATUS PrependPacket( PNDIS_PACKET Packet, PCHAR Data, UINT Length,
BOOLEAN Copy ) {
PNDIS_BUFFER Buffer;
NDIS_STATUS Status;
PCHAR NewBuf;
if( Copy ) {
NewBuf = ExAllocatePool( NonPagedPool, Length );
if( !NewBuf ) return STATUS_NO_MEMORY;
RtlCopyMemory( NewBuf, Data, Length );
} else NewBuf = Data;
NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, Data, Length );
if( Status != NDIS_STATUS_SUCCESS ) return Status;
NdisChainBufferAtFront( Packet, Buffer );
return STATUS_SUCCESS;
}
void GetDataPtr( PNDIS_PACKET Packet,
UINT Offset,
PCHAR *DataOut,
PUINT Size ) {
PNDIS_BUFFER Buffer;
NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL);
if( !Buffer ) return;
SkipToOffset( Buffer, Offset, DataOut, Size );
}
NDIS_STATUS AllocatePacketWithBufferX( PNDIS_PACKET *NdisPacket,
PCHAR Data, UINT Len,
PCHAR File, UINT Line ) {
#if 0
PNDIS_PACKET Packet;
PNDIS_BUFFER Buffer;
NDIS_STATUS Status;
PCHAR NewData;
NewData = ExAllocatePool( NonPagedPool, Len );
if( !NewData ) return NDIS_STATUS_NOT_ACCEPTED; // XXX
TrackWithTag(EXALLOC_TAG, NewData, File, Line);
if( Data )
RtlCopyMemory(NewData, Data, Len);
NdisAllocatePacket( &Status, &Packet, GlobalPacketPool );
if( Status != NDIS_STATUS_SUCCESS ) {
ExFreePool( NewData );
return Status;
}
TrackWithTag(NDIS_PACKET_TAG, Packet, File, Line);
NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, NewData, Len );
if( Status != NDIS_STATUS_SUCCESS ) {
ExFreePool( NewData );
FreeNdisPacket( Packet );
}
TrackWithTag(NDIS_BUFFER_TAG, Buffer, File, Line);
NdisChainBufferAtFront( Packet, Buffer );
*NdisPacket = Packet;
#endif
return NDIS_STATUS_SUCCESS;
}
VOID FreeNdisPacketX
( PNDIS_PACKET Packet,
PCHAR File,
UINT Line )
/*
* FUNCTION: Frees an NDIS packet
* ARGUMENTS:
* Packet = Pointer to NDIS packet to be freed
*/
{
#if 0
PNDIS_BUFFER Buffer, NextBuffer;
TI_DbgPrint(DEBUG_PBUFFER, ("Packet (0x%X)\n", Packet));
/* Free all the buffers in the packet first */
NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL);
for (; Buffer != NULL; Buffer = NextBuffer) {
PVOID Data;
UINT Length;
NdisGetNextBuffer(Buffer, &NextBuffer);
NdisQueryBuffer(Buffer, &Data, &Length);
UntrackFL(File,Line,Buffer);
NdisFreeBuffer(Buffer);
UntrackFL(File,Line,Data);
ExFreePool(Data);
}
/* Finally free the NDIS packet discriptor */
UntrackFL(File,Line,Packet);
NdisFreePacket(Packet);
#endif
}

View file

@ -1,4 +1,4 @@
; $Id: undis.def,v 1.1 2004/09/30 05:40:14 arty Exp $
; $Id: undis.def,v 1.2 2004/10/06 04:40:34 arty Exp $
;
; reactos/drivers/lib/undis/undis.def
;
@ -37,12 +37,16 @@ NdisFreeBuffer@4
NdisQueryBuffer@12
NdisFreePacket@4
MmMapLockedPages@8
KeLowerIrql@4
KeRaiseIrql@8
@ExReleaseFastMutex@4
@ExAcquireFastMutex@4
@InterlockedPushEntrySList@8
@InterlockedPopEntrySList@4
RecursiveMutexLeave
RecursiveMutexEnter
RecursiveMutexInit
RecursiveMutexInit
AllocatePacketWithBufferX
FreeNdisPacketX
GetDataPtr
CopyPacketToBuffer
AdjustPacket
ExpInitLookasideLists