📄 rndis_pdd.c
字号:
// 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;
// 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"));
}
// discard outstanding messages when reset
static VOID PDD_DiscardPendingMessages()
{
PLIST_ENTRY pLink;
PDATA_WRAPPER pDataWrapper;
DWORD dwDiscards = 0;
while (!IsListEmpty(&(g_RndisKitlDev.listTxRndisMessageQueue))) {
// remove pending message
pLink = RemoveHeadList(&(g_RndisKitlDev.listTxRndisMessageQueue));
pDataWrapper = CONTAINING_RECORD(pLink, DATA_WRAPPER, Link);
// let MDD free buffer
MddSendRndisMessageComplete(pDataWrapper);
// record number
++dwDiscards;
}
KITLOutputDebugString("Discard %d Pending Messages\r\n", dwDiscards);
}
////////////////////////////////////////////////////////////////////////////////
// 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"));
PDD_DiscardPendingMessages();
break;
case REQ_ID_SOFT_RESET:
OALMSG(OAL_ETHER&&OAL_FUNC, (L"PDD_Set:REQ_ID_SOFT_RESET\r\n"));
PDD_DiscardPendingMessages();
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)
{
GetRNDISMACAddress((UINT16*) g_RndisMacAddress);
}
// compute a unique device serial number
void SetRNDISSerialNumber(void)
{
BYTE b;
int i;
BYTE *pIdBytes;
DWORD dwBytesReturned = 0;
UINT16 mac[3];
GetRNDISMACAddress(mac);
pIdBytes = (BYTE*)&mac[0];
for (i=0; i< 6; 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(mac) * 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
));
}
// Device Register Access.
void WriteUDCRegister(DWORD dwOffset, DWORD dwData) {
PREFAST_ASSERT(pUsbDevReg!=NULL);
WRITE_REGISTER_ULONG(pUsbDevReg + dwOffset, dwData);
}
DWORD ReadUDCRegister(DWORD dwOffset) {
PREFAST_ASSERT(pUsbDevReg!=NULL);
return READ_REGISTER_ULONG(pUsbDevReg + dwOffset);
}
DWORD ReadControlRegister() { return ReadUDCRegister(DEVICE_CONTROL_REGISTER); }
void WriteControlRegister(DWORD dwData) { WriteUDCRegister(DEVICE_CONTROL_REGISTER, dwData);}
DWORD ReadIntrCtr0Register() { return ReadUDCRegister(DEVICE_INT_CR0_REGISTER); }
DWORD ReadIntrCtr1Register() { return ReadUDCRegister(DEVICE_INT_CR1_REGISTER); }
DWORD ReadIntrStatus0Register() { return ReadUDCRegister(DEVICE_INT_SR0_REGISTER); }
DWORD ReadIntrStatus1Register() { return ReadUDCRegister(DEVICE_INT_SR1_REGISTER); }
void WriteIntrCtr0Register(DWORD dwData) { WriteUDCRegister(DEVICE_INT_CR0_REGISTER, dwData); }
void WriteIntrCtr1Register(DWORD dwData) { WriteUDCRegister(DEVICE_INT_CR1_REGISTER, dwData); }
void WriteIntrStatus0Register(DWORD dwData) { WriteUDCRegister(DEVICE_INT_SR0_REGISTER,dwData); }
void WriteIntrStatus1Register(DWORD dwData) { WriteUDCRegister(DEVICE_INT_SR1_REGISTER,dwData); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -