📄 rndis.c
字号:
if (ProcessNDISSet(SET_Oid, SetData, SET_Message->InformationBufferLength))
SET_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
else
SET_Response->Status = REMOTE_NDIS_STATUS_NOT_SUPPORTED;
break;
case REMOTE_NDIS_RESET_MSG:
/* Soft reset the adapter */
ResponseReady = true;
RNDIS_RESET_CMPLT_t* RESET_Response = (RNDIS_RESET_CMPLT_t*)&RNDISMessageBuffer;
RESET_Response->MessageType = REMOTE_NDIS_RESET_CMPLT;
RESET_Response->MessageLength = sizeof(RNDIS_RESET_CMPLT_t);
RESET_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
RESET_Response->AddressingReset = 0;
break;
case REMOTE_NDIS_KEEPALIVE_MSG:
/* Keep alive message sent to the adapter every 5 seconds when idle to ensure it is still responding */
ResponseReady = true;
RNDIS_KEEPALIVE_MSG_t* KEEPALIVE_Message = (RNDIS_KEEPALIVE_MSG_t*)&RNDISMessageBuffer;
RNDIS_KEEPALIVE_CMPLT_t* KEEPALIVE_Response = (RNDIS_KEEPALIVE_CMPLT_t*)&RNDISMessageBuffer;
KEEPALIVE_Response->MessageType = REMOTE_NDIS_KEEPALIVE_CMPLT;
KEEPALIVE_Response->MessageLength = sizeof(RNDIS_KEEPALIVE_CMPLT_t);
KEEPALIVE_Response->RequestId = KEEPALIVE_Message->RequestId;
KEEPALIVE_Response->Status = REMOTE_NDIS_STATUS_SUCCESS;
break;
}
}
/** Processes RNDIS query commands, retrieving information from the adapter and reporting it back to the host. The requested
* parameter is given as an OID value.
*
* \param OId OId value of the parameter being queried
* \param QueryData Pointer to any extra query data being sent by the host to the device inside the RNDIS message buffer
* \param QuerySize Size in bytes of the extra query data being sent by the host
* \param ResponseData Pointer to the start of the query response inside the RNDIS message buffer
* \param ResponseSize Pointer to the size in bytes of the response data being sent to the host
*
* \return Boolean true if the query was handled, false otherwise
*/
static bool ProcessNDISQuery(uint32_t OId, void* QueryData, uint16_t QuerySize,
void* ResponseData, uint16_t* ResponseSize)
{
/* Handler for REMOTE_NDIS_QUERY_MSG messages */
switch (OId)
{
case OID_GEN_SUPPORTED_LIST:
*ResponseSize = sizeof(AdapterSupportedOIDList);
/* Copy the list of supported NDIS OID tokens to the response buffer */
memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));
return true;
case OID_GEN_HARDWARE_STATUS:
*ResponseSize = sizeof(uint32_t);
/* Always indicate hardware ready */
*((uint32_t*)ResponseData) = NdisHardwareStatusReady;
return true;
case OID_GEN_MEDIA_SUPPORTED:
case OID_GEN_MEDIA_IN_USE:
*ResponseSize = sizeof(uint32_t);
/* Indicate 802.3 (Ethernet) supported by the adapter */
*((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIUM_802_3;
return true;
case OID_GEN_VENDOR_ID:
*ResponseSize = sizeof(uint32_t);
/* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */
*((uint32_t*)ResponseData) = 0x00FFFFFF;
return true;
case OID_GEN_MAXIMUM_FRAME_SIZE:
case OID_GEN_TRANSMIT_BLOCK_SIZE:
case OID_GEN_RECEIVE_BLOCK_SIZE:
*ResponseSize = sizeof(uint32_t);
/* Indicate that the maximum frame size is the size of the ethernet frame buffer */
*((uint32_t*)ResponseData) = ETHERNET_FRAME_SIZE_MAX;
return true;
case OID_GEN_VENDOR_DESCRIPTION:
*ResponseSize = sizeof(AdapterVendorDescription);
/* Copy vendor description string to the response buffer */
memcpy_P(ResponseData, AdapterVendorDescription, sizeof(AdapterVendorDescription));
return true;
case OID_GEN_MEDIA_CONNECT_STATUS:
*ResponseSize = sizeof(uint32_t);
/* Always indicate that the adapter is connected to a network */
*((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIA_STATE_CONNECTED;
return true;
case OID_GEN_LINK_SPEED:
*ResponseSize = sizeof(uint32_t);
/* Indicate 10Mb/s link speed */
*((uint32_t*)ResponseData) = 100000;
return true;
case OID_802_3_PERMANENT_ADDRESS:
case OID_802_3_CURRENT_ADDRESS:
*ResponseSize = sizeof(MAC_Address_t);
/* Copy over the fixed adapter MAC to the response buffer */
memcpy_P(ResponseData, &AdapterMACAddress, sizeof(MAC_Address_t));
return true;
case OID_802_3_MAXIMUM_LIST_SIZE:
*ResponseSize = sizeof(uint32_t);
/* Indicate only one multicast address supported */
*((uint32_t*)ResponseData) = 1;
return true;
case OID_GEN_CURRENT_PACKET_FILTER:
*ResponseSize = sizeof(uint32_t);
/* Indicate the current packet filter mask */
*((uint32_t*)ResponseData) = CurrPacketFilter;
return true;
case OID_GEN_XMIT_OK:
case OID_GEN_RCV_OK:
case OID_GEN_XMIT_ERROR:
case OID_GEN_RCV_ERROR:
case OID_GEN_RCV_NO_BUFFER:
case OID_802_3_RCV_ERROR_ALIGNMENT:
case OID_802_3_XMIT_ONE_COLLISION:
case OID_802_3_XMIT_MORE_COLLISIONS:
*ResponseSize = sizeof(uint32_t);
/* Unused statistic OIDs - always return 0 for each */
*((uint32_t*)ResponseData) = 0;
return true;
case OID_GEN_MAXIMUM_TOTAL_SIZE:
*ResponseSize = sizeof(uint32_t);
/* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */
*((uint32_t*)ResponseData) = (sizeof(RNDISMessageBuffer) + ETHERNET_FRAME_SIZE_MAX);
return true;
default:
return false;
}
}
/** Processes RNDIS set commands, setting adapter parameters to values given by the host. The requested parameter is given
* as an OID value.
*
* \param OId OId value of the parameter being set
* \param SetData Pointer to the parameter value in the RNDIS message buffer
* \param SetSize Size in bytes of the parameter value being sent by the host
*
* \return Boolean true if the set was handled, false otherwise
*/
static bool ProcessNDISSet(uint32_t OId, void* SetData, uint16_t SetSize)
{
/* Handler for REMOTE_NDIS_SET_MSG messages */
switch (OId)
{
case OID_GEN_CURRENT_PACKET_FILTER:
/* Save the packet filter mask in case the host queries it again later */
CurrPacketFilter = *((uint32_t*)SetData);
/* Set the RNDIS state to initialized if the packet filter is non-zero */
CurrRNDISState = ((CurrPacketFilter) ? RNDIS_Data_Initialized : RNDIS_Data_Initialized);
return true;
case OID_802_3_MULTICAST_LIST:
/* Do nothing - throw away the value from the host as it is unused */
return true;
default:
return false;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -