Simple library which captures the remaining link-time dependencies for ip.a

Incomplete as yet.

Open question: how to make ip.a ambiguously linkable without building it
twice in it's present form.  Oskit was relatively simple because the
system dependencies were already isolated.  We need to capture and isolate
system dependencies in ip.a as well.

svn path=/trunk/; revision=11117
This commit is contained in:
Art Yerkes 2004-09-29 04:54:26 +00:00
parent 91a2bfd277
commit 107ff56d07
4 changed files with 1114 additions and 0 deletions

View file

@ -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*/

View file

@ -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 <basetsd.h>
#include <ddk/ntddk.h>
//#include <windef.h>
#include <ndisfake.h>
#include "miniport.h"
#include "protocol.h"
#include <debug.h>
/* 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 */

View file

@ -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

View file

@ -0,0 +1,718 @@
#define __NTDRIVER__
#include <ndissys.h>
#include <buffer.h>
#undef __NTDRIVER__
#include <ndishack.h>
/* 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);
}