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

📄 rndismin.c

📁 6410BSP3
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//

#include <windows.h>
#include <oal.h>
#include <ndis.h>
#include <usbdbgrndis.h>
#include <usbdbgddsi.h>
#include "rndismin.h"
#include "usbrndis.h"


///=============================================================================
/// Local defines
///=============================================================================

#define USBDBG_KITL_MTU             1520        // same as KITL_MTU
#define MAX_OUTGOING_PKT_SIZE       USBDBG_KITL_MTU
#define MAX_OUTGOING_MSG_SIZE       1024

#define RNDIS_MAX_TRANSFER_SIZE     8192        

#define MDD_DRIVER_MAJOR_VERSION    1
#define MDD_DRIVER_MINOR_VERSION    0

#define DEFAULT_MULTICASTLIST_MAX   8   //  Most adapters should support
                                        //      this minimum no..

// vendorid sent to host in response to OID_GEN_VENDOR_ID
// 0xFFFFFF = IEEE-registered code not available
#define RNDIS_VENDORID  0xFFFFFF;
// NIC description sent to host in response to OID_GEN_VENDOR_DESCRIPTION
#define RNDIS_VENDORDESC "Microsoft RNDIS virtual adapter miniport.\0"


///=============================================================================
/// Static variables
///=============================================================================

static struct
{
    RNDIS_MESSAGE rndisMsg;
    BYTE          outgoingBuf[MAX_OUTGOING_MSG_SIZE];
} m_outgoingMsg;

static struct
{
    RNDIS_MESSAGE rndisMsg;
    BYTE          outgoingPktBuf[MAX_OUTGOING_PKT_SIZE];
} m_outgoingPkt;

static RNDIS_MESSAGE m_rndisMsg;

// vendorid sent to host in response to OID_GEN_VENDOR_ID
static const UINT32 m_rndisVendorId = RNDIS_VENDORID;
// NIC description sent to host in response to OID_GEN_VENDOR_DESCRIPTION
static const UCHAR m_pucRndisVendorDesc[] = RNDIS_VENDORDESC;

static UINT32 RNdisMddSupportedOids[] = 
{
    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_CRC_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,
    OID_GEN_MAXIMUM_SEND_PACKETS,
    OID_GEN_VENDOR_DRIVER_VERSION,
    OID_GEN_MEDIA_CONNECT_STATUS,

/*
//not supported
#ifdef NDIS50_MINIPORT

    //
    //  Power Management..
    //
    
    OID_PNP_CAPABILITIES,
    OID_PNP_SET_POWER,
    OID_PNP_QUERY_POWER,
    OID_PNP_ADD_WAKE_UP_PATTERN,
    OID_PNP_REMOVE_WAKE_UP_PATTERN,
    OID_PNP_ENABLE_WAKE_UP    
#endif
*/
};      

static struct 
{
    UINT32              state;                  //  From host point of view.

    //  Rndis miniport operation.
    DWORD               dwCurrentPacketFilter;  //  Current Filter.     
    UCHAR               MacAddr[6];
    UCHAR               MulticastAddresses[DEFAULT_MULTICASTLIST_MAX][6];
    DWORD               dwMulticastListInUse;
}   m_rndisDev;


///=============================================================================
/// Local functions
///=============================================================================

#if 0
extern ULONG SC_GetThreadCallStack (HANDLE hThrd, ULONG dwMaxFrames,
                                    LPVOID lpFrames, DWORD dwFlags,
                                    DWORD dwSkip);
//------------------------------------------------------------------------------
// Description: (utility function) Logs call stack to serial port
//
// Note: Not available in bootloader 
static
void
LogCallStack()
{
    HANDLE hThread = GetCurrentThread();
    #define MAX_FRAMES 10
    CallSnapshotEx lpFrames[MAX_FRAMES];
    DWORD dwCnt, i = 0;

    USBDBGMSG(USBDBG_ZONE_INFO, (L"Current Stack: \r\n"));

    dwCnt = SC_GetThreadCallStack   (hThread,
                                    MAX_FRAMES,
                                    lpFrames,
                                    STACKSNAP_EXTENDED_INFO,
                                    0);
    for (i=0; i < dwCnt; i++)
        USBDBGMSG(USBDBG_ZONE_INFO, (L"RA=0x%x FP=0x%x CP=0x%x PR=0x%x\r\n",
                    lpFrames[i]));

}
#endif

#ifdef DEBUG
static
void
DumpPacket(
    DWORD zone,
    BYTE* pData,
    UINT32 cbDataSize
    )
{
    UINT32 i;

    if (g_UsbDbgZones & (zone))
    {
        for (i=0; i < cbDataSize; i++)
        {
            USBDBGMSG(zone, (L"%02X ", *((PUCHAR)(pData+i))));
            if ( (i+1) % 25 == 0)
                USBDBGMSG(zone, (L"\r\n"));
        }
        if ( i % 25 != 0)
            USBDBGMSG(zone, (L"\r\n"));
    }
}
#endif


//------------------------------------------------------------------------------
// Description: Process NDIS query request
//
// Arguments:
//      NDIS_OID    NDIS OID
//      PVOID       pvInformationBuffer
//      ULONG       ulInformationBufferLength
//      PULONG      pulBytesWritten
//      PULONG      pulBytesNeeded
//
//  Return Value:
//      NDIS_STATUS
//
static 
NDIS_STATUS
HostMiniQueryInformation(    
    IN NDIS_OID Oid,
    IN PVOID    pvInformationBuffer,
    IN ULONG    ulInformationBufferLength,
    OUT PULONG  pulBytesWritten,
    OUT PULONG  pulBytesNeeded
    )
{       
    ULONG       GenericUlong;
    USHORT      GenericUshort;
    PUCHAR      pucBuffer    = (PUCHAR)&GenericUlong;       
    ULONG       ulTotalBytes = sizeof(ULONG);       
    NDIS_STATUS NdisStatus   = NDIS_STATUS_SUCCESS;

    *pulBytesNeeded = *pulBytesWritten = 0;

    switch (Oid) 
    {   
        case OID_GEN_MAC_OPTIONS:
            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:
            pucBuffer = (PUCHAR)RNdisMddSupportedOids;
            ulTotalBytes   = sizeof(RNdisMddSupportedOids);         
            break;

        case OID_GEN_HARDWARE_STATUS:           
            GenericUlong = NdisHardwareStatusReady;         
            break;

        case OID_GEN_MEDIA_SUPPORTED:
        case OID_GEN_MEDIA_IN_USE:
            GenericUlong = NdisMedium802_3;         
            break;

        case OID_GEN_MAXIMUM_FRAME_SIZE:
            GenericUlong = 1500;
            break;

        case OID_GEN_LINK_SPEED:
            GenericUlong = (ULONG)(100000);
            break;

        case OID_GEN_TRANSMIT_BLOCK_SIZE:
            GenericUlong = 1518;
            break;      

        case OID_GEN_RECEIVE_BLOCK_SIZE:
            GenericUlong = 1518;
            break;

        case OID_GEN_MAXIMUM_LOOKAHEAD:
            GenericUlong = 1500;
            break;

        case OID_GEN_VENDOR_ID:
            GenericUlong = m_rndisVendorId;
            ulTotalBytes = 4;
            break;

        case OID_GEN_VENDOR_DESCRIPTION:        
            pucBuffer = (PUCHAR) &m_pucRndisVendorDesc[0];
            ulTotalBytes = strlen(m_pucRndisVendorDesc);
            break;

        case OID_GEN_VENDOR_DRIVER_VERSION:
            GenericUshort = (MDD_DRIVER_MAJOR_VERSION << 8) + 
                            (MDD_DRIVER_MINOR_VERSION);
            pucBuffer    = (PUCHAR)&GenericUshort;
            ulTotalBytes = sizeof(USHORT);
            break;

        case OID_GEN_CURRENT_PACKET_FILTER:         
            GenericUlong = m_rndisDev.dwCurrentPacketFilter;
            break;

        case OID_GEN_MAXIMUM_TOTAL_SIZE:
            GenericUlong = (ULONG)(1514);
            break;

        case OID_GEN_MEDIA_CONNECT_STATUS:
            GenericUlong = NdisMediaStateConnected;
            break;

        case OID_802_3_PERMANENT_ADDRESS:
            pucBuffer    = m_rndisDev.MacAddr;
            ulTotalBytes = 6;
            break;

        case OID_802_3_CURRENT_ADDRESS:            
            pucBuffer    = m_rndisDev.MacAddr;
            ulTotalBytes = 6;
            break;

        case OID_GEN_MAXIMUM_SEND_PACKETS:
            //  Arbitrarily chosen number..
            GenericUlong = 16;
            break;

        case OID_802_3_MAXIMUM_LIST_SIZE:
            GenericUlong = RNDIS_MAX_PACKETS_PER_MESSAGE;             
            break;
        
        case OID_GEN_XMIT_OK:
            GenericUlong = 0;   
            break;

        case OID_GEN_RCV_OK:
            GenericUlong = 0;   
            break;

        case OID_GEN_XMIT_ERROR:                    
            GenericUlong = 0;
            break;

        case OID_GEN_RCV_ERROR:                 
            GenericUlong = 0;
            break;

        case OID_GEN_RCV_NO_BUFFER:                 
            GenericUlong = 0;
            break;

        case OID_GEN_RCV_CRC_ERROR:                 
            GenericUlong = 0x00;
            break;
        
        default:
            USBDBGMSG(USBDBG_ZONE_WARN, (
                L"RNdis:: OID[%x] not yet implemented!\r\n", Oid
                ));         
            NdisStatus = NDIS_STATUS_INVALID_OID;
            break;
    
    }   //  switch()


    //  Everyone gets here...

    if (NdisStatus == NDIS_STATUS_SUCCESS) 
    {
        if (ulTotalBytes > ulInformationBufferLength) 
        {
            //  Not enough room in pvInformationBuffer. 
            *pulBytesNeeded = ulTotalBytes;
            NdisStatus = NDIS_STATUS_INVALID_LENGTH;
        } 
        else 
        {
            //  Store result.
            memcpy(pvInformationBuffer, pucBuffer, ulTotalBytes);
            *pulBytesWritten = ulTotalBytes;         
        }   
    }
    
    return NdisStatus;  

}

//------------------------------------------------------------------------------
//
//  Description: Handles a set operation for a single Oid
//
//  Arguments:
//   Oid                         - The OID of the set.
//   pvInformationBuffer         - Holds the data to be set.
//   ulInformationBufferLength   - The length of pvInformationBuffer.
//   pulBytesRead                - If the call is successful, returns the
//                                 number of bytes read from pvInformationBuffer
//   pulBytesNeeded              - If there is not enough data in 
//                                 pvInformationBuffer 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
//
static 
NDIS_STATUS
HostMiniSetInformation(
   IN   NDIS_OID    Oid,
   IN   PVOID       pvInformationBuffer,
   IN   ULONG       ulInformationBufferLength,
   OUT  PULONG      pulBytesRead,
   OUT  PULONG      pulBytesNeeded
   )
{    
    PUCHAR          InfoBuffer      = (PUCHAR)pvInformationBuffer;    
    DWORD           dwFilter;

    switch (Oid) 
    { 

        case OID_802_3_MULTICAST_LIST:                                      
            *pulBytesRead = ulInformationBufferLength;
            *pulBytesNeeded = 0;
            
            if ((ulInformationBufferLength % 6) != 0)
                return NDIS_STATUS_INVALID_LENGTH;          

            if ((ulInformationBufferLength / 6) > DEFAULT_MULTICASTLIST_MAX)
                return NDIS_STATUS_MULTICAST_FULL;
            
            memcpy(&(m_rndisDev.MulticastAddresses),
                    pvInformationBuffer, 
                    ulInformationBufferLength);

            m_rndisDev.dwMulticastListInUse = ulInformationBufferLength / 6;

            //  todo VEHub interface
            //  Do something here to inform VEHub that we are listening to the
            //  new set of multicast addresses..

⌨️ 快捷键说明

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