📄 rndis.c
字号:
OALMSG(OAL_ERROR, (L"No mem for RX data\r\n"));
MDDFreeDataWrapper(g_pEP1DataWrapper);
return;
}
g_pEP1DataWrapper->dwDataSize = MAX_INCOMING_BUFFER;
}
// g_EP1Transfer.dwCallerPermissions;
g_EP1Transfer.pvBuffer = g_pEP1DataWrapper->pucData;
// g_EP1Transfer.dwBufferPhysicalAddress; // not used
g_EP1Transfer.cbBuffer = g_pEP1DataWrapper->dwDataSize;
g_EP1Transfer.cbTransferred = 0;
g_EP1Transfer.dwUsbError = UFN_NOT_COMPLETE_ERROR; // Possible values are in usbfntypes.h
g_EP1Transfer.pvPddData = NULL;
g_EP1Transfer.pvPddTransferInfo = NULL;
g_EP1Transfer.dwFlags = 0;
g_pddInterface.pfnIssueTransfer( g_pddInterface.pvPddContext, 1, &g_EP1Transfer );
}
// parses the setup packet received on EP0
BOOL HandleSetupPacket(USB_DEVICE_REQUEST *pUdr, EP0_REQUEST *pRequest)
{
if (pUdr->bmRequestType & (USB_REQUEST_CLASS | USB_REQUEST_VENDOR)) {
if (PDD_DoVendorCommand(pUdr, pRequest)) {
// do nothing
} else {
OALMSG(OAL_ERROR, (
L"**** Unhandled verndor command 0x%x\r\n", pUdr->bRequest
));
pRequest->eDir = EP0Setup;
pRequest->pucData = NULL;
pRequest->dwExpectedSize = 0;
pRequest->dwActualSize = 0;
pRequest->pfnNotification = NULL;
pRequest->pvUser = NULL;
}
return TRUE;
}
// standard chapter 9 commands
pRequest->eDir = EP0Setup;
pRequest->pucData = NULL;
pRequest->dwExpectedSize = 0;
pRequest->dwActualSize = 0;
pRequest->pfnNotification = NULL;
pRequest->pvUser = NULL;
switch(pUdr->bRequest) {
case USB_REQUEST_GET_STATUS:
if (pUdr->bmRequestType == 0x82) {
// TODO: handle this
OALMSG(OAL_WARN, (L"***RequestType==0x82\r\n"));
// check for the stall bit
}
break;
case USB_REQUEST_CLEAR_FEATURE:
if (pUdr->bmRequestType == 0x02) {
// TODO: handle this
OALMSG(OAL_WARN, (L"***RequestType==0x02\r\n"));
}
break;
case USB_REQUEST_SET_FEATURE:
if (pUdr->bmRequestType == 0x02) {
// TODO: handle this
OALMSG(OAL_WARN, (L"***RequestType==0x02\r\n"));
}
break;
case USB_REQUEST_SET_ADDRESS:
// TODO: handle this
break;
case USB_REQUEST_GET_DESCRIPTOR:
if (PDD_GetDescriptor(pUdr, pRequest)) {
// do nothing
} else {
OALMSG(OAL_ERROR, (
L"*** UnHandled GET_DESCRIPTOR request:0x%x\r\n",
pUdr->wValue
));
}
break;
case USB_REQUEST_SET_DESCRIPTOR:
// TODO: handle this
break;
case USB_REQUEST_GET_CONFIGURATION:
// TODO: handle this
break;
case USB_REQUEST_SET_CONFIGURATION:
OALStall(5000);
// setup RX transfer on EP1
SetupEP1Transfer();
////pDev->ucConfigValue = (BYTE)pUdr->wValue;
break;
case USB_REQUEST_GET_INTERFACE:
// TODO: handle this
break;
case USB_REQUEST_SET_INTERFACE:
// TODO: handle this
break;
case USB_REQUEST_SYNC_FRAME:
// TODO: handle this
break;
default:
OALMSG(OAL_WARN, (
L"*** Unknown request 0x%x\r\n", pUdr->bRequest
));
}
return TRUE;
}
// indicates to the KITL MDD that a packet has been sent
void TxComplete(void)
{
RNDIS_KITLDEV *pRndisKitlDev = &g_RndisKitlDev;
OALMSG(OAL_ETHER&&OAL_FUNC, (
L"SendPacket request completed! [%d bytes]\r\n",
g_EP2Transfer.cbTransferred
));
MddSendRndisPacketComplete(pRndisKitlDev->pTxDataWrapper);
OALMSG(OAL_ETHER&&OAL_FUNC, (L"Done\r\n"));
pRndisKitlDev->pTxDataWrapper = NULL;
}
// The USB FN PDD will call this function to notify it of various events (data sent/received,
// setup packet received, device addressed, reset, etc.
BOOL WINAPI NotifyHandler (
PVOID pvMddContext,
DWORD dwMsg,
DWORD dwParam
)
{
USB_DEVICE_REQUEST request;
EP0_REQUEST EP0Request;
STransfer *pTransfer;
switch( dwMsg )
{
case UFN_MSG_SETUP_PACKET:
request = *(USB_DEVICE_REQUEST*)(void*)dwParam;
g_udr = request;
if( !HandleSetupPacket( &g_udr, &EP0Request ) )
{
OALMSG(OAL_ERROR, (L"ERROR PARSING SETUP PACKET\r\n"));
}
memcpy(&g_RndisKitlDev.EP0Request, &EP0Request, sizeof(EP0Request));
g_RndisKitlDev.EP0Request.dwProcessed = 0;
g_RndisKitlDev.EP0Request.fCompleted = FALSE;
if (g_RndisKitlDev.EP0Request.eDir != EP0Setup) {
g_EP0DataWrapper.pucData = g_RndisKitlDev.EP0Request.pucData;
g_EP0DataWrapper.dwDataSize = g_RndisKitlDev.EP0Request.dwActualSize;
// g_EP2Transfer.dwCallerPermissions;
g_EP0Transfer.pvBuffer = g_EP0DataWrapper.pucData;
// g_EP2Transfer.dwBufferPhysicalAddress; // not used
g_EP0Transfer.cbBuffer = g_EP0DataWrapper.dwDataSize;
g_EP0Transfer.cbTransferred = 0;
g_EP0Transfer.dwUsbError = UFN_NOT_COMPLETE_ERROR; // Possible values are in usbfntypes.h
g_EP0Transfer.pvPddData = NULL;
g_EP0Transfer.pvPddTransferInfo = NULL;
if (g_RndisKitlDev.EP0Request.eDir == EP0In) {
OALMSG(OAL_ETHER&&OAL_FUNC, (L"Got SETUP IN packet\r\n"));
g_EP0Transfer.dwFlags = USB_REQUEST_DEVICE_TO_HOST;
g_EP0TransferState = TS_SENDING_MESSAGE;
g_pddInterface.pfnIssueTransfer( g_pddInterface.pvPddContext, 0, &g_EP0Transfer );
}
else
{
OALMSG(OAL_ETHER&&OAL_FUNC, (L"Got SETUP OUT packet.\r\n"));
g_EP0Transfer.dwFlags = 0;
g_EP0TransferState = TS_RECEIVING_MESSAGE;
g_pddInterface.pfnIssueTransfer( g_pddInterface.pvPddContext, 0, &g_EP0Transfer );
}
}
else
{
OALMSG(OAL_ETHER&&OAL_FUNC, (
L"Got SETUP <NO DATA: %x %x %x %x %x> packet.\r\n",
g_udr.bmRequestType, g_udr.bRequest, g_udr.wValue, g_udr.wIndex,
g_udr.wLength
));
// Send the SETUP ACK packet
g_EP0TransferState = TS_IDLE;
g_pddInterface.pfnSendControlStatusHandshake( g_pddInterface.pvPddContext, 0 );
}
break;
case UFN_MSG_TRANSFER_COMPLETE:
pTransfer = (STransfer *)dwParam;
if( pTransfer == &g_EP0Transfer )
{
switch( g_EP0TransferState )
{
case TS_RECEIVING_MESSAGE:
g_EP0TransferState = TS_IDLE;
OALMSG(OAL_ETHER&&OAL_FUNC, (L"Done receiving data.\r\n"));
g_pddInterface.pfnSendControlStatusHandshake( g_pddInterface.pvPddContext, 0 );
if (g_RndisKitlDev.EP0Request.pfnNotification) {
OALMSG(OAL_ETHER&&OAL_FUNC, (L"Received a message!\r\n"));
g_RndisKitlDev.EP0Request.pfnNotification(&g_RndisKitlDev.EP0Request, g_RndisKitlDev.EP0Request.pvUser);
}
memset(&g_RndisKitlDev.EP0Request, 0, sizeof (g_RndisKitlDev.EP0Request));
break;
case TS_SENDING_MESSAGE:
OALMSG(OAL_ETHER&&OAL_FUNC, (L"Done sending data.\r\n"));
g_EP0TransferState = TS_IDLE;
g_pddInterface.pfnSendControlStatusHandshake( g_pddInterface.pvPddContext, 0 );
if (g_RndisKitlDev.EP0Request.pfnNotification) {
OALMSG(OAL_ETHER&&OAL_FUNC, (L"SendMessage request completed!\r\n"));
g_RndisKitlDev.EP0Request.pfnNotification(&g_RndisKitlDev.EP0Request, g_RndisKitlDev.EP0Request.pvUser);
//memset(&g_RndisKitlDev.EP0Request, 0, sizeof (g_RndisKitlDev.EP0Request));
g_RndisKitlDev.EP0Request.pfnNotification = NULL;
g_RndisKitlDev.EP0Request.pvUser = NULL;
}
break;
}
}
else if( pTransfer == &g_EP1Transfer )
{
// BULK OUT data received on EP1
OALMSG(OAL_ETHER&&OAL_FUNC, (
L"Received a packet [%d bytes]!\r\n", pTransfer->cbTransferred
));
// notify the MDD
g_pEP1DataWrapper->dwDataSize = pTransfer->cbTransferred;
MddIndicateRndisPacket(g_pEP1DataWrapper);
g_pEP1DataWrapper = NULL;
// setup another transfer
SetupEP1Transfer();
}
else if( pTransfer == &g_EP2Transfer )
{
if( g_EP2TransferState == TS_SENDING_PACKET )
{
if( ( g_EP2Transfer.cbTransferred % EPMaxSize ) == 0 )
{
// g_EP2Transfer.dwCallerPermissions;
g_EP2Transfer.dwFlags = USB_REQUEST_DEVICE_TO_HOST;
#ifdef USE_1BYTE_TERMINATING_PACKETS
g_EP2Transfer.pvBuffer = &g_ucScratch;
g_EP2Transfer.cbBuffer = sizeof(UCHAR);
#else
g_EP2Transfer.pvBuffer = NULL;
g_EP2Transfer.cbBuffer = 0;
#endif
// g_EP2Transfer.dwBufferPhysicalAddress; // not used
g_EP2Transfer.cbTransferred = 0;
g_EP2Transfer.dwUsbError = UFN_NOT_COMPLETE_ERROR; // Possible values are in usbfntypes.h
g_EP2Transfer.pvPddData = NULL;
g_EP2Transfer.pvPddTransferInfo = NULL;
OALMSG(OAL_ETHER&&OAL_FUNC, (
L"Sending NULL terminator for the packet...\r\n"
));
g_EP2TransferState = TS_SENDING_PACKET_TERMINATOR;
g_pddInterface.pfnIssueTransfer( g_pddInterface.pvPddContext, 2, &g_EP2Transfer );
}
else
{
g_EP2TransferState = TS_IDLE;
TxComplete();
}
}
else if( g_EP2TransferState == TS_SENDING_PACKET_TERMINATOR )
{
ASSERT( g_EP2Transfer.dwUsbError == UFN_NO_ERROR );
OALMSG(OAL_ETHER&&OAL_FUNC, (L"SendPacket NULL terminator sent!\r\n"));
g_EP2TransferState = TS_IDLE;
TxComplete();
}
else
{
OALMSG(OAL_ERROR, (L"Unexpected EP2 transfer state!"));
}
}
else if( pTransfer == &g_EP3Transfer )
{
OALMSG(OAL_ETHER&&OAL_FUNC, (
L"EP3 Interrupt successfully sent!\r\n"
));
// interrupt succesfully sent
}
else
{
OALMSG(OAL_ERROR, (L"INVALID TRANSFER!\r\n"));
}
break;
case UFN_MSG_BUS_EVENTS:
switch( dwParam )
{
case UFN_DETACH:
g_devState = DS_DETACHED;
break;
case UFN_ATTACH:
g_devState = DS_ATTACHED;
break;
case UFN_RESET:
g_devState = DS_DEFAULT;
g_EP0TransferState = TS_IDLE;
g_EP2TransferState = TS_IDLE;
break;
case UFN_SUSPEND:
g_devState = DS_ATTACHED;
break;
case UFN_RESUME:
g_devState = DS_ATTACHED;
break;
default:
ASSERT(!"Unexpected bus event!");
}
break;
case UFN_MSG_BUS_SPEED:
break;
case UFN_MSG_SET_ADDRESS:
if( dwParam )
{
g_devState = DS_ADDRESSED;
}
else
{
g_devState = DS_DEFAULT;
}
// we should call pfnSetAddress here
break;
default:
ASSERT(!"Unexpected Msg in NotifyHandler!");
}
return FALSE;
}
// register the USB device, setup the non zero endpoints
void RegisterUSBDevice()
{
static USB_DEVICE_DESCRIPTOR deviceDescriptor;
static UFN_ENDPOINT rgEndPoints[3];
static UFN_INTERFACE Interface;
static UFN_CONFIGURATION deviceConfiguration;
deviceConfiguration.pInterfaces = &Interface;
deviceConfiguration.Descriptor.bNumInterfaces = 1;
Interface.pEndpoints = rgEndPoints;
Interface.Descriptor.bNumEndpoints = 3;
rgEndPoints[0].Descriptor.bEndpointAddress = 0x01; // EP1, OUT (BULK)
rgEndPoints[0].Descriptor.wMaxPacketSize = EPMaxSize;
rgEndPoints[0].Descriptor.bmAttributes = 0;
rgEndPoints[1].Descriptor.bEndpointAddress = 0x82; // EP2, IN (BULK)
rgEndPoints[1].Descriptor.wMaxPacketSize = EPMaxSize;
rgEndPoints[1].Descriptor.bmAttributes = 0;
rgEndPoints[2].Descriptor.bEndpointAddress = 0x83; // EP3, IN (INT)
rgEndPoints[2].Descriptor.wMaxPacketSize = EPMaxSize;
rgEndPoints[2].Descriptor.bmAttributes = 0;
deviceDescriptor.bMaxPacketSize0 = EP0MaxSize;
// We assume knowledge of the RegisterDevice function implementation and pass very simplified arguments
g_pddInterface.pfnRegisterDevice( g_pddInterface.pvPddContext,
NULL, NULL, NULL,
&deviceDescriptor, &deviceConfiguration, NULL,
NULL, 0 );
}
// initialize the USB KITL driver
BOOL PDDInit(
RNDIS_PDD_CHARACTERISTICS* pRndisPddCharacteristics,
PBYTE pBaseAddress
)
{
PDDZONE0 = 0;
PDDZONE = 0;
MDDZONE0 = 0;
MDDZONE = 1;
MDDZONE2 = 1;
MDDZONE3 = 1;
MDDZONE4 = 1;
MDDZONE5 = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -