📄 usbrndis.c
字号:
}
// get end pt max pkt sizes from PDD
//
static
BOOL
UpdateUSBDesc(
)
{
UINT32 epNum;
// get end pt max size from PDD
for (epNum=0; epNum <= MAX_ENDPT; epNum++)
{
if (!m_pddIfc.pfnIoctl(
USBDBG_PDD_IOCTL_ENDPT_MAXPACKETSIZE,
(LPVOID) &epNum,
sizeof(epNum),
(LPVOID) &m_epMaxPktSize[epNum],
sizeof(m_epMaxPktSize[epNum]),
NULL))
{
USBDBGMSG(USBDBG_ZONE_ERROR, (
L"ERROR!usbdbg: Failed to retrieve maxpacketsize from PDD "
L"for ep=%d\r\n", epNum));
return FALSE;
}
}
m_deviceDesc.pUsbDeviceDescriptor->bMaxPacketSize0 =
(UCHAR) m_epMaxPktSize[CONTROL_ENDPT];
m_pBulkOutEndPtDesc->wMaxPacketSize = (WORD) m_epMaxPktSize[BULKOUT_ENDPT];
m_pBulkInEndPtDesc->wMaxPacketSize = (WORD) m_epMaxPktSize[BULKIN_ENDPT];
m_pIntInEndPtDesc->wMaxPacketSize = (WORD) m_epMaxPktSize[INTIN_ENDPT];
return TRUE;
}
///=============================================================================
/// Public Functions (RndisMin -> UsbRndis)
///=============================================================================
// Called by RndisMin to deinitialize
//
void
UsbRndis_Deinit(
)
{
// abort all transfers
AbortTransfers(TRUE, TRUE);
// disconnect
m_pddIfc.pfnDisconnect();
// deinit
m_pddIfc.pfnDeinit();
}
// Called by RndisMin & UsbRndis to get "interesting" events from PDD
//
UINT32
UsbRndis_EventHandler(
)
{
USBDBG_MSG msg = USBDBG_MSG_NOMSG;
DWORD retVal;
DWORD epNum;
static USB_DEVICE_REQUEST pendingUdr;
static BOOL fProcessingSetupRequest = FALSE;
USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbdbg:+UsbRndis_EventHandler\r\n"));
// call PDD to get any interesting events
retVal = m_pddIfc.pfnEventHandler(&msg, &m_MsgParamBuf[0]);
//quit if error
if (retVal != ERROR_SUCCESS)
{
USBDBGMSG(USBDBG_ZONE_ERROR, (
L"ERROR!usbdbg:UsbRndis_EventHandler\r\n"));
goto clean;
}
switch (msg)
{
// a packet received on an EP
case USBDBG_MSG_EP_RX_PKT:
{
epNum = *((DWORD*)m_MsgParamBuf);
ContinueRxTransfer(epNum);
break;
}
// a packet sent on an EP
case USBDBG_MSG_EP_TX_PKT:
{
epNum = *((DWORD*)m_MsgParamBuf);
ContinueTxTransfer(epNum);
break;
}
// set up packet recvd
case USBDBG_MSG_SETUP_PACKET:
{
USB_DEVICE_REQUEST udr = *((USB_DEVICE_REQUEST*) m_MsgParamBuf);
BOOL fProcessRndisMsg = FALSE;
// if a transfer is already in progress on EP0, mark this
// setup packet pending and return to unwind stack.
if (fProcessingSetupRequest)
{
m_fSetupCancelled = TRUE;
pendingUdr = udr;
// stop any transfers on EP0
if (m_epTransfers[0].status & USBDBG_TRANSFER_STATUS_INPROGRESS)
{
AbortTransfer(CONTROL_ENDPT, ENDPT_DIR_RX);
AbortTransfer(CONTROL_ENDPT, ENDPT_DIR_TX);
}
goto clean;
}
else
{
m_fSetupCancelled = FALSE;
}
fProcessingSetupRequest = TRUE;
ProcessSetupPacket(&udr, &fProcessRndisMsg);
fProcessingSetupRequest = FALSE;
//rndis msg received?
if (fProcessRndisMsg)
ProcessRndisMsg(m_ep0MsgRxBuffer, udr.wLength);
// while a setup packet was being processed another might have come
// in. udr's processing was cancelled and the pending udr was stored
// in m_pendingUdr.
while (m_fSetupCancelled)
{
m_fSetupCancelled = FALSE;
fProcessingSetupRequest = TRUE;
ProcessSetupPacket(&pendingUdr, &fProcessRndisMsg);
fProcessingSetupRequest = FALSE;
if (fProcessRndisMsg)
ProcessRndisMsg(m_ep0MsgRxBuffer, udr.wLength);
}
break;
}
case USBDBG_MSG_BUS_EVENT_DETACH:
case USBDBG_MSG_BUS_EVENT_SUSPEND:
case USBDBG_MSG_BUS_EVENT_RESET:
{
// tell rndismin layer
RndisPdd_SetRndisState(TRUE);
// abort all transfers
AbortTransfers(TRUE, TRUE);
// bus speed is determined, update ep's maxpktsize
UpdateUSBDesc();
break;
}
default:
break;
}
clean:
USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbdbg:-UsbRndis_EventHandler.msg=%d\r\n",
msg));
return msg;
}
// Called by RndisMin to send an RNDIS Message.
// We don't do the actual sending here but save it. We then trigger Interrupt
// endpoint to send interrupt to host which in turn uses EP0 to get data by
// sending GET_ENCAPSULATED_RESPONSE
//
void
UsbRndis_SendMessage(
PBYTE rndisMsg, /* (IN) rndis message to send */
UINT32 rndisMsgLen /* (IN) cb of rndisMsg */
)
{
USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbdbg:+UsbRndis_SendMessage.\r\n"));
m_rndisMsgToSend.pbData = rndisMsg;
m_rndisMsgToSend.cbData = rndisMsgLen;
m_rndisMsgToSend.fMsgSent = FALSE;
USBDBGMSG(USBDBG_ZONE_VERBOSE, (
L"UsbDbg:Queueing RNDIS Msg [%d bytes]. Issuing EP1 INT IN "
L"interrupt...\r\n",
rndisMsgLen
));
// send INT IN msg
SendRecvData(INTIN_ENDPT,
ENDPT_DIR_TX,
(PBYTE) &m_interruptData,
sizeof(m_interruptData),
0);
USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbdbg:-UsbRndis_SendMessage.\r\n"));
}
// Called by RndisMin to receive data packets (over EP3 BULK OUT)
//
DWORD
UsbRndis_RecvData(
PBYTE pbBuffer,
DWORD cbBufSize
)
{
DWORD cbRecvdData = 0;
DWORD epNum = BULKOUT_ENDPT; // data comes in on BULK OUT EP3
DWORD retryCnt = 0;
EPTransfer* pTransfer = &m_epTransfers[epNum];
#define RECV_RETRY_COUNT 20
USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbdbg:+UsbRndis_RecvData.\r\n"));
// call common events handler if rx in progress
while ((pTransfer->status & USBDBG_TRANSFER_STATUS_INPROGRESS) &&
(retryCnt++ < RECV_RETRY_COUNT))
{
UsbRndis_EventHandler();
}
if (pTransfer->status & USBDBG_TRANSFER_STATUS_COMPLETE)
{
// copy to return buffer
cbRecvdData = RndisPdd_ProcessRecvdData(pTransfer->pbBuffer,
pTransfer->cbTransferred,
pbBuffer,
cbBufSize);
}
//clean:
// if a transfer is not in progress start next transfer
if (!(pTransfer->status & USBDBG_TRANSFER_STATUS_INPROGRESS))
{
StartTransfer(epNum,
ENDPT_DIR_RX,
&m_BulkRxPktBuf[0],
sizeof(m_BulkRxPktBuf),
0);
}
USBDBGMSG(USBDBG_ZONE_FUNC, (L"usbdbg:-UsbRndis_RecvData.\r\n"));
return cbRecvdData;
}
// Called by RndisMin to send data packets (over EP2 BULK IN)
//
DWORD
UsbRndis_SendData(
UINT8 *pData, /* (IN) data to send */
UINT32 cbDataLen /* (IN) cb of data to send */
)
{
return SendRecvData(BULKIN_ENDPT, ENDPT_DIR_TX, pData, cbDataLen, 0);
}
//
// Called by RndisMin to check if the last rndis message has been sent
//
BOOL
UsbRndis_RndisMsgSent(
)
{
return m_rndisMsgToSend.fMsgSent;
}
void
UsbRndis_SetPower(
BOOL fPowerOff
)
{
m_pddIfc.pfnSetPower(fPowerOff);
}
// Called by RndisMin to initialize UsbDbgRndis stack
//
BOOL /* TRUE if success, FALSE if error */
UsbRndis_Init(
UINT16 mac[3] /* (IN) device mac address */
)
{
m_rndisMsgToSend.fMsgSent = TRUE;
m_mddInterface.version = 2;
memset(&m_pddIfc, 0, sizeof(m_pddIfc));
// Compute USB serial number using mac address.
// To be used later.
//
if (!ComputeUSBSerialNumber(mac))
return FALSE;
// get usbdbgpdd function table
//
if( UsbDbgPdd_Init(&m_mddInterface,
&m_pddIfc,
(USBDBG_DEVICE_DESCRIPTOR*) &m_deviceDesc
) != ERROR_SUCCESS)
{
USBDBGMSG(USBDBG_ZONE_ERROR, (
L"ERROR!usbdbg:UsbDbgPdd_Init failed!\r\n"));
return FALSE;
}
// verify m_pddIfc
//
if ((m_pddIfc.version != 2) ||
(!m_pddIfc.pfnDeinit) ||
(!m_pddIfc.pfnConnect) ||
(!m_pddIfc.pfnDisconnect) ||
(!m_pddIfc.pfnIoctl) ||
(!m_pddIfc.pfnEventHandler) ||
(!m_pddIfc.pfnRecvData) ||
(!m_pddIfc.pfnSendData) ||
(!m_pddIfc.pfnSendCmd) ||
(!m_pddIfc.pfnSetPower))
{
USBDBGMSG(USBDBG_ZONE_ERROR, (
L"ERROR!usbdbg:Incorrect USBDBGPDD interface. UsbDbgPdd_Init "
L"failed!\r\n"));
return FALSE;
}
// get max sizes of Endpoints from PDD and store in m_pucUSBDescriptors
//
if (!UpdateUSBDesc())
return FALSE;
// kick off the attach/reset process
//
if (!m_pddIfc.pfnConnect((USBDBG_DEVICE_DESCRIPTOR*) &m_deviceDesc))
return FALSE;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -