⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adapter.c

📁 ndis windows网络驱动程序的范例
💻 C
📖 第 1 页 / 共 3 页
字号:
/*++

Copyright (c) 1996  Microsoft Corporation

Module Name:

    adapter.c

Abstract:

    routines for binding/unbinding to/from underlying miniport drivers

Author:

    Jim Mateer 4-1-97

Environment:

    Kernel Mode

Revision History:

--*/

#include "ImSamp.h"
#pragma hdrstop

PADAPTER CurrentAdapter;


VOID
BindToLowerMP(
	OUT	PNDIS_STATUS			Status,
	IN	NDIS_HANDLE				BindContext,
	IN	PNDIS_STRING			MPDeviceName,
	IN	PVOID					SystemSpecific1,
	IN	PVOID					SystemSpecific2
	);

STATIC NDIS_STATUS
GetAdapterRegistryData(
    PNDIS_STRING IMParamsKey,
    PADAPTER Adapter
    );


STATIC VOID
ProcessLowerMPOpenAdapter(
    IN  PADAPTER Adapter,
    IN  NDIS_STATUS Status
    );

VOID
LowerMPOpenAdapterComplete(
    IN  NDIS_HANDLE ProtocolBindingContext,
    IN  NDIS_STATUS Status,
    IN  NDIS_STATUS OpenErrorStatus
    );

STATIC NDIS_STATUS
AllocatePacketPool(
    PADAPTER Adapter                   
    );

STATIC NDIS_STATUS
AllocateReceiveBufferPools(
    PADAPTER Adapter
    );

//NDIS_STATUS
//AddPipeToPSA(
//    PADAPTER Adapter
//    );


PADAPTER
FindAdapterByInstanceNumber(
#if BINARY_COMPATIBLE
    CHAR InstanceNumber
#else
    WCHAR InstanceNumber
#endif
    );

PADAPTER
FindAdapterByName(
    PWCHAR AdapterName
    );

NDIS_STATUS
MPInitialize(
	OUT PNDIS_STATUS			OpenErrorStatus,
	OUT PUINT					SelectedMediumIndex,
	IN	PNDIS_MEDIUM			MediumArray,
	IN	UINT					MediumArraySize,
	IN	NDIS_HANDLE				MiniportAdapterHandle,
	IN	NDIS_HANDLE				WrapperConfigurationContext
	);

VOID
UnbindFromLowerMP(
	OUT	PNDIS_STATUS			Status,
	IN	NDIS_HANDLE				ProtocolBindingContext,
	IN	NDIS_HANDLE				UnbindContext
	);

VOID
DerefAdapter(
    PADAPTER Adapter
    );

VOID
CleanupAdapter(
    PADAPTER Adapter
    );

VOID
LowerMPCloseAdapterComplete(
    IN  NDIS_HANDLE ProtocolBindingContext,
    IN  NDIS_STATUS Status
    );

VOID
CLUnloadProtocol(
    VOID
    );

VOID
MPHalt(
	IN	NDIS_HANDLE				MiniportAdapterContext
	);

NDIS_STATUS
MPReset(
	OUT PBOOLEAN				AddressingReset,
	IN	NDIS_HANDLE				MiniportAdapterContext
	);

#if DBG
VOID
DumpAdapter(
    PADAPTER Adapter
    );
#endif


#pragma NDIS_PAGEABLE_FUNCTION(BindToLowerMP)
#pragma NDIS_PAGEABLE_FUNCTION(GetAdapterRegistryData)

VOID
BindToLowerMP(
	OUT	PNDIS_STATUS			Status,
	IN	NDIS_HANDLE				BindContext,
	IN	PNDIS_STRING			MPDeviceName,
	IN	PVOID					SystemSpecific1,
	IN	PVOID					SystemSpecific2
	)

/*++

Routine Description:

    Bind to the underlying MP. Allocate space for an adapter structure,
    initializing its fields. Try to open the adapter indicated in MPDeviceName.

Arguments:

    See the DDK...

Return Values:

    None

--*/

{
    PADAPTER Adapter;
	NDIS_STATUS OpenAdapterStatus;
	NDIS_STATUS OpenErrorStatus;
    NDIS_STATUS LocalStatus;
    NDIS_MEDIUM MediumArray[] = {
        NdisMediumFddi,
        NdisMedium802_5,
        NdisMedium802_3
        };
	UINT MediumArraySize = sizeof( MediumArray ) / sizeof( NDIS_MEDIUM );
    UINT MediaIndex;
    ULONG AdapterStructSize;

    PAGED_CODE();

#if BINARY_COMPATIBLE
    ImDbgOut( DBG_INFO, DBG_PROTOCOL | DBG_INIT, ("BindToLowerMP: %s\n", MPDeviceName->Buffer ));
#else
    ImDbgOut( DBG_INFO, DBG_PROTOCOL | DBG_INIT, ("BindToLowerMP: %ws\n", MPDeviceName->Buffer ));
#endif

    //
    // allocate enough space for the structure and two unicode buffers to hold
    // the IM and underlying MP device names. We add an extra Unicode char to
    // to the IM device name to hold the instance char that is be appended later
    // on and another unicode char to separate the two strings for reading
    //

    AdapterStructSize = sizeof( ADAPTER ) + IMMPName.Length + MPDeviceName->Length +
        2 * sizeof( UNICODE_NULL );

    IMAllocatePool( Adapter, AdapterStructSize, Adapter );

    if ( Adapter == NULL ) {
        PWCHAR StringData[2];

        StringData[0] = IMDriverName.Buffer;
        StringData[1] = L"Adapter";
        NdisWriteErrorLogEntry(IMDriverObject,
                               (ULONG)EVENT_TRANSPORT_RESOURCE_POOL,
                               0,
                               2,
                               &StringData,
                               0,
                               NULL);

        *Status = NDIS_STATUS_RESOURCES;
        return;
    }

    //
    // set our state to initializing
    //

    Adapter->IMMPState = ADAPTER_STATE_INITIALIZING;

    //
    // make the device name point to the buffer allocated at the back of the
    // structure.
    //

    Adapter->IMDeviceName.MaximumLength = IMMPName.Length + sizeof( UNICODE_NULL );
    Adapter->IMDeviceName.Length = Adapter->IMDeviceName.MaximumLength;
    Adapter->IMDeviceName.Buffer = (PWSTR)( Adapter + 1 );

    Adapter->MPDeviceName.MaximumLength = MPDeviceName->Length;
    Adapter->MPDeviceName.Length = Adapter->MPDeviceName.MaximumLength;
    Adapter->MPDeviceName.Buffer = (PWSTR)((PCHAR)Adapter->IMDeviceName.Buffer +
                                           Adapter->IMDeviceName.MaximumLength +
                                           sizeof( UNICODE_NULL ));

    NdisMoveMemory( Adapter->MPDeviceName.Buffer, MPDeviceName->Buffer, MPDeviceName->Length );

    LocalStatus = GetAdapterRegistryData( (PNDIS_STRING)SystemSpecific1, Adapter );

    if ( !NT_SUCCESS( LocalStatus )) {

#if BINARY_COMPATIBLE
        ImDbgOut(DBG_FAILURE, DBG_PROTOCOL | DBG_INIT,
                 ("(%08X) BindToLowerMP: Couldn't get registry data %08X (%s)\n",
                  Adapter, LocalStatus, MPDeviceName->Buffer ));
#else
        ImDbgOut(DBG_FAILURE, DBG_PROTOCOL | DBG_INIT,
                 ("(%08X) BindToLowerMP: Couldn't get registry data %08X (%ws)\n",
                  Adapter, LocalStatus, MPDeviceName->Buffer ));
#endif

        *Status = NDIS_STATUS_FAILURE;

        IMFreePool( Adapter );
        return;

    }

    //
    // init the event now since we use it in the completion handler
    //
    // remember our binding context so we can complete BindAdapter later on
    //

    NdisInitializeEvent( &Adapter->BlockingEvent );
    Adapter->BindContext = BindContext;


	// Open the adapter below us.
    NdisOpenAdapter(&OpenAdapterStatus,
                    &OpenErrorStatus,
                    &Adapter->LowerMPHandle,
					&MediaIndex,
                    MediumArray,
					MediumArraySize,
                    ClientProtocolHandle,
                    Adapter,
                    MPDeviceName,
                    0,
                    NULL);

    //
    // Memphis doesn't like you to do NdisRequests from within the OpenAdapterComplete
    // handler so wait for OpenAdapterComplete to finish and then do the follow up
    // processing.
    //

    if ( OpenAdapterStatus == NDIS_STATUS_PENDING ) {

        NdisWaitEvent( &Adapter->BlockingEvent, 0 );
        NdisResetEvent( &Adapter->BlockingEvent );
    } else {

        Adapter->FinalStatus = OpenAdapterStatus;
    }

    if ( NT_SUCCESS( Adapter->FinalStatus )) {

        Adapter->MediaType = MediumArray[ MediaIndex ];
    }

    ProcessLowerMPOpenAdapter( Adapter, Adapter->FinalStatus );

    *Status = Adapter->FinalStatus;

} // BindToLowerMP


STATIC NDIS_STATUS
GetAdapterRegistryData(
    PNDIS_STRING IMParamsKey,
    PADAPTER Adapter
    )

/*++

Routine Description:

    Obtain the IMSamp specific info associated with the underlying MP

Arguments:

    IMParamsKey - location in the registry

    Adapter - pointer to adapter context struct

Return Value:

    NDIS_STATUS_SUCCESS if everything worked ok

--*/

{
    NDIS_STATUS Status;
    NDIS_HANDLE ConfigHandle;
    NDIS_STRING IMInstanceNumberKey = NDIS_STRING_CONST( "InstanceNumber" );
    PNDIS_CONFIGURATION_PARAMETER ConfigParam;
    ULONG i;
    PWCHAR StringData[2];
    PVOID DumpData;

    PAGED_CODE();

    NdisOpenProtocolConfiguration( &Status, &ConfigHandle, IMParamsKey );

    if ( !NT_SUCCESS( Status )) {

#if BINARY_COMPATIBLE
        ImDbgOut(DBG_FAILURE, DBG_PROTOCOL | DBG_INIT,
                 ( "(%08X) GetAdapterRegistryData: can't open key %s (%08X)\n",
                   Adapter, IMParamsKey->Buffer, Status ));
#else
        ImDbgOut(DBG_FAILURE, DBG_PROTOCOL | DBG_INIT,
                 ( "(%08X) GetAdapterRegistryData: can't open key %ws (%08X)\n",
                   Adapter, IMParamsKey->Buffer, Status ));
#endif

        return Status;
    }

    //
    // get the IM device instance number and build the device instance string
    //

    NdisReadConfiguration(&Status,
                          &ConfigParam,
                          ConfigHandle,
                          &IMInstanceNumberKey,
                          NdisParameterInteger);


    if ( !NT_SUCCESS( Status )) {

        ImDbgOut(DBG_FAILURE, DBG_PROTOCOL | DBG_INIT,
                 ("(%08X) GetAdapterRegistryData: Missing InstanceNumber key\n", Adapter));

        Status = NDIS_STATUS_FAILURE;
        goto CloseConfig;
    }

    Adapter->DevInstance = (USHORT)ConfigParam->ParameterData.IntegerData;

    NdisMoveMemory( Adapter->IMDeviceName.Buffer, IMMPName.Buffer, IMMPName.Length );

    Adapter->IMDeviceName.Buffer[ IMMPName.Length / sizeof( WCHAR ) ] = L'0' + Adapter->DevInstance;


CloseConfig:
    NdisCloseConfiguration( ConfigHandle );

    return Status;

} // GetAdapterRegistryData


STATIC VOID
ProcessLowerMPOpenAdapter(
    IN  PADAPTER Adapter,
    IN  NDIS_STATUS Status
    )

/*++

Routine Description:

    Complete the binding on the lower miniport. Initialize the adapter structure, query
    the MP for certain funtionality and initialize the associated IM miniport device

Arguments:

    see the DDK

Return Values:

    None

--*/

