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

📄 adapter.c

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


    //
    // initialize the corresponding device instance associated with the underlying
    // miniport. NdisIMInitializeDeviceInstanceEx doesn't want the \Device part of
    // the name so we strip that off
    //

    NdisInitUnicodeString( &IMDevName, &Adapter->IMDeviceName.Buffer[ 8 ] );


    //
    // temporarily stuff the adapter pointer into a global so we can find it when
    // MiniportInitialize is called.
    CurrentAdapter = Adapter;

    Status = NdisIMInitializeDeviceInstance( LMDriverHandle, &IMDevName );

    if ( !NT_SUCCESS( Status )) {
        
#if BINARY_COMPATIBLE
        ImDbgOut(DBG_FAILURE, DBG_PROTOCOL,
                 ("(%08X) ProcessLowerMPOpenAdapter: can't init IM device %s (%08X)\n",
                  Adapter, IMDevName.Buffer, Status));
#else
        ImDbgOut(DBG_FAILURE, DBG_PROTOCOL,
                 ("(%08X) ProcessLowerMPOpenAdapter: can't init IM device %ws (%08X)\n",
                  Adapter, IMDevName.Buffer, Status));
#endif

        ErrorLogData[ 0 ] = IM_ERROR_CANT_INITIALIZE_IMSAMP_DEVICE;
        ErrorLogData[ 1 ] = Status;

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

        goto ErrorExit;
    }

    Adapter->ShutdownMask |= SHUTDOWN_DEINIT_DEV_INSTANCE;

    return;

    //
    // when things go wrong...
    //

ErrorExit:

    DerefAdapter( Adapter );

} // ProcessLowerMPOpenAdapter


VOID
LowerMPOpenAdapterComplete(
    IN  PADAPTER Adapter,
    IN  NDIS_STATUS Status,
    IN  NDIS_STATUS OpenErrorStatus
    )

/*++

Routine Description:

    Signal that the binding on the lower miniport is complete

Arguments:

    see the DDK

Return Values:

    None

--*/

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

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

    //
    // stuff the final status in the Adapter block and signal the bind handler to continue
    //

    Adapter->FinalStatus = Status;
    NdisSetEvent( &Adapter->BlockingEvent );

} // LowerMPOpenAdapterComplete


STATIC NDIS_STATUS
AllocatePacketPool(
    PADAPTER Adapter                   
    )

/*++

Routine Description:

    Allocate the packet pool. Note there are no buffers associated with this pool.

Arguments:

    Adapter - pointer to adapter context block

Return Value:

    None

--*/

{
    NDIS_STATUS Status;
    PNDIS_PACKET Packet;
    ULONG ErrorLogData[2];
    ULONG i;
    ULONG ProtoReservedSize;

    NdisInitializeSListHead( &Adapter->PacketSList );
    NdisAllocateSpinLock( &Adapter->PacketSListLock );

    //
    // figure the amount of space we need in the protocol reserved area.
    //

    ProtoReservedSize =  sizeof( IM_PACKET_CONTEXT );

    NdisAllocatePacketPool(&Status,
                           &Adapter->PacketPoolHandle,
                           ConfigData.PacketPoolSize,
                           ProtoReservedSize);

    if ( NT_SUCCESS( Status )) {

        Adapter->ShutdownMask |= SHUTDOWN_DEALLOC_PACKET_POOL;

        for ( i = 0; i < ConfigData.PacketPoolSize; ++i ) {

            NdisAllocatePacket( &Status, &Packet, Adapter->PacketPoolHandle );

            if ( !NT_SUCCESS( Status )) {

                ErrorLogData[ 0 ] = IM_ERROR_PACKET;
                ErrorLogData[ 1 ] = Status;

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

                return Status;
            }

            IMSetTag( IM_PACKET_CONTEXT_FROM_PACKET( Adapter, Packet ), PacketContext );
            NdisInterlockedPushEntrySList(&Adapter->PacketSList,
                                          (PSINGLE_LIST_ENTRY)Packet->ProtocolReserved,
                                          &Adapter->PacketSListLock);
        }
    } else {

        ErrorLogData[ 0 ] = IM_ERROR_PACKET_POOL;
        ErrorLogData[ 1 ] = Status;

        NdisWriteErrorLogEntry(Adapter->LowerMPHandle,
                               NDIS_ERROR_CODE_OUT_OF_RESOURCES,
                               2,
                               ErrorLogData);
    }

    return Status;

}   // AllocatePacketPool


STATIC NDIS_STATUS
AllocateReceiveBufferPools(
    PADAPTER Adapter
    )

/*++

Routine Description:

    Allocate two buffer pools, one used for header and lookahead data and the other
    for residual lookahead data

Arguments:

    Adapter - pointer to adapter context block

Return Value:

    None

--*/

{
    NDIS_STATUS Status;
    ULONG i;
    PVOID SysBuffer;
    PNDIS_BUFFER NdisBuffer;
    PIM_BUFFER_CONTEXT BufContext;
    ULONG HeaderSize;
    ULONG FrameSize;            // doesn't include the header
    NDIS_ERROR_CODE ErrorCode;
    ULONG ErrorLogData[2];

    //
    // max amount of data w/o the MAC header
    //

    Status = MakeLocalNdisRequest(Adapter,
                                  OID_GEN_MAXIMUM_FRAME_SIZE,
                                  &FrameSize,
                                  sizeof( FrameSize ),
                                  NULL);

    if ( !NT_SUCCESS( Status )) {

        ImDbgOut(DBG_FAILURE, DBG_PROTOCOL,
                 ("(%08X) AllocateReceiveBufferPool: Can't get frame size - Status %08X\n",
                  Adapter, Status));
        
        ErrorCode = NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER;
        ErrorLogData[ 0 ] = IM_ERROR_MISSING_OID;
        ErrorLogData[ 1 ] = OID_GEN_MAXIMUM_FRAME_SIZE;

        goto ErrorExit;
    }

    //
    // this one includes the header
    //

    Status = MakeLocalNdisRequest(Adapter,
                                  OID_GEN_MAXIMUM_TOTAL_SIZE,
                                  &Adapter->TotalSize,
                                  sizeof( Adapter->TotalSize ),
                                  NULL);

    if ( !NT_SUCCESS( Status )) {

        ImDbgOut(DBG_FAILURE, DBG_PROTOCOL,
                 ("(%08X) AllocateReceiveBufferPool: Can't get total size - Status %08X\n",
                  Adapter, Status));
        
        ErrorCode = NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER;
        ErrorLogData[ 0 ] = IM_ERROR_MISSING_OID;
        ErrorLogData[ 1 ] = OID_GEN_MAXIMUM_TOTAL_SIZE;

        goto ErrorExit;
    }

    //
    // figure the real header size
    //

    HeaderSize = Adapter->TotalSize - FrameSize;

    Status = MakeLocalNdisRequest(Adapter,
                                  OID_GEN_MAXIMUM_LOOKAHEAD,
                                  &Adapter->LookaheadBufferSize,
                                  sizeof( Adapter->LookaheadBufferSize ),
                                  NULL);

    if ( !NT_SUCCESS( Status )) {

        ImDbgOut(DBG_FAILURE, DBG_PROTOCOL,
                 ("(%08X) AllocateReceiveBufferPool: Can't get lookahead size - Status %08X\n",
                  Adapter, Status));
        
        ErrorCode = NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER;
        ErrorLogData[ 0 ] = IM_ERROR_MISSING_OID;
        ErrorLogData[ 1 ] = OID_GEN_MAXIMUM_LOOKAHEAD;

        goto ErrorExit;
    }

    //
    // figure the buffer size for the lookahead buffers, which also include
    // the header. The residual buffer size is the total size, since the MP
    // can indicate less than the max lookahead buffer size, we need to be
    // prepared to receive the whole frame in the residual buffer. On the
    // other hand, the MP can indicate more than the lookahead size, so we
    // might bypass the lookahead buffer and just use a residual buffer on
    // the receive.
    //

    Adapter->LookaheadBufferSize += HeaderSize;

    //
    // init the lookahead buffer pool
    //

    NdisInitializeSListHead( &Adapter->LookaheadSList );
    NdisAllocateSpinLock( &Adapter->LookaheadSListLock );

    NdisAllocateBufferPool(&Status,
                           &Adapter->LookaheadPoolHandle,
                           ConfigData.LookaheadPoolSize);

    if ( !NT_SUCCESS( Status )) {

        ErrorCode = NDIS_ERROR_CODE_OUT_OF_RESOURCES;
        ErrorLogData[ 0 ] = IM_ERROR_LOOKAHEAD_POOL;
        ErrorLogData[ 1 ] = Status;

        goto ErrorExit;
    }

    Adapter->ShutdownMask |= SHUTDOWN_DEALLOC_LOOKAHEAD_POOL;

    for ( i = 0; i < ConfigData.LookaheadPoolSize; ++i ) {

        IMAllocatePoolNoStructTag( SysBuffer, Adapter->LookaheadBufferSize, LookaheadBuffer );

        if ( SysBuffer == NULL ) {

            ErrorCode = NDIS_ERROR_CODE_OUT_OF_RESOURCES;
            ErrorLogData[ 0 ] = IM_ERROR_VM_LOOKAHEAD_BUFFER;
            ErrorLogData[ 1 ] = (ULONG)NDIS_STATUS_RESOURCES;

            goto ErrorExit;
        }

        NdisAllocateBuffer(&Status,
                           &NdisBuffer,
                           Adapter->LookaheadPoolHandle,
                           SysBuffer,
                           Adapter->LookaheadBufferSize);

        if ( !NT_SUCCESS( Status )) {

            ErrorCode = NDIS_ERROR_CODE_OUT_OF_RESOURCES;
            ErrorLogData[ 0 ] = IM_ERROR_LOOKAHEAD_BUFFER;
            ErrorLogData[ 1 ] = Status;

            goto ErrorExit;
        }

        //
        // use the VM area to store a pointer back to the NDIS buffer and link it
        // onto the S List.
        //

        BufContext = (PIM_BUFFER_CONTEXT)SysBuffer;
        BufContext->NdisBuffer = NdisBuffer;

        NdisInterlockedPushEntrySList(&Adapter->LookaheadSList,
                                      &BufContext->SListEntry,
                                      &Adapter->LookaheadSListLock);
    }

    //
    // same thing for the residual buffer pool
    //

    NdisInitializeSListHead( &Adapter->ResidualSList );
    NdisAllocateSpinLock( &Adapter->ResidualSListLock );

    NdisAllocateBufferPool(&Status,
                           &Adapter->ResidualPoolHandle,
                           ConfigData.ResidualPoolSize);

    if ( !NT_SUCCESS( Status )) {

        ErrorCode = NDIS_ERROR_CODE_OUT_OF_RESOURCES;
        ErrorLogData[ 0 ] = IM_ERROR_RESIDUAL_POOL;
        ErrorLogData[ 1 ] = Status;

        goto ErrorExit;
    }

    Adapter->ShutdownMask |= SHUTDOWN_DEALLOC_RESIDUAL_POOL;

    for ( i = 0; i < ConfigData.ResidualPoolSize; ++i ) {

        IMAllocatePoolNoStructTag( SysBuffer, Adapter->TotalSize, ResidualBuffer );

        if ( SysBuffer == NULL ) {

            ErrorCode = NDIS_ERROR_CODE_OUT_OF_RESOURCES;
            ErrorLogData[ 0 ] = IM_ERROR_VM_RESIDUAL_BUFFER;
            ErrorLogData[ 1 ] = (ULONG)NDIS_STATUS_RESOURCES;

            goto ErrorExit;
        }

        NdisAllocateBuffer(&Status,
                           &NdisBuffer,
                           Adapter->ResidualPoolHandle,
                           SysBuffer,
                           Adapter->TotalSize);

        if ( !NT_SUCCESS( Status )) {

            ErrorCode = NDIS_ERROR_CODE_OUT_OF_RESOURCES;
            ErrorLogData[ 0 ] = IM_ERROR_RESIDUAL_BUFFER;
            ErrorLogData[ 1 ] = Status;

            goto ErrorExit;
        }

        //
        // use the VM area to store a pointer back to the NDIS buffer and link it
        // onto the S List.
        //

        BufContext = (PIM_BUFFER_CONTEXT)SysBuffer;
        BufContext->NdisBuffer = NdisBuffer;

        NdisInterlockedPushEntrySList(&Adapter->ResidualSList,
                                      &BufContext->SListEntry,
                                      &Adapter->ResidualSListLock);
    }

    return Status;

    //
    // when things go awry
    //

ErrorExit:

    NdisWriteErrorLogEntry( Adapter->LowerMPHandle, ErrorCode, 2, ErrorLogData );
    return Status;

}   // AllocateReceiveBufferPool






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
	)

/*++

Routine Description:

    Imsample's device initialization routine. The list of media types is
    checked to be sure it is one that we support. If so, match up the name of
    the device being opened with one of the adapters to which we've bound.

Arguments:

    See the DDK...

Return Values:

    None

--*/

{
    NDIS_HANDLE ConfigHandle;
    NDIS_STATUS Status;
    NDIS_STRING IMInstanceNumberKey = NDIS_STRING_CONST( "InstanceNumber" );
    PNDIS_CONFIGURATION_PARAMETER ConfigParam;
    ULONG IMInstanceNumber;
    PLIST_ENTRY NextAdapter;
    PADAPTER AdapterInList;
    ULONG ErrorLogData[2];

    ImDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPInitialize: Enter\n"));

    //
    // open registry and look at keys in the MP device instance. we need to figure out
    // which instance we're initializing. The setup junk put in InstanceNumber so we
    // can figure this out at this time. We pick up other instance specific info at
    // this time. We have to do this locally, since we don't have a pointer to the
    // adapter context struct that is associated with this initialization
    //

    NdisOpenConfiguration( &Status, &ConfigHandle, WrapperConfigurationContext );

    if ( !NT_SUCCESS( Status )) {

        return Status;
    }

  
 // Read the instance number. For example, if we are initializing ImSampMP4, then this should return
 // the number stores in CurrentControlSet/Services/ImSampMP4/Parameters/InstanceNumber, which should be a 4
  
    NdisReadConfiguration(&Status,
                          &ConfigParam,
                          ConfigHandle,
                          &IMInstanceNumberKey,
                          NdisParameterInteger);


    if ( !NT_SUCCESS( Status )) {

        ImDbgOut(DBG_FAILURE, DBG_MINIPORT | DBG_INIT,
                 ("MPInitialize: Missing InstanceNumber key\n"));

        ErrorLogData[ 0 ] = IM_ERROR_BAD_REGISTRY_DATA;
        ErrorLogData[ 1 ] = IM_ERROR_MISSING_IMSAMP_MP_INSTANCE_KEY;

        NdisWriteErrorLogEntry(MiniportAdapterHandle,
                               NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER,
                               2,
                               ErrorLogData);

        NdisCloseConfiguration( ConfigHandle );
        return NDIS_STATUS_FAILURE;
    }

    IMInstanceNumber = ConfigParam->ParameterData.IntegerData;

    NdisCloseConfiguration( ConfigHandle );

    // We now know which adapter we are initializing (say ImSampMP4, for example)
    // look through our adapter list and match based on device instance
    // The adapter list is created when the protocol section opens the existing adapters below us.

    NdisAcquireSpinLock( &AdapterListLock );

    NextAdapter = AdapterList.Flink;
    while ( NextAdapter != &AdapterList ) {

        AdapterInList = CONTAINING_RECORD( NextAdapter, ADAPTER, Linkage );

        if ( AdapterInList->DevInstance == IMInstanceNumber ) {

            break;
        }

        NextAdapter = NextAdapter->Flink;
    }

    NdisReleaseSpinLock( &AdapterListLock );

    //
    // check that we really found a matching adapter
    //

    if ( NextAdapter == &AdapterList ) {

        // This means we have an IM MP entry that does not match up with an actual adapter. This is bad.   
        ImDbgOut(DBG_FAILURE, DBG_MINIPORT | DBG_INIT, ("Can't find adapter for MP dev # %d\n",
                                                        IMInstanceNumber));

        ErrorLogData[ 0 ] = IM_ERROR_BAD_REGISTRY_DATA;
        ErrorLogData[ 1 ] = IM_ERROR_INVALID_IMSAMP_MP_INSTANCE;

        NdisWriteErrorLogEntry(MiniportAdapterHandle,
                               NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER,
                               2,
                               ErrorLogData);

        return NDIS_STATUS_FAILURE;
    }

    //
    // lookup our media type in the supplied media array
    //

    for (--MediumArraySize ; MediumArraySize > 0; ) {

        if ( MediumArray[ MediumArraySize ] == AdapterInList->MediaType ) {

            break;
        }

        if ( MediumArraySize == 0 ) {

            break;
        }

        --MediumArraySize;
    }

⌨️ 快捷键说明

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