📄 rndis.c
字号:
// Return Value:
//
// TRUE if successful, FALSE otherwise.
//
void
RndisSendRndisMessage(
DWORD dwRndisMessageType,
DWORD dwRequestId,
NDIS_STATUS NdisStatus,
PUCHAR pucInBuffer,
DWORD dwBufferLength,
DWORD dwUnspecified1)
{
UINT uiMessageSize;
PRNDIS_MESSAGE pRndisMessage;
DATA_WRAPPER * pDataWrapper;
// BOOL bReturn;
CELOGMSG (ZONE_RNDIS,
(TEXT("RNdis:: Create [%s] InBuff[0x%x] Size[%d] Unspec[%d]\r\n"),
dwRndisMessageType == REMOTE_NDIS_INITIALIZE_CMPLT ?
TEXT("INIT-CMPLT") :
dwRndisMessageType == REMOTE_NDIS_QUERY_CMPLT ?
TEXT("QUERY-CMPLT"):
dwRndisMessageType == REMOTE_NDIS_SET_CMPLT ?
TEXT("SET-CMPLT") :
dwRndisMessageType == REMOTE_NDIS_RESET_CMPLT ?
TEXT("RESET-CMPLT"):
dwRndisMessageType == REMOTE_NDIS_KEEPALIVE_CMPLT ?
TEXT("KEEPALIVE-CMPLT") : TEXT("UNKNOWN!"),
pucInBuffer,
dwBufferLength,
dwUnspecified1));
/*
pDataWrapper = ALLOCATE_DATA_WRAPPER();
if (pDataWrapper == NULL)
{
//
// We run out of memory, so can't reply. Just return.
//
CELOGMSG (ZONE_ERROR,
(TEXT("RNdis:: No mem in RndisSendRndisMessage()\r\n")));
return;
}
*/
switch (dwRndisMessageType)
{
////////////////////////////////////////////////////////////////////////
case REMOTE_NDIS_INITIALIZE_CMPLT:
{
PRNDIS_INITIALIZE_COMPLETE pInitComplete;
uiMessageSize = RNDIS_MESSAGE_SIZE(RNDIS_INITIALIZE_COMPLETE);
if (!(uiMessageSize<=MAX_PACKET_SIZE))
EdbgOutputDebugString("ASSERT Fail at uiMessageSize(%d)<=MAX_PACKET_SIZE(%d)\r\n",
uiMessageSize,MAX_PACKET_SIZE);
//
// No extra buffer needed.
// AFListOffset and AFListSize don't seem to be needed.
// so let's just create the buffer and have it sent..
//
pDataWrapper = (DATA_WRAPPER *)AllocBuffer (&MsgBufferDesc, (WORD)(uiMessageSize+sizeof(DATA_WRAPPER))) ;//LocalAlloc(0, uiMessageSize);
if (pDataWrapper == NULL)
{
EdbgOutputDebugString("RNdis:: No mem for INITIALIZE_COMPLETE.\r\n");
return;
}
pRndisMessage = (PRNDIS_MESSAGE)(pDataWrapper+1);
//
// Have the buffer, fill it in now..
//
pRndisMessage->NdisMessageType = dwRndisMessageType;
pRndisMessage->MessageLength = uiMessageSize;
pInitComplete = &(pRndisMessage->Message.InitializeComplete);
pInitComplete->RequestId = dwRequestId;
pInitComplete->Status = NdisStatus;
pInitComplete->MajorVersion = SUPPORTED_RNDIS_MAJOR_VER;
pInitComplete->MinorVersion = SUPPORTED_RNDIS_MINOR_VER;
pInitComplete->DeviceFlags = RNDIS_DF_CONNECTIONLESS;
pInitComplete->Medium = 0x00;
pInitComplete->MaxPacketsPerMessage = RNDIS_MAX_PACKETS_PER_MESSAGE;
pInitComplete->AFListOffset = 0x00;
pInitComplete->AFListSize = 0x00;
pInitComplete->MaxTransferSize = RndisMdd.dwDeviceMaxRx;
//
// 8 byte alignment, to cater for non x86 devices..
//
pInitComplete->PacketAlignmentFactor = 0x03;
CELOGMSG(1,
(TEXT("RndisSendRndisMessage():: RNDIS_INIT_COMPLETE..\r\n")));
break;
}
////////////////////////////////////////////////////////////////////////
case REMOTE_NDIS_QUERY_CMPLT:
{
PRNDIS_QUERY_COMPLETE pQueryComplete;
PUCHAR pucBuffer;
UINT uiRndisQuerySize;
uiRndisQuerySize = RNDIS_MESSAGE_SIZE(RNDIS_QUERY_COMPLETE);
uiMessageSize = uiRndisQuerySize + dwBufferLength;
if (!(uiMessageSize<=MAX_PACKET_SIZE))
EdbgOutputDebugString("ASSERT Fail at uiMessageSize(%d)<=MAX_PACKET_SIZE(%d)\r\n",
uiMessageSize,MAX_PACKET_SIZE);
//
// Extra space for queried information to be returned.
//
pDataWrapper = (DATA_WRAPPER *)AllocBuffer (&MsgBufferDesc, (WORD)(sizeof(DATA_WRAPPER)+uiMessageSize)) ;//LocalAlloc(0, uiMessageSize);
if (pDataWrapper == NULL)
{
EdbgOutputDebugString("RNdis:: No mem for INITIALIZE_COMPLETE.\r\n");
return;
}
pRndisMessage = (PRNDIS_MESSAGE)(pDataWrapper+1);
pucBuffer = (PUCHAR)pRndisMessage + uiRndisQuerySize;
// CELOGMSG (0,
// (TEXT("uiMessageSize = [%d] - dwBufferLength = [%d]\r\n"),
// uiMessageSize,
// dwBufferLength));
//
// Have the buffer will fill now..
//
pRndisMessage->NdisMessageType = dwRndisMessageType;
pRndisMessage->MessageLength = uiMessageSize;
pQueryComplete = &(pRndisMessage->Message.QueryComplete);
pQueryComplete->RequestId = dwRequestId;
pQueryComplete->Status = NdisStatus;
pQueryComplete->InformationBufferLength = dwUnspecified1;
// CELOGMSG (0, (TEXT("dwBufferLength = [%d]\r\n"),
// dwBufferLength));
pQueryComplete->InformationBufferOffset =
(dwBufferLength == 0) ?
(0) :
(pucBuffer - (PUCHAR)pQueryComplete);
if (dwBufferLength)
memcpy(pucBuffer, pucInBuffer, dwUnspecified1);
break;
}
////////////////////////////////////////////////////////////////////////
// Both messages have same entries..
// They are only interested in NdisStatus..
//
case REMOTE_NDIS_KEEPALIVE_CMPLT:
case REMOTE_NDIS_SET_CMPLT:
{
PRNDIS_KEEPALIVE_COMPLETE pKeepAliveOrSetComplete;
uiMessageSize = RNDIS_MESSAGE_SIZE(RNDIS_KEEPALIVE_COMPLETE);
if (!(uiMessageSize<=MAX_PACKET_SIZE))
EdbgOutputDebugString("ASSERT Fail at uiMessageSize(%d)<=MAX_PACKET_SIZE(%d)\r\n",
uiMessageSize,MAX_PACKET_SIZE);
pDataWrapper = (DATA_WRAPPER *)AllocBuffer (&MsgBufferDesc, (WORD)(sizeof(DATA_WRAPPER)+uiMessageSize)) ;//LocalAlloc(0, uiMessageSize);
if (pDataWrapper == NULL)
{
EdbgOutputDebugString("RNdis:: No mem for INITIALIZE_COMPLETE.\r\n");
return;
}
pRndisMessage = (PRNDIS_MESSAGE)(pDataWrapper+1);
pRndisMessage->NdisMessageType = dwRndisMessageType;
pRndisMessage->MessageLength = uiMessageSize;
pKeepAliveOrSetComplete = &(pRndisMessage->Message.KeepaliveComplete);
pKeepAliveOrSetComplete->RequestId = dwRequestId;
pKeepAliveOrSetComplete->Status = NdisStatus;
break;
}
////////////////////////////////////////////////////////////////////////
case REMOTE_NDIS_RESET_CMPLT:
{
PRNDIS_RESET_COMPLETE pResetComplete;
uiMessageSize = RNDIS_MESSAGE_SIZE(RNDIS_KEEPALIVE_COMPLETE);
if (!(uiMessageSize<=MAX_PACKET_SIZE))
EdbgOutputDebugString("ASSERT Fail at uiMessageSize(%d)<=MAX_PACKET_SIZE(%d)\r\n",
uiMessageSize,MAX_PACKET_SIZE);
pDataWrapper = (DATA_WRAPPER *)AllocBuffer (&MsgBufferDesc, (WORD)(sizeof(DATA_WRAPPER)+uiMessageSize)) ;//LocalAlloc(0, uiMessageSize);
if (pDataWrapper == NULL)
{
EdbgOutputDebugString("RNdis:: No mem for INITIALIZE_COMPLETE.\r\n");
return;
}
pRndisMessage = (PRNDIS_MESSAGE)(pDataWrapper+1);
pRndisMessage->NdisMessageType = dwRndisMessageType;
pRndisMessage->MessageLength = uiMessageSize;
pResetComplete = &(pRndisMessage->Message.ResetComplete);
//
// Reset is always successful..
// We always require host to return the multicast list etc..
//
pResetComplete->Status = NDIS_STATUS_SUCCESS;
pResetComplete->AddressingReset = 0x01;
break;
}
////////////////////////////////////////////////////////////////////////
default:
EdbgOutputDebugString("RNdis:: Should not happen!\r\n");
//ASSERT(0);
//FREE_DATA_WRAPPER(pDataWrapper);
return;
}
//
// Send it out..
// Buffer will return back to us and freed in
// MddSendRndisMessageComplete()
//
pDataWrapper->Link.Flink= pDataWrapper->Link.Blink=NULL;
pDataWrapper->pucData = (PUCHAR)pRndisMessage;
pDataWrapper->dwDataSize = uiMessageSize;
//PDD_SendRndisMessage(pDataWrapper);
RndisMdd.PddCharacteristics.SendRndisMessageHandler(pDataWrapper);
// CELOGMSG (ZONE_MEM,
// (TEXT("**> RndisMsg send :: buff[0x%x] l[%d] Wrap[0x%x]\r\n"),
// pDataWrapper->pucData,
// pDataWrapper->dwDataSize,
// pDataWrapper));
/*
{
DWORD dwStartSec=OEMEthGetSecs();
bReturn=FALSE;
do
{
//
// PDD is idling, kick start the sending process..
//
if (PDD_SendRndisMessage(&DataWrapper)) {
bReturn = TRUE;
}
PDD_ISR();
}while (!bReturn && (OEMEthGetSecs()- dwStartSec <1));
if (bReturn) { //
while (!PDD_IsMessageSend() && (OEMEthGetSecs()- dwStartSec <1));
PDD_ISR();
}
};
if (!bReturn)
EdbgOutputDebugString("ASSERT Return(%d)\r\n",bReturn);
*/
// ASSERT(bReturn);
} // RndisSendRndisMessage()
////////////////////////////////////////////////////////////////////////////////
// RndisProcessMessage()
//
// Routine Description:
//
// This function process RNDIS message received.
//
// Arguments:
//
// None.
//
// Return Value:
//
// TRUE if successful, FALSE otherwise.
//
void
RndisProcessMessage(PDATA_WRAPPER pDataWrapper)
{
PRNDIS_MESSAGE pRndisMessage;
// CELOGMSG(0,
// (TEXT("RNdis:: RndisProcessOneMessage().\r\n")));
#if 0
DumpMemory(
pDataWrapper->pucData,
pDataWrapper->dwDataSize);
#endif
pRndisMessage = (PRNDIS_MESSAGE) pDataWrapper->pucData;
CELOGMSG (ZONE_RNDIS,
(TEXT("RNdis:: Processing RndisMessage [%s] - Length [%d]\r\n"),
pRndisMessage->NdisMessageType == REMOTE_NDIS_INITIALIZE_MSG ?
TEXT("RNDIS_INITIALIZE") :
pRndisMessage->NdisMessageType == REMOTE_NDIS_HALT_MSG ?
TEXT("RNDIS_HALT") :
pRndisMessage->NdisMessageType == REMOTE_NDIS_QUERY_MSG ?
TEXT("RNDIS_QUERY") :
pRndisMessage->NdisMessageType == REMOTE_NDIS_SET_MSG ?
TEXT("RNDIS_SET") :
pRndisMessage->NdisMessageType == REMOTE_NDIS_RESET_MSG ?
TEXT("RNDIS_RESET") :
pRndisMessage->NdisMessageType == REMOTE_NDIS_PACKET_MSG ?
TEXT("RNDIS_PACKET") :
pRndisMessage->NdisMessageType == REMOTE_NDIS_INDICATE_STATUS_MSG ?
TEXT("RNDIS_INDICATE") :
pRndisMessage->NdisMessageType == REMOTE_NDIS_KEEPALIVE_MSG ?
TEXT("RNDIS_KEEPALIVE") :
TEXT("UNKNOWN!"),
pRndisMessage->MessageLength));
/*
CELOGMSG (0,
(TEXT("RNdis:: Wrapper[0x%x] - Buffer[0x%x] l=[%d]!\r\n"),
pDataWrapper,
pDataWrapper->pucData,
pDataWrapper->dwDataSize));
*/
switch (pRndisMessage->NdisMessageType)
{
case REMOTE_NDIS_INITIALIZE_MSG:
{
PRNDIS_INITIALIZE_REQUEST pInitializeRequest;
NDIS_STATUS NdisStatus;
// HANDLE hThread;
pInitializeRequest = &pRndisMessage->Message.InitializeRequest;
CELOGMSG (ZONE_RNDIS,
(TEXT("RNdis:: ReqID[0x%x] - Ver[%d-%d] - MaxXfer[%d]\r\n"),
pInitializeRequest->RequestId,
pInitializeRequest->MajorVersion,
pInitializeRequest->MinorVersion,
pInitializeRequest->MaxTransferSize));
//
// We support SUPPORTED_RNDIS_MAJOR_VERSION, so bail out if
// it's not.
//
if (pInitializeRequest->MajorVersion > SUPPORTED_RNDIS_MAJOR_VER ||
(pInitializeRequest->MajorVersion == SUPPORTED_RNDIS_MAJOR_VER &&
pInitializeRequest->MinorVersion > SUPPORTED_RNDIS_MINOR_VER))
{
CELOGMSG (ZONE_RNDIS,
(TEXT("RNdisMini Err!! unsupported RNDIS host ver.\r\n")));
EdbgOutputDebugString("RNDISMINI Err!! unsupported RNDIS host ver.\r\n");
NdisStatus = NDIS_STATUS_FAILURE;
}
else
{
ULONG ulRequiredLength;
//
// The very first business is to make sure we are all in the
// INIT state (i.e MDD & PDD).
// The reason is we may get this message at anytime even during
// initialized stated.
// For example this may happen when PDD stalls one of the end
// point when it encounters error..
// or when RNDIS host does not receive KEEP_ALIVE return within
// a specified period of time..
//
if (RndisMdd.dwDeviceState != RNDIS_UNINITIALIZED)
{
//
// This will put us back to RNDIS_UNINITIALIZED state.
//
CELOGMSG (ZONE_RNDIS,(TEXT("ERROR! RndisInitialize msg received!!! \r\n")));
EdbgOutputDebugString("ERROR! RndisInitialize msg received!!! \r\n");
//
// Well, DeInitialize RNDISMINI1 if necessary, but don't
// hard reset PDD..
//
RndisRestart(FALSE);
}
//ASSERT(RndisMdd.dwDeviceState == RNDIS_UNINITIALIZED);
if (!(RndisMdd.dwDeviceState == RNDIS_UNINITIALIZED))
EdbgOutputDebugString("ASSERT at File(%s) line (%d)\r\n",__THIS_FILE__, __LINE__);
//
// Okay, we are in business.
// Initialize all we need, and return a reply..
//
NdisStatus = NDIS_STATUS_SUCCESS;
//
// Remember HOST's MAX RX.
//
RndisMdd.dwHostMaxRx = pInitializeRequest->MaxTransferSize;
//
// Alloc memory for it, free the previous allocated chunk..
//
/*
if (RndisMdd.pucTxBuffer)
LocalFree(RndisMdd.pucTxBuffer);
RndisMdd.pucTxBuffer = LocalAlloc(0, RndisMdd.dwHostMaxRx);
if (RndisMdd.pucTxBuffer == NULL)
{
CELOGMSG (ZONE_ERROR,
(TEXT("RNdis:: Error, No mem for TX buff..\r\n")));
NdisStatus = NDIS_STATUS_FAILURE;
}
*/
//
// Get PDD's maximum RX buffer.
//
if (NdisStatus == NDIS_STATUS_SUCCESS &&
//!PDD_Get(
!RndisMdd.PddCharacteristics.GetHandler(
REQ_ID_DEVICE_MAX_RX,
&(RndisMdd.dwDeviceMaxRx),
sizeof(RndisMdd.dwDeviceMaxRx),
&ulRequiredLength))
{
//
// This should never happen!!
// a DWORD should be enough..
//
EdbgOutputDebugString("ASSERT at File(%s) line (%d)\r\n",__THIS_FILE__, __LINE__);
NdisStatus = NDIS_STATUS_FAILURE;
}
EdbgOutputDebugString("RndisMdd:: PDD's max RX buffer = [%d] bytes.\r\n",RndisMdd.dwDeviceMaxRx);
}
//
// Send the reply out..
//
CELOGMSG (ZONE_RNDIS,
(TEXT("Send InitializeComplete Status[0x%x] ID[0x%x]\r\n"),
NdisStatus,
pInitializeRequest->RequestId));
RndisSendRndisMessage(
REMOTE_NDIS_INITIALIZE_CMPLT,
pInitializeRequest->RequestId,
NdisStatus,
NULL,
0x00,
0x00);
RndisMdd.dwDeviceState = RNDIS_INITIALIZED;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -