📄 rndis.c
字号:
CELOGMSG (ZONE_MEM,
(TEXT("%%> RcvRndisPacket[0x%x] alloced.\r\n"),
pRcvRndisPacket));
memset(
pRcvRndisPacket,
0x00,
sizeof(RCV_RNDIS_PACKET));
CELOGMSG (0,
(TEXT("Initially: pRcvRndisPacket->dwReturnsPending == [%d]\r\n"),
pRcvRndisPacket->dwReturnsPending));
pRcvRndisPacket->pDataWrapper = pDataWrapper;
//
// Prepare NDIS packets for indicating up.
//
do
{
pRndisPacket = RNDIS_MESSAGE_PTR_TO_MESSAGE_PTR(pRndisMessage);
//
// Some sanity checks.
//
if (pRndisMessage->MessageLength > dwLengthRemaining)
{
CELOGMSG (ZONE_ERROR,
(TEXT("RNdis:: Invalid RndisPacket l[%d] rem [%d]\r\n"),
pRndisMessage->MessageLength,
dwLengthRemaining));
break;
}
if (pRndisPacket->DataLength > pRndisMessage->MessageLength)
{
CELOGMSG (ZONE_ERROR,
(TEXT("RNdis:: Err! RndisPacket l[%d]>MsgLen[%d]\r\n"),
pRndisPacket->DataLength,
pRndisMessage->MessageLength));
break;
}
//
// Allocate an NDIS packet to do the indication with.
//
NdisAllocatePacket(
&NdisStatus,
&pNdisPacket,
NdisPacketPool);
if (NdisStatus != NDIS_STATUS_SUCCESS)
{
pNdisPacket = NULL;
CELOGMSG (ZONE_ERROR,
(TEXT("RNdis:: Err! no mem for NDIS_PACKET...\r\n")));
break;
}
//
// Protocol driver can keep the packet and return later..
//
NDIS_SET_PACKET_HEADER_SIZE(pNdisPacket, 14);
NDIS_SET_PACKET_STATUS(pNdisPacket, NDIS_STATUS_SUCCESS);
NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(
pNdisPacket, NULL, 0);
//
// Here is the NDIS_BUFFER wrapper.
//
NdisAllocateBuffer(
&NdisStatus,
&pNdisBuffer,
NdisBufferPool,
GET_PTR_TO_RNDIS_DATA_BUFF(pRndisPacket),
pRndisPacket->DataLength);
if (NdisStatus != NDIS_STATUS_SUCCESS)
{
CELOGMSG (ZONE_ERROR,
(TEXT("RNdis:: Err! non mem for NDIS_BUFFER..\r\n")));
NdisFreePacket(pNdisPacket);
break;
}
//
// Cool, by here we have NDIS_PACKET and NDIS_BUFFER..
// Link them and queue them in PacketArray.
//
NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);
#if 0
CELOGMSG (ZONE_RNDIS, (TEXT("RX packet [%d] bytes: \r\n"),
pNdisBuffer->BufferLength));
DumpMemory(
pNdisBuffer->VirtualAddress,
MIN(48, pNdisBuffer->BufferLength));
#endif
CELOGMSG (0, (TEXT(">> [%d] bytes.\r\n"),
pNdisBuffer->BufferLength));
PacketArray[dwNumberOfPackets] = pNdisPacket;
dwNumberOfPackets++;
*(RESERVED_FROM_RECV_PACKET(pNdisPacket)) = pRcvRndisPacket;
//
// Next packet please..
//
dwLengthRemaining -= pRndisMessage->MessageLength;
pRndisMessage =
(PRNDIS_MESSAGE)((ULONG_PTR)pRndisMessage +
pRndisMessage->MessageLength);
NdisInterlockedIncrement(
&pRcvRndisPacket->dwReturnsPending);
CELOGMSG (0,
(TEXT("pRcvRndisPacket->dwReturnsPending == [%d]\r\n"),
pRcvRndisPacket->dwReturnsPending));
//
// See if we have reached the maximum, or there is no packet
// left in the RNDIS_PACKET message.
// We should have told RNDIS host the max ndis packet it may
// include in one RNDIS_MESSAGE. So if it goes beyond that
// we toss 'em..
//
if ((dwNumberOfPackets == RNDIS_MAX_PACKETS_PER_MESSAGE) ||
(dwLengthRemaining < RNDIS_MESSAGE_SIZE(RNDIS_PACKET)))
{
ASSERT(dwNumberOfPackets < RNDIS_MAX_PACKETS_PER_MESSAGE);
break;
}
}
while (dwLengthRemaining >= RNDIS_MESSAGE_SIZE(RNDIS_PACKET));
//
// Indicate to VMINI which will pass it to CE stack.
// Each packet will then come back via RndisReturnIndicatedPacket()
// when the dwReturnsPending == 0 we then release the
// pRcvRndisPacket and return the PDATA_WRAPPER to PDD.
//
if (dwNumberOfPackets)
{
ASSERT(pRcvRndisPacket->dwReturnsPending == dwNumberOfPackets);
CELOGMSG (ZONE_RNDIS,
(TEXT("IND to RNDISMINI1 [0x%x]: DataWrap[0x%x]-[%d]pkts.\r\n"),
pRcvRndisPacket,
pRcvRndisPacket->pDataWrapper,
dwNumberOfPackets));
VMiniIndicatePackets(
PacketArray,
dwNumberOfPackets);
RndisMdd.dwTransmitOkay += dwNumberOfPackets;
//
// CE VMINI will call RndisReturnIndicatedPacket() to return
// this packet.
//
bReturnImmediately = FALSE;
}
}
while (FALSE);
//
// If we don't need to retain this packet, return to PDD immediately..
//
if (bReturnImmediately)
{
//
// indicate this packet is returned immediately..
//
RndisMdd.PddCharacteristics.IndicateRndisPacketCompleteHandler(
pDataWrapper);
if (pRcvRndisPacket)
{
FREE_RCV_RNDIS_PACKET(pRcvRndisPacket);
CELOGMSG (ZONE_MEM,
(TEXT("%%> RcvRndisPacket[0x%x] freed.\r\n"),
pRcvRndisPacket));
}
}
*/
} // RndisProcessPacket()
////////////////////////////////////////////////////////////////////////////////
// RndisReturnIndicatedPacket()
//
// Routine Description:
//
// Handle packet return sent to VMini earlier..
//
// Arguments:
//
// pNdisPacket :: The packet we indicate to VMini in
// VMiniIndicatePackets().
//
// Return Value:
//
// TRUE if successful, FALSE otherwise.
//
/*
void
RndisReturnIndicatedPacket(
PNDIS_PACKET pNdisPacket)
{
PRCV_RNDIS_PACKET pRcvRndisPacket;
DWORD dwReturnsPending;
PNDIS_BUFFER pNdisBuffer;
pRcvRndisPacket = *(RESERVED_FROM_RECV_PACKET(pNdisPacket));
dwReturnsPending = NdisInterlockedDecrement(
&pRcvRndisPacket->dwReturnsPending);
CELOGMSG (ZONE_RNDIS,
(TEXT("RNDISMINI1 Returns[0x%x] : Wrap[0x%x] Pend[%d]\r\n"),
pRcvRndisPacket,
pRcvRndisPacket->pDataWrapper,
dwReturnsPending));
NdisQueryPacket(
pNdisPacket,
NULL,
NULL,
&pNdisBuffer,
NULL);
NdisFreePacket(pNdisPacket);
NdisFreeBuffer(pNdisBuffer);
if (dwReturnsPending == 0)
{
//
// All NDIS_PACKETs consumed, we can now return the PDATA_WRAPPER
// passed to us in RndisProcessPacket() and then release the
// RCV_RNDIS_PACKET wrapper.
//
CELOGMSG (0,
(TEXT("RNdis:: VMini consumed RNDIS_PACKET[0x%x]..\r\n"),
pRcvRndisPacket));
RndisMdd.PddCharacteristics.IndicateRndisPacketCompleteHandler(
pRcvRndisPacket->pDataWrapper);
FREE_RCV_RNDIS_PACKET (pRcvRndisPacket);
CELOGMSG (ZONE_MEM,
(TEXT("%%> RcvRndisPacket[0x%x] freed.\r\n"),
pRcvRndisPacket));
}
} // RndisReturnIndicatedPacket()
*/
LPVOID
NKCreateStaticMapping(
DWORD dwPhysBase,
DWORD dwSize
) ;
////////////////////////////////////////////////////////////////////////////////
// RndisInit()
//
// Routine Description:
//
// Our one and only chance to init..
//
// Arguments:
//
// None.
//
// Return Value:
//
// TRUE if successful, FALSE otherwise.
//
BOOL RndisInit( BYTE *pbBaseAddress, DWORD dwMultiplier, USHORT MacAddr[3])
{
DWORD dwWaitMSec;
#define INITIALTIME_SEC 100
// NDIS_STATUS Status;
DWORD dwSysInt=0;
EdbgOutputDebugString("Rndis:: initialization: with addr=%x\r\n",pbBaseAddress);
if (pbBaseAddress ) { // Open the following
pbBaseAddress=
(PBYTE)NKCreateStaticMapping((DWORD)pbBaseAddress>>8,0x100000L);
EdbgOutputDebugString("Rndis:: Address static map to addr=%x\r\n",pbBaseAddress);
};
memset(&RndisMdd,0,sizeof(RndisMdd));
RndisMdd.bPddSending = FALSE;
EdbgOutputDebugString("Rndis:: initialization!\r\n");
// Initialize The Buffer
InitBuffer(&MsgBufferDesc, MsgBuffer , MAX_PACKET_SIZE+4*(sizeof(DATA_WRAPPER)+sizeof(DWORD)));
// Initialize The Ethnet Frame Buffer
InitBuffer(&EthBufferDesc, EthBuffer , (MAX_ETH_BLOCK+sizeof(DWORD))*10);
if (PDDInit(&(RndisMdd.PddCharacteristics), pbBaseAddress)) {
DWORD dwStartSec;
ULONG ulRequiredLength=0;
EdbgOutputDebugString("Rndis:: PDDInit Success!\r\n");
RndisMdd.dwDeviceState = RNDIS_UNINITIALIZED;
if (pbBaseAddress==NULL) { // First Time initialize.
if (!RndisMdd.PddCharacteristics.GetHandler(
REQ_ID_DEVICE_MACADDR,
MacAddr,
6,
&ulRequiredLength))
{
EdbgOutputDebugString("Rndis:: Err no MAC address read from PDD.\r\n");
return FALSE;
}
}
memcpy(RndisMdd.PermanentNwAddr,MacAddr,6);
RndisMdd.PermanentNwAddr[0] |= 0x02;
EdbgOutputDebugString("Rndis:: Get MAC address %x,%x,%x\r\n",MacAddr[0],MacAddr[1],MacAddr[2]);
dwStartSec=OEMEthGetSecs();
while (OEMEthGetSecs()-dwStartSec<=INITIALTIME_SEC) {
// PDD_ISR();
RndisMdd.PddCharacteristics.ISRHandler(&dwWaitMSec);
if (RndisMdd.dwDeviceState == RNDIS_INITIALIZED) {
break;
}
}
}
if (RndisMdd.dwDeviceState == RNDIS_INITIALIZED) {
DWORD dwStartSec=OEMEthGetSecs();
EdbgOutputDebugString("Rndis:: initialization: Success\r\n");
while (OEMEthGetSecs()-dwStartSec<=5) {
PVOID pDataBuffer=NULL;
WORD wLength;
RndisMdd.PddCharacteristics.ISRHandler(&dwWaitMSec);
// Dump Any data we recevied.
if (GetFirstUsedBuffer(&EthBufferDesc,&pDataBuffer, &wLength)==TRUE && pDataBuffer!=NULL) {
FreeBuffer(&EthBufferDesc,pDataBuffer);
};
};
return TRUE;
}
else {
EdbgOutputDebugString("Rndis:: initialization: Fail!\r\n");
return FALSE;
};
} // RndisInit()
DWORD RndisGetIrq() {
// Ugly, We do not have any other way to return IRQ.
return RndisMdd.PddCharacteristics.dwIRQ;
};
void RndisGetPCICard(PDWORD pdwBaseAddr, PBYTE pucIrq)
{
*pdwBaseAddr=RndisMdd.PddCharacteristics.dwBaseAddr;
*pucIrq=(BYTE)RndisMdd.PddCharacteristics.dwIRQ;
}
////////////////////////////////////////////////////////////////////////////////
// RndisDeInit()
//
// Routine Description:
//
// Reverse what's done in RndisInit()
//
// Arguments:
//
// None.
//
// Return Value:
//
// None.
//
void
RndisDeInit(void)
{
/*
NdisFreePacketPool(NdisPacketPool);
NdisFreeBufferPool(NdisBufferPool);
SetEvent(g_TxEvent);
ExDeleteNPagedLookasideList(&RcvRndisPacketLookAsideList);
*/
} // RndisDeInit()
void
RndisCurrentPacketFilter(DWORD dwFilter)
{
// Do know how.
}
BOOL
RndisMulticastList(PUCHAR pucMulticastAddresses, DWORD dwNoOfAddresses)
{
return TRUE;
}
DWORD
RndisGetPendingInts(void)
{
DWORD dwWaitMSec;
//EdbgOutputDebugString("+NE2000GetPendingInts\r\n");
// PDD_ISR();
RndisMdd.PddCharacteristics.ISRHandler(&dwWaitMSec);
//EdbgOutputDebugString("-NE2000GetPendingInts\r\n");
if (GetFirstUsedBuffer(&EthBufferDesc,NULL,NULL)) {
#ifdef DEBUG_SINGLE_CHAR
EdbgOutputDebugString("R"); // indicating a received packet
#endif
return INTR_TYPE_RX;
}
#ifdef DEBUG_SINGLE_CHAR
EdbgOutputDebugString("B"); // discarding non-ARP broadcast traffic.
#endif
return 0;
} // NE2000GetPendingInts
void RndisEnableInts (void )
{
RndisMdd.PddCharacteristics.SetHandler(REQ_ID_ENABLE_INT,NULL,0);
};
void RndisDisableInts (void)
{
RndisMdd.PddCharacteristics.SetHandler(REQ_ID_DISABLE_INT,NULL,0);
};
DWORD RndisSetOptions(DWORD dwOptions)
{
return dwOptions;
}
void MddInitializeCriticalSection(CRITICAL_SECTION *pCS) {;};
void MddDeleteCriticalSection(CRITICAL_SECTION *pCS){;};
void MddEnterCriticalSection(CRITICAL_SECTION *pCS){;};
void MddLeaveCriticalSection(CRITICAL_SECTION *pCS){;};
void RndisMiniCeLogMsg (LPCTSTR szFormat,... )
{
/* TCHAR szBuffer[1024];
va_list pArgs;
va_start(pArgs, szFormat);
_vsntprintf(szBuffer, sizeof(szBuffer)/sizeof(TCHAR), szFormat, pArgs);
va_end(pArgs);
CeLogData(TRUE,CELID_RAW_WCHAR,szBuffer,(WORD)((_tcslen(szBuffer)+1)*sizeof(TCHAR)),
CELZONE_ALWAYSON, 0, 0, FALSE);
*/
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -