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

📄 ne2000adapter.cpp

📁 VC++ 6.0NDIS, NDIS Miniport NIC Drivers
💻 CPP
📖 第 1 页 / 共 5 页
字号:

        GenericULong = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND  |
                               NDIS_MAC_OPTION_RECEIVE_SERIALIZED  |
                               NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
                               NDIS_MAC_OPTION_NO_LOOPBACK
                               );

        break;

    case OID_GEN_SUPPORTED_LIST:

        MoveSource = (PVOID)(Ne2000SupportedOids);
        MoveBytes = sizeof(Ne2000SupportedOids);
        break;

    case OID_GEN_HARDWARE_STATUS:

        HardwareStatus = NdisHardwareStatusReady;
        MoveSource = (PVOID)(&HardwareStatus);
        MoveBytes = sizeof(NDIS_HARDWARE_STATUS);

        break;

    case OID_GEN_MEDIA_SUPPORTED:
    case OID_GEN_MEDIA_IN_USE:

        MoveSource = (PVOID) (&Medium);
        MoveBytes = sizeof(NDIS_MEDIUM);
        break;

    case OID_GEN_MAXIMUM_LOOKAHEAD:

        GenericULong = NE2000_MAX_LOOKAHEAD;

        break;


    case OID_GEN_MAXIMUM_FRAME_SIZE:

        GenericULong = (ULONG)(1514 - NE2000_HEADER_SIZE);

        break;


    case OID_GEN_MAXIMUM_TOTAL_SIZE:

        GenericULong = (ULONG)(1514);

        break;


    case OID_GEN_LINK_SPEED:

        GenericULong = (ULONG)(100000);

        break;


    case OID_GEN_TRANSMIT_BUFFER_SPACE:

        GenericULong = (ULONG)(Info.NumBuffers * TX_BUF_SIZE);

        break;

    case OID_GEN_RECEIVE_BUFFER_SPACE:

        GenericULong = (ULONG)(0x2000 - (Info.NumBuffers * TX_BUF_SIZE));

        break;

    case OID_GEN_TRANSMIT_BLOCK_SIZE:

        GenericULong = (ULONG)(TX_BUF_SIZE);

        break;

    case OID_GEN_RECEIVE_BLOCK_SIZE:

        GenericULong = (ULONG)(256);

        break;

    case OID_GEN_VENDOR_ID:

        NdisMoveMemory(
            (PVOID)&GenericULong,
            Info.PermanentAddress,
            3
            );
        GenericULong &= 0xFFFFFF00;
        MoveSource = (PVOID)(&GenericULong);
        MoveBytes = sizeof(GenericULong);
        break;

    case OID_GEN_VENDOR_DESCRIPTION:

        MoveSource = (PVOID)"Novell 2000 Adapter.";
        MoveBytes = 21;
        break;

    case OID_GEN_DRIVER_VERSION:

        GenericUShort = ((USHORT)NDIS_MAJOR_VERSION << 8) |
                NDIS_MINOR_VERSION;

        MoveSource = (PVOID)(&GenericUShort);
        MoveBytes = sizeof(GenericUShort);
        break;

    case OID_GEN_CURRENT_LOOKAHEAD:

        GenericULong = (ULONG)(Info.MaxLookAhead);
        break;

    case OID_802_3_PERMANENT_ADDRESS:

        NE2000_MOVE_MEM((PCHAR)GenericArray,
                    Info.PermanentAddress,
                    NE2000_LENGTH_OF_ADDRESS);

        MoveSource = (PVOID)(GenericArray);
        MoveBytes = sizeof(Info.PermanentAddress);

        break;

    case OID_802_3_CURRENT_ADDRESS:

        NE2000_MOVE_MEM((PCHAR)GenericArray,
                    Info.StationAddress,
                    NE2000_LENGTH_OF_ADDRESS);

        MoveSource = (PVOID)(GenericArray);
        MoveBytes = sizeof(Info.StationAddress);

        break;

    case OID_802_3_MAXIMUM_LIST_SIZE:

        GenericULong = (ULONG) (Info.MulticastListMax);
        break;

    case OID_GEN_XMIT_OK:

        GenericULong = (UINT)(Info.FramesXmitGood);
        break;

    case OID_GEN_RCV_OK:

        GenericULong = (UINT)(Info.FramesRcvGood);
        break;

    case OID_GEN_XMIT_ERROR:

        GenericULong = (UINT)(Info.FramesXmitBad);
        break;

    case OID_GEN_RCV_ERROR:

        GenericULong = (UINT)(Info.CrcErrors);
        break;

    case OID_GEN_RCV_NO_BUFFER:

        GenericULong = (UINT)(Info.MissedPackets);
        break;

    case OID_802_3_RCV_ERROR_ALIGNMENT:

        GenericULong = (UINT)(Info.FrameAlignmentErrors);
        break;

    case OID_802_3_XMIT_ONE_COLLISION:

        GenericULong = (UINT)(Info.FramesXmitOneCollision);
        break;

    case OID_802_3_XMIT_MORE_COLLISIONS:

        GenericULong = (UINT)(Info.FramesXmitManyCollisions);
        break;

    default:

        StatusToReturn = NDIS_STATUS_INVALID_OID;
        break;

    }


    if (StatusToReturn == NDIS_STATUS_SUCCESS) 
    {

        if (MoveBytes > BytesLeft) 
        {

            // Not enough room in InformationBuffer. Punt

            *BytesNeeded = MoveBytes;

            StatusToReturn = NDIS_STATUS_INVALID_LENGTH;

        }
        else 
        {

            // Store result.
            NE2000_MOVE_MEM(InfoBuffer, MoveSource, MoveBytes);

            (*BytesWritten) += MoveBytes;

        }
    }

    return StatusToReturn;
}


/*++
Routine Description:
    SetInformationHandler handles a set operation for a
    single OID.
Arguments:
    Oid - The OID of the set.
    InformationBuffer - Holds the data to be set.
    InformationBufferLength - The length of InformationBuffer.
    BytesRead - If the call is successful, returns the number
        of bytes read from InformationBuffer.
    BytesNeeded - If there is not enough data in InformationBuffer
        to satisfy the OID, returns the amount of storage needed.
Return Value:
    NDIS_STATUS_SUCCESS
    NDIS_STATUS_PENDING
    NDIS_STATUS_INVALID_LENGTH
    NDIS_STATUS_INVALID_OID

--*/
NDIS_STATUS KdNe2000Adapter::SetInformationHandler(IN NDIS_OID Oid,
                                                   IN PVOID InformationBuffer,
                                                   IN ULONG InformationBufferLength,
                                                   OUT PULONG BytesRead,
                                                   OUT PULONG BytesNeeded)
{
    // General Algorithm:
    // 
    //     Verify length
    //     Switch(Request)
    //        Process Request
    UINT BytesLeft = InformationBufferLength;
    PUCHAR InfoBuffer = (PUCHAR)(InformationBuffer);
    // Variables for a particular request
    UINT OidLength;
    // Variables for holding the new values to be used.
    ULONG LookAhead;
    ULONG Filter;
    // Status of the operation.
    NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;

    DebugDump(DBG_LEVEL3,("In SetInfo\n"));

    // Get Oid and Length of request
    OidLength = BytesLeft;

    switch (Oid) 
    {

        case OID_802_3_MULTICAST_LIST:
            // Verify length
            if ((OidLength % NE2000_LENGTH_OF_ADDRESS) != 0)
            {
                StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
                *BytesRead = 0;
                *BytesNeeded = 0;
                break;
            }

            // Set the new list on the adapter.
            NdisMoveMemory(Info.Addresses, InfoBuffer, OidLength);
            //  If we are currently receiving all multicast or
            //  we are promsicuous then we DO NOT call this, or
            //  it will reset those settings.
            // 
            if(!(Info.PacketFilter & (NDIS_PACKET_TYPE_ALL_MULTICAST |
                                      NDIS_PACKET_TYPE_PROMISCUOUS)))
            {
                StatusToReturn = DispatchSetMulticastAddressList();
            }
            else
            {
                //  Our list of multicast addresses is kept by the
                //  wrapper.
                StatusToReturn = NDIS_STATUS_SUCCESS;
            }
            break;

        case OID_GEN_CURRENT_PACKET_FILTER:

            // Verify length
            if (OidLength != 4 ) 
            {
                StatusToReturn = NDIS_STATUS_INVALID_LENGTH;

                *BytesRead = 0;
                *BytesNeeded = 0;

                break;
            }

            NE2000_MOVE_MEM(&Filter, InfoBuffer, 4);
            // Verify bits
            if (Filter & (NDIS_PACKET_TYPE_SOURCE_ROUTING |
                  NDIS_PACKET_TYPE_SMT |
                  NDIS_PACKET_TYPE_MAC_FRAME |
                  NDIS_PACKET_TYPE_FUNCTIONAL |
                  NDIS_PACKET_TYPE_ALL_FUNCTIONAL |
                  NDIS_PACKET_TYPE_GROUP))
            {

                StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
                *BytesRead = 4;
                *BytesNeeded = 0;
                break;
            }

            // Set the new value on the adapter.
            Info.PacketFilter = Filter;
            StatusToReturn = DispatchSetPacketFilter();
            break;

        case OID_GEN_CURRENT_LOOKAHEAD:
            // Verify length
            if (OidLength != 4) 
            {

                StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
                *BytesRead = 0;
                *BytesNeeded = 0;
                break;
            }
            // Store the new value.
            NE2000_MOVE_MEM(&LookAhead, InfoBuffer, 4);

            if (LookAhead <= NE2000_MAX_LOOKAHEAD) 
            {
                Info.MaxLookAhead = LookAhead;
            }
            else 
            {
                StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
            }
            break;

        default:

            StatusToReturn = NDIS_STATUS_INVALID_OID;
            *BytesRead = 0;
            *BytesNeeded = 0;

            break;
    }


    if (StatusToReturn == NDIS_STATUS_SUCCESS) 
    {

        *BytesRead = BytesLeft;
        *BytesNeeded = 0;

    }

    return(StatusToReturn);
}


/*** Interrupt handlers ***/

/*++
Routine Description:
    This routine is used to turn off the interrupt mask.
--*/
VOID KdNe2000Adapter::DisableInterruptHandler()
{

    IF_LOG( Ne2000Log('p'); )

    CardBlockInterrupts(this);
}



/*++
Routine Description:
    This is the interrupt handler which is registered with the operating
    system. If several are pending (i.e. transmit complete and receive),
    handle them all.  Block new interrupts until all pending interrupts
    are handled.
Arguments:
    InterruptRecognized - Boolean value which returns TRUE if the
        ISR recognizes the interrupt as coming from this adapter.
    QueueDpc - TRUE if a DPC should be queued.
--*/

VOID KdNe2000Adapter::ISRHandler(OUT PBOOLEAN InterruptRecognized, OUT PBOOLEAN QueueDpc)
{

    DebugDump(DBG_LEVEL4,("In KdNe2000Adapter::ISRHandler\n"));

    IF_LOG(Ne2000Log('i');)
    // Force the INT signal from the chip low. When all
    // interrupts are acknowledged interrupts will be unblocked,
    CardBlockInterrupts(this);

    IF_LOG( Ne2000Log('I'); )

    *InterruptRecognized = TRUE;
    *QueueDpc = TRUE;
    return;
}


/*++
Routine Description:
    This is the deferred processing routine for interrupts.  It
    reads from the Interrupt Status Register any outstanding

⌨️ 快捷键说明

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