{
    NTSTATUS EventStatus;
    PWSTR SecondaryName;
    NDIS_HARDWARE_STATUS HWStatus;
    NDIS_MEDIA_STATE MediaState = 0xFFFFFFFF;
    NDIS_STRING IMDevName;
    ULONG MacOptions;
    ULONG ErrorLogData[2];
    PWCHAR StringData[2];
    PVOID DumpData;

    ImDbgOut(DBG_TRACE, DBG_PROTOCOL, ("(%08X) ProcessLowerMPOpenAdapter\n", Adapter));

    //
    // see if it worked; clean up and get out
    //

    if ( !NT_SUCCESS( Status )) {

        ImDbgOut(DBG_FAILURE,
                 DBG_PROTOCOL,
                 ("(%08X) ProcessLowerMPOpenAdapter: binding failed %08X\n", Adapter, Status));

        if ( Status == NDIS_STATUS_ADAPTER_NOT_FOUND ) {

            EventStatus = EVENT_TRANSPORT_ADAPTER_NOT_FOUND;

        } else {

            EventStatus = EVENT_TRANSPORT_BINDING_FAILED;
        }

        StringData[0] = Adapter->IMDeviceName.Buffer;
        StringData[1] = Adapter->MPDeviceName.Buffer;
        DumpData = &Status;

        NdisWriteErrorLogEntry(IMDriverObject,
                               EventStatus,
                               0,
                               2,
                               &StringData,
                               sizeof( Status ),
                               DumpData);

        IMFreePool( Adapter );
        return;
    }

    //
    // initialize the variables associated with this structure. From this point on,
    // DerefAdapter must be called if any errors are encountered.
    //

    NdisAllocateSpinLock( &Adapter->Lock );
    Adapter->RefCount = 1;
    ImDbgOut( DBG_TRACE, DBG_REFCNTS, ("(%08X) =1 Adapter\n", Adapter ));
    InitializeListHead( &Adapter->ClientList );
    Adapter->ShutdownMask = 0;


    //
    // add adapter on list of known adapters
    //

    NdisInterlockedInsertTailList( &AdapterList, &Adapter->Linkage, &AdapterListLock );

    //
    // determine if adapter is ready for use. All adapters probably support hardware
    // status. If they don't, then we'll assume it must be ready for use. If the
    // HW status indicates ok, then check for media connect state which is new for 4.0.
    // If the media is not connected, then we wait until we get an indication that it
    // is connected and then we query the adapter for its link speed. This is important
    // for multi-speed adapters, like 10/100 ethernet.
    //
     //

    Status = MakeLocalNdisRequest(Adapter,
                                  OID_GEN_HARDWARE_STATUS,
                                  &HWStatus,
                                  sizeof( HWStatus ),
                                  NULL);

    if ( Status == NDIS_STATUS_INVALID_OID || HWStatus == NdisHardwareStatusReady ) {

        Status = MakeLocalNdisRequest(Adapter,
                                      OID_GEN_MEDIA_CONNECT_STATUS,
                                      &MediaState,
                                      sizeof( MediaState ),
                                      NULL);

        if ( Status == NDIS_STATUS_INVALID_OID || MediaState == NdisMediaStateConnected ) {

            Status = MakeLocalNdisRequest(Adapter,
                                          OID_GEN_LINK_SPEED,
                                          &Adapter->LinkSpeed,
                                          sizeof( Adapter->LinkSpeed ),
                                          NULL);

            if ( !NT_SUCCESS( Status )) {

                ImDbgOut(DBG_INFO, DBG_PROTOCOL,
                         ("(%08X) ProcessLowerMPOpenAdapter: Can't get link speed - Status %08X\n",
                          Adapter, Status));
        
                ErrorLogData[ 0 ] = IM_ERROR_MISSING_OID;
                ErrorLogData[ 1 ] = OID_GEN_LINK_SPEED;

                NdisWriteErrorLogEntry(Adapter->LowerMPHandle,
                                       NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER,
                                       2,
                                       ErrorLogData);

                goto ErrorExit;
            }

         } else {

            ImDbgOut(DBG_INFO, DBG_PROTOCOL,
                     ("(%08X) ProcessLowerMPOpenAdapter: Media not connected\n", Adapter ));
        }
    } else {

        ImDbgOut(DBG_INFO, DBG_PROTOCOL,
                 ("(%08X) ProcessLowerMPOpenAdapter: HW Status not ready (%d)\n", HWStatus));
    }

    //
    // determine whether we can copy the lookahead data directly
    //

    Status = MakeLocalNdisRequest(Adapter,
                                  OID_GEN_MAC_OPTIONS,
                                  &MacOptions,
                                  sizeof( MacOptions ),
                                  NULL);

    if ( NT_SUCCESS( Status )) {

        Adapter->CopyLookaheadData = (BOOLEAN)(MacOptions & NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA);
    }

    //
    // allocate a packet pool with no buffers. We allocate all the packets and
    // stuff them on a lookaside list so we don't take the hit later on
    //

    Status = AllocatePacketPool( Adapter );

    if ( !NT_SUCCESS( Status )) {

        goto ErrorExit;
    }

    //
    // now allocate two buffer pools: one to hold header plus lookahead data and the
    // other for residual lookahead data that is copied via NdisTransferData.
    //

    Status = AllocateReceiveBufferPools( Adapter );

    if ( !NT_SUCCESS( Status )) {

        goto ErrorExit;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -