📄 rndis.c
字号:
OALMSG(OAL_ETHER&&OAL_FUNC, (L"+RNDIS_USBFN_PDDInit\r\n"));
g_mddInterface.dwVersion = 1;
g_mddInterface.pfnNotify = NotifyHandler;
memset( &g_pddInterface, 0, sizeof(g_pddInterface) );
g_pddInterface.dwVersion = 1;
// configure clock, I2C cotroller, USB OTG transceiver and USB OTG controller
InitializeHardware();
// initialize usb function unit
if( UfnPdd_Init( NULL, NULL, &g_mddInterface, &g_pddInterface ) != ERROR_SUCCESS )
{
OALMSG(OAL_ERROR, (L"UfnPdd_Init failed!"));
return FALSE;
}
// register device
RegisterUSBDevice();
// attach device to USB bus
g_pddInterface.pfnStart( g_pddInterface.pvPddContext );
SetRNDISMACAddress();
SetRNDISSerialNumber();
//
// Everything ok, fill up our characteristics.
//
memset(pRndisPddCharacteristics, 0x00, sizeof(RNDIS_PDD_CHARACTERISTICS));
pRndisPddCharacteristics->SendRndisMessageHandler = PDD_SendRndisMessage;
pRndisPddCharacteristics->SendRndisPacketHandler = PDD_SendRndisPacket;
pRndisPddCharacteristics->SetHandler = PDD_Set;
pRndisPddCharacteristics->GetHandler = PDD_Get;
pRndisPddCharacteristics->ISRHandler = PDD_ISR;
pRndisPddCharacteristics->dwIRQ = -1; // @todo : check this
pRndisPddCharacteristics->dwMaxRx = MAX_INCOMING_BUFFER;
pRndisPddCharacteristics->dwBaseAddr = (DWORD)pBaseAddress/*USB_CLIENT_BASE*/; // TODO: check this
pRndisPddCharacteristics->IndicateRndisPacketCompleteHandler = PDD_IndicateRndisPacketComplete;
// we are not a PCI device
pRndisPddCharacteristics->bPCIDevice = FALSE;
//
// Everything is fine... Proceed!
//
InitializeListHead(&g_RndisKitlDev.listTxRndisMessageQueue);
OALMSG(OAL_ETHER&&OAL_FUNC, (
L" RNDIS_USBFN_PDDInit: initialization completed\r\n"
));
OALMSG(OAL_ETHER&&OAL_FUNC, (L"-RNDIS_USBFN_PDDInit\r\n"));
PDDZONE0 = 0;
PDDZONE = 0;
MDDZONE0 = 0;
MDDZONE = 0;
MDDZONE2 = 0;
MDDZONE3 = 0; // 1
MDDZONE4 = 0;
MDDZONE5 = 0;
return TRUE;
}
void PDDDeinit(void)
{
OALMSG(OAL_ETHER&&OAL_FUNC, (L"+RNDIS_USBFN_PDDDenit\r\n"));
OALMSG(OAL_ETHER&&OAL_FUNC, (L"-RNDIS_USBFN_PDDDenit\r\n"));
}
////////////////////////////////////////////////////////////////////////////////
// PDD_SendRndisMessage()
//
// Routine Description:
//
// This routine is called by MDD to send one buffer through control
// channel.
//
// Arguments:
//
// pDataWrapper :: Structure containing the data..
//
// Return Value:
//
// None.
//
void PDD_SendRndisMessage(PDATA_WRAPPER pDataWrapper)
{
OALMSG(OAL_ETHER&&OAL_FUNC, (L"+RNDIS_USBFN_PDD_SendRndisMessage\r\n"));
//
// We don't do the actual sending here but queue it up...
// We then trigger Interrupt endpoint to send interrupt to host which will in turn
// use EP0 to GET_ENCAPSULATED_RESPONSE
InsertTailList((&g_RndisKitlDev.listTxRndisMessageQueue), &(pDataWrapper->Link));
OALMSG(OAL_ETHER&&OAL_FUNC, (
L"+RNDIS_USBFN_PDD_SendRndisMessage: message queued.\r\n"
));
// Interrupt (via interrupt endpoint) the host to GET_ENCAPSULATED_RESPONSE
// g_EP3Transfer.dwCallerPermissions;
g_EP3Transfer.dwFlags = USB_REQUEST_DEVICE_TO_HOST;
g_EP3Transfer.pvBuffer = &g_InterruptData;
// g_EP3Transfer.dwBufferPhysicalAddress; // not used
g_EP3Transfer.cbBuffer = sizeof(g_InterruptData);
g_EP3Transfer.cbTransferred = 0;
g_EP3Transfer.dwUsbError = UFN_NOT_COMPLETE_ERROR; // Possible values are in usbfntypes.h
g_EP3Transfer.pvPddData = NULL;
g_EP3Transfer.pvPddTransferInfo = NULL;
OALMSG(OAL_ETHER&&OAL_FUNC, (
L"+RNDIS_USBFN_PDD_SendRndisMessage: issuing interrupt...\r\n"
));
g_pddInterface.pfnIssueTransfer( g_pddInterface.pvPddContext, 3, &g_EP3Transfer );
OALMSG(OAL_ETHER&&OAL_FUNC, (L"-RNDIS_USBFN_PDD_SendRndisMessage\r\n"));
}
////////////////////////////////////////////////////////////////////////////////
// PDD_SendRndisPacket()
//
// Routine Description:
//
// This routine is called by MDD to send data to host via IN pipe.
// PDD is guaranteed to have only one outstanding packet to send until
// the packet is retured to MDD via MddSendRndisPacketComplete()
//
// Arguments:
//
// pDataWrapper :: structure holding data we need to send.
//
// Return Value:
//
// None.
//
void PDD_SendRndisPacket(PDATA_WRAPPER pDataWrapper)
{
OALMSG(OAL_ETHER&&OAL_FUNC, (L"+RNDIS_USBFN_PDD_SendRndisPacket\r\n"));
OALMSG(OAL_ETHER&&OAL_FUNC, (
L"Got SendPacket Request [%d bytes]\r\n", pDataWrapper->dwDataSize
));
if (g_RndisKitlDev.pTxDataWrapper != NULL) {
//
// BAD!
// This should never happen!!
// Return the packet immediately..
//
OALMSG(OAL_ERROR, (L"****Multiple pending send rndis packet!!\r\n"));
MddSendRndisPacketComplete(pDataWrapper);
}
// save the data wrapper pointer so we can return later it in TxComplete call
g_RndisKitlDev.pTxDataWrapper = pDataWrapper;
// Get permision same as caller
// perm = GetCurrentPermissions();
// SetProcPermissions(pTransfer->dwCallerPermissions);
// g_EP2Transfer.dwCallerPermissions;
g_EP2Transfer.dwFlags = USB_REQUEST_DEVICE_TO_HOST;
g_EP2Transfer.pvBuffer = pDataWrapper->pucData;
// g_EP2Transfer.dwBufferPhysicalAddress; // not used
g_EP2Transfer.cbBuffer = pDataWrapper->dwDataSize;
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;
g_EP2TransferState = TS_SENDING_PACKET;
g_pddInterface.pfnIssueTransfer( g_pddInterface.pvPddContext, 2, &g_EP2Transfer );
OALMSG(OAL_ETHER&&OAL_FUNC, (L"-RNDIS_USBFN_PDD_SendRndisPacket\r\n"));
}
////////////////////////////////////////////////////////////////////////////////
// PDD_Set()
//
// Routine Description:
//
// This routine is used by the MDD to set misc aspects of USB
// communication.
//
// Arguments:
//
// uiRequestId :: As defined in rndismini.h
// pvData :: What to set to.
// ulDataLength :: The length of data pointed to by pvData.
//
// Return Value:
//
// TRUE :: If successful.
// FALSE :: otherwise..
//
BOOL PDD_Set(
IN UINT uiRequestId,
IN PVOID pvData,
IN ULONG ulDataLength)
{
BOOL fRet = TRUE;
OALMSG(OAL_ETHER&&OAL_FUNC, (L"+RNDIS_USBFN_PDD_Set\r\n"));
// TODO: finish all requests here
switch(uiRequestId) {
case REQ_ID_HARD_RESET:
OALMSG(OAL_ETHER&&OAL_FUNC, (L"PDD_Set:REQ_ID_HARD_RESET\r\n"));
break;
case REQ_ID_SOFT_RESET:
OALMSG(OAL_ETHER&&OAL_FUNC, (L"PDD_Set:REQ_ID_SOFT_RESET\r\n"));
break;
case REQ_ID_ENABLE_INT:
OALMSG(OAL_ETHER&&OAL_FUNC, (L"PDD_Set:REQ_ID_ENABLE_INT\r\n"));
break;
case REQ_ID_DISABLE_INT:
OALMSG(OAL_ETHER&&OAL_FUNC, (L"PDD_Set:REQ_ID_DISABLE_INT\r\n"));
break;
default:
OALMSG(OAL_ETHER&&OAL_FUNC, (
L"PDD_Set:Unknown request:0x%x\r\n", uiRequestId
));
fRet = FALSE;
break;
}
OALMSG(OAL_ETHER&&OAL_FUNC, (L"-RNDIS_USBFN_PDD_Set\r\n"));
return fRet;
}
////////////////////////////////////////////////////////////////////////////////
// PDD_Get()
//
// Routine Description:
//
// This routine is used by MDD to query information pertaining to
// PDD (like vendor ID, Vendor description, etc).
//
// Arguments:
//
// uiRequestId :: as defined in RndisMini.h
// pvData :: The return buffer.
// ulDataLength :: Length of the buffer.
// ulRequiredLength :: Return by us if the passed in buffer is not enough.
//
// Return Value:
//
// TRUE :: If successful.
// FALSE :: otherwise..
//
BOOL PDD_Get(
IN UINT uiRequestId,
IN PVOID pvData,
IN ULONG ulDataLength,
OUT ULONG *pulRequiredLength)
{
BOOL fRet = FALSE;
ULONG GenericUlong;
ULONG ulTotalBytes;
PUCHAR pucBuffer;
OALMSG(OAL_ETHER&&OAL_FUNC, (L"+RNDIS_USBFN_PDD_Get\r\n"));
switch(uiRequestId) {
case REQ_ID_VENDOR_ID:
pucBuffer = pucVendorID;
ulTotalBytes = strlen(pucVendorID);
break;
case REQ_ID_VENDOR_DESCRIPTION:
pucBuffer = pucVendorDescription;
ulTotalBytes = strlen(pucVendorDescription);
break;
case REQ_ID_DEVICE_MAX_RX:
GenericUlong = MAX_INCOMING_BUFFER;
pucBuffer = (UCHAR *)&GenericUlong;
ulTotalBytes = sizeof(GenericUlong);
break;
case REQ_ID_DEVICE_MACADDR:
pucBuffer = g_RndisMacAddress;
ulTotalBytes = sizeof(g_RndisMacAddress);
break;
default:
OALMSG(OAL_ETHER&&OAL_FUNC, (
L"-PDD_Get: unknown request 0x%x\r\n", uiRequestId
));
pucBuffer = NULL;
ulTotalBytes = 0;
break;
}
if (pucBuffer) {
if (pulRequiredLength)
*pulRequiredLength = ulTotalBytes;
if (ulTotalBytes <= ulDataLength) {
memcpy(pvData, pucBuffer, ulTotalBytes);
fRet = TRUE;
}
}
OALMSG(OAL_ETHER&&OAL_FUNC, (L"-RNDIS_USBFN_PDD_Get\r\n"));
return fRet;
}
////////////////////////////////////////////////////////////////////////////////
// PDD_ISR()
//
// Routine Description:
//
// This function handles the USB interrupt.
//
// Arguments:
//
// pdwWaitTime :: The next time out value while waiting for interrupt..
//
// Return Value:
//
// TRUE :: We want more interrupt coming..
// FALSE :: We have enough, getting outta here!!! that's the end of
// eveything.. (in theory, should never be used..).
//
BOOL PDD_ISR(PDWORD pdwWaitTime)
{
InterruptThread( g_pddInterface.pvPddContext );
return TRUE;
} // PDD_ISR()
////////////////////////////////////////////////////////////////////////////////
// PDD_IndicateRndisPacketComplete()
//
// Routine Description:
//
// Called by MDD when the data passed to it via MddIndicateRndisPacket is
// completed.
//
// Arguments:
//
// pucBuffer :: Buffer passed in MddIndicateRndisPacket.
// uiBufferSize :: Size of the buffer.
//
// Return Value:
//
// None.
//
void PDD_IndicateRndisPacketComplete(PDATA_WRAPPER pDataWrapper)
{
OALMSG(OAL_ETHER&&OAL_FUNC, (
L"+RNDIS_USBFN_PDD_IndicateRndisPacketComplete\r\n"
));
MDDFreeMem(pDataWrapper->pucData);
MDDFreeDataWrapper(pDataWrapper);
OALMSG(OAL_ETHER&&OAL_FUNC, (
L"-RNDIS_USBFN_PDD_IndicateRndisPacketComplete\r\n"
));
}
// compute a unique MAC address
void SetRNDISMACAddress(void)
{
DWORD udId = GetUniqueDeviceID();
g_RndisMacAddress[2] = (UCHAR)(udId);
g_RndisMacAddress[3] = (UCHAR)(udId >> 8);
g_RndisMacAddress[4] = (UCHAR)(udId >> 16);
g_RndisMacAddress[5] = (UCHAR)(udId >> 24);
}
// compute a unique device serial number
void SetRNDISSerialNumber(void)
{
BYTE b;
int i;
BYTE *pIdBytes;
DWORD dwBytesReturned = 0;
DWORD udId = GetUniqueDeviceID();
pIdBytes = (BYTE*)&udId;
for (i=0; i< sizeof(udId); i++) {
b = pIdBytes[i] & 0xff;
gs_SerialNumber.ptcbString[i * 2] = DigitTable[b % 16];
gs_SerialNumber.ptcbString[(i * 2) + 1] = DigitTable[b / 16];
}
gs_SerialNumber.ptcbString[sizeof(udId) * 2] = '\0';
gs_SerialNumber.ucbLength = sizeof(gs_SerialNumber);
gs_SerialNumber.udbDescriptorType = USB_STRING_DESCRIPTOR_TYPE;
OALMSG(OAL_ETHER&&OAL_FUNC, (
L"RNDIS Serial Number=[%s]\r\n", gs_SerialNumber.ptcbString
));
}
#pragma optimize ( "", on )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -