diff --git a/reactos/drivers/lib/undis/include/ndishack.h b/reactos/drivers/lib/undis/include/ndishack.h new file mode 100644 index 00000000000..afd9c105a00 --- /dev/null +++ b/reactos/drivers/lib/undis/include/ndishack.h @@ -0,0 +1,284 @@ +#ifndef _NDISHACK_H +#define _NDISHACK_H + +#ifndef __NTDRIVER__ + +struct _RECURSIVE_MUTEX; + +#undef KeAcquireSpinLockAtDpcLevel +#undef KeReleaseSpinLockFromDpcLevel +#undef KeRaiseIrql +#undef KeLowerIrql + +#define NdisAllocateBuffer XNdisAllocateBuffer +#define NdisAllocatePacket XNdisAllocatePacket +#define NdisFreeBuffer XNdisFreeBuffer +#define NdisFreePacket XNdisFreePacket +#define NDIS_BUFFER_TO_SPAN_PAGES XNDIS_BUFFER_TO_SPAN_PAGES +#define ExAllocatePool XExAllocatePool +#define ExFreePool XExFreePool +#define KeAcquireSpinLock XKeAcquireSpinLock +#define KeAcquireSpinLockAtDpcLevel XKeAcquireSpinLockAtDpcLevel +#define KeReleaseSpinLock XKeReleaseSpinLock +#define KeReleaseSpinLockFromDpcLevel XKeReleaseSpinLockFromDpcLevel +#define KeInitializeSpinLock XKeInitializeSpinLock +#define InterlockedIncrement XInterlockedIncrement +#define InterlockedDecrement XInterlockedDecrement +#define ExQueueWorkItem XExQueueWorkItem +#define ExAcquireFastMutex XExAcquireFastMutex +#define ExReleaseFastMutex XExReleaseFastMutex +#define KeSetEvent XKeSetEvent +#define KeBugCheck XKeBugCheck +#define ExInterlockedInsertTailList XExInterlockedInsertTailList +#define KeInitializeEvent XKeInitializeEvent +#define KeRaiseIrql XKeRaiseIrql +#define KeLowerIrql XKeLowerIrql +#define ExFreeToNPagedLookasideList XExFreeToNPagedLookasideList +#define ExAllocateFromNPagedLookasideList XExAllocateFromNPagedLookasideList +#define ExInitializeNPagedLookasideList XExInitializeNPagedLookasideList +#define KeInitializeTimer XKeInitializeTimer +#define KeSetTimer XKeSetTimer +#define KeSetTimerEx XKeSetTimerEx +#define KeCancelTimer XKeCancelTimer +#define KeWaitForSingleObject XKeWaitForSingleObject +#define KeInitializeDpc XKeInitializeDpc + +extern VOID XNdisAllocateBuffer( PNDIS_STATUS Status, PNDIS_BUFFER *Buffer, NDIS_HANDLE BufferPool, PVOID Data, UINT Size ); +extern VOID XNdisFreeBuffer( PNDIS_BUFFER Buffer ); +extern VOID XNdisAllocatePacket( PNDIS_STATUS Status, PNDIS_PACKET *Packet, NDIS_HANDLE PacketPool ); +extern VOID XNdisFreePacket( PNDIS_PACKET Packet ); +extern ULONG XNDIS_BUFFER_TO_SPAN_PAGES(IN PNDIS_BUFFER Buffer); +extern PVOID STDCALL XExAllocatePool( POOL_TYPE Type, ULONG Size ); +extern VOID STDCALL XExFreePool( PVOID Buffer ); +extern VOID STDCALL XKeRaiseIrql( KIRQL NewIrql, PKIRQL OldIrql ); +extern VOID STDCALL XKeLowerIrql( KIRQL NewIrql ); +extern VOID STDCALL XKeAcquireSpinLock( PKSPIN_LOCK Lock, PKIRQL Irql ); +extern VOID STDCALL XKeReleaseSpinLock( PKSPIN_LOCK Lock, KIRQL Irql ); +extern VOID STDCALL XKeAcquireSpinLockAtDpcLevel( PKSPIN_LOCK Lock ); +extern VOID STDCALL XKeReleaseSpinLockFromDpcLevel( PKSPIN_LOCK Lock ); +extern VOID STDCALL XKeInitializeSpinLock( PKSPIN_LOCK Lock ); +extern LONG FASTCALL XInterlockedIncrement( PLONG Addend ); +extern LONG FASTCALL XInterlockedDecrement( PLONG Addend ); +extern VOID STDCALL XExQueueWorkItem( PWORK_QUEUE_ITEM WorkItem, + WORK_QUEUE_TYPE Type ); +extern VOID STDCALL XExAcquireFastMutex( PFAST_MUTEX Mutex ); +extern VOID STDCALL XExReleaseFastMutex( PFAST_MUTEX Mutex ); +extern LONG STDCALL XKeSetEvent( PKEVENT Event, KPRIORITY Increment, + BOOLEAN Wiat ); +extern VOID STDCALL XKeBugCheck( ULONG Code ); +extern VOID STDCALL XExInterlockedInsertTailList( PLIST_ENTRY Head, + PLIST_ENTRY Item, + PKSPIN_LOCK Lock ); +extern VOID STDCALL XKeInitializeTimer( PKTIMER Timer ); +extern VOID STDCALL XKeInitializeEvent( PKEVENT Event, + EVENT_TYPE Type, + BOOLEAN State); +extern VOID STDCALL XKeSetTimer( PKTIMER Timer, + LARGE_INTEGER DueTime, + PKDPC Dpc ); +extern VOID STDCALL XKeSetTimerEx( PKTIMER Timer, + LARGE_INTEGER DueTime, + LONG Period, + PKDPC Dpc ); +extern VOID STDCALL XKeCancelTimer( PKTIMER Timer ); +extern NTSTATUS STDCALL XKeWaitForSingleObject +( PVOID Object, + KWAIT_REASON WaitReason, + KPROCESSOR_MODE WaitMode, + BOOLEAN Alertable, + PLARGE_INTEGER Timeout + ); +extern VOID STDCALL KeInitializeDpc (PKDPC Dpc, + PKDEFERRED_ROUTINE DeferredRoutine, + PVOID DeferredContext); + + +extern UINT RecursiveMutexEnter( struct _RECURSIVE_MUTEX *RM, BOOLEAN Write ); +extern VOID RecursiveMutexLeave( struct _RECURSIVE_MUTEX *RM ); +extern VOID RecursiveMutexInit( struct _RECURSIVE_MUTEX *RM ); +extern VOID STDCALL ExDeleteNPagedLookasideList +(PNPAGED_LOOKASIDE_LIST Lookaside); +extern VOID STDCALL ExInitializeNPagedLookasideList +( PNPAGED_LOOKASIDE_LIST Lookaside, + PALLOCATE_FUNCTION Allocate, + PFREE_FUNCTION Free, + ULONG Flags, + ULONG Size, + ULONG Tag, + USHORT Depth ); + + + +#undef NdisGetFirstBufferFromPacket +#undef NdisQueryBuffer +#undef NdisQueryPacket + +/* + * VOID + * ExFreeToNPagedLookasideList ( + * PNPAGED_LOOKASIDE_LIST Lookaside, + * PVOID Entry + * ); + * + * FUNCTION: + * Inserts (pushes) the specified entry into the specified + * nonpaged lookaside list. + * + * ARGUMENTS: + * Lookaside = Pointer to the nonpaged lookaside list + * Entry = Pointer to the entry that is inserted in the lookaside list + */ +static +inline +VOID +ExFreeToNPagedLookasideList ( + IN PNPAGED_LOOKASIDE_LIST Lookaside, + IN PVOID Entry + ) +{ + Lookaside->Free( Entry ); +} + +/* + * PVOID + * ExAllocateFromNPagedLookasideList ( + * PNPAGED_LOOKASIDE_LIST LookSide + * ); + * + * FUNCTION: + * Removes (pops) the first entry from the specified nonpaged + * lookaside list. + * + * ARGUMENTS: + * Lookaside = Pointer to a nonpaged lookaside list + * + * RETURNS: + * Address of the allocated list entry + */ +static +inline +PVOID +ExAllocateFromNPagedLookasideList ( + IN PNPAGED_LOOKASIDE_LIST Lookaside + ) +{ + PVOID Entry; + + Entry = (Lookaside->Allocate)(Lookaside->Type, + Lookaside->Size, + Lookaside->Tag); + + return Entry; +} + +/* + * VOID + * NdisGetFirstBufferFromPacket( + * IN PNDIS_PACKET _Packet, + * OUT PNDIS_BUFFER * _FirstBuffer, + * OUT PVOID * _FirstBufferVA, + * OUT PUINT _FirstBufferLength, + * OUT PUINT _TotalBufferLength) + */ +#define NdisGetFirstBufferFromPacket(_Packet, \ + _FirstBuffer, \ + _FirstBufferVA, \ + _FirstBufferLength, \ + _TotalBufferLength) \ +{ \ + PNDIS_BUFFER _Buffer; \ + \ + _Buffer = (_Packet)->Private.Head; \ + *(_FirstBuffer) = _Buffer; \ + if (_Buffer != NULL) \ + { \ + *(_FirstBufferVA) = (_Buffer)->MappedSystemVa; \ + *(_FirstBufferLength) = (_Buffer)->Size; \ + _Buffer = _Buffer->Next; \ + *(_TotalBufferLength) = *(_FirstBufferLength); \ + while (_Buffer != NULL) { \ + *(_TotalBufferLength) += (_Buffer)->Size; \ + _Buffer = _Buffer->Next; \ + } \ + } \ + else \ + { \ + *(_FirstBufferVA) = 0; \ + *(_FirstBufferLength) = 0; \ + *(_TotalBufferLength) = 0; \ + } \ +} + +/* + * VOID + * NdisQueryBuffer( + * IN PNDIS_BUFFER Buffer, + * OUT PVOID *VirtualAddress OPTIONAL, + * OUT PUINT Length) + */ +#define NdisQueryBuffer(Buffer, \ + VirtualAddress, \ + Length) \ +{ \ + if (VirtualAddress) \ + *((PVOID*)VirtualAddress) = Buffer->MappedSystemVa; \ + \ + *((PUINT)Length) = (Buffer)->Size; \ +} + +/* + * VOID + * NdisQueryPacket( + * IN PNDIS_PACKET Packet, + * OUT PUINT PhysicalBufferCount OPTIONAL, + * OUT PUINT BufferCount OPTIONAL, + * OUT PNDIS_BUFFER *FirstBuffer OPTIONAL, + * OUT PUINT TotalPacketLength OPTIONAL); + */ +#define NdisQueryPacket(Packet, \ + PhysicalBufferCount, \ + BufferCount, \ + FirstBuffer, \ + TotalPacketLength) \ +{ \ + if (FirstBuffer) \ + *((PNDIS_BUFFER*)FirstBuffer) = (Packet)->Private.Head; \ + if ((TotalPacketLength) || (BufferCount) || (PhysicalBufferCount)) \ + { \ + if (!(Packet)->Private.ValidCounts) { \ + UINT _Offset; \ + UINT _PacketLength; \ + PNDIS_BUFFER _NdisBuffer; \ + UINT _PhysicalBufferCount = 0; \ + UINT _TotalPacketLength = 0; \ + UINT _Count = 0; \ + \ + for (_NdisBuffer = (Packet)->Private.Head; \ + _NdisBuffer != (PNDIS_BUFFER)NULL; \ + _NdisBuffer = _NdisBuffer->Next) \ + { \ + _PhysicalBufferCount += XNDIS_BUFFER_TO_SPAN_PAGES(_NdisBuffer); \ + NdisQueryBufferOffset(_NdisBuffer, &_Offset, &_PacketLength); \ + _TotalPacketLength += _PacketLength; \ + _Count++; \ + } \ + (Packet)->Private.PhysicalCount = _PhysicalBufferCount; \ + (Packet)->Private.TotalLength = _TotalPacketLength; \ + (Packet)->Private.Count = _Count; \ + (Packet)->Private.ValidCounts = TRUE; \ + } \ + \ + if (PhysicalBufferCount) \ + *((PUINT)PhysicalBufferCount) = (Packet)->Private.PhysicalCount; \ + \ + if (BufferCount) \ + *((PUINT)BufferCount) = (Packet)->Private.Count; \ + \ + if (TotalPacketLength) \ + *((PUINT)TotalPacketLength) = (Packet)->Private.TotalLength; \ + } \ +} + +#endif/*__NTDRIVER__*/ + +#endif/*_NDISHACK_H*/ diff --git a/reactos/drivers/lib/undis/include/ndissys.h b/reactos/drivers/lib/undis/include/ndissys.h new file mode 100644 index 00000000000..3b39c2e3e9a --- /dev/null +++ b/reactos/drivers/lib/undis/include/ndissys.h @@ -0,0 +1,85 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS NDIS library + * FILE: ndissys.h + * PURPOSE: NDIS library definitions + * NOTES: Spin lock acquire order: + * - Miniport list lock + * - Adapter list lock + */ +#ifndef __NDISSYS_H +#define __NDISSYS_H + +#define NDIS50 1 /* Use NDIS 5.0 structures by default */ + +//#include +#include +//#include +#include + +#include "miniport.h" +#include "protocol.h" + +#include + +/* Exported functions */ +#ifdef _MSC_VER +#define EXPORT __declspec(dllexport) +#else +#define EXPORT STDCALL +#endif + + +#ifdef DBG + +#define DEBUG_REFCHECK(Object) { \ + if ((Object)->RefCount <= 0) { \ + NDIS_DbgPrint(MIN_TRACE, ("Object at (0x%X) has invalid reference count (%d).\n", \ + (Object), (Object)->RefCount)); \ + } \ +} + +#else + +#define DEBUG_REFCHECK(Object) + +#endif + + +/* + * VOID ReferenceObject( + * PVOID Object) + */ +#define ReferenceObject(Object) \ +{ \ + DEBUG_REFCHECK(Object); \ + NDIS_DbgPrint(DEBUG_REFCOUNT, ("Referencing object at (0x%X). RefCount (%d).\n", \ + (Object), (Object)->RefCount)); \ + \ + InterlockedIncrement(&((Object)->RefCount)); \ +} + +/* + * VOID DereferenceObject( + * PVOID Object) + */ +#define DereferenceObject(Object) \ +{ \ + DEBUG_REFCHECK(Object); \ + NDIS_DbgPrint(DEBUG_REFCOUNT, ("Dereferencing object at (0x%X). RefCount (%d).\n", \ + (Object), (Object)->RefCount)); \ + \ + if (InterlockedDecrement(&((Object)->RefCount)) == 0) \ + PoolFreeBuffer(Object); \ +} + + +#define MIN(value1, value2) \ + ((value1 < value2)? value1 : value2) + +#define MAX(value1, value2) \ + ((value1 > value2)? value1 : value2) + +#endif /* __NDISSYS_H */ + +/* EOF */ diff --git a/reactos/drivers/lib/undis/makefile b/reactos/drivers/lib/undis/makefile new file mode 100644 index 00000000000..ce5c72dfb51 --- /dev/null +++ b/reactos/drivers/lib/undis/makefile @@ -0,0 +1,27 @@ +# $Id: makefile,v 1.1 2004/09/29 04:54:26 arty Exp $ + +PATH_TO_TOP = ../../.. + +TARGET_TYPE = library + +TARGET_NAME = undis + +TARGET_PCH = include/ndissys.h + +TARGET_CFLAGS = -Iinclude -I../../net/ndis/include -DNDIS_WRAPPER -Wall -Werror + +# ndis/io.o +# ndis/time.o +# ndis/cm.o +# ndis/miniport.o +# ndis/cl.o +# ndis/co.o +# ndis/40gone.o \ +# ndis/50gone.o +# ndis/stubs.o +TARGET_OBJECTS = \ + ndis/compat.o + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk diff --git a/reactos/drivers/lib/undis/ndis/compat.c b/reactos/drivers/lib/undis/ndis/compat.c new file mode 100644 index 00000000000..4e35093b47f --- /dev/null +++ b/reactos/drivers/lib/undis/ndis/compat.c @@ -0,0 +1,718 @@ +#define __NTDRIVER__ +#include +#include +#undef __NTDRIVER__ +#include + +/* global list and lock of Miniports NDIS has registered */ +LIST_ENTRY MiniportListHead; +KSPIN_LOCK MiniportListLock; + +/* global list and lock of adapters NDIS has registered */ +LIST_ENTRY AdapterListHead; +KSPIN_LOCK AdapterListLock; + +/* global list and lock of orphan adapters waiting to be claimed by a miniport */ +LIST_ENTRY OrphanAdapterListHead; +KSPIN_LOCK OrphanAdapterListLock; + +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; + Lookaside->Tag = Tag; + Lookaside->Depth = Depth; +} + +LONG FASTCALL InterlockedIncrement( PLONG Addend ) { return ++(*Addend); } +LONG FASTCALL InterlockedDecrement( PLONG Addend ) { return --(*Addend); } +void STDCALL KeBugCheck(ULONG x) { assert(0); } +PVOID STDCALL ExAllocatePool( POOL_TYPE Type, ULONG Bytes ) { + return ExAllocatePoolWithTag( 0, Type, Bytes ); +} +PVOID STDCALL ExAllocatePoolWithTag( ULONG Tag, POOL_TYPE Type, ULONG Bytes ) { + PUINT Data = malloc( Bytes + 4 ); + if( Data ) { Data[0] = Tag; return &Data[1]; } + return Data; +} +VOID STDCALL KeInitializeSpinLock( PKSPIN_LOCK Lock ) { } +VOID STDCALL ExFreePool( PVOID Data ) { free( Data ); } +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 STDCALL XExAcquireFastMutex( PFAST_MUTEX Mutex ) { } +VOID STDCALL XExReleaseFastMutex( PFAST_MUTEX Mutex ) { } +VOID STDCALL XKeInitializeEvent( PKEVENT Event, + EVENT_TYPE Type, + BOOLEAN State ) { } + +VOID STDCALL XExInterlockedInsertTailList( PLIST_ENTRY Head, + PLIST_ENTRY Item, + PKSPIN_LOCK Lock ) { + InsertTailList( Head, Item ); +} + +UINT RecursiveMutexEnter( struct _RECURSIVE_MUTEX *RM, BOOLEAN Write ) { + return 0; +} +VOID RecursiveMutexLeave( struct _RECURSIVE_MUTEX *RM ) { } +VOID RecursiveMutexInit( struct _RECURSIVE_MUTEX *RM ) { } + +static LIST_ENTRY WorkQueue = { &WorkQueue, &WorkQueue }; + +VOID STDCALL XExQueueWorkItem( PWORK_QUEUE_ITEM WorkItem, + WORK_QUEUE_TYPE Type ) { + InsertTailList( &WorkQueue, &WorkItem->List ); +} + +LIST_ENTRY Timers = { &Timers, &Timers }; +LARGE_INTEGER CurTime = { }; + +VOID STDCALL XKeInitializeTimer( PKTIMER Timer ) { +} + +VOID STDCALL XKeSetTimerEx( PKTIMER Timer, LARGE_INTEGER DueTime, LONG Period, + PKDPC Dpc ) { + Timer->DueTime.QuadPart = CurTime.QuadPart; + if( DueTime.QuadPart > 0 ) Timer->DueTime.QuadPart = DueTime.QuadPart; + else Timer->DueTime.QuadPart -= DueTime.QuadPart; + Timer->DueTime.QuadPart = DueTime.QuadPart; + Timer->Dpc = Dpc; + InsertTailList( &Timers, &Timer->TimerListEntry ); +} + +VOID STDCALL XKeSetTimer( PKTIMER Timer, LARGE_INTEGER DueTime, PKDPC Dpc ) { + XKeSetTimer( Timer, DueTime, Dpc ); +} + +VOID STDCALL XKeCancelTimer( PKTIMER Timer ) { + PLIST_ENTRY ListEntry; + + for( ListEntry = Timers.Flink; + ListEntry != &Timers; + ListEntry = ListEntry->Flink ) { + if( ListEntry == &Timer->TimerListEntry ) { + RemoveEntryList( &Timer->TimerListEntry ); + return; + } + } +} + +VOID TimerTick( LARGE_INTEGER Time ) { + PLIST_ENTRY ListEntry; + PKTIMER Timer; + + while( (ListEntry = RemoveHeadList( &Timers )) ) { + Timer = CONTAINING_RECORD( ListEntry, KTIMER, TimerListEntry ); + if( Timer->DueTime.QuadPart < Time.QuadPart ) + (Timer->Dpc->DeferredRoutine)( Timer->Dpc, + Timer->Dpc->DeferredContext, + Timer->Dpc->SystemArgument1, + Timer->Dpc->SystemArgument2 ); + } + + if( Timer ) + InsertHeadList( &Timers, &Timer->TimerListEntry ); +} + +LONG STDCALL XKeSetEvent( PKEVENT Event, KPRIORITY Increment, BOOLEAN Wait ) { + return 0; +} + +/* Host uses this */ +PWORK_QUEUE_ITEM GetWorkQueueItem() { + PLIST_ENTRY ListEntry = RemoveHeadList( &WorkQueue ); + if( ListEntry ) + return CONTAINING_RECORD(ListEntry, WORK_QUEUE_ITEM, List); + else + return NULL; +} + +VOID STDCALL ExDeleteNPagedLookasideList(PNPAGED_LOOKASIDE_LIST Lookaside) { +} + +NTSTATUS STDCALL XKeWaitForSingleObject +( PVOID Object, + KWAIT_REASON WaitReason, + KPROCESSOR_MODE WaitMode, + BOOLEAN Alertable, + PLARGE_INTEGER Timeout + ) { + return STATUS_SUCCESS; +} + +VOID STDCALL XKeInitializeDpc (PKDPC Dpc, + PKDEFERRED_ROUTINE DeferredRoutine, + PVOID DeferredContext) { + Dpc->DeferredRoutine = DeferredRoutine; + Dpc->DeferredContext = DeferredContext; +} + + + +BOOLEAN +MiniAdapterHasAddress( + PLOGICAL_ADAPTER Adapter, + PNDIS_PACKET Packet) +/* + * FUNCTION: Determines wether a packet has the same destination address as an adapter + * ARGUMENTS: + * Adapter = Pointer to logical adapter object + * Packet = Pointer to NDIS packet + * RETURNS: + * TRUE if the destination address is that of the adapter, FALSE if not + */ +{ + UINT Length; + PUCHAR Start1; + PUCHAR Start2; + PNDIS_BUFFER NdisBuffer; + UINT BufferLength; + + NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n")); + +#ifdef DBG + if(!Adapter) + { + NDIS_DbgPrint(MID_TRACE, ("Adapter object was null\n")); + return FALSE; + } + + if(!Packet) + { + NDIS_DbgPrint(MID_TRACE, ("Packet was null\n")); + return FALSE; + } +#endif + + NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, NULL); + + if (!NdisBuffer) + { + NDIS_DbgPrint(MID_TRACE, ("Packet contains no buffers.\n")); + return FALSE; + } + + NdisQueryBuffer(NdisBuffer, (PVOID)&Start2, &BufferLength); + + /* FIXME: Should handle fragmented packets */ + + switch (Adapter->NdisMiniportBlock.MediaType) + { + case NdisMedium802_3: + Length = ETH_LENGTH_OF_ADDRESS; + /* Destination address is the first field */ + break; + + default: + NDIS_DbgPrint(MIN_TRACE, ("Adapter has unsupported media type (0x%X).\n", Adapter->NdisMiniportBlock.MediaType)); + return FALSE; + } + + if (BufferLength < Length) + { + NDIS_DbgPrint(MID_TRACE, ("Buffer is too small.\n")); + return FALSE; + } + + Start1 = (PUCHAR)&Adapter->Address; + NDIS_DbgPrint(MAX_TRACE, ("packet address: %x:%x:%x:%x:%x:%x adapter address: %x:%x:%x:%x:%x:%x\n", + *((char *)Start1), *(((char *)Start1)+1), *(((char *)Start1)+2), *(((char *)Start1)+3), *(((char *)Start1)+4), *(((char *)Start1)+5), + *((char *)Start2), *(((char *)Start2)+1), *(((char *)Start2)+2), *(((char *)Start2)+3), *(((char *)Start2)+4), *(((char *)Start2)+5)) + ); + + return (RtlCompareMemory((PVOID)Start1, (PVOID)Start2, Length) == Length); +} + +VOID +MiniDisplayPacket( + PNDIS_PACKET Packet) +{ +//#ifdef DBG +#if 0 + ULONG i, Length; + UCHAR Buffer[64]; + if ((DebugTraceLevel | DEBUG_PACKET) > 0) { + Length = CopyPacketToBuffer( + (PUCHAR)&Buffer, + Packet, + 0, + 64); + + DbgPrint("*** PACKET START ***"); + + for (i = 0; i < Length; i++) { + if (i % 12 == 0) + DbgPrint("\n%04X ", i); + DbgPrint("%02X ", Buffer[i]); + } + + DbgPrint("*** PACKET STOP ***\n"); + } +#endif /* DBG */ +} + +NDIS_STATUS +MiniDoRequest( + PLOGICAL_ADAPTER Adapter, + PNDIS_REQUEST NdisRequest) +/* + * FUNCTION: Sends a request to a miniport + * ARGUMENTS: + * Adapter = Pointer to logical adapter object + * NdisRequest = Pointer to NDIS request structure describing request + * RETURNS: + * Status of operation + */ +{ + NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n")); + + Adapter->NdisMiniportBlock.MediaRequest = NdisRequest; + + switch (NdisRequest->RequestType) + { + case NdisRequestQueryInformation: + return (*Adapter->Miniport->Chars.QueryInformationHandler)( + Adapter->NdisMiniportBlock.MiniportAdapterContext, + NdisRequest->DATA.QUERY_INFORMATION.Oid, + NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer, + NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength, + (PULONG)&NdisRequest->DATA.QUERY_INFORMATION.BytesWritten, + (PULONG)&NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded); + break; + + case NdisRequestSetInformation: + return (*Adapter->Miniport->Chars.SetInformationHandler)( + Adapter->NdisMiniportBlock.MiniportAdapterContext, + NdisRequest->DATA.SET_INFORMATION.Oid, + NdisRequest->DATA.SET_INFORMATION.InformationBuffer, + NdisRequest->DATA.SET_INFORMATION.InformationBufferLength, + (PULONG)&NdisRequest->DATA.SET_INFORMATION.BytesRead, + (PULONG)&NdisRequest->DATA.SET_INFORMATION.BytesNeeded); + break; + + default: + return NDIS_STATUS_FAILURE; + } +} + + +VOID +MiniDisplayPacket2( + PVOID HeaderBuffer, + UINT HeaderBufferSize, + PVOID LookaheadBuffer, + UINT LookaheadBufferSize) +{ +#ifdef DBG + if ((DebugTraceLevel | DEBUG_PACKET) > 0) { + ULONG i, Length; + PUCHAR p; + + DbgPrint("*** RECEIVE PACKET START ***\n"); + DbgPrint("HEADER:"); + p = HeaderBuffer; + for (i = 0; i < HeaderBufferSize; i++) { + if (i % 16 == 0) + DbgPrint("\n%04X ", i); + DbgPrint("%02X ", *p); + *(ULONG_PTR*)p += 1; + } + + DbgPrint("\nFRAME:"); + + p = LookaheadBuffer; + Length = (LookaheadBufferSize < 64)? LookaheadBufferSize : 64; + for (i = 0; i < Length; i++) { + if (i % 16 == 0) + DbgPrint("\n%04X ", i); + DbgPrint("%02X ", *p); + *(ULONG_PTR*)p += 1; + } + + DbgPrint("\n*** RECEIVE PACKET STOP ***\n"); + } +#endif /* DBG */ +} + +VOID +MiniIndicateData( + PLOGICAL_ADAPTER Adapter, + NDIS_HANDLE MacReceiveContext, + PVOID HeaderBuffer, + UINT HeaderBufferSize, + PVOID LookaheadBuffer, + UINT LookaheadBufferSize, + UINT PacketSize) +/* + * FUNCTION: Indicate received data to bound protocols + * ARGUMENTS: + * Adapter = Pointer to logical adapter + * MacReceiveContext = MAC receive context handle + * HeaderBuffer = Pointer to header buffer + * HeaderBufferSize = Size of header buffer + * LookaheadBuffer = Pointer to lookahead buffer + * LookaheadBufferSize = Size of lookahead buffer + * PacketSize = Total size of received packet + */ +{ + /* KIRQL OldIrql; */ + PLIST_ENTRY CurrentEntry; + PADAPTER_BINDING AdapterBinding; + + NDIS_DbgPrint(DEBUG_MINIPORT, ("Called. Adapter (0x%X) HeaderBuffer (0x%X) " + "HeaderBufferSize (0x%X) LookaheadBuffer (0x%X) LookaheadBufferSize (0x%X).\n", + Adapter, HeaderBuffer, HeaderBufferSize, LookaheadBuffer, LookaheadBufferSize)); + + MiniDisplayPacket2(HeaderBuffer, HeaderBufferSize, LookaheadBuffer, LookaheadBufferSize); + + /* + * XXX Think about this. This is probably broken. Spinlocks are + * taken out for now until i comprehend the Right Way to do this. + * + * This used to acquire the MiniportBlock spinlock and hold it until + * just before the call to ReceiveHandler. It would then release and + * subsequently re-acquire the lock. + * + * I don't see how this does any good, as it would seem he's just + * trying to protect the packet list. If someobdy else dequeues + * a packet, we are in fact in bad shape, but we don't want to + * necessarily call the receive handler at elevated irql either. + * + * therefore: We *are* going to call the receive handler at high irql + * (due to holding the lock) for now, and eventually we have to + * figure out another way to protect this packet list. + * + * UPDATE: this is busted; this results in a recursive lock acquisition. + */ + //NDIS_DbgPrint(MAX_TRACE, ("acquiring miniport block lock\n")); + //KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); + { + CurrentEntry = Adapter->ProtocolListHead.Flink; + NDIS_DbgPrint(DEBUG_MINIPORT, ("CurrentEntry = %x\n", CurrentEntry)); + + if (CurrentEntry == &Adapter->ProtocolListHead) + { + NDIS_DbgPrint(DEBUG_MINIPORT, ("WARNING: No upper protocol layer.\n")); + } + + while (CurrentEntry != &Adapter->ProtocolListHead) + { + AdapterBinding = CONTAINING_RECORD(CurrentEntry, ADAPTER_BINDING, AdapterListEntry); + NDIS_DbgPrint(DEBUG_MINIPORT, ("AdapterBinding = %x\n", AdapterBinding)); + + /* see above */ + /* KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); */ + +#ifdef DBG + if(!AdapterBinding) + { + NDIS_DbgPrint(MIN_TRACE, ("AdapterBinding was null\n")); + break; + } + + if(!AdapterBinding->ProtocolBinding) + { + NDIS_DbgPrint(MIN_TRACE, ("AdapterBinding->ProtocolBinding was null\n")); + break; + } + + if(!AdapterBinding->ProtocolBinding->Chars.u4.ReceiveHandler) + { + NDIS_DbgPrint(MIN_TRACE, ("AdapterBinding->ProtocolBinding->Chars.u4.ReceiveHandler was null\n")); + break; + } +#endif + + NDIS_DbgPrint + (MID_TRACE, + ("XXX (%x) %x %x %x %x %x %x %x XXX\n", + *AdapterBinding->ProtocolBinding->Chars.u4.ReceiveHandler, + AdapterBinding->NdisOpenBlock.ProtocolBindingContext, + MacReceiveContext, + HeaderBuffer, + HeaderBufferSize, + LookaheadBuffer, + LookaheadBufferSize, + PacketSize)); + + /* call the receive handler */ + (*AdapterBinding->ProtocolBinding->Chars.u4.ReceiveHandler)( + AdapterBinding->NdisOpenBlock.ProtocolBindingContext, + MacReceiveContext, + HeaderBuffer, + HeaderBufferSize, + LookaheadBuffer, + LookaheadBufferSize, + PacketSize); + + /* see above */ + /* KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); */ + + CurrentEntry = CurrentEntry->Flink; + } + } + //KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); + + NDIS_DbgPrint(MAX_TRACE, ("Leaving.\n")); +} + + +PLOGICAL_ADAPTER +MiniLocateDevice( + PNDIS_STRING AdapterName) +/* + * FUNCTION: Finds an adapter object by name + * ARGUMENTS: + * AdapterName = Pointer to name of adapter + * RETURNS: + * Pointer to logical adapter object, or NULL if none was found. + * If found, the adapter is referenced for the caller. The caller + * is responsible for dereferencing after use + */ +{ + KIRQL OldIrql; + PLIST_ENTRY CurrentEntry; + PLOGICAL_ADAPTER Adapter = 0; + + ASSERT(AdapterName); + + NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n")); + + if(IsListEmpty(&AdapterListHead)) + { + NDIS_DbgPrint(DEBUG_MINIPORT, ("No registered miniports for protocol to bind to\n")); + return NULL; + } + + KeAcquireSpinLock(&AdapterListLock, &OldIrql); + { + do + { + CurrentEntry = AdapterListHead.Flink; + + while (CurrentEntry != &AdapterListHead) + { + Adapter = CONTAINING_RECORD(CurrentEntry, LOGICAL_ADAPTER, ListEntry); + + ASSERT(Adapter); + + NDIS_DbgPrint(DEBUG_MINIPORT, ("AdapterName = %wZ\n", &AdapterName)); + NDIS_DbgPrint(DEBUG_MINIPORT, ("DeviceName = %wZ\n", &Adapter->DeviceName)); + + if (RtlCompareUnicodeString(AdapterName, &Adapter->DeviceName, TRUE) == 0) + { + ReferenceObject(Adapter); + break; + } + + CurrentEntry = CurrentEntry->Flink; + } + } while (0); + } + KeReleaseSpinLock(&AdapterListLock, OldIrql); + + if(Adapter) + { + NDIS_DbgPrint(DEBUG_MINIPORT, ("Leaving. Adapter found at 0x%x\n", Adapter)); + } + else + { + NDIS_DbgPrint(DEBUG_MINIPORT, ("Leaving (adapter not found).\n")); + } + + return Adapter; +} + +/* + * @implemented + */ +ULONG +XNDIS_BUFFER_TO_SPAN_PAGES( + IN PNDIS_BUFFER Buffer) +/* + * FUNCTION: Determines how many physical pages a buffer is made of + * ARGUMENTS: + * Buffer = Pointer to NDIS buffer descriptor + */ +{ + if (Buffer->Size == 0) + return 1; + + return ADDRESS_AND_SIZE_TO_SPAN_PAGES( + MmGetMdlVirtualAddress(Buffer), + MmGetMdlByteCount(Buffer)); +} + +/* + * @implemented + */ +VOID +XNdisAllocateBuffer( + OUT PNDIS_STATUS Status, + OUT PNDIS_BUFFER * Buffer, + IN NDIS_HANDLE PoolHandle, + IN PVOID VirtualAddress, + IN UINT Length) +/* + * FUNCTION: Allocates an NDIS buffer descriptor + * ARGUMENTS: + * Status = Address of buffer for status + * Buffer = Address of buffer for NDIS buffer descriptor + * PoolHandle = Handle returned by NdisAllocateBufferPool + * VirtualAddress = Pointer to virtual address of data buffer + * Length = Number of bytes in data buffer + */ +{ + KIRQL OldIrql; + PNETWORK_HEADER Temp; + PNDIS_BUFFER_POOL Pool = (PNDIS_BUFFER_POOL)PoolHandle; + + NDIS_DbgPrint(MAX_TRACE, ("Status (0x%X) Buffer (0x%X) PoolHandle (0x%X) " + "VirtualAddress (0x%X) Length (%d)\n", + Status, Buffer, PoolHandle, VirtualAddress, Length)); + +#if 0 + Temp = Pool->FreeList; + while( Temp ) { + NDIS_DbgPrint(MID_TRACE,("Free buffer -> %x\n", Temp)); + Temp = Temp->Next; + } + + NDIS_DbgPrint(MID_TRACE,("|:. <- End free buffers")); +#endif + + if(!VirtualAddress && !Length) return; + + KeAcquireSpinLock(&Pool->SpinLock, &OldIrql); + + if (Pool->FreeList) { + Temp = Pool->FreeList; + Pool->FreeList = Temp->Next; + + KeReleaseSpinLock(&Pool->SpinLock, OldIrql); + + Temp->Next = NULL; + + Temp->Mdl.Next = (PMDL)NULL; + Temp->Mdl.Size = (CSHORT)(sizeof(MDL) + + (ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress, Length) * sizeof(ULONG))); + Temp->Mdl.MdlFlags = (MDL_SOURCE_IS_NONPAGED_POOL | MDL_ALLOCATED_FIXED_SIZE); + ; Temp->Mdl.StartVa = (PVOID)PAGE_ROUND_DOWN(VirtualAddress); + Temp->Mdl.ByteOffset = (ULONG_PTR)(VirtualAddress - PAGE_ROUND_DOWN(VirtualAddress)); + Temp->Mdl.ByteCount = Length; + Temp->Mdl.MappedSystemVa = VirtualAddress; + + Temp->BufferPool = Pool; + + *Buffer = (PNDIS_BUFFER)Temp; + *Status = NDIS_STATUS_SUCCESS; + } else { + KeReleaseSpinLock(&Pool->SpinLock, OldIrql); + *Status = NDIS_STATUS_FAILURE; + NDIS_DbgPrint(MID_TRACE, ("Can't get another packet.\n")); + KeBugCheck(0); + } +} + +/* + * @implemented + */ +VOID +XNdisAllocatePacket( + OUT PNDIS_STATUS Status, + OUT PNDIS_PACKET * Packet, + IN NDIS_HANDLE PoolHandle) +/* + * FUNCTION: Allocates an NDIS packet descriptor + * ARGUMENTS: + * Status = Address of buffer for status + * Packet = Address of buffer for packet descriptor + * PoolHandle = Handle returned by NdisAllocatePacketPool + */ +{ + KIRQL OldIrql; + PNDIS_PACKET Temp; + PNDIS_PACKET_POOL Pool = (PNDIS_PACKET_POOL)PoolHandle; + + NDIS_DbgPrint(MAX_TRACE, ("Status (0x%X) Packet (0x%X) PoolHandle (0x%X).\n", + Status, Packet, PoolHandle)); + + KeAcquireSpinLock(&Pool->SpinLock.SpinLock, &OldIrql); + + if (Pool->FreeList) { + Temp = Pool->FreeList; + Pool->FreeList = (PNDIS_PACKET)Temp->Private.Head; + + KeReleaseSpinLock(&Pool->SpinLock.SpinLock, OldIrql); + + RtlZeroMemory(&Temp->Private, sizeof(NDIS_PACKET_PRIVATE)); + Temp->Private.Pool = Pool; + + *Packet = Temp; + *Status = NDIS_STATUS_SUCCESS; + } else { + *Status = NDIS_STATUS_RESOURCES; + KeReleaseSpinLock(&Pool->SpinLock.SpinLock, OldIrql); + } +} + +/* + * @implemented + */ +VOID +XNdisFreeBuffer( + IN PNDIS_BUFFER Buffer) +/* + * FUNCTION: Puts an NDIS buffer descriptor back in it's pool + * ARGUMENTS: + * Buffer = Pointer to buffer descriptor + */ +{ + KIRQL OldIrql; + PNDIS_BUFFER_POOL Pool; + PNETWORK_HEADER Temp = (PNETWORK_HEADER)Buffer; + + NDIS_DbgPrint(MAX_TRACE, ("Buffer (0x%X).\n", Buffer)); + + Pool = Temp->BufferPool; + + KeAcquireSpinLock(&Pool->SpinLock, &OldIrql); + Temp->Next = (PNETWORK_HEADER)Pool->FreeList; + Pool->FreeList = (PNETWORK_HEADER)Temp; + KeReleaseSpinLock(&Pool->SpinLock, OldIrql); +} + + +/* + * @implemented + */ +VOID +XNdisFreePacket( + IN PNDIS_PACKET Packet) +/* + * FUNCTION: Puts an NDIS packet descriptor back in it's pool + * ARGUMENTS: + * Packet = Pointer to packet descriptor + */ +{ + KIRQL OldIrql; + + NDIS_DbgPrint(MAX_TRACE, ("Packet (0x%X).\n", Packet)); + + KeAcquireSpinLock(&Packet->Private.Pool->SpinLock.SpinLock, &OldIrql); + Packet->Private.Head = (PNDIS_BUFFER)Packet->Private.Pool->FreeList; + Packet->Private.Pool->FreeList = Packet; + KeReleaseSpinLock(&Packet->Private.Pool->SpinLock.SpinLock, OldIrql); +} +