📄 rndis.c
字号:
//
// Instantiate CE Miniport driver RNDISMINI1
//
/*
hThread = CreateThread(0,
0,
(LPTHREAD_START_ROUTINE)RndisStartRNDISMINI1,
NULL,
0,
NULL );
CloseHandle(hThread);
*/
break;
}
////////////////////////////////////////////////////////////////////////
case REMOTE_NDIS_QUERY_MSG:
{
PRNDIS_QUERY_REQUEST pRndisRequest;
NDIS_STATUS NdisStatus;
ULONG ulBytesWritten;
ULONG ulBytesNeeded;
UCHAR *pucBuffer;
if(RndisMdd.dwDeviceState == RNDIS_UNINITIALIZED)
break;
pRndisRequest = &pRndisMessage->Message.QueryRequest;
CELOGMSG (ZONE_RNDIS,
(TEXT("RNdis:: Query: ID[0x%x]:OID[0x%x]:Buff[%d-%d]\r\n"),
pRndisRequest->RequestId,
pRndisRequest->Oid,
pRndisRequest->InformationBufferLength,
pRndisRequest->InformationBufferOffset));
//
// Special treatment for this OID.
// RNDIS host will only pass down 4 bytes, so let's just stuff it
// with our own buffer and blast it back to the RNDIS.
//
if (pRndisRequest->Oid == OID_GEN_SUPPORTED_LIST)
{
extern UINT RNdisMddSupportedOids[];
pucBuffer = (PUCHAR)RNdisMddSupportedOids;
HostMiniQueryInformation(
pRndisRequest->Oid,
NULL,
0x00,
&ulBytesWritten,
&ulBytesNeeded);
ulBytesWritten = ulBytesNeeded;
ulBytesNeeded = 0x00;
NdisStatus = NDIS_STATUS_SUCCESS;
}
else
{
//
// Pass this to our miniport handler..
//
pucBuffer =
(PUCHAR)((PUCHAR)pRndisRequest +
pRndisRequest->InformationBufferOffset);
if (!(
pRndisRequest->InformationBufferLength ==
(ULONG) (pDataWrapper->pucData + pDataWrapper->dwDataSize
- pucBuffer)))
EdbgOutputDebugString("ASSERT at File(%s) line (%d)\r\n",__THIS_FILE__, __LINE__);
// CELOGMSG (0,
// (TEXT("RNdis:: Claimed length = [%d] actual [%d]\r\n"),
// pRndisRequest->InformationBufferLength,
// (pDataWrapper->pucData +
// pDataWrapper->dwDataSize -
// pucBuffer)));
NdisStatus =
HostMiniQueryInformation(
pRndisRequest->Oid,
pucBuffer,
pRndisRequest->InformationBufferLength,
&ulBytesWritten,
&ulBytesNeeded);
// CELOGMSG (0, (TEXT("QueryInfo returns [%d]\r\n"),
// ulBytesWritten));
#if 0
DumpMemory(
pucBuffer,
ulBytesWritten);
#endif
}
//
// Reply back to host..
//
RndisSendRndisMessage(
REMOTE_NDIS_QUERY_CMPLT,
pRndisRequest->RequestId,
NdisStatus,
pucBuffer,
ulBytesWritten,
ulBytesWritten ? ulBytesWritten : ulBytesNeeded);
break;
}
////////////////////////////////////////////////////////////////////////
case REMOTE_NDIS_SET_MSG:
{
PRNDIS_SET_REQUEST pRndisSet;
NDIS_STATUS NdisStatus;
ULONG ulBytesRead;
ULONG ulBytesNeeded;
UCHAR *pucBuffer;
if(RndisMdd.dwDeviceState == RNDIS_UNINITIALIZED)
break;
pRndisSet = &pRndisMessage->Message.SetRequest;
// CELOGMSG (0,
// (TEXT("RNdis:: Set: ID[0x%x]:OID[0x%x]:Buff[%d-%d]\r\n"),
// pRndisSet->RequestId,
// pRndisSet->Oid,
// pRndisSet->InformationBufferLength,
// pRndisSet->InformationBufferOffset));
pucBuffer =
(PUCHAR)((PUCHAR)pRndisSet +
pRndisSet->InformationBufferOffset);
NdisStatus = HostMiniSetInformation(
pRndisSet->Oid,
pucBuffer,
pRndisSet->InformationBufferLength,
&ulBytesRead,
&ulBytesNeeded);
//
// Reply back to host on the status..
//
RndisSendRndisMessage(
REMOTE_NDIS_SET_CMPLT,
pRndisSet->RequestId,
NdisStatus,
NULL,
0,
0);
break;
}
////////////////////////////////////////////////////////////////////////
case REMOTE_NDIS_KEEPALIVE_MSG:
{
PRNDIS_KEEPALIVE_REQUEST pKeepAliveRequest;
if(RndisMdd.dwDeviceState == RNDIS_UNINITIALIZED)
break;
CELOGMSG (ZONE_RNDIS,
(TEXT("RNdis:: REMOTE_NDIS_KEEPALIVE_MSG.\r\n")));
pKeepAliveRequest = &pRndisMessage->Message.KeepaliveRequest;
//
// [stjong] DISCONNECTION HANDLING
// We probably need to keep track of this to detect
// device being disconnected..
//
//
// We are here host!!!
//
RndisSendRndisMessage(
REMOTE_NDIS_KEEPALIVE_CMPLT,
pKeepAliveRequest->RequestId,
RNDIS_STATUS_SUCCESS,
NULL,
0,
0);
break;
}
////////////////////////////////////////////////////////////////////////
case REMOTE_NDIS_HALT_MSG:
{
if(RndisMdd.dwDeviceState == RNDIS_UNINITIALIZED)
break;
EdbgOutputDebugString("RndisMini recv REMOTE_NDIS_HALT_MSG from host!\r\n");
//
// PDD needs to reset.
//
RndisRestart(TRUE);
break;
}
////////////////////////////////////////////////////////////////////////
case REMOTE_NDIS_RESET_MSG:
{
if(RndisMdd.dwDeviceState == RNDIS_UNINITIALIZED)
break;
EdbgOutputDebugString("RndisMini rcv REMOTE_NDIS_RESET_MSG from host!\r\n");
//
// Soft reset us, don't reset PDD..
//
RndisRestart(FALSE);
//
// Reply this message.
//
RndisSendRndisMessage(
REMOTE_NDIS_RESET_CMPLT,
0x00,
0x00,
NULL,
0,
0);
break;
}
////////////////////////////////////////////////////////////////////////
case REMOTE_NDIS_INDICATE_STATUS_MSG:
{
if(RndisMdd.dwDeviceState == RNDIS_UNINITIALIZED)
break;
break;
}
////////////////////////////////////////////////////////////////////////
default:
EdbgOutputDebugString("RNdis:: Unknown RNDIS msg, buff[0x%x] l=[%d]!\r\n",
pDataWrapper->pucData,
pDataWrapper->dwDataSize);
#if 0
DumpMemory(
pDataWrapper->pucData,
pDataWrapper->dwDataSize);
#endif
break;
}
} // RndisProcessMessage()
#define RECV_RETRY_COUNT 10
UINT16 RndisEDbgGetFrame(BYTE * pData, UINT16 *pdwLength)
{
BOOL bRet=FALSE;
DWORD dwStartSec;
DWORD dwWaitMSec;
DWORD dwRetryCount;
// EdbgOutputDebugString("Rndis::RndisEDbgGetFrame RndisMdd.dwCurrentPacketFilter=%d \r\n",RndisMdd.dwCurrentPacketFilter);
dwStartSec=OEMEthGetSecs();
while (RndisMdd.dwCurrentPacketFilter == 0 && OEMEthGetSecs()-dwStartSec<2)
//PDD_ISR();
RndisMdd.PddCharacteristics.ISRHandler(&dwWaitMSec);
if (pData && pdwLength && *pdwLength) {
PVOID pDataBuffer=NULL;
WORD wLength;
dwStartSec=OEMEthGetSecs();
bRet=FALSE;
/*
while (InBuffer.dwDataSize==0 &&(OEMEthGetSecs()- dwStartSec <2))
PDD_ISR();
if (InBuffer.dwDataSize!=0) {
*pdwLength=(UINT16)min (*pdwLength , InBuffer.dwDataSize);
memcpy(pData,(PVOID)InBuffer.rcvBuffer,*pdwLength);
bRet=TRUE;
}
else
*pdwLength=0;
*/
dwRetryCount=0;
while ((GetFirstUsedBuffer(&EthBufferDesc,&pDataBuffer, &wLength)==FALSE || pDataBuffer==NULL)
&& dwRetryCount++<RECV_RETRY_COUNT)
// PDD_ISR();
RndisMdd.PddCharacteristics.ISRHandler(&dwWaitMSec);
if (GetFirstUsedBuffer(&EthBufferDesc,&pDataBuffer, &wLength)==TRUE && pDataBuffer!=NULL) {
wLength=min(*pdwLength,wLength);
memcpy(pData,pDataBuffer,wLength);
*pdwLength=wLength;
FreeBuffer(&EthBufferDesc,pDataBuffer);
CELOGDUMPDATA(ZONE_DATA,CELID_RAW_UCHAR,pData,(WORD)*pdwLength);
}
else
*pdwLength=0;
// InBuffer.dwDataSize=0;
// EdbgOutputDebugString("Rndis::RndisEDbgGetFrame return %d bytes\r\n",*pdwLength);
return *pdwLength;
}
else
return 0;
}
////////////////////////////////////////////////////////////////////////////////
// RndisProcessPacket()
//
// Routine Description:
//
// This function process one RNDIS packet received.
//
// Arguments:
//
// None.
//
// Return Value:
//
// None.
//
BOOL
RndisProcessPacket (PDATA_WRAPPER pDataWrapper)
{
PRCV_RNDIS_PACKET pRcvRndisPacket = NULL;
BOOL bReturnImmediately = TRUE;
PRNDIS_MESSAGE pRndisMessage = (PRNDIS_MESSAGE) pDataWrapper->pucData;
DWORD dwLengthRemaining = pDataWrapper->dwDataSize;
DWORD dwPacketCount=0;
static DWORD dwOverRunCount=0;
CELOGMSG (ZONE_DATA,(TEXT("Rndis::ProcessPacket (%d Bytes) \r\n"),dwLengthRemaining));
if (!(RndisMdd.dwDeviceState != RNDIS_UNINITIALIZED))
EdbgOutputDebugString("ASSERT at File(%s) line (%d)\r\n",__THIS_FILE__, __LINE__);
// CELOGMSG(0,
// (TEXT("RNdis:: RndisProcessPacket().\r\n")));
while (pRndisMessage && dwLengthRemaining >= RNDIS_MESSAGE_SIZE(RNDIS_PACKET) ) {
PVOID pBuffer;
PRNDIS_PACKET pRndisPacket = RNDIS_MESSAGE_PTR_TO_MESSAGE_PTR(pRndisMessage);
if (pRndisMessage->NdisMessageType != REMOTE_NDIS_PACKET_MSG)
{
//
// This packet is to be returned immediately..
//
CELOGMSG (ZONE_DATA,(TEXT("Rndis::ProcessPacket Wrong Data Type 0x%x\n\r\r\n")));
EdbgOutputDebugString("Wrong Data Type 0x%x\r\n",pRndisMessage->NdisMessageType);
return FALSE;
};
CELOGMSG (ZONE_DATA,(TEXT("Rndis::ProcessPacket Message Length is %d\r\n"),pRndisMessage->MessageLength));
if (pRndisMessage->MessageLength > dwLengthRemaining) {
CELOGMSG (ZONE_ERROR,
(TEXT("RNdis:: Invalid RndisPacket l[%d] rem [%d]\r\n"),
pRndisMessage->MessageLength,
dwLengthRemaining));
EdbgOutputDebugString("RNdis:: Invalid RndisPacket l[%d] rem [%d]\r\n",
pRndisMessage->MessageLength,dwLengthRemaining);
return FALSE;
}
if (pRndisPacket->DataLength > pRndisMessage->MessageLength) {
EdbgOutputDebugString("Wrong Data DataLength Msg=0x%x,Pkt=0x%x\n\r",
pRndisMessage->NdisMessageType,pRndisPacket->DataLength);
return FALSE;
}
/* CELOGMSG (ZONE_DATA,(TEXT("Rndis::ProcessPacket Existing Data %d byte \r\n"),InBuffer.dwDataSize));
if ( InBuffer.dwDataSize!=0) {
EdbgOutputDebugString("Overrun=0x%x\n\r",++dwOverRunCount);
}
InBuffer.dwDataSize=min(pRndisPacket->DataLength,MAX_PACKET_SIZE);
memcpy((PVOID)InBuffer.rcvBuffer,GET_PTR_TO_RNDIS_DATA_BUFF(pRndisPacket),InBuffer.dwDataSize);
*/
if (pRndisPacket->DataLength>1520) {
EdbgOutputDebugString("Buffer is too big 0x%x\n\r",pRndisPacket->DataLength);
CELOGMSG (ZONE_ERROR,(TEXT("Buffer is too big 0x%x\n\r"),pRndisPacket->DataLength));
return FALSE;
};
pBuffer= AllocBuffer (&EthBufferDesc, (WORD)pRndisPacket->DataLength);
if (pBuffer) {
CELOGMSG (ZONE_DATA,(TEXT("Rndis::ProcessPacket Existing Data %d \r\n"),pRndisPacket->DataLength));
memcpy(pBuffer,GET_PTR_TO_RNDIS_DATA_BUFF(pRndisPacket),pRndisPacket->DataLength);
CELOGDUMPDATA(ZONE_DATA,CELID_RAW_UCHAR,pBuffer,(WORD)pRndisPacket->DataLength);
dwPacketCount++;
}
else {
EdbgOutputDebugString("Overrun=0x%x\n\r",++dwOverRunCount);
CELOGMSG (ZONE_ERROR,(TEXT("Overrun=0x%x\n\r"),++dwOverRunCount));
return FALSE;
};
dwLengthRemaining -= pRndisMessage->MessageLength;
pRndisMessage =
(PRNDIS_MESSAGE)(((BYTE *)pRndisMessage) +
pRndisMessage->MessageLength);
};
CELOGMSG (ZONE_DATA,(TEXT("Rndis::ProcessPacket %d packet copied\r\n"),dwPacketCount));
return TRUE;
// CELOGMSG (0,
// (TEXT("RNdis:: Wrapper[0x%x] - Buffer[0x%x] l=[%d]!\r\n"),
// pDataWrapper,
// pDataWrapper->pucData,
// pDataWrapper->dwDataSize));
// CELOGMSG (0,
// (TEXT(">>>>>>>> RNDIS_PACKET [0x%x] - [%d] bytes..\r\n"),
// pDataWrapper,
// pDataWrapper->dwDataSize));
//
// Start Processing RNDIS packet.
//
/*
do
{
DWORD dwNumberOfPackets = 0x00;
DWORD dwLengthRemaining = pDataWrapper->dwDataSize;
PRNDIS_PACKET pRndisPacket;
PNDIS_PACKET PacketArray[RNDIS_MAX_PACKETS_PER_MESSAGE];
PNDIS_PACKET pNdisPacket;
PNDIS_BUFFER pNdisBuffer;
NDIS_STATUS NdisStatus;
//
// toss it immediately if it is not RNDIS_PACKET message.
//
if (pRndisMessage->NdisMessageType != REMOTE_NDIS_PACKET_MSG)
{
//
// This packet is to be returned immediately..
//
break;
}
//
// Allocate the RCV_RNDIS_PACKET, if we can't return the PDD
// buffer immediately..
//
pRcvRndisPacket = ALLOCATE_RCV_RNDIS_PACKET();
if (pRcvRndisPacket == NULL)
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -