mirror of
https://github.com/reactos/reactos.git
synced 2025-07-13 07:04:15 +00:00
More stuff moved out of ip lib.
svn path=/trunk/; revision=11207
This commit is contained in:
parent
91447e78e2
commit
4368f11574
2 changed files with 771 additions and 21 deletions
|
@ -1,9 +1,16 @@
|
||||||
|
struct _NDIS_BUFFER;
|
||||||
#define __NTDRIVER__
|
#define __NTDRIVER__
|
||||||
#include <ndissys.h>
|
#include <ndissys.h>
|
||||||
#include <buffer.h>
|
#include <buffer.h>
|
||||||
#undef __NTDRIVER__
|
#undef __NTDRIVER__
|
||||||
#include <ndishack.h>
|
#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 */
|
/* global list and lock of Miniports NDIS has registered */
|
||||||
LIST_ENTRY MiniportListHead;
|
LIST_ENTRY MiniportListHead;
|
||||||
KSPIN_LOCK MiniportListLock;
|
KSPIN_LOCK MiniportListLock;
|
||||||
|
@ -18,6 +25,19 @@ KSPIN_LOCK OrphanAdapterListLock;
|
||||||
|
|
||||||
static KSPIN_LOCK ExpGlobalListLock = { 0, };
|
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
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
@ -52,19 +72,285 @@ ExInterlockedInsertTailList(PLIST_ENTRY ListHead,
|
||||||
return(Old);
|
return(Old);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID STDCALL ExInitializeNPagedLookasideList
|
static
|
||||||
( PNPAGED_LOOKASIDE_LIST Lookaside,
|
inline
|
||||||
PALLOCATE_FUNCTION Allocate,
|
PSINGLE_LIST_ENTRY
|
||||||
PFREE_FUNCTION Free,
|
PopEntrySList(
|
||||||
ULONG Flags,
|
PSLIST_HEADER ListHead
|
||||||
ULONG Size,
|
)
|
||||||
ULONG Tag,
|
{
|
||||||
USHORT Depth ) {
|
PSINGLE_LIST_ENTRY ListEntry;
|
||||||
Lookaside->Allocate = Allocate;
|
|
||||||
Lookaside->Free = Free;
|
ListEntry = ListHead->Next.Next;
|
||||||
Lookaside->Size = Size;
|
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->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
|
#define NTOSAPI
|
||||||
|
@ -168,8 +454,6 @@ VOID STDCALL KeAcquireSpinLock( PKSPIN_LOCK Lock, PKIRQL Irql ) { }
|
||||||
VOID STDCALL KeReleaseSpinLock( PKSPIN_LOCK Lock, KIRQL Irql ) { }
|
VOID STDCALL KeReleaseSpinLock( PKSPIN_LOCK Lock, KIRQL Irql ) { }
|
||||||
VOID STDCALL KeAcquireSpinLockAtDpcLevel( PKSPIN_LOCK Lock ) { }
|
VOID STDCALL KeAcquireSpinLockAtDpcLevel( PKSPIN_LOCK Lock ) { }
|
||||||
VOID STDCALL KeReleaseSpinLockFromDpcLevel( 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 ExAcquireFastMutex( PFAST_MUTEX Mutex ) { }
|
||||||
VOID FASTCALL ExReleaseFastMutex( PFAST_MUTEX Mutex ) { }
|
VOID FASTCALL ExReleaseFastMutex( PFAST_MUTEX Mutex ) { }
|
||||||
VOID STDCALL KeInitializeEvent( PKEVENT Event,
|
VOID STDCALL KeInitializeEvent( PKEVENT Event,
|
||||||
|
@ -265,9 +549,6 @@ PWORK_QUEUE_ITEM GetWorkQueueItem() {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID STDCALL ExDeleteNPagedLookasideList(PNPAGED_LOOKASIDE_LIST Lookaside) {
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS STDCALL KeWaitForSingleObject
|
NTSTATUS STDCALL KeWaitForSingleObject
|
||||||
( PVOID Object,
|
( PVOID Object,
|
||||||
KWAIT_REASON WaitReason,
|
KWAIT_REASON WaitReason,
|
||||||
|
@ -867,3 +1148,468 @@ VOID DDKAPI NdisFreePacket(IN PNDIS_PACKET Packet)
|
||||||
PVOID DDKAPI MmMapLockedPages( PMDL Mdl, KPROCESSOR_MODE Mode ) {
|
PVOID DDKAPI MmMapLockedPages( PMDL Mdl, KPROCESSOR_MODE Mode ) {
|
||||||
return Mdl->MappedSystemVa;
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
; reactos/drivers/lib/undis/undis.def
|
||||||
;
|
;
|
||||||
|
@ -37,12 +37,16 @@ NdisFreeBuffer@4
|
||||||
NdisQueryBuffer@12
|
NdisQueryBuffer@12
|
||||||
NdisFreePacket@4
|
NdisFreePacket@4
|
||||||
MmMapLockedPages@8
|
MmMapLockedPages@8
|
||||||
KeLowerIrql@4
|
|
||||||
KeRaiseIrql@8
|
|
||||||
@ExReleaseFastMutex@4
|
@ExReleaseFastMutex@4
|
||||||
@ExAcquireFastMutex@4
|
@ExAcquireFastMutex@4
|
||||||
@InterlockedPushEntrySList@8
|
@InterlockedPushEntrySList@8
|
||||||
@InterlockedPopEntrySList@4
|
@InterlockedPopEntrySList@4
|
||||||
RecursiveMutexLeave
|
RecursiveMutexLeave
|
||||||
RecursiveMutexEnter
|
RecursiveMutexEnter
|
||||||
RecursiveMutexInit
|
RecursiveMutexInit
|
||||||
|
AllocatePacketWithBufferX
|
||||||
|
FreeNdisPacketX
|
||||||
|
GetDataPtr
|
||||||
|
CopyPacketToBuffer
|
||||||
|
AdjustPacket
|
||||||
|
ExpInitLookasideLists
|
Loading…
Add table
Add a link
Reference in a new issue