📄 usbrndis.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 <usb100.h>
#include <usbdbgddsi.h>
#include <usbfntypes.h>
#include <usbdbgutils.h>
#include "usbrndis.h"
///=============================================================================
/// extern variables
///=============================================================================
///=============================================================================
/// Extern functions
///=============================================================================
// implemented by PDD
extern BOOL UsbDbgPdd_Init (USBDBG_MDD_INTERFACE_INFO* pMddIfc,
USBDBG_PDD_INTERFACE_INFO* pPddIfc,
USBDBG_DEVICE_DESCRIPTOR* pDeviceDesc);
///=============================================================================
/// Local defines
///=============================================================================
#define SEND_RECV_TIME_OUT 20 // 20 secs
// Class Interface
#define CS_INTERFACE 0x24
//USB Communication Class specific request code used by RNDIS
#define SEND_ENCAPSULATED_COMMAND 0x00
#define GET_ENCAPSULATED_RESPONSE 0x01
#define EP0_MAX_MSG_RECV_BUFFER 1024
///=============================================================================
/// Local function prototypes
///=============================================================================
///=============================================================================
/// Static variables
///=============================================================================
// usb rndis descriptor
static UCHAR m_pucUSBDescriptors[] =
{
////////////////////////////////////////////////////////////////////////////
// Standard Device Descriptor
//
/* 0 */ 18, // bLength = 18 bytes.
/* 1 */ USB_DEVICE_DESCRIPTOR_TYPE, // bDescriptorType = DEVICE
/* 2 */ 0x10, 0x01, // bcdUSB = 1.1
/* 4 */ 0x02, // bDeviceClass = CDC
/* 5 */ 0x00, // bDeviceSubClass = 0
/* 6 */ 0x00, // bDeviceProtocol = 0
/* 7 */ 0, // bMaxPacketSize0 = EP0 buffer size. retrieved from PDD. 0 by default.
/* 8 */ 0x5E, 0x04, // idVendor = Microsoft Vendor ID.
/* 10 */ 0x01, 0x03, // idProduct = Microsoft generic RNDISMINI Product ID.
/* 12 */ 0x01, 0x00, // bcdDevice = 0.1
/* 14 */ 0x01, // iManufacturer = OEM should fill this..
/* 15 */ 0x02, // iProduct = OEM should fill this..
/* 16 */ 0x03, // iSerialNumber = OEM should fill this..
/* 17 */ 0x01, // bNumConfigs = 1
////////////////////////////////////////////////////////////////////////////
// RNDIS requires only one configuration as follows..
// And we have 2 interfaces (Communication Class if & Dataclass if).
//
/* 18 */ 9, // bLength = 9 bytes.
/* 19 */ USB_CONFIGURATION_DESCRIPTOR_TYPE, // bDescriptorType = CONFIGURATION
/* 20 */ 0x3e, 0x00, // wTotalLength = From offset 18 to end <---
/* 22 */ 0x02, // bNumInterfaces = 2 (RNDIS spec).
/* 23 */ 0x01, // bConfValue = 1
/* 24 */ 0x00, // iConfiguration = unused.
/* 25 */ 0xC0, // bmAttributes = Self-Powered & Bus-Powered
/* 26 */ 0x32, // MaxPower = 100mA
////////////////////////////////////////////////////////////////////////////
// Communication Class INTERFACE descriptor.
// RNDIS specifies 2 endpoints, EP0 & notification element (interrupt)
//
/* 27 */ 9, // bLength = 9 bytes.
/* 28 */ USB_INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType = INTERFACE
/* 29 */ 0x00, // bInterfaceNo = 0
/* 30 */ 0x00, // bAlternateSet = 0
/* 31 */ 0x01, // bNumEndPoints = 1 (RNDIS spec)
/* 32 */ 0x02, // bInterfaceClass = CDC
/* 33 */ 0x00, // bIfSubClass = 0
/* 34 */ 0x00, // bIfProtocol = 0
/* 35 */ 0x00, // iInterface = unused.
////////////////////////////////////////////////////////////////////////////
// Functional Descriptors for Communication Class Interface
// per RNDIS spec.
//
/* 36 */ 5, // bFunctionLength = 5 bytes.
/* 37 */ CS_INTERFACE, // bDescriptorType = Class Interface
/* 38 */ 0x01, // bDescSubType = CALL MGMT func descriptor.
/* 39 */ 0x00, // bmCapabilities = See sect 5.2.3.2 USB CDC
/* 40 */ 0x01, // bDataInterface = 1 data class i/f.
/* 41 */ 4, // bFunctionLength = 4 bytes.
/* 42 */ CS_INTERFACE, // bDescriptorType = Class Interface
/* 43 */ 0x02, // bDescSubType = ABSTRACT ctrl mgmt desc.
/* 44 */ 0x00, // bmCapabilities = See sect 5.2.3.3 USB CDC
/* 45 */ 5, // bFunctionLength = 5 bytes.
/* 46 */ CS_INTERFACE, // bDescriptorType = Class Interface.
/* 47 */ 0x02, // bDescSubType = UNION func descriptor.
/* 48 */ 0x00, // bMasterIf = i/f 0 is the master if.
/* 49 */ 0x01, // bSlaveIf = i/f 1 is the slave if.
////////////////////////////////////////////////////////////////////////////
// Endpoint descriptors for Communication Class Interface
//
/* 50 */ 7, // bLength = 7 bytes.
/* 51 */ USB_ENDPOINT_DESCRIPTOR_TYPE, // bDescriptorType = ENDPOINT
/* 52 */ 0x83, // bEndpointAddr = IN - EP3
/* 53 */ 0x03, // bmAttributes = Interrupt endpoint.
/* 54 */ 0, 0x00, // wMaxPacketSize. retrieved from PDD. 0 by default.
/* 56 */ 80, // bInterval = 80 ms polling from host.
////////////////////////////////////////////////////////////////////////////
// Data Class INTERFACE descriptor.
//
/* 57 */ 9, // bLength = 9 bytes.
/* 58 */ USB_INTERFACE_DESCRIPTOR_TYPE, // bDescriptorType = INTERFACE
/* 59 */ 0x01, // bInterfaceNo = 1
/* 60 */ 0x00, // bAlternateSet = 0
/* 61 */ 0x02, // bNumEndPoints = 2 (RNDIS spec)
/* 62 */ 0x0A, // bInterfaceClass = Data if class (RNDIS spec)
/* 63 */ 0x00, // bIfSubClass = unused.
/* 64 */ 0x00, // bIfProtocol = unused.
/* 65 */ 0x00, // iInterface = unused.
////////////////////////////////////////////////////////////////////////////
// Endpoint descriptors for Data Class Interface
//
/* 66 */ 7, // bLength = 7 bytes.
/* 67 */ USB_ENDPOINT_DESCRIPTOR_TYPE, // bDescriptorType = ENDPOINT [IN]
/* 68 */ 0x82, // bEndpointAddr = IN -- EP2
/* 69 */ 0x02, // bmAttributes = BULK
/* 70 */ 0, 0x00, // wMaxPacketSize. retrieved from PDD. 0 by default.
/* 72 */ 0, // bInterval = ignored for BULK.
/* 73 */ 7, // bLength = 7 bytes.
/* 74 */ USB_ENDPOINT_DESCRIPTOR_TYPE, // bDescriptorType = ENDPOINT [OUT]
/* 75 */ 0x01, // bEndpointAddr = OUT -- EP1
/* 76 */ 0x02, // bmAttributes = BULK
/* 77 */ 0, 0x00, // wMaxPacketSize. retrieved from PDD. 0 by default.
/* 79 */ 0 // bInterval = ignored for BULK.
}; // m_pucUSBDescriptors[]
// bookkeeping pointers and defines to m_pucUSBDescriptors
// change the offsets if you change m_pucUSBDescriptors
//
static USB_ENDPOINT_DESCRIPTOR* const m_pIntInEndPtDesc =
(USB_ENDPOINT_DESCRIPTOR*) &m_pucUSBDescriptors[50];
static USB_ENDPOINT_DESCRIPTOR* const m_pBulkInEndPtDesc =
(USB_ENDPOINT_DESCRIPTOR*) &m_pucUSBDescriptors[66];
static USB_ENDPOINT_DESCRIPTOR* const m_pBulkOutEndPtDesc =
(USB_ENDPOINT_DESCRIPTOR*) &m_pucUSBDescriptors[73];
static USB_ENDPOINT_DESCRIPTOR* const m_pUsbEndPointDescriptor[] =
{ (USB_ENDPOINT_DESCRIPTOR*) &m_pucUSBDescriptors[50],
(USB_ENDPOINT_DESCRIPTOR*) &m_pucUSBDescriptors[66],
(USB_ENDPOINT_DESCRIPTOR*) &m_pucUSBDescriptors[73]
};
static const USBDBG_INTERFACE_DESCRIPTOR m_intrfcDesc1 =
{
(USB_INTERFACE_DESCRIPTOR*) &m_pucUSBDescriptors[27],
(USB_ENDPOINT_DESCRIPTOR**) &m_pUsbEndPointDescriptor[0]
};
static const USBDBG_INTERFACE_DESCRIPTOR m_intrfcDesc2 =
{
(USB_INTERFACE_DESCRIPTOR*) &m_pucUSBDescriptors[57],
(USB_ENDPOINT_DESCRIPTOR**) &m_pUsbEndPointDescriptor[1]
};
static const USBDBG_INTERFACE_DESCRIPTOR* const m_pIntrfcDesc[] =
{
&m_intrfcDesc1,
&m_intrfcDesc2
};
static const USBDBG_CONFIG_DESCRIPTOR m_configDesc1 =
{
(USB_CONFIGURATION_DESCRIPTOR *) &m_pucUSBDescriptors[18],
(USBDBG_INTERFACE_DESCRIPTOR**) &m_pIntrfcDesc[0]
};
static const USBDBG_CONFIG_DESCRIPTOR* const m_configDesc[] =
{
&m_configDesc1
};
static const USBDBG_DEVICE_DESCRIPTOR m_deviceDesc =
{
(USB_DEVICE_DESCRIPTOR* ) &m_pucUSBDescriptors,
(USBDBG_CONFIG_DESCRIPTOR**) &m_configDesc[0]
};
#define CONFIGDESC_LEN 62 // len from starting of
// USB_CONFIGURATION_DESCRIPTOR_TYPE to end (80)
#define CONTROL_ENDPT 0 // control endpt
#define BULKOUT_ENDPT 1 // logical bulkout endpoint
#define BULKIN_ENDPT 2 // logical bulkin endpoint
#define INTIN_ENDPT 3 // logical intin endpoint
#define MAX_ENDPT INTIN_ENDPT
typedef struct {
DWORD Notification;
DWORD dwReserved;
} INTERRUPT_DATA, *PINTERRUPT_DATA;
static const INTERRUPT_DATA m_interruptData = {
0x01, // notification
0x00 // reserved
};
#define USBSERIALNUM_DEFAULT L"FFFFFFFFFFFF\0"
static USB_STRING m_UsbSerialNum =
{
sizeof(USBSERIALNUM_DEFAULT) + 2,
USB_STRING_DESCRIPTOR_TYPE,
USBSERIALNUM_DEFAULT
};
static const USB_STRING_DESCRIPTOR m_SupportedLang =
{
0x04,
USB_STRING_DESCRIPTOR_TYPE,
0x0409 // US English by default
};
static const USB_STRING m_Manufacturer =
{
sizeof(MANUFACTURER) + 2,
USB_STRING_DESCRIPTOR_TYPE,
MANUFACTURER
};
static const USB_STRING m_Product =
{
sizeof(PRODUCT) + 2,
USB_STRING_DESCRIPTOR_TYPE,
PRODUCT
};
static struct
{
PBYTE pbData;
UINT32 cbData;
BOOL fMsgSent;
} m_rndisMsgToSend;
static BYTE m_ep0MsgRxBuffer[EP0_MAX_MSG_RECV_BUFFER];
static BYTE m_MsgParamBuf[64]; // 64 bytes message buffer
// when registering with the USBFN PDD layer, the PDD will fill in this
// structure with appropriate data and function pointers
static USBDBG_PDD_INTERFACE_INFO m_pddIfc;
// contains the MDD version information
static USBDBG_MDD_INTERFACE_INFO m_mddInterface;
typedef struct {
PBYTE pbBuffer;
DWORD cbTransferSize;
DWORD transferFlags;
DWORD status;
DWORD cbTransferred;
DWORD SendRecvNULL;
DWORD cbToTransfer;
} EPTransfer;
static EPTransfer m_epTransfers[MAX_ENDPT+1];
static DWORD m_epMaxPktSize[MAX_ENDPT+1];
#define MAX_BULKRX_PKT_SIZE 1600
static BYTE m_BulkRxPktBuf[MAX_BULKRX_PKT_SIZE];
static BOOL m_fSetupCancelled = FALSE;
// transfer status'
#define USBDBG_TRANSFER_STATUS_INPROGRESS 0x00000001
#define USBDBG_TRANSFER_STATUS_COMPLETE 0x00000002
#define USBDBG_TRANSFER_STATUS_ABORTED 0x00000004
#define USBDBG_TRANSFER_STATUS_STARTED 0x00000008
///=============================================================================
/// Private Function Prototypes
///=============================================================================
///=============================================================================
/// Private Functions
///=============================================================================
// compute a unique device serial number using device MAC
static
BOOL
ComputeUSBSerialNumber(
UINT16 mac[3]
)
{
const TCHAR DigitTable[] = TEXT("0123456789ABCDEF");
BYTE b;
int i;
BYTE *pIdBytes;
DWORD dwBytesReturned = 0;
pIdBytes = (BYTE*)&mac[0];
for (i=0; i< 6; i++) {
b = pIdBytes[i];
m_UsbSerialNum.pwcbString[i * 2] = DigitTable[b % 16];
m_UsbSerialNum.pwcbString[(i * 2) + 1] = DigitTable[b / 16];
}
m_UsbSerialNum.pwcbString[sizeof(mac) * 2] = '\0';
return TRUE;
}
// start a transmit or receive transfer
static
void
StartTransfer(
DWORD epNum,
DWORD dir,
UINT8 *pData,
UINT32 cbDataLen,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -