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

📄 ne2000adapter.cpp

📁 VC++ 6.0NDIS, NDIS Miniport NIC Drivers
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#include "../../../include/kdndis.h"
#include "ne2000.h"
#include "ne2000adapter.h"



void NE2000RawWritePortBufferUchar(ULONG Port, PUCHAR Buffer, ULONG Length)
{
        PUCHAR Current = (Buffer);
        PUCHAR End = Current + Length;
        for ( ; Current < End; ++Current) 
        {
            WRITE_PORT_UCHAR((PUCHAR)Port,*(UNALIGNED UCHAR *)Current);
            KeStallExecutionProcessor(1);
        }
}

void NE2000RawWritePortBufferUshort(ULONG Port,PUSHORT Buffer, ULONG Length)
{
        PUSHORT Current = Buffer;
        PUSHORT End = Current + Length;
        for ( ; Current < End; ++Current) 
        {
            WRITE_PORT_USHORT((PUSHORT)Port,*(UNALIGNED USHORT *)Current);
            KeStallExecutionProcessor(1);
        }
}

void NE2000RawWritePortBufferUlong(ULONG Port,PULONG Buffer,ULONG Length)
{ 
        PULONG Current = Buffer; 
        PULONG End = Current + Length; 
        for ( ; Current < End; ++Current) 
        { 
            WRITE_PORT_ULONG((PULONG)Port,*(UNALIGNED ULONG *)Current); 
            KeStallExecutionProcessor(1); 
        } 
}


/*++
Routine Description:
    Determines the type of the interrupt on the card. The order of
    importance is overflow, then transmit complete, then receive.
    Counter MSB is handled first since it is simple.
Arguments:
    Adapter - pointer to the adapter block
    InterruptStatus - Current Interrupt Status.
Return Value:
    The type of the interrupt
--*/
#define CARD_GET_INTERRUPT_TYPE(_A, _I)                 \
  (_I & ISR_COUNTER) ?                               \
      COUNTER :                                      \
      (_I & ISR_OVERFLOW ) ?                         \
      _A->SyncCardUpdateCounters(), OVERFLOW :                 \
        (_I & (ISR_XMIT|ISR_XMIT_ERR)) ?           \
          TRANSMIT :                                     \
        (_I & ISR_RCV) ?                               \
          RECEIVE :                                  \
        (_I & ISR_RCV_ERR) ?                           \
              _A->SyncCardUpdateCounters(), RECEIVE :  \
              UNKNOWN



VOID
CardGetMulticastBit(UCHAR Address[NE2000_LENGTH_OF_ADDRESS],
                    UCHAR * Byte, UCHAR * Value);




UCHAR KdNe2000Adapter::BlankBuffer[] = "                                                           ";





UINT KdNe2000Adapter::Ne2000SupportedOids[] = {
    OID_GEN_SUPPORTED_LIST,
    OID_GEN_HARDWARE_STATUS,
    OID_GEN_MEDIA_SUPPORTED,
    OID_GEN_MEDIA_IN_USE,
    OID_GEN_MAXIMUM_LOOKAHEAD,
    OID_GEN_MAXIMUM_FRAME_SIZE,
    OID_GEN_MAXIMUM_TOTAL_SIZE,
    OID_GEN_MAC_OPTIONS,
    OID_GEN_PROTOCOL_OPTIONS,
    OID_GEN_LINK_SPEED,
    OID_GEN_TRANSMIT_BUFFER_SPACE,
    OID_GEN_RECEIVE_BUFFER_SPACE,
    OID_GEN_TRANSMIT_BLOCK_SIZE,
    OID_GEN_RECEIVE_BLOCK_SIZE,
    OID_GEN_VENDOR_DESCRIPTION,
    OID_GEN_VENDOR_ID,
    OID_GEN_DRIVER_VERSION,
    OID_GEN_CURRENT_PACKET_FILTER,
    OID_GEN_CURRENT_LOOKAHEAD,
    OID_GEN_XMIT_OK,
    OID_GEN_RCV_OK,
    OID_GEN_XMIT_ERROR,
    OID_GEN_RCV_ERROR,
    OID_GEN_RCV_NO_BUFFER,
    OID_802_3_PERMANENT_ADDRESS,
    OID_802_3_CURRENT_ADDRESS,
    OID_802_3_MULTICAST_LIST,
    OID_802_3_MAXIMUM_LIST_SIZE,
    OID_802_3_RCV_ERROR_ALIGNMENT,
    OID_802_3_XMIT_ONE_COLLISION,
    OID_802_3_XMIT_MORE_COLLISIONS
    };



KdNe2000Adapter::KdNe2000Adapter():KdNdisAdapter()
{
    // Clear out the adapter block, which sets all default values to FALSE,
    // or NULL.
    NdisZeroMemory (&Info, sizeof(NE2000_ADAPTER));
}


KdNe2000Adapter::~KdNe2000Adapter()
{

}



/*++
    Initializes the Adapter adapter and registers resources with the
    wrapper.
    OpenErrorStatus - Extra status bytes for opening token ring adapters.
    pConf -  a handle to an open configuration to be use for NdisReadConfiguration.
                        (it was created by the KdNdisMiniport::StaticInitializeHandler
    WrapperConfigurationContext - we only need this for the NdisReadMcaPosInformation and to pass on to the adapter
Return Value:
    NDIS_STATUS_SUCCESS
    NDIS_STATUS_PENDING
--*/
NDIS_STATUS KdNe2000Adapter::Init(PNDIS_STATUS OpenErrorStatus, KdNdisConfiguration  *pConf, NDIS_HANDLE WrapperConfigurationContext)

{
    // String names of all the parameters that will be read.
    PCWSTR IOAddressStr = L"IoBaseAddress";
    PCWSTR InterruptStr = L"InterruptNumber";
    PCWSTR MaxMulticastListStr = L"MaximumMulticastList";
    PCWSTR NetworkAddressStr = L"NetworkAddress";
    PCWSTR BusTypeStr = L"BusType";
    PCWSTR CardTypeStr = L"CardType";
    // TRUE if there is a configuration error.
    BOOLEAN ConfigError = FALSE;
    // A special value to log concerning the error.
    ULONG ConfigErrorValue = 0;
    // The slot number the adapter is located in, used for
    // Microchannel adapters.
    UINT SlotNumber = 0;
    // TRUE if it is unnecessary to read the Io Base Address
    // and Interrupt from the registry.  Used for Microchannel
    // adapters, which get this information from the slot
    // information.
    BOOLEAN SkipIobaseAndInterrupt = FALSE;
    // The network address the adapter should use instead of the
    // the default burned in address.
    PVOID NetAddress;

    // The number of bytes in the address.  It should be
    // NE2000_LENGTH_OF_ADDRESS
    UINT Length;
    // These are used when calling RegisterAdapter.
    // 
    // The physical address of the base I/O port.
    DWORD IoBaseAddr;
    // The interrupt number to use.
    DWORD InterruptNumber;
    // The number of multicast address to be supported.
    DWORD MaxMulticastList;
    // Status of Ndis calls.
    NDIS_STATUS Status;
    // temp dword for reading from the config
    DWORD ConfigReadDword;


    //  Read in the card type.
    Status = pConf->QueryDWORD(CardTypeStr,&ConfigReadDword,NE2000_ISA);
    Info.CardType = (WORD)ConfigReadDword;

    // Read net address
    Status = pConf->QueryNetworkAddress(&NetAddress,&Length);
    if ((Length == NE2000_LENGTH_OF_ADDRESS) && (Status == NDIS_STATUS_SUCCESS)) 
    {
        // Save the address that should be used.
        NdisMoveMemory(Info.StationAddress, NetAddress, NE2000_LENGTH_OF_ADDRESS);
    }

    // Read Bus Type (for NE2/AE2 support)
    Status = pConf->QueryDWORD(BusTypeStr,&ConfigReadDword,NdisInterfaceIsa);
    Info.BusType = (NDIS_INTERFACE_TYPE)ConfigReadDword;


    // Read I/O Address
    Status = pConf->QueryDWORD(IOAddressStr,&IoBaseAddr,DEFAULT_IOBASEADDR);
    // Check that the value is valid.
    if ((IoBaseAddr < MIN_IOBASEADDR) ||
        (IoBaseAddr > MAX_IOBASEADDR)) 
    {

        ConfigError = TRUE;
        ConfigErrorValue = (ULONG)IoBaseAddr;
        goto RegisterAdapter;

    }

    // Read interrupt number
    Status = pConf->QueryDWORD(InterruptStr,&InterruptNumber,DEFAULT_INTERRUPTNUMBER);
    // Verify that the value is valid.
    if ((InterruptNumber < MIN_IRQ) ||
        (InterruptNumber > MAX_IRQ)) 
    {

        ConfigError = TRUE;
        ConfigErrorValue = (ULONG)InterruptNumber;
        goto RegisterAdapter;

    }

    //  If the adapter is a pcmcia card then get the memory window
    //  address for later use.
    if (NE2000_PCMCIA == Info.CardType)
    {
        PCWSTR AttributeMemoryAddrStr = L"PCCARDAttributeMemoryAddress";
        PCWSTR AttributeMemorySizeStr = L"PCCARDAttributeMemorySize";
        //  Read the attribute memory address.
        Status = pConf->QueryDWORD(AttributeMemoryAddrStr,&Info.AttributeMemoryAddress,0xd4000);
        //  Read the size of the attribute memory range.
        Status = pConf->QueryDWORD(AttributeMemorySizeStr,&Info.AttributeMemorySize,0x1000);
    }
    // Read MaxMulticastList
    Status = pConf->QueryDWORD(MaxMulticastListStr,&MaxMulticastList,DEFAULT_MULTICASTLISTMAX);


RegisterAdapter:

    // Now to use this information and register with the wrapper
    // and initialize the adapter.
    DebugDump(DBG_LEVEL3,(
        "Registering adapter # buffers %ld\n"
        "Card type: 0x%x\n"
        "I/O base addr 0x%lx\n"
        "interrupt number %ld\n"
        "max multicast %ld\nattribute memory address 0x%X\n"
        "attribute memory size 0x%X\n"
        "CardType: %d\n",
        DEFAULT_NUMBUFFERS,
        Info.CardType,
        IoBaseAddr,
        InterruptNumber,
        DEFAULT_MULTICASTLISTMAX,
        Info.AttributeMemoryAddress,
        Info.AttributeMemorySize,
        Info.CardType ));



    // Set up the parameters.
    Info.NumBuffers = DEFAULT_NUMBUFFERS;
    Info.IoBaseAddr = (PVOID)IoBaseAddr;
    Info.InterruptNumber = (CCHAR)InterruptNumber;
    Info.MulticastListMax = MaxMulticastList;
    Info.MaxLookAhead = NE2000_MAX_LOOKAHEAD;

    // Now do the work.
    if (Register(
          WrapperConfigurationContext,
          ConfigError,
          ConfigErrorValue
          ) != NDIS_STATUS_SUCCESS) 
   {

        return NDIS_STATUS_FAILURE;
   }

    DebugDump(DBG_LEVEL3, ("KdNe2000Adapter::Register succeeded\n" ));
    return NDIS_STATUS_SUCCESS;
}


/*** The Handlers ****/


/*++

    HaltHandler removes an adapter that was previously initialized.

--*/
VOID KdNe2000Adapter::HaltHandler()


{

    // Shut down the chip.
    CardStop();

    // Disconnect the interrupt line.
    DeregisterInterrupt();

    // Pause, waiting for any DPC stuff to clear.
    NdisStallExecution(250000);

    DeregisterIoPortRange((ULONG)Info.IoBaseAddr,0x20,(PVOID)Info.IoPAddr);

    // Remove the adapter from the global queue of adapters.
    GetMiniportOwner()->RemoveAdapter(this);
    delete this;
    return;
}




/*++

Routine Description:

    The ResetHandler request instructs the Miniport to issue a hardware reset
    to the network adapter.  The driver also resets its software state.  See
    the description of NdisMReset for a detailed description of this request.

Arguments:

    AddressingReset - Does the adapter need the addressing information reloaded.


Return Value:

    The function value is the status of the operation.

--*/
NDIS_STATUS KdNe2000Adapter::ResetHandler(OUT PBOOLEAN AddressingReset)
{

    // Temporary looping variable
    UINT i;

    // Clear the values for transmits, they will be reset these for after
    // the reset is completed.
    Info.NextBufToFill = 0;
    Info.NextBufToXmit = 0;
    Info.CurBufXmitting = (XMIT_BUF)-1;

    Info.FirstPacket = NULL;
    Info.LastPacket = NULL;

    for (i=0; i<Info.NumBuffers; i++) {
            Info.BufferStatus[i] = EMPTY;
    }

    // Physically reset the card.
    Info.NicInterruptMask = IMR_RCV | IMR_XMIT | IMR_XMIT_ERR | IMR_OVERFLOW;

    return (CardReset() ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
}


/*++
Routine Description:
    The QueryInformationHandler process a Query request for
    NDIS_OIDs that are specific about the Driver.
    Oid - the NDIS_OID to process.
    InformationBuffer -  a pointer into the
    NdisRequest->InformationBuffer into which store the result of the query.
    InformationBufferLength - a pointer to the number of bytes left in the
    InformationBuffer.
    BytesWritten - a pointer to the number of bytes written into the
    InformationBuffer.
    BytesNeeded - If there is not enough room in the information buffer
    then this will contain the number of bytes needed to complete the
    request.

Return Value:
    The function value is the status of the operation.
--*/
NDIS_STATUS KdNe2000Adapter::QueryInformationHandler(IN NDIS_OID Oid,                                                    
                                                     IN PVOID InformationBuffer,
                                                     IN ULONG InformationBufferLength,
                                                     OUT PULONG BytesWritten,
                                                     OUT PULONG BytesNeeded)
{

    //   General Algorithm:
    //      Switch(Request)
    //         Get requested information
    //         Store results in a common variable.
    //      default:
    //         Try protocol query information
    //         If that fails, fail query.
    // 
    //      Copy result in common variable to result buffer.
    //   Finish processing

    UINT BytesLeft = InformationBufferLength;
    PUCHAR InfoBuffer = (PUCHAR)(InformationBuffer);
    NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
    NDIS_HARDWARE_STATUS HardwareStatus = NdisHardwareStatusReady;
    NDIS_MEDIUM Medium = NdisMedium802_3;

    // This variable holds result of query
    ULONG GenericULong;
    USHORT GenericUShort;
    UCHAR GenericArray[6];
    UINT MoveBytes = sizeof(ULONG);
    PVOID MoveSource = (PVOID)(&GenericULong);

    // Make sure that int is 4 bytes.  Else GenericULong must change
    // to something of size 4.
    ASSERT(sizeof(ULONG) == 4);

    // Switch on request type
    switch (Oid) 
    {

    case OID_GEN_MAC_OPTIONS:

⌨️ 快捷键说明

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