Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

576 lines
12 KiB

/*++
Copyright (c) 1990-1995 Microsoft Corporation
Module Name:
Miniport.c
Abstract:
This file contains the procedures that makeup most of the NDIS 3.1
Miniport interface.
Author:
Tony Bell (TonyBe) June 06, 1995
Environment:
Kernel Mode
Revision History:
TonyBe 06/06/95 Created
--*/
#include "wan.h"
//
// Local function prototypes
//
#ifndef USE_NDIS_MINIPORT_CALLBACK
VOID
DeferredTimerFunction(
PVOID System1,
PADAPTERCB AdapterCB,
PVOID System2,
PVOID System3
);
#endif // end of !USE_NDIS_MINIPORT_CALLBACK
//
// End local function prototypes
//
BOOLEAN
NdisWanCheckForHang(
IN NDIS_HANDLE MiniportAdapterContext
)
/*++
Routine Name:
NdisWanCheckForHang
Routine Description:
This routine checks to see is this adapter needs to be reset, and if it
does the return value is set to TRUE. I can't think of any reason that
we might use this right now, but I'm sure that there will be.
Arguments:
MiniportAdapterContext - AdapterContext that is given to the wrapper in
NdisMSetAttributes call. Is our AdapterCB.
Return Values:
TRUE - Reset Adapter
FALSE - Don't reset adapter
--*/
{
PADAPTERCB AdapterCB = (PADAPTERCB)MiniportAdapterContext;
BOOLEAN Status = FALSE;
NdisWanInterlockedInc(&AdapterCB->ulReferenceCount);
//
// Does this adapter need to be reset?
//
if (AdapterCB->Flags & ASK_FOR_RESET) {
Status = TRUE;
}
NdisWanInterlockedDec(&AdapterCB->ulReferenceCount);
return (Status);
}
VOID
NdisWanHalt(
IN NDIS_HANDLE MiniportAdapterContext
)
/*++
Routine Name:
NdisWanHalt
Routine Description:
This routine free's all resources for the adapter.
Arguments:
MiniportAdapterContext - AdapterContext that is given to the wrapper in
NdisMSetAttributes call. Is our AdapterCB.
Return Values:
None
--*/
{
PADAPTERCB AdapterCB = (PADAPTERCB)MiniportAdapterContext;
NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("NdisWanHalt: Enter"));
NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("AdapterCB: 0x%x", AdapterCB));
NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("NdisWanHalt: Exit"));
}
NDIS_STATUS
NdisWanInitialize(
OUT PNDIS_STATUS OpenErrorStatus,
OUT PUINT SelectedMediumIndex,
IN PNDIS_MEDIUM MediumArray,
IN UINT MediumArraySize,
IN NDIS_HANDLE MiniportAdapterHandle,
IN NDIS_HANDLE WrapperConfigurationContext
)
/*++
Routine Name:
NdisWanInitialize
Routine Description:
This routine is called after NdisWan registers itself as a Miniport driver.
It is responsible for installing NdisWan as a Miniport driver, creating
adapter control blocks for each adapter NdisWan exposes (should only be 1),
and initializing all adapter specific variables
Arguments:
OpenErrorStatus - Returns information about the error if this function
returns NDIS_STATUS_OPEN_ERROR. Used for TokenRing.
SelectedMediumIndex - An index into the MediumArray that specifies the
medium type of this driver. Should be WAN or 802.3
MediumArray - An array of medium types supported by the NDIS library
MediumArraySize - Size of the medium array
MiniportAdapterHandle - Handle assigned by the NDIS library that defines
this miniport driver. Used as handle in subsequent
calls to the NDIS library.
WrapperConfigurationContext - Handle used to read configuration information
from the registry
Return Values:
NDIS_STATUS_ADAPTER_NOT_FOUND
NDIS_STATUS_FAILURE
NDIS_STATUS_NOT_ACCEPTED
NDIS_STATUS_OPEN_ERROR
NDIS_STATUS_RESOURCES
NDIS_STATUS_UNSUPPORTED_MEDIA
--*/
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PADAPTERCB AdapterCB;
UINT Index;
NDIS_HANDLE ConfigHandle;
ULONG NetworkAddressLength;
#ifdef NT
LARGE_INTEGER TickCount, SystemTime;
#endif
NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("NdisWanInitialize: Enter"));
//
// We have to be type 802.3 to the ndis wrapper, but the
// wrapper will expose us to the transports as type wan.
//
for (Index = 0; Index < MediumArraySize; Index++) {
if (MediumArray[Index] == NdisMedium802_3) {
break;
}
}
//
// We don't have a match so we are screwed
//
if (Index == MediumArraySize) {
return (NDIS_STATUS_UNSUPPORTED_MEDIA);
}
*SelectedMediumIndex = Index;
//
// Allocate and initialize miniport adapter structure
//
#ifdef MINIPORT_NAME
Status = NdisWanCreateAdapterCB(&AdapterCB, &((PNDIS_MINIPORT_BLOCK)(MiniportAdapterHandle))->MiniportName);
#else
Status = NdisWanCreateAdapterCB(&AdapterCB, NULL);
#endif
if (Status != NDIS_STATUS_SUCCESS) {
NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MINIPORT,
("Error Creating AdapterCB! Status: 0x%x - %s",
Status, NdisWanGetNdisStatus(Status)));
return (NDIS_STATUS_FAILURE);
}
NdisMSetAttributesEx(MiniportAdapterHandle,
AdapterCB,
(UINT)-1,
NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT |
NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT,
NdisInterfaceInternal);
AdapterCB->MediumType = MediumArray[Index];
AdapterCB->ulReferenceCount = 0;
AdapterCB->hMiniportHandle = MiniportAdapterHandle;
NdisOpenConfiguration(&Status,
&ConfigHandle,
WrapperConfigurationContext);
if (Status == NDIS_STATUS_SUCCESS) {
NdisReadNetworkAddress(&Status,
(PVOID*)&(AdapterCB->NetworkAddress),
&NetworkAddressLength,
ConfigHandle);
NdisCloseConfiguration(ConfigHandle);
if (Status != NDIS_STATUS_SUCCESS ||
NetworkAddressLength != ETH_LENGTH_OF_ADDRESS) {
goto BuildAddress;
}
} else {
BuildAddress:
#ifdef NT
KeQueryTickCount(&TickCount);
KeQuerySystemTime(&SystemTime);
AdapterCB->NetworkAddress[0] = (UCHAR)((TickCount.LowPart >> 16) ^
(SystemTime.LowPart >> 16)) &
0xFE;
AdapterCB->NetworkAddress[1] = (UCHAR)((TickCount.LowPart >> 8) ^
(SystemTime.LowPart >> 8));
AdapterCB->NetworkAddress[2] = (UCHAR)(TickCount.LowPart ^
SystemTime.LowPart);
//
// The following three bytes will be filled in at lineup time
//
AdapterCB->NetworkAddress[3] = 0x00;
AdapterCB->NetworkAddress[4] = 0x00;
AdapterCB->NetworkAddress[5] = 0x00;
#endif
}
#ifndef USE_NDIS_MINIPORT_CALLBACK
NdisMInitializeTimer(&AdapterCB->DeferredTimer,
AdapterCB->hMiniportHandle,
DeferredTimerFunction,
AdapterCB);
#endif // end of !USE_NDIS_MINIPORT_CALLBACK
NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("NdisWanInitialize: Exit"));
return (NDIS_STATUS_SUCCESS);
}
NDIS_STATUS
NdisWanQueryInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesWritten,
OUT PULONG BytesNeeded
)
/*++
Routine Name:
Routine Description:
Arguments:
Return Values:
--*/
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PADAPTERCB AdapterCB = (PADAPTERCB)MiniportAdapterContext;
NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("NdisWanQueryInformation: Enter Oid: 0x%4.4x", Oid));
NdisWanInterlockedInc(&AdapterCB->ulReferenceCount);
Status = NdisWanOidProc(AdapterCB,
Oid,
QUERY_OID,
InformationBuffer,
InformationBufferLength,
BytesWritten,
BytesNeeded);
NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("NdisWanQueryInformation: Exit"));
NdisWanInterlockedDec(&AdapterCB->ulReferenceCount);
return (Status);
}
NDIS_STATUS
NdisWanReconfigure(
OUT PNDIS_STATUS OpenErrorStatus,
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_HANDLE WrapperConfigurationContext
)
/*++
Routine Name:
Routine Description:
Arguments:
Return Values:
--*/
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PADAPTERCB AdapterCB = (PADAPTERCB)MiniportAdapterContext;
NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("NdisWanReconfigure: Enter"));
NdisWanInterlockedInc(&AdapterCB->ulReferenceCount);
NdisWanInterlockedDec(&AdapterCB->ulReferenceCount);
NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("NdisWanReconfigure: Exit"));
return (Status);
}
NDIS_STATUS
NdisWanReset(
OUT PBOOLEAN AddressingReset,
IN NDIS_HANDLE MiniportAdapterContext
)
/*++
Routine Name:
Routine Description:
Arguments:
Return Values:
--*/
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PADAPTERCB AdapterCB = (PADAPTERCB)MiniportAdapterContext;
NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("NdisWanReset: Enter"));
DbgPrint("NDISWAN: Resest for Adapter: 0x%8.8x\n", AdapterCB);
NdisWanInterlockedInc(&AdapterCB->ulReferenceCount);
AdapterCB->Flags &= ~ASK_FOR_RESET;
NdisWanInterlockedDec(&AdapterCB->ulReferenceCount);
NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("NdisWanReset: Exit"));
return (Status);
}
NDIS_STATUS
NdisWanSetInformation(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_OID Oid,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesWritten,
OUT PULONG BytesNeeded
)
/*++
Routine Name:
Routine Description:
Arguments:
Return Values:
--*/
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PADAPTERCB AdapterCB = (PADAPTERCB)MiniportAdapterContext;
NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("NdisWanSetInformation: Enter Oid: 0x%4.4x", Oid));
NdisWanInterlockedInc(&AdapterCB->ulReferenceCount);
Status = NdisWanOidProc(AdapterCB,
Oid,
SET_OID,
InformationBuffer,
InformationBufferLength,
BytesWritten,
BytesNeeded);
NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("NdisWanSetInformation: Exit"));
NdisWanInterlockedDec(&AdapterCB->ulReferenceCount);
return (Status);
}
#ifdef USE_NDIS_MINIPORT_CALLBACK
VOID
DeferredCallback(
PADAPTERCB AdapterCB,
PVOID Context
)
{
BOOLEAN Again;
ULONG Type = (ULONG)Context;
NdisAcquireSpinLock(&AdapterCB->Lock);
NdisWanInterlockedInc(&AdapterCB->ulReferenceCount);
do {
Again = FALSE;
//
// Chec the receive indication queue first
//
if (!IsDeferredQueueEmpty(&AdapterCB->DeferredQueue[ReceiveIndication])) {
NdisWanProcessReceiveIndications(AdapterCB);
Again = TRUE;
}
//
// Check the send complete queue
//
if (!IsDeferredQueueEmpty(&AdapterCB->DeferredQueue[SendComplete])) {
NdisWanProcessSendCompletes(AdapterCB);
Again = TRUE;
}
//
// Check the loopback queue
//
if (!IsDeferredQueueEmpty(&AdapterCB->DeferredQueue[Loopback])) {
NdisWanProcessLoopbacks(AdapterCB);
Again = TRUE;
}
//
// Check the indications queue
//
if (!IsDeferredQueueEmpty(&AdapterCB->DeferredQueue[StatusIndication])) {
NdisWanProcessStatusIndications(AdapterCB);
Again = TRUE;
}
} while (Again);
if (AdapterCB->Flags & RECEIVE_COMPLETE) {
NdisWanDoReceiveComplete(AdapterCB);
AdapterCB->Flags &= ~RECEIVE_COMPLETE;
}
AdapterCB->Flags &= ~DEFERRED_CALLBACK_SET;
NdisReleaseSpinLock(&AdapterCB->Lock);
NdisWanInterlockedDec(&AdapterCB->ulReferenceCount);
}
#else // end of USE_NDIS_MINIPORT_CALLBACK
VOID
DeferredTimerFunction(
PVOID System1,
PADAPTERCB AdapterCB,
PVOID System2,
PVOID System3
)
{
BOOLEAN Again;
NdisAcquireSpinLock(&AdapterCB->Lock);
NdisWanInterlockedInc(&AdapterCB->ulReferenceCount);
do {
Again = FALSE;
//
// Chec the receive indication queue first
//
if (!IsDeferredQueueEmpty(&AdapterCB->DeferredQueue[ReceiveIndication])) {
NdisWanProcessReceiveIndications(AdapterCB);
Again = TRUE;
}
//
// Check the send complete queue
//
if (!IsDeferredQueueEmpty(&AdapterCB->DeferredQueue[SendComplete])) {
NdisWanProcessSendCompletes(AdapterCB);
Again = TRUE;
}
//
// Check the loopback queue
//
if (!IsDeferredQueueEmpty(&AdapterCB->DeferredQueue[Loopback])) {
NdisWanProcessLoopbacks(AdapterCB);
Again = TRUE;
}
//
// Check the indications queue
//
if (!IsDeferredQueueEmpty(&AdapterCB->DeferredQueue[StatusIndication])) {
NdisWanProcessStatusIndications(AdapterCB);
Again = TRUE;
}
} while (Again);
if (AdapterCB->Flags & RECEIVE_COMPLETE) {
NdisWanDoReceiveComplete(AdapterCB);
AdapterCB->Flags &= ~RECEIVE_COMPLETE;
}
AdapterCB->Flags &= ~DEFERRED_TIMER_SET;
NdisReleaseSpinLock(&AdapterCB->Lock);
NdisWanInterlockedDec(&AdapterCB->ulReferenceCount);
}
#endif // end of !USE_NDIS_MINIPORT_CALLBACK