From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/ntos/ndis/testmac/makefile | 6 + private/ntos/ndis/testmac/sources | 41 ++ private/ntos/ndis/testmac/testmac.c | 1236 +++++++++++++++++++++++++++++++++++ private/ntos/ndis/testmac/testmac.h | 349 ++++++++++ 4 files changed, 1632 insertions(+) create mode 100644 private/ntos/ndis/testmac/makefile create mode 100644 private/ntos/ndis/testmac/sources create mode 100644 private/ntos/ndis/testmac/testmac.c create mode 100644 private/ntos/ndis/testmac/testmac.h (limited to 'private/ntos/ndis/testmac') diff --git a/private/ntos/ndis/testmac/makefile b/private/ntos/ndis/testmac/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/ntos/ndis/testmac/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/ntos/ndis/testmac/sources b/private/ntos/ndis/testmac/sources new file mode 100644 index 000000000..e54919b71 --- /dev/null +++ b/private/ntos/ndis/testmac/sources @@ -0,0 +1,41 @@ +!IF 0 + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + + +Author: + + Steve Wood (stevewo) 12-Apr-1990 + +NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl + +!ENDIF + +MAJORCOMP=ntos +MINORCOMP=ndis + +TARGETNAME=testmac +TARGETPATH=\nt\public\sdk\lib +TARGETTYPE=DRIVER + +TARGETLIBS=$(BASEDIR)\public\sdk\lib\*\ndis.lib + +INCLUDES=..\..\inc + +SOURCES=testmac.c + +RELATIVE_DEPTH=..\.. + +MSC_WARNING_LEVEL=/W3 /WX + diff --git a/private/ntos/ndis/testmac/testmac.c b/private/ntos/ndis/testmac/testmac.c new file mode 100644 index 000000000..ad689ca82 --- /dev/null +++ b/private/ntos/ndis/testmac/testmac.c @@ -0,0 +1,1236 @@ +/*++ + +Copyright (c) 1990 Microsoft Corporation + +Module Name: + + testmac.c + +Abstract: + + simple MAC to test the NDIS wrapper. + Mostly taken from the Elnkii code spec. + +Author: + + Adam Barr (adamba) 14-Jul-1990 + +Environment: + + Kernel mode, FSD + +Revision History: + + +--*/ + +#include + +#include + +#include "testmac.h" + + +/*++ + +Routine Description: + + This is the initialization routine for the driver. It is invoked once + when the driver is loaded into the system. Its job is to initialize all + the structures which will be used by the FSD. + +Arguments: + + DriverObject - Pointer to driver object created by the system. + +Return Value: + + None. + +--*/ + + + +static +NTSTATUS +TestMacDispatch( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ) + +/*++ + +Routine Description: + + This routine is the main dispatch routine for the FSD. This routine + accepts an I/O Request Packet (IRP) and either performs the request + itself, or it passes it to the FSP for processing. + +Arguments: + + DeviceObject - Pointer to the device object for this driver. + + Irp - Pointer to the request packet representing the I/O request. + +Return Value: + + The function value is the status of the operation. + + +--*/ + +{ + KIRQL oldIrql; + + DeviceObject; + + KeRaiseIrql( DISPATCH_LEVEL, &oldIrql ); + IoCompleteRequest( Irp, 0 ); + KeLowerIrql( oldIrql ); + + return STATUS_NOT_IMPLEMENTED; +} + + + + +MAC_BLOCK GlobalMacBlock; +UCHAR * AdapterNames[] = { + "\\Device\\TestMac0", + "\\Device\\TestMac1", + "\\Device\\TestMac2" + }; + + +NTSTATUS +DriverEntry( + IN PDRIVER_OBJECT DriverObject + ) +{ + PMAC_BLOCK NewMacP = &GlobalMacBlock; + NDIS_STATUS Status; + CLONG i; + STRING AdapterName; + + // Initialize the driver object with this driver's entry points. + for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) { + DriverObject->MajorFunction[i] = TestMacDispatch; + } + + // Initialize the wrapper + NdisInitializeWrapper( (PVOID)DriverObject, NULL, NULL); + + NewMacP->Debug = FALSE; + + // set up driver object, etc. + NewMacP->DriverObject = DriverObject; + KeInitializePowerStatus(&NewMacP->PowerStatus); + NewMacP->PowerBoolean = FALSE; + KeInsertQueuePowerStatus(&NewMacP->PowerStatus, &NewMacP->PowerBoolean); + NdisAllocateSpinLock(&NewMacP->SpinLock); + + NewMacP->NumAdapters = 0; + NewMacP->AdapterQueue = (PADAPTER_BLOCK)NULL; + + // get ready to call NdisRegisterMac + NewMacP->MacCharacteristics.MajorNdisVersion = 3; + NewMacP->MacCharacteristics.MinorNdisVersion = 0; + NewMacP->MacCharacteristics.Reserved = 0; + NewMacP->MacCharacteristics.OpenAdapterHandler = TestMacOpenAdapter; + NewMacP->MacCharacteristics.CloseAdapterHandler = TestMacCloseAdapter; + NewMacP->MacCharacteristics.SetPacketFilterHandler = TestMacSetPacketFilter; + NewMacP->MacCharacteristics.AddMulticastAddressHandler = + TestMacAddMulticastAddress; + NewMacP->MacCharacteristics.DeleteMulticastAddressHandler = + TestMacDeleteMulticastAddress; + NewMacP->MacCharacteristics.SendHandler = TestMacSend; + NewMacP->MacCharacteristics.TransferDataHandler = TestMacTransferData; + NewMacP->MacCharacteristics.QueryInformationHandler = + TestMacQueryInformation; + NewMacP->MacCharacteristics.SetInformationHandler = TestMacSetInformation; + NewMacP->MacCharacteristics.ResetHandler = TestMacReset; + NewMacP->MacCharacteristics.TestHandler = TestMacTest; + NewMacP->MacCharacteristics.NameLength = sizeof("TESTMAC"); + RtlMoveMemory(NewMacP->MacCharacteristics.Name, "TESTMAC", 8); + + NdisRegisterMac(&Status, + &NewMacP->NdisMacHandle, + &NewMacP->MacCharacteristics, + sizeof(NewMacP->MacCharacteristics)+8); + + if (Status != NDIS_STATUS_SUCCESS) { + // NdisRegisterMac failed + if (NewMacP->Debug) + DbgPrint(" [ RegisterMac FAILURE %d ] ", Status); + KeRemoveQueuePowerStatus(&NewMacP->PowerStatus); + NdisFreeSpinLock(&NewMacP->SpinLock); + return STATUS_UNSUCCESSFUL; + } + + for (i=0; i<3; i++) { + RtlInitString(&AdapterName, AdapterNames[i]); + if (TestMacRegisterAdapter(&AdapterName, i) != NDIS_STATUS_SUCCESS) + return STATUS_UNSUCCESSFUL; + } + + return STATUS_SUCCESS; +} + + +// +// MacRegisterAdapter +// +// NT will call this function when a new adapter should be opened +// +// - allocates space for adapter block and open blocks +// - initializes the open block +// - calls NdisRegisterAdapter +// + +static +NDIS_STATUS +TestMacRegisterAdapter( + IN PSTRING AdapterName, + IN UINT AdapterNumber + ) +{ + PADAPTER_BLOCK NewAdaptP; + NDIS_STATUS Status; + UINT i; + + // OK to allocate memory now + NewAdaptP = (PADAPTER_BLOCK)AllocPhys(sizeof(ADAPTER_BLOCK)); + if (NewAdaptP == (PADAPTER_BLOCK)NULL) + return NDIS_STATUS_FAILURE; + + NewAdaptP->AdapterName = AdapterName; + NewAdaptP->AdapterNumber = AdapterNumber; + + NewAdaptP->MaxOpens = 4; + NewAdaptP->MulticastListMax = 8; + NewAdaptP->MulticastDontModify = FALSE; + + // need to get this memory now + NewAdaptP->OpenBlocks = + (POPEN_BLOCK)AllocPhys(sizeof(OPEN_BLOCK) * NewAdaptP->MaxOpens); + if (NewAdaptP->OpenBlocks == (POPEN_BLOCK)NULL) + { + FreePhys((PVOID)NewAdaptP); + return NDIS_STATUS_FAILURE; + } + + ++(NewAdaptP->MulticastListMax); // to allow for broadcast address + // need to get this memory now + NewAdaptP->MulticastList = (PMULTICAST_ENTRY) + AllocPhys(sizeof(MULTICAST_ENTRY) * (NewAdaptP->MulticastListMax)); + if (NewAdaptP->MulticastList == (PMULTICAST_ENTRY)NULL) { + FreePhys((PVOID)NewAdaptP->OpenBlocks); + FreePhys((PVOID)NewAdaptP); + return NDIS_STATUS_FAILURE; + } + NdisAllocateSpinLock(&NewAdaptP->MulticastSpinLock); + + // set up the broadcast address as first multicast list entry + NewAdaptP->MulticastListSize = 1; + RtlMoveMemory(NewAdaptP->MulticastList->Address, + BroadcastAddress, ADDRESS_LEN); + NewAdaptP->MulticastList->ProtocolMask = ~(MASK)0; // not really needed + + NewAdaptP->LoopbackQueue = (PNDIS_PACKET)NULL; + NdisAllocateSpinLock(&NewAdaptP->LoopbackSpinLock); + + NewAdaptP->NumOpens = 0; + NewAdaptP->OpenQueue = (POPEN_BLOCK)NULL; + + // set up free list of open blocks + NewAdaptP->FreeOpenQueue = NewAdaptP->OpenBlocks; + for (i = 0; i < NewAdaptP->MaxOpens-1; i++) + NewAdaptP->OpenBlocks[i].NextOpen = &(NewAdaptP->OpenBlocks[i+1]); + NewAdaptP->OpenBlocks[i].NextOpen = (POPEN_BLOCK)NULL; + + NewAdaptP->MacBlock = &GlobalMacBlock; + + NdisAcquireSpinLock(&GlobalMacBlock.SpinLock); + NewAdaptP->NextAdapter = GlobalMacBlock.AdapterQueue; + GlobalMacBlock.AdapterQueue = NewAdaptP; + NdisReleaseSpinLock(&GlobalMacBlock.SpinLock); + + NewAdaptP->Debug = GlobalMacBlock.Debug; + + Status = NdisRegisterAdapter(&NewAdaptP->NdisAdapterHandle, + GlobalMacBlock.NdisMacHandle, + (NDIS_HANDLE)NewAdaptP, + AdapterName); + + if (Status != NDIS_STATUS_SUCCESS) { + if (NewAdaptP->Debug) + DbgPrint(" [ NdisRegisterAdapter FAILURE %d ] ", Status); + //*\\ take us out of GlobalMacBlock.AdapterQueue; + FreePhys((PVOID)NewAdaptP->OpenBlocks); + FreePhys((PVOID)NewAdaptP); + return NDIS_STATUS_FAILURE; + } + + KeInitializeDpc(&NewAdaptP->IndicateDpc, + TestMacIndicateDpc, (PVOID)NewAdaptP); + NewAdaptP->DpcQueued = FALSE; + + return NDIS_STATUS_SUCCESS; +} + + + +// +// MacOpenAdapter +// +// NDIS function +// + +static +NDIS_STATUS +TestMacOpenAdapter( + OUT NDIS_HANDLE * MacBindingHandle, + IN NDIS_HANDLE RequestHandle, + IN NDIS_HANDLE NdisBindingContext, + IN NDIS_HANDLE MacAdapterContext, + IN PSTRING AddressingInformation OPTIONAL + ) +{ +#define AdaptP ((PADAPTER_BLOCK)MacAdapterContext) + POPEN_BLOCK NewOpenP; + + RequestHandle; + + // take care of linking us in to the appropriate lists + NdisAcquireSpinLock(&AdaptP->MacBlock->SpinLock); + if (AdaptP->NumOpens == AdaptP->MaxOpens) { + NdisReleaseSpinLock(&AdaptP->MacBlock->SpinLock); + return NDIS_STATUS_FAILURE; + } + // rearrange free list + NewOpenP = AdaptP->FreeOpenQueue; + AdaptP->FreeOpenQueue = NewOpenP->NextOpen; + + // and link us on to active list + NewOpenP->NextOpen = AdaptP->OpenQueue; + AdaptP->OpenQueue = NewOpenP; + + ++(AdaptP->NumOpens); + NdisReleaseSpinLock(&AdaptP->MacBlock->SpinLock); + + // set up the open block + NewOpenP->AdapterBlock = AdaptP; + NewOpenP->MacBlock = AdaptP->MacBlock; + NewOpenP->NdisBindingContext = NdisBindingContext; + NewOpenP->AddressingInformation = AddressingInformation; + // set nth bit of Multicast bit (where n is our index in AdaptP->OpenBlocks) + NewOpenP->MulticastBit = 1; + NewOpenP->MulticastBit <<= AdaptP->OpenBlocks - NewOpenP; + + NewOpenP->Debug = AdaptP->Debug; + + if (NewOpenP->Debug) + DbgPrint("--> TestMacOpenAdapter %d\n", AdaptP->AdapterNumber); + + //*\\ initialize OpenData to zero + + *MacBindingHandle = (NDIS_HANDLE)NewOpenP; + return NDIS_STATUS_SUCCESS; +#undef AdaptP +} + + + +// +// MacCloseAdapter +// +// NDIS function +// + +static +NDIS_STATUS +TestMacCloseAdapter( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle + ) +{ +#define OpenP ((POPEN_BLOCK)MacBindingHandle) + PADAPTER_BLOCK AdaptP = OpenP->AdapterBlock; + POPEN_BLOCK TmpOpenP; + + RequestHandle; + + if (OpenP->Debug) + DbgPrint("--> TestMacCloseAdapter %d\n", AdaptP->AdapterNumber); + + // first zap us off the multicast address list + TestMacKillMulticastAddresses(AdaptP, OpenP->MulticastBit); + + // now remove us from the list of opens for this adapter + NdisAcquireSpinLock(&AdaptP->MacBlock->SpinLock); + + // take us off active list + if (OpenP == AdaptP->OpenQueue) + AdaptP->OpenQueue = OpenP->NextOpen; + else { + TmpOpenP = AdaptP->OpenQueue; + while (TmpOpenP->NextOpen != OpenP) + TmpOpenP = TmpOpenP->NextOpen; + TmpOpenP->NextOpen = OpenP->NextOpen; + } + + // put us on free list + OpenP->NextOpen = AdaptP->FreeOpenQueue; + AdaptP->FreeOpenQueue = OpenP; + + --(AdaptP->NumOpens); + NdisReleaseSpinLock(&AdaptP->MacBlock->SpinLock); + + return NDIS_STATUS_SUCCESS; +#undef OpenP +} + + + + +// +// MacSetPacketFilter +// +// NDIS function +// +// - set appropriate bits in the adapter filters +// - modify the card Receive Configuration Register if needed +// + +static +NDIS_STATUS +TestMacSetPacketFilter( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle, + IN UINT PacketFilter + ) +{ +#define OpenP ((POPEN_BLOCK)MacBindingHandle) + PADAPTER_BLOCK AdaptP = OpenP->AdapterBlock; + MASK BitOn = OpenP->MulticastBit; + MASK BitOff = ~(OpenP->MulticastBit); + + RequestHandle; + + if (OpenP->Debug) + DbgPrint("--> TestMacSetPacketFilter %d\n", AdaptP->AdapterNumber); + + // acquire AdaptP->MulticastSpinLock + TestMacGetMulticastAccess(AdaptP); + + if (PacketFilter & NDIS_PACKET_TYPE_DIRECTED) + AdaptP->DirectedFilter |= BitOn; + else + AdaptP->DirectedFilter &= BitOff; + + if (PacketFilter & NDIS_PACKET_TYPE_MULTICAST) + AdaptP->MulticastFilter |= BitOn; + else + AdaptP->MulticastFilter &= BitOff; + + if (PacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST) + AdaptP->AllMulticastFilter |= BitOn; + else + AdaptP->AllMulticastFilter &= BitOff; + + if (PacketFilter & NDIS_PACKET_TYPE_BROADCAST) + AdaptP->BroadcastFilter |= BitOn; + else + AdaptP->BroadcastFilter &= BitOff; + + if (PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS) + AdaptP->PromiscuousFilter |= BitOn; + else + AdaptP->PromiscuousFilter &= BitOff; + + NdisReleaseSpinLock(&AdaptP->MulticastSpinLock); + + return NDIS_STATUS_SUCCESS; +#undef OpenP +} + + + +// +// MacAddMulticastAddress +// +// NDIS function +// +// - add the address to the list if needed +// - modify the card multicast registers if needed +// + +static +NDIS_STATUS +TestMacAddMulticastAddress( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle, + IN PSTRING MulticastAddress + ) +{ +#define OpenP ((POPEN_BLOCK)MacBindingHandle) + PADAPTER_BLOCK AdaptP = OpenP->AdapterBlock; + PMULTICAST_ENTRY MCSlot; + + RequestHandle; + + if (OpenP->Debug) + DbgPrint("--> TestMacAddMulticastAddress %d\n", AdaptP->AdapterNumber); + + // acquire AdaptP->MulticastSpinLock + TestMacGetMulticastAccess(AdaptP); + + // see if this address exists in our list + MCSlot = TestMacFindMulticastAddress(AdaptP->MulticastList, + AdaptP->MulticastListSize, MulticastAddress->Buffer); + if (MCSlot == (PMULTICAST_ENTRY)NULL) { + // see if our list is full + if (AdaptP->MulticastListSize == AdaptP->MulticastListMax) { + NdisReleaseSpinLock(&AdaptP->MulticastSpinLock); + return NDIS_MULTICAST_LIST_FULL; + } + // add us at the end + MCSlot = &(AdaptP->MulticastList[AdaptP->MulticastListSize]); + ++(AdaptP->MulticastListSize); + RtlMoveMemory(MCSlot->Address, MulticastAddress->Buffer, ADDRESS_LEN); + MCSlot->ProtocolMask = OpenP->MulticastBit; // so far, only us + } else { + if (MCSlot->ProtocolMask & OpenP->MulticastBit) { + NdisReleaseSpinLock(&AdaptP->MulticastSpinLock); + return NDIS_MULTICAST_EXISTS; + } + MCSlot->ProtocolMask |= OpenP->MulticastBit; + } + + NdisReleaseSpinLock(&AdaptP->MulticastSpinLock); + + return NDIS_STATUS_SUCCESS; +#undef OpenP +} + + +// +// GetMulticastAccess +// +// - acquire AdaptP->MulticastSpinLock in a lazy fashion +// + +static +VOID +TestMacGetMulticastAccess( + IN PADAPTER_BLOCK AdaptP + ) +{ + for (;;) { + NdisAcquireSpinLock(&AdaptP->MulticastSpinLock); + if (AdaptP->MulticastDontModify) { + NdisReleaseSpinLock(&AdaptP->MulticastSpinLock); + // wait a little bit.. + } else + return; + } +} + + +// just hack this in +static +UINT +ExCompareMemory( + PUCHAR s, + PUCHAR t, + UINT l + ) +{ + UINT i; + + for (i=0; iAddress[4]) + continue; + if (ExCompareMemory(MulticastAddress, List->Address, ADDRESS_LEN) == 0) + return List; + } + return (PMULTICAST_ENTRY)NULL; +} + + +// +// KillMulticastAddresses +// +// removes all multicast entries with MulticastBit on +// +// - called when an open is closed +// - if this is the last reference to an entry, remove it +// + +static +VOID +TestMacKillMulticastAddresses( + IN PADAPTER_BLOCK AdaptP, + IN MASK MulticastBit + ) +{ + PMULTICAST_ENTRY List = AdaptP->MulticastList; + PMULTICAST_ENTRY End = &List[AdaptP->MulticastListSize]; + PMULTICAST_ENTRY Dest; + + // acquire AdaptP->MulticastSpinLock + TestMacGetMulticastAccess(AdaptP); + + Dest = List; + while (List < End) { + List->ProtocolMask &= ~MulticastBit; + if (List->ProtocolMask != 0) { + if (Dest < List) + RtlMoveMemory(Dest, List, sizeof(MULTICAST_ENTRY)); + ++Dest; + } + ++List; + } + AdaptP->MulticastListSize = Dest - AdaptP->MulticastList; + + NdisReleaseSpinLock(&AdaptP->MulticastSpinLock); +} + + + +// +// MacDeleteMulticastAddress +// +// NDIS function +// + +static +NDIS_STATUS +TestMacDeleteMulticastAddress( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle, + IN PSTRING MulticastAddress + ) +{ +#define OpenP ((POPEN_BLOCK)MacBindingHandle) + PADAPTER_BLOCK AdaptP = OpenP->AdapterBlock; + PMULTICAST_ENTRY MCSlot; + + RequestHandle; + + if (OpenP->Debug) + DbgPrint("--> TestMacDeleteMulticastAddress %d\n", AdaptP->AdapterNumber); + + // acquire AdaptP->MulticastSpinLock + TestMacGetMulticastAccess(AdaptP); + + MCSlot = TestMacFindMulticastAddress(AdaptP->MulticastList, + AdaptP->MulticastListSize, MulticastAddress->Buffer); + if (MCSlot == (PMULTICAST_ENTRY)NULL) { + NdisReleaseSpinLock(&AdaptP->MulticastSpinLock); + return NDIS_MULTICAST_NOT_FOUND; + } else { + if (!(MCSlot->ProtocolMask & OpenP->MulticastBit)) { + NdisReleaseSpinLock(&AdaptP->MulticastSpinLock); + return NDIS_MULTICAST_NOT_FOUND; + } else { + MCSlot->ProtocolMask &= ~(OpenP->MulticastBit); + if (MCSlot->ProtocolMask == 0) { // nobody using it + // remove this entry from the list + --(AdaptP->MulticastListSize); + if (MCSlot != &AdaptP->MulticastList[AdaptP->MulticastListSize]) + RtlMoveMemory(MCSlot, + &AdaptP->MulticastList[AdaptP->MulticastListSize], + sizeof(MULTICAST_ENTRY)); + } + } + } + NdisReleaseSpinLock(&AdaptP->MulticastSpinLock); + + return NDIS_STATUS_SUCCESS; +#undef OpenP +} + + + +// +// MacSend +// +// NDIS function +// + +static +NDIS_STATUS +TestMacSend( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle, + IN PNDIS_PACKET Packet + ) +{ +#define OpenP ((POPEN_BLOCK)MacBindingHandle) + PADAPTER_BLOCK AdaptP = ((POPEN_BLOCK)MacBindingHandle)->AdapterBlock; + PMAC_RESERVED Reserved = RESERVED(Packet); + + if (OpenP->Debug) + DbgPrint("--> TestMacSend %d\n", AdaptP->AdapterNumber); + + if (OpenP->Debug) { + UCHAR Buf[80]; + UINT Len; + Len = TestMacCopyOver(Buf, Packet, 0, 80); + DbgPrint("Message <%.*s>\n", Len, Buf); + } + + Reserved->RequestHandle = RequestHandle; + Reserved->OpenBlock = (POPEN_BLOCK)MacBindingHandle; + Reserved->NextPacket = (PNDIS_PACKET)NULL; + TestMacSetLoopbackFlag(Packet); + + if (Reserved->Loopback) { + Reserved->Status = 1; + NdisAcquireSpinLock(&AdaptP->LoopbackSpinLock); + TestMacLoopbackPacket(AdaptP, Packet); + NdisReleaseSpinLock(&AdaptP->LoopbackSpinLock); + } + + return NDIS_STATUS_PENDING; // will complete when looped back +#undef OpenP +} + + +// +// SetLoopbackFlag +// +// sets the loopback flag in the reserved section of a packet +// if it has a multicast destination address +// + +static +VOID +TestMacSetLoopbackFlag( + IN OUT PNDIS_PACKET Packet + ) +{ + UINT Dummy; + PNDIS_BUFFER FirstBuf; + PVOID BufVA; + PMAC_RESERVED Reserved = RESERVED(Packet); + +#if 0 + NdisQueryPacket(Packet, NULL, &Dummy, &FirstBuf, NULL); + NdisQueryBuffer(FirstBuf, NULL, &BufVA, &Dummy); + Reserved->Loopback = (BOOLEAN)((((PUCHAR)BufVA)[0] & 1) != 0); +#else + Dummy; FirstBuf; BufVA; + Reserved->Loopback = TRUE; +#endif +} + + +// +// LoopbackPacket +// +// put a packet on the loopback queue +// +// - call this with LoopbackSpinLock held +// +// + +static +VOID +TestMacLoopbackPacket( + IN PADAPTER_BLOCK AdaptP, + IN OUT PNDIS_PACKET Packet + ) +{ + PMAC_RESERVED Reserved = RESERVED(Packet); + + if (AdaptP->LoopbackQueue == (PNDIS_PACKET)NULL) { + AdaptP->LoopbackQueue = Packet; + AdaptP->LoopbackQTail = Packet; + } else { + PMAC_RESERVED Res2 = RESERVED(AdaptP->LoopbackQTail); + Res2->NextPacket = Packet; + AdaptP->LoopbackQTail = Packet; + } + Reserved->NextPacket = (PNDIS_PACKET)NULL; + + if (!AdaptP->DpcQueued) { + AdaptP->DpcQueued = TRUE; + KeInsertQueueDpc(&AdaptP->IndicateDpc, NULL, NULL); + } +} + + + +// +// IndicateLoopbackPacket +// +// indicates a loopback packet to the protocols +// +// - the protocol must want to receive multicast/broadcast packets +// - the address must be on his multicast list +// + +static +VOID +TestMacIndicateLoopbackPacket( + IN PADAPTER_BLOCK AdaptP, + IN PNDIS_PACKET Packet + ) +{ + PMULTICAST_ENTRY MCSlot; + POPEN_BLOCK CurOpen; + MASK EffectiveMask; + UINT IndicateLen; + UINT PacketLen; + NDIS_STATUS Status; + + // copy destination address of packet into AdaptP->Lookahead + if (TestMacCopyOver(AdaptP->Lookahead, Packet, 0, ADDRESS_LEN) < ADDRESS_LEN) { + return; + // error, runt packet + } + + NdisAcquireSpinLock(&AdaptP->MulticastSpinLock); + AdaptP->MulticastDontModify = TRUE; + NdisReleaseSpinLock(&AdaptP->MulticastSpinLock); + + if (AdaptP->Lookahead[0] & 1) { + // if bit x in EffectiveMask is on, the protocol x wants this packet + MCSlot = TestMacFindMulticastAddress(AdaptP->MulticastList, + AdaptP->MulticastListSize, AdaptP->Lookahead); + if (MCSlot == (PMULTICAST_ENTRY)NULL) + EffectiveMask = AdaptP->MulticastFilter | AdaptP->PromiscuousFilter; + else if (MCSlot == &AdaptP->MulticastList[0]) // broadcast + EffectiveMask = AdaptP->BroadcastFilter | AdaptP->PromiscuousFilter; + else + EffectiveMask = MCSlot->ProtocolMask & + (AdaptP->MulticastFilter | AdaptP->AllMulticastFilter | + AdaptP->PromiscuousFilter); + } else { + EffectiveMask = AdaptP->DirectedFilter | AdaptP->PromiscuousFilter; + } + + // as long as somebody wants it, indicate it + if (EffectiveMask != 0) { + PacketLen = TestMacPacketSize(Packet); + IndicateLen = (PacketLen > 256) ? 256 : PacketLen; + // copy the lookahead data into a contiguous buffer + TestMacCopyOver(AdaptP->Lookahead+ADDRESS_LEN, + Packet, ADDRESS_LEN, IndicateLen-ADDRESS_LEN); + CurOpen = AdaptP->OpenQueue; + while (CurOpen) { + if (CurOpen->MulticastBit & EffectiveMask) { + NdisIndicateReceive(&Status, + CurOpen->NdisBindingContext, + (NDIS_HANDLE)AdaptP, + AdaptP->Lookahead, + IndicateLen, + PacketLen); + } + CurOpen = CurOpen->NextOpen; + } + } + + NdisAcquireSpinLock(&AdaptP->MulticastSpinLock); + AdaptP->MulticastDontModify = FALSE; + NdisReleaseSpinLock(&AdaptP->MulticastSpinLock); +} + + +// +// PacketSize +// +// returns the number of bytes of data in a packet +// + +static +UINT +TestMacPacketSize( + IN PNDIS_PACKET Packet + ) +{ + PNDIS_BUFFER CurBuffer; + UINT Dummy; + UINT BufLen; + UINT TotLen; + + TotLen = 0; + NdisQueryPacket(Packet, NULL, &Dummy, &CurBuffer, NULL); + while (CurBuffer != (PNDIS_BUFFER)NULL) { + NdisQueryBuffer(CurBuffer, NULL, NULL, &BufLen); + TotLen += BufLen; + NdisGetNextBuffer(CurBuffer, &CurBuffer); + } + return TotLen; +} + + +// +// CopyOver +// +// copy bytes from a packet into a buffer +// +// - returns the actual number of bytes copied +// + +static +UINT +TestMacCopyOver( + OUT PUCHAR Buf, // destination + IN PNDIS_PACKET Packet, // source packet + IN UINT Offset, // offset in packet + IN UINT Length // number of bytes to copy + ) +{ + PNDIS_BUFFER CurBuffer; + UINT Dummy; + UINT BytesCopied; + PUCHAR BufVA; + UINT BufLen; + UINT ToCopy; + UINT CurOffset; + + BytesCopied = 0; + // first move to Offset bytes into the packet + CurOffset = 0; + NdisQueryPacket(Packet, NULL, &Dummy, &CurBuffer, NULL); + while (CurBuffer != (PNDIS_BUFFER)NULL) { + NdisQueryBuffer(CurBuffer, NULL, (PVOID *) &BufVA, &BufLen); + if (CurOffset + BufLen > Offset) + break; + CurOffset += BufLen; + NdisGetNextBuffer(CurBuffer, &CurBuffer); + } + // see if we went off the end of the packet + if (CurBuffer == (PNDIS_BUFFER)NULL) + return 0; + // now copy over Length bytes + BufVA += (Offset - CurOffset); + BufLen -= (Offset - CurOffset); + for (;;) { + ToCopy = (BytesCopied+BufLen > Length) ? Length - BytesCopied : BufLen; + RtlMoveMemory(Buf+BytesCopied, BufVA, ToCopy); + BytesCopied += ToCopy; + if (BytesCopied == Length) + return BytesCopied; + NdisGetNextBuffer(CurBuffer, &CurBuffer); + if (CurBuffer == (PNDIS_BUFFER)NULL) + break; + NdisQueryBuffer(CurBuffer, NULL, (PVOID *) &BufVA, &BufLen); + } + return BytesCopied; +} + + + +// +// NdisTransferData +// +// NDIS function +// +// - AdaptP->LoopbackPacket will be FALSE if this is for a normal +// indication, otherwise it will point to a loopback packet +// + +static +NDIS_STATUS +TestMacTransferData( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle, + IN NDIS_HANDLE MacReceiveContext, + IN UINT ByteOffset, + IN UINT BytesToTransfer, + OUT PNDIS_PACKET Packet, + OUT PUINT BytesTransferred + ) +{ +#define OpenP ((POPEN_BLOCK)MacBindingHandle) +#define AdaptP ((PADAPTER_BLOCK)MacReceiveContext) + + RequestHandle; ByteOffset; BytesToTransfer; Packet; BytesTransferred; + + if (OpenP->Debug) + DbgPrint("--> TestMacTransferData %d\n", AdaptP->AdapterNumber); + + if (AdaptP->LoopbackPacket != (PNDIS_PACKET)NULL) { + PNDIS_BUFFER CurBuffer; + UINT Dummy; + PUCHAR BufVA; + UINT BufLen, Copied; + UINT CurOff; + + // have to copy data from AdaptP->LoopbackPacket into Packet + NdisQueryPacket(Packet, NULL, &Dummy, &CurBuffer, NULL); + CurOff = ByteOffset; + while (CurBuffer != (PNDIS_BUFFER)NULL) { + NdisQueryBuffer(CurBuffer, NULL, (PVOID *) &BufVA, &BufLen); + Copied = TestMacCopyOver(BufVA, AdaptP->LoopbackPacket, + CurOff, BufLen); + CurOff += Copied; + if (Copied < BufLen) + break; + NdisGetNextBuffer(CurBuffer, &CurBuffer); + } + *BytesTransferred = CurOff - ByteOffset; + } + + return NDIS_STATUS_SUCCESS; +#undef AdaptP +#undef OpenP +} + + + +// +// MacQueryInformation +// +// NDIS function +// + +static +NDIS_STATUS +TestMacQueryInformation( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle, + IN NDIS_INFORMATION_CLASS InformationClass, + OUT PVOID Buffer, + IN UINT BufferLength + ) +{ +#define OpenP ((POPEN_BLOCK)MacBindingHandle) + PADAPTER_BLOCK AdaptP = OpenP->AdapterBlock; + UINT i; + static UCHAR StationAddress[] = { 0x00, 0x00, 0x00, 0x01, 0x02, 0x03 }; + + RequestHandle; InformationClass; Buffer; BufferLength; + + if (OpenP->Debug) + DbgPrint("--> TestMacQueryInformation %d\n", AdaptP->AdapterNumber); + + + switch (InformationClass) { + + case NdisInfoStationAddress: + RtlMoveMemory(Buffer, StationAddress, 6); + break; + + } + +#if 0 + if ((UINT)InformationClass == 1) { + // show multicast list + PMULTICAST_ENTRY MCSlot, End; + POPEN_BLOCK CurOpen; + PUCHAR Tcp; + + NdisAcquireSpinLock(&AdaptP->MulticastSpinLock); + AdaptP->MulticastDontModify = TRUE; + NdisReleaseSpinLock(&AdaptP->MulticastSpinLock); + + MCSlot = AdaptP->MulticastList; + End = &AdaptP->MulticastList[AdaptP->MulticastListSize]; + while (MCSlot < End) { + Tcp = MCSlot->Address; + for (i=0; i<6; i++) { + if (Tcp[i] >= ' ' && Tcp[i] <= 'z') + DbgPrint(" %c ", Tcp[i]); + else + DbgPrint("%2x ", Tcp[i]); + } + CurOpen = AdaptP->OpenQueue; + while (CurOpen != (POPEN_BLOCK)NULL) { + if (CurOpen->MulticastBit & MCSlot->ProtocolMask) + DbgPrint(CurOpen == OpenP ? " X" : " x"); + else + DbgPrint(" "); + CurOpen = CurOpen->NextOpen; + } + DbgPrint("\n"); + ++MCSlot; + } + + NdisAcquireSpinLock(&AdaptP->MulticastSpinLock); + AdaptP->MulticastDontModify = FALSE; + NdisReleaseSpinLock(&AdaptP->MulticastSpinLock); + } +#else + i; +#endif + + return NDIS_STATUS_SUCCESS; +#undef OpenP +} + + + +// +// MacSetInformation +// +// NDIS function +// + +static +NDIS_STATUS +TestMacSetInformation( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle, + IN NDIS_INFORMATION_CLASS InformationClass, + IN PVOID Buffer, + IN UINT BufferLength + ) +{ +#define OpenP ((POPEN_BLOCK)MacBindingHandle) + PADAPTER_BLOCK AdaptP = OpenP->AdapterBlock; + + RequestHandle; InformationClass; Buffer; BufferLength; + + if (OpenP->Debug) + DbgPrint("--> TestMacSetInformation %d\n", AdaptP->AdapterNumber); + + // this will involve the OpenData and AdapterData structures + + return NDIS_STATUS_SUCCESS; +#undef OpenP +} + + + +// +// MacReset +// +// NDIS function +// + +static +NDIS_STATUS +TestMacReset( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle + ) +{ +#define OpenP ((POPEN_BLOCK)MacBindingHandle) + PADAPTER_BLOCK AdaptP = OpenP->AdapterBlock; + POPEN_BLOCK TmpOpenP; + + RequestHandle; + + if (OpenP->Debug) + DbgPrint("--> TestMacReset %d\n", AdaptP->AdapterNumber); + + TmpOpenP = AdaptP->OpenQueue; + while (TmpOpenP != (POPEN_BLOCK)NULL) { + NdisIndicateStatus(TmpOpenP->NdisBindingContext, NDIS_STATUS_RESET, 0); + TmpOpenP = TmpOpenP->NextOpen; + } + + return NDIS_STATUS_SUCCESS; +#undef OpenP +} + + + +// +// MacTest +// +// NDIS function +// + +static +NDIS_STATUS +TestMacTest( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle + ) +{ +#define OpenP ((POPEN_BLOCK)MacBindingHandle) + PADAPTER_BLOCK AdaptP = OpenP->AdapterBlock; + + RequestHandle; + + if (OpenP->Debug) + DbgPrint("--> TestMacTest %d\n", AdaptP->AdapterNumber); + + return NDIS_STATUS_SUCCESS; +#undef OpenP +} + + +static +VOID +TestMacIndicateDpc( + IN PKDPC Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2 + ) +{ +#define AdaptP ((PADAPTER_BLOCK)DeferredContext) + PNDIS_PACKET LPacket; + PMAC_RESERVED Reserved; + POPEN_BLOCK CurOpen; + + UNREFERENCED_PARAMETER(Dpc); + UNREFERENCED_PARAMETER(SystemArgument1); + UNREFERENCED_PARAMETER(SystemArgument2); + + // loopback any waiting packets + NdisAcquireSpinLock(&AdaptP->LoopbackSpinLock); + while (AdaptP->LoopbackQueue) { + // take the first packet off the queue + LPacket = AdaptP->LoopbackQueue; + Reserved = RESERVED(LPacket); + AdaptP->LoopbackQueue = RESERVED(AdaptP->LoopbackQueue)->NextPacket; + NdisReleaseSpinLock(&AdaptP->LoopbackSpinLock); + AdaptP->LoopbackPacket = LPacket; + // actually indicate it + TestMacIndicateLoopbackPacket(AdaptP, AdaptP->LoopbackPacket); + NdisAcquireSpinLock(&AdaptP->LoopbackSpinLock); + // complete the packet if needed + if (Reserved->RequestHandle != 0) { + NdisCompleteSend( + Reserved->OpenBlock->NdisBindingContext, + Reserved->RequestHandle, + NDIS_STATUS_SUCCESS); + } + } + AdaptP->DpcQueued = FALSE; + NdisReleaseSpinLock(&AdaptP->LoopbackSpinLock); + + // indicate ReceiveComplete + CurOpen = AdaptP->OpenQueue; + while (CurOpen) { + NdisIndicateReceiveComplete(CurOpen->NdisBindingContext); + CurOpen = CurOpen->NextOpen; + } + +#undef AdaptP +} diff --git a/private/ntos/ndis/testmac/testmac.h b/private/ntos/ndis/testmac/testmac.h new file mode 100644 index 000000000..750bb213e --- /dev/null +++ b/private/ntos/ndis/testmac/testmac.h @@ -0,0 +1,349 @@ + +/*++ + +Copyright (c) 1990 Microsoft Corporation + +Module Name: + + testmac.h + +Abstract: + + Definitions for test MAC. + Motsly taken from the Elnkii code spec. + +Author: + + Adam Barr (adamba) 16-Jul-1990 + +Revision History: + +--*/ + +#define AllocPhys(s) ExAllocatePool(NonPagedPool, s) +#define FreePhys(s) ExFreePool(s) + +#define ADDRESS_LEN 6 + +typedef ULONG MASK; + +UCHAR BroadcastAddress[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + + +// only have one of these structures + +typedef struct _MAC_BLOCK { + // NDIS information + NDIS_HANDLE NdisMacHandle; // returned from NdisRegisterMac + NDIS_MAC_CHARACTERISTICS MacCharacteristics; + UCHAR MacName[8]; + // adapters registered for us + UINT NumAdapters; + struct _ADAPTER_BLOCK * AdapterQueue; + // should we be verbose + BOOLEAN Debug; + // NT specific + PDRIVER_OBJECT DriverObject; + KPOWER_STATUS PowerStatus; + BOOLEAN PowerBoolean; + NDIS_SPIN_LOCK SpinLock; // guards NumAdapter and AdapterQueue +} MAC_BLOCK, * PMAC_BLOCK; + + +// the multicast address list consists of these +typedef struct _MULTICAST_ENTRY { + UCHAR Address[ADDRESS_LEN]; + MASK ProtocolMask; // determines which opens it applies to +} MULTICAST_ENTRY, * PMULTICAST_ENTRY; + +// one of these per adapter registered + +typedef struct _ADAPTER_BLOCK { + // NDIS information + NDIS_HANDLE NdisAdapterHandle; // returned from NdisRegisterAdapter + PSTRING AdapterName; + // used to mark us + UINT AdapterNumber; + // links with our MAC + PMAC_BLOCK MacBlock; + struct _ADAPTER_BLOCK * NextAdapter; // used by MacBlock->OpenQueue + // opens for this adapter + UINT MaxOpens; // maximum number + struct _OPEN_BLOCK * OpenBlocks; // storage for MaxOpens OPEN_BLOCKs + UINT NumOpens; + struct _OPEN_BLOCK * OpenQueue; + struct _OPEN_BLOCK * FreeOpenQueue; + // should we be verbose + BOOLEAN Debug; + // PROTOCOL.INI information + UINT MulticastListMax; + // these are for the current packet + UCHAR PacketHeader[4]; + UCHAR Lookahead[256]; + UINT PacketLen; + // receive information + UINT MulticastListSize; // current size + PMULTICAST_ENTRY MulticastList; + NDIS_SPIN_LOCK MulticastSpinLock; // guards all data in this section + BOOLEAN MulticastDontModify; // an extended spinlock + MASK MulticastFilter; // these filters work as explained + MASK DirectedFilter; // in the design note + MASK BroadcastFilter; + MASK PromiscuousFilter; + MASK AllMulticastFilter; + // loopback information + PNDIS_PACKET LoopbackQueue; + PNDIS_PACKET LoopbackQTail; + NDIS_SPIN_LOCK LoopbackSpinLock; + PNDIS_PACKET LoopbackPacket; + // NT specific + PKINTERRUPT Interrupt; + KDPC IndicateDpc; + BOOLEAN DpcQueued; +} ADAPTER_BLOCK, * PADAPTER_BLOCK; + +// general macros +#define MSB(value) ((UCHAR)((value) << 8)) +#define LSB(value) ((UCHAR)((value) && 0xff)) + +// one of these per open on the adapter + +typedef struct _OPEN_BLOCK { + // NDIS information + NDIS_HANDLE NdisBindingContext; // passed to MacOpenAdapter + PSTRING AddressingInformation; // not used currently + // links to our adapter + PADAPTER_BLOCK AdapterBlock; + struct _OPEN_BLOCK * NextOpen; + // links to our MAC + PMAC_BLOCK MacBlock; // faster than using AdapterBlock->MacBlock + // should we be verbose + BOOLEAN Debug; + // used for multicast addresses + MASK MulticastBit; +} OPEN_BLOCK, * POPEN_BLOCK; + + + +// the reserved section of a packet + +typedef struct _MAC_RESERVED { // can't be more than 16 bytes + PNDIS_PACKET NextPacket; // used to in the transmit queue (4 bytes) + NDIS_HANDLE RequestHandle; // for async send completion (4 bytes) + POPEN_BLOCK OpenBlock; // so we know who to complete to (4 bytes) + USHORT Status; // completion status (2 bytes) + BOOLEAN Loopback; // is this a loopback packet (1 byte) + BOOLEAN ReadyToComplete; // is one out of xmit or loopback done (1 byte) +} MAC_RESERVED, * PMAC_RESERVED; + +// macro to retrieve the MAC_RESERVED structure from a packet +#define RESERVED(Packet) ((PMAC_RESERVED)((Packet)->MacReserved)) + +extern MAC_BLOCK GlobalMacBlock; + + +// +// function prototypes +// + + +NTSTATUS +TestMacInitialize( + IN PDRIVER_OBJECT DriverObject + ); + + +static +NTSTATUS +TestMacDispatch( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + + +static +NDIS_STATUS +TestMacRegisterAdapter( + IN PSTRING AdapterName, + IN UINT AdapterNumber + ); + + +static +NDIS_STATUS +TestMacOpenAdapter( + OUT NDIS_HANDLE * MacBindingHandle, + IN NDIS_HANDLE RequestHandle, + IN NDIS_HANDLE NdisBindingContext, + IN NDIS_HANDLE MacAdapterContext, + IN PSTRING AddressingInformation OPTIONAL + ); + + +static +NDIS_STATUS +TestMacCloseAdapter( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle + ); + + +static +NDIS_STATUS +TestMacSetPacketFilter( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle, + IN UINT PacketFilter + ); + + +static +NDIS_STATUS +TestMacAddMulticastAddress( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle, + IN PSTRING MulticastAddress + ); + + +static +VOID +TestMacGetMulticastAccess( + IN PADAPTER_BLOCK AdaptP + ); + + +static +PMULTICAST_ENTRY +TestMacFindMulticastAddress( + IN PMULTICAST_ENTRY List, + IN UINT Size, + IN PUCHAR MulticastAddress + ); + + +static +VOID +TestMacKillMulticastAddresses( + IN PADAPTER_BLOCK AdaptP, + IN MASK MulticastBit + ); + + +static +NDIS_STATUS +TestMacDeleteMulticastAddress( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle, + IN PSTRING MulticastAddress + ); + + +static +NDIS_STATUS +TestMacSend( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle, + IN PNDIS_PACKET Packet + ); + + +static +VOID +TestMacSetLoopbackFlag( + IN OUT PNDIS_PACKET Packet + ); + + +static +VOID +TestMacLoopbackPacket( + IN PADAPTER_BLOCK AdaptP, + IN OUT PNDIS_PACKET Packet + ); + + +static +VOID +TestMacIndicateLoopbackPacket( + IN PADAPTER_BLOCK AdaptP, + IN PNDIS_PACKET Packet + ); + + +static +UINT +TestMacPacketSize( + IN PNDIS_PACKET Packet + ); + + +static +UINT +TestMacCopyOver( + OUT PUCHAR Buf, + IN PNDIS_PACKET Packet, + IN UINT Offset, + IN UINT Length + ); + + +static +NDIS_STATUS +TestMacTransferData( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle, + IN NDIS_HANDLE MacReceiveContext, + IN UINT ByteOffset, + IN UINT BytesToTransfer, + OUT PNDIS_PACKET Packet, + OUT PUINT BytesTransferred + ); + + +static +NDIS_STATUS +TestMacQueryInformation( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle, + IN NDIS_INFORMATION_CLASS InformationClass, + OUT PVOID Buffer, + IN UINT BufferLength + ); + + +static +NDIS_STATUS +TestMacSetInformation( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle, + IN NDIS_INFORMATION_CLASS InformationClass, + IN PVOID Buffer, + IN UINT BufferLength + ); + + +static +NDIS_STATUS +TestMacReset( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle + ); + + +static +NDIS_STATUS +TestMacTest( + IN NDIS_HANDLE MacBindingHandle, + IN NDIS_HANDLE RequestHandle + ); + + +static +VOID +TestMacIndicateDpc( + IN PKDPC Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2 + ); -- cgit v1.2.3