📄 rndismin.c
字号:
//
// 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 + -