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

📄 rndismin.c

📁 6410BSP3
💻 C
📖 第 1 页 / 共 3 页
字号:
            return NDIS_STATUS_SUCCESS;
            break;
        
        case OID_GEN_CURRENT_PACKET_FILTER:
            *pulBytesRead   = ulInformationBufferLength;
            *pulBytesNeeded = 0;

            if (ulInformationBufferLength != 4 ) 
                return NDIS_STATUS_INVALID_LENGTH;                        
        
            memcpy (&dwFilter, pvInformationBuffer, 4);
        
            //  Reject types we don't support..
            if (dwFilter & 
                 (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)) 
            {
                return NDIS_STATUS_NOT_SUPPORTED;               
            }           

            USBDBGMSG(USBDBG_ZONE_INFO, (
                L"RNdis:: New filter set: [0x%x] --> [0x%x]\r\n",
                 m_rndisDev.dwCurrentPacketFilter, dwFilter
                 ));

            //  Hence we support:
            //  DIRECTED, MULTICAST, ALL_MULTICAST, BROADCAST, 
            //  Set the new value on the adapter..
            
            m_rndisDev.dwCurrentPacketFilter = dwFilter;

            if (dwFilter)                           
                m_rndisDev.state = RNDIS_INITIALIZED;
            else            
                m_rndisDev.state = RNDIS_DATA_INITIALIZED;

            return NDIS_STATUS_SUCCESS;
            break;

        case OID_GEN_CURRENT_LOOKAHEAD:
            //  No need to record requested lookahead length since we
            //  always indicate the whole packet.
            *pulBytesRead = 4;
            return NDIS_STATUS_SUCCESS;
            break;

        default:
            *pulBytesRead = 0;
            *pulBytesNeeded = 0;
            return NDIS_STATUS_INVALID_OID;
    }
    
}

//------------------------------------------------------------------------------
//  Prepare a rndis packet for transmission
//
static
BOOL
PrepareRndisPacket(
    PBYTE pbData,
    UINT32 cbData
    )
{
    UINT32 outPktLen;
    UINT32 tmp;
    PRNDIS_PACKET   pRndisPacket;

    outPktLen = RNDIS_MESSAGE_SIZE (RNDIS_PACKET) + cbData;
    
    if (outPktLen < cbData)     //overflow
    {
        USBDBGMSG(USBDBG_ZONE_ERROR, (
            L"RNdis:: ERROR! Outgoing pkt is too big, bailing out!\r\n"
            ));
        return FALSE;
    }        

    tmp = outPktLen;
    
    //  Pad it to multiple of 8 bytes (required by RNDIS host).
    outPktLen += (8 - (outPktLen % 8));

    
    if ((outPktLen > sizeof(m_outgoingPkt)) || (outPktLen < tmp))
    {
        USBDBGMSG(USBDBG_ZONE_ERROR, (
            L"RNdis:: Outgoing pkt is bigger than buffer size, bailing out!\r\n"
            ));
        return FALSE;
    }   

    //  Fill up the RNDIS_PACKET header
    //
    m_outgoingPkt.rndisMsg.NdisMessageType = REMOTE_NDIS_PACKET_MSG;
    m_outgoingPkt.rndisMsg.MessageLength   = outPktLen; 

    pRndisPacket = &(m_outgoingPkt.rndisMsg.Message.Packet);

    pRndisPacket->DataOffset            = sizeof(RNDIS_PACKET);
    pRndisPacket->DataLength            = cbData;
    pRndisPacket->OOBDataOffset         = 0x00;
    pRndisPacket->OOBDataLength         = 0x00;
    pRndisPacket->NumOOBDataElements    = 0x00;
    pRndisPacket->PerPacketInfoOffset   = 0x00;
    pRndisPacket->PerPacketInfoLength   = 0x00;
    pRndisPacket->VcHandle              = 0x00;
    pRndisPacket->Reserved              = 0x00;
    

    //copy the data to outgoing packet buffer
    memcpy(pRndisPacket+1,pbData,cbData);

    return TRUE;
}

//------------------------------------------------------------------------------
//  Send the Rndis message to host (as opposed to a data packet)
//
static
void
SendRndisMessage(
    DWORD       dwRndisMessageType,
    DWORD       dwRequestId,
    NDIS_STATUS NdisStatus,
    PUCHAR      pucInBuffer,
    DWORD       dwBufferLength,
    DWORD       dwUnspecified1
    )
{
    UINT32      uiMessageSize;

    switch (dwRndisMessageType)
    {
        case REMOTE_NDIS_INITIALIZE_CMPLT:
        {
            PRNDIS_INITIALIZE_COMPLETE  pInitComplete;

            uiMessageSize = RNDIS_MESSAGE_SIZE(RNDIS_INITIALIZE_COMPLETE);  

            m_outgoingMsg.rndisMsg.NdisMessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
            m_outgoingMsg.rndisMsg.MessageLength   = uiMessageSize;
            pInitComplete = &(m_outgoingMsg.rndisMsg.Message.InitializeComplete);
            pInitComplete->RequestId             = dwRequestId;
            pInitComplete->Status                = NdisStatus;
            pInitComplete->MajorVersion          = SUPPORTED_RNDIS_MAJOR_VER;
            pInitComplete->MinorVersion          = SUPPORTED_RNDIS_MINOR_VER;
            pInitComplete->DeviceFlags           = RNDIS_DF_CONNECTIONLESS;
            pInitComplete->Medium                = 0x00;    
            pInitComplete->MaxPacketsPerMessage  = RNDIS_MAX_PACKETS_PER_MESSAGE;           
            pInitComplete->AFListOffset          = 0x00;    
            pInitComplete->AFListSize            = 0x00;            
            pInitComplete->MaxTransferSize       = RNDIS_MAX_TRANSFER_SIZE;
            //   8 byte alignment, to cater for non x86 devices..
            pInitComplete->PacketAlignmentFactor = 0x03;    

            break;
        }

        case REMOTE_NDIS_QUERY_CMPLT:
        {
            PRNDIS_QUERY_COMPLETE   pQueryComplete;
            PUCHAR                  pucBuffer;          
            UINT                    uiRndisQuerySize;

            uiRndisQuerySize = RNDIS_MESSAGE_SIZE(RNDIS_QUERY_COMPLETE);            
            uiMessageSize    = uiRndisQuerySize + dwBufferLength;

            if (uiMessageSize > sizeof(m_outgoingMsg))
            {
                USBDBGMSG(USBDBG_ZONE_ERROR, (
                    L"RNdis:: SendRndisMessage: REMOTE_NDIS_QUERY_CMPLT: "
                    L"Message too big for statically allocated space.\r\n"
                    ));
                break;
            }
            
            pucBuffer = (PUCHAR)(&m_outgoingMsg.rndisMsg) + uiRndisQuerySize;

            //  Have the buffer will fill now..
            //

            m_outgoingMsg.rndisMsg.NdisMessageType = dwRndisMessageType;
            m_outgoingMsg.rndisMsg.MessageLength   = uiMessageSize;     
            pQueryComplete = &(m_outgoingMsg.rndisMsg.Message.QueryComplete);
            pQueryComplete->RequestId               = dwRequestId;          
            pQueryComplete->Status                  = NdisStatus;
            pQueryComplete->InformationBufferLength = dwUnspecified1;           

            pQueryComplete->InformationBufferOffset = (dwBufferLength == 0) ? 
                    (0) : 
                    (pucBuffer - (PUCHAR)pQueryComplete);           

            if (dwBufferLength)             
                memcpy(pucBuffer, pucInBuffer, dwUnspecified1);

            break;
        }

        //  Both messages have same entries..
        //  They are only interested in NdisStatus..
        //

        case REMOTE_NDIS_KEEPALIVE_CMPLT:
        case REMOTE_NDIS_SET_CMPLT:
        {
            PRNDIS_KEEPALIVE_COMPLETE   pKeepAliveOrSetComplete;

            uiMessageSize = RNDIS_MESSAGE_SIZE(RNDIS_KEEPALIVE_COMPLETE); 
            
            if (uiMessageSize > sizeof(m_outgoingMsg))
            {
                USBDBGMSG(USBDBG_ZONE_ERROR, (
                    L"RNdis:: SendRndisMessage: REMOTE_NDIS_SET_CMPLT: Message "
                    L"too big for statically allocated space.\r\n"
                    ));
                break;
            }

            m_outgoingMsg.rndisMsg.NdisMessageType = dwRndisMessageType;
            m_outgoingMsg.rndisMsg.MessageLength   = uiMessageSize;
            pKeepAliveOrSetComplete = &(m_outgoingMsg.rndisMsg.Message.KeepaliveComplete);
            pKeepAliveOrSetComplete->RequestId = dwRequestId;
            pKeepAliveOrSetComplete->Status    = NdisStatus;
            break;
        }

        case REMOTE_NDIS_RESET_CMPLT:
        {
            PRNDIS_RESET_COMPLETE   pResetComplete;

            uiMessageSize = RNDIS_MESSAGE_SIZE(RNDIS_RESET_COMPLETE); 
            
            if (uiMessageSize > sizeof(m_outgoingMsg))
            {
                USBDBGMSG(USBDBG_ZONE_ERROR, (
                    L"RNdis:: SendRndisMessage: REMOTE_NDIS_RESET_CMPLT: "
                    L"Message too big for statically allocated space.\r\n"
                    ));
                break;
            }
            
            m_outgoingMsg.rndisMsg.NdisMessageType = dwRndisMessageType;
            m_outgoingMsg.rndisMsg.MessageLength   = uiMessageSize;
            pResetComplete = &(m_outgoingMsg.rndisMsg.Message.ResetComplete);

            //  Reset is always successful..
            //  We always require host to return the multicast list etc..
            pResetComplete->Status          = NDIS_STATUS_SUCCESS;          
            pResetComplete->AddressingReset = 0x00;                     
            break;
        }
        
        default:
            USBDBGMSG(USBDBG_ZONE_ERROR, (
                L"ERROR: SendRndisMessage:: Incorrect message send "
                L"request\r\n"));
            return;
    }


    //  Send it out..
    //  Buffer will return back to us and freed in 
    //  RndisPdd_SendMessageComplete()
    USBDBGMSG (USBDBG_ZONE_VERBOSE,
        (L"RNdis:: Sending Msg [%s]\r\n",
        dwRndisMessageType == REMOTE_NDIS_INITIALIZE_CMPLT  ? 
            L"INIT-CMPLT" :
        dwRndisMessageType == REMOTE_NDIS_QUERY_CMPLT       ? 
            L"QUERY-CMPLT":
        dwRndisMessageType == REMOTE_NDIS_SET_CMPLT         ? 
            L"SET-CMPLT"  :
        dwRndisMessageType == REMOTE_NDIS_RESET_CMPLT       ? 
            L"RESET-CMPLT":
        dwRndisMessageType == REMOTE_NDIS_KEEPALIVE_CMPLT   ? 
            L"KEEPALIVE-CMPLT" :
            L"UNKNOWN!"
        ));

    UsbRndis_SendMessage((PBYTE)&m_outgoingMsg,
                         m_outgoingMsg.rndisMsg.MessageLength);

}

//------------------------------------------------------------------------------
//  Wait for Rndis to Init.
//
static 
BOOL
IsRndisInit(
    )
{
    DWORD retryCnt = 0;
    
    if (m_rndisDev.dwCurrentPacketFilter != 0)
        return TRUE;

#define INIT_RETRY_COUNT 5

    // call event handler to give an opportunity to initialize
    do
    {
        UsbRndis_EventHandler();
    }
    while ((m_rndisDev.dwCurrentPacketFilter == 0) && 
           (retryCnt++ < INIT_RETRY_COUNT));
           
    // if not initialized return FALSE
    if (m_rndisDev.dwCurrentPacketFilter == 0)
    {
        USBDBGMSG(USBDBG_ZONE_VERBOSE, (
            L"INFO: RNdis:: Not initialized. Aborting send/recv frame\r\n"
            ));
        return FALSE;
    }

    return TRUE;
}

/// Public Functions (interface implementation)
/// 
///

//---------------------------------------------------------------------------//
/// incoming OAL_KITL_ETH_DRIVER interface

//------------------------------------------------------------------------------
// Description: Signature matches OAL_KITLETH_INIT defined in oal_kitl.h
//              Called by KITL or DLE to initialize USB DBG RNDIS.
//
// Returns: TRUE if initialized
//          else returns FALSE
// 
BOOL 
Rndis_Init(
    UINT8 *pAddress,
    UINT32 offset,
    UINT16 mac[3]
    )
{
#define INITIALTIME_SEC 300
    DWORD dwStartSec;

    m_rndisDev.state = RNDIS_UNINITIALIZED;

    // copy mac address
    //
    if ((mac[0] == 0) && (mac[1] == 0) && (mac[2] == 0))
    {
        USBDBGMSG(USBDBG_ZONE_ERROR, (
            L"ERROR: RNdis:: Empty MAC address passed to Rndis_Init\r\n"
            ));
        return FALSE;
    }
    
    memcpy(&m_rndisDev.MacAddr, &mac[0], 6);
    USBDBGMSG(USBDBG_ZONE_INFO, (
        L"RNdis:: Init: MAC address:%x-%x-%x-%x-%x-%x\r\n",
        m_rndisDev.MacAddr[0], m_rndisDev.MacAddr[1],
        m_rndisDev.MacAddr[2], m_rndisDev.MacAddr[3],
        m_rndisDev.MacAddr[4], m_rndisDev.MacAddr[5]
        )); 

    // init lower layer - usbrndis
    //
    UsbRndis_Init(mac);

    
    // For RNDIS packets to flow from host to device, MAC address of the
    // the virtual ethernet adapter and device MAC address should be different.
    // Change OUI to locally administered address.
    m_rndisDev.MacAddr[0] |= 0x02;

    USBDBGMSG(USBDBG_ZONE_INFO, (L"UsbDbgRndis:: Waiting to connect ...\r\n"));

    // wait for RNDIS init msg from host and filters for INITIALTIME_SEC
    //
    dwStartSec=OEMKitlGetSecs();
    while (OEMKitlGetSecs()-dwStartSec<=INITIALTIME_SEC) {
        UsbRndis_EventHandler();             // call message handler
        if (m_rndisDev.dwCurrentPacketFilter != 0)
            break;
    }

    // print success/failure message
    //
    if (m_rndisDev.dwCurrentPacketFilter != 0) {
        USBDBGMSG(USBDBG_ZONE_INFO, (L"RNdis:: initialization: Success\r\n"));
        return TRUE;
    }
    else {
        USBDBGMSG(USBDBG_ZONE_ERROR, (L"RNdis:: initialization: Fail!\r\n"));
        return FALSE;
    }    
}

void 
Rndis_EnableInts(
    )
{
    //empty
}

void
Rndis_DisableInts(
    )
{
    //empty
}   

void
Rndis_CurrentPktFilter(
    UINT32 filter
    )
{
    //empty
}

//------------------------------------------------------------------------------
// Description: Signature matches OAL_KITLETH_SEND_FRAME defined in oal_kitl.h
//              Called by KITL or DLE to send a packet over USB DBG RNDIS.
//
// Returns: ERROR_SUCCESS if no error
//          else return error code
// 
UINT16
Rndis_SendFrame(

⌨️ 快捷键说明

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