📄 protocol.cpp
字号:
//********************************************************************
// 日期: 2004/08/11 - 11:8:2004 0:40
// 名前: tiamo
// 描述: protocol
//*********************************************************************
#include "stdafx.h"
NDIS_MEDIUM MediumArray[1] = {NdisMedium802_3};
BOOLEAN g_bIsTimeToBind = FALSE;
// open complete
VOID protocolOpenAdapterComplete(PBIND_CONTEXT pBindContext,NDIS_STATUS status,NDIS_STATUS openErrorStatus)
{
pBindContext->m_ulFlags |= BIND_CONTEXT_LOWER_ADAPTER_OPENED;
pBindContext->m_statusCallback = status;
NdisSetEvent(&pBindContext->m_evCallback);
}
// close complete
VOID protocolCloseAdapterComplete(PBIND_CONTEXT pBindContext,NDIS_STATUS status)
{
pBindContext->m_ulFlags |= BIND_CONTEXT_LOWER_ADAPTER_CLOSED;
pBindContext->m_statusCallback = status;
NdisSetEvent(&pBindContext->m_evCallback);
}
// send complete
VOID protocolSendComplete(PBIND_CONTEXT pBindContext,PNDIS_PACKET pPacket,NDIS_STATUS status)
{
PPPPOE_PACKET pPPPOEPacket = reinterpret_cast<PPROTOCOL_RESERVED>(pPacket->ProtocolReserved)->m_pPPPOEPacket;
pPPPOEPacket->m_status = status;
DereferencePacket(pPPPOEPacket);
DereferenceBind(pPPPOEPacket->m_pBindContext);
}
// transfer data complete
VOID protocolTransferDataComplete(PBIND_CONTEXT pBindContext,PNDIS_PACKET pPacket,NDIS_STATUS status,UINT uByteTransferred)
{
PPPPOE_PACKET pPPPOEPacket = reinterpret_cast<PPROTOCOL_RESERVED>(pPacket->ProtocolReserved)->m_pPPPOEPacket;
if(status != NDIS_STATUS_SUCCESS)
{
DereferencePacket(pPPPOEPacket);
return;
}
// reversed data,so convert it
if(pPPPOEPacket->m_ulFlags & PPPOE_PACKET_BUFFER_REVERSED)
{
LONG const TEMP_BUFFER_SIZE = 100;
UCHAR temp[TEMP_BUFFER_SIZE];
UCHAR ucHead[PPPOE_MIN_ETH_FRAME_SIZE];
LONG lCurrentOffset = uByteTransferred;
LONG lCopyLen = TEMP_BUFFER_SIZE;
// copy to temp buffer first
NdisMoveMemory(ucHead,pPPPOEPacket->m_pucFrame + PPPOE_MAX_FRAME_SIZE,PPPOE_MIN_ETH_FRAME_SIZE);
while(lCurrentOffset)
{
lCurrentOffset -= lCopyLen;
if(lCurrentOffset < 0)
{
lCopyLen += lCurrentOffset;
lCurrentOffset = 0;
}
// copy to temp buffer first
NdisMoveMemory(temp,pPPPOEPacket->m_pucFrame + lCurrentOffset,lCopyLen);
// copy back
NdisMoveMemory(pPPPOEPacket->m_pucFrame + lCurrentOffset + PPPOE_MIN_ETH_FRAME_SIZE,temp,lCopyLen);
}
NdisMoveMemory(pPPPOEPacket->m_pucFrame,ucHead,PPPOE_MIN_ETH_FRAME_SIZE);
pPPPOEPacket->m_ulFlags &= ~PPPOE_PACKET_BUFFER_REVERSED;
}
// insert to the list
NdisInterlockedInsertTailList(&pBindContext->m_ltRecvPacket,&pPPPOEPacket->m_ltPackets,&pBindContext->m_lockSelf);
}
// request complete
VOID protocolRequestComplete(PBIND_CONTEXT pBindContext,PNDIS_REQUEST pRequest,NDIS_STATUS status)
{
__try
{
if(pRequest->RequestType == NdisRequestQueryInformation)
{
switch(pRequest->DATA.QUERY_INFORMATION.Oid)
{
case OID_802_3_CURRENT_ADDRESS:
pBindContext->m_ulFlags |= BIND_CONTEXT_MAC_ADDRESS_GOT;
break;
case OID_GEN_LINK_SPEED:
pBindContext->m_ulFlags |= BIND_CONTEXT_LINK_SPPED_GOT;
break;
case OID_GEN_MAXIMUM_FRAME_SIZE:
pBindContext->m_ulFlags |= BIND_CONTEXT_MAX_FRAME_SIZE_GOT;
break;
default:
__leave;
break;
}
}
else
{
if(pRequest->DATA.SET_INFORMATION.Oid != OID_GEN_CURRENT_PACKET_FILTER)
__leave;
if(status == NDIS_STATUS_SUCCESS)
{
if(pBindContext->m_ulFlags & BIND_CONTEXT_PACKET_FILTER_SET)
pBindContext->m_ulFlags &= ~BIND_CONTEXT_PACKET_FILTER_SET;
else
pBindContext->m_ulFlags |= BIND_CONTEXT_PACKET_FILTER_SET;
}
}
NdisSetEvent(&pBindContext->m_evCallback);
pBindContext->m_statusCallback = status;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
}
// receive complete
VOID protocolReceiveComplete(PBIND_CONTEXT pBindContext)
{
NdisAcquireSpinLock(&pBindContext->m_lockSelf);
if(!pBindContext->m_bProcessingRecvPacket)
{
pBindContext->m_bProcessingRecvPacket = TRUE;
while(!IsListEmpty(&pBindContext->m_ltRecvPacket))
{
PLIST_ENTRY pEntry = RemoveHeadList(&pBindContext->m_ltRecvPacket);
NdisReleaseSpinLock(&pBindContext->m_lockSelf);
// get packet
PPPPOE_PACKET pPacket = CONTAINING_RECORD(pEntry,PPPOE_PACKET,m_ltPackets);
// initialize packet member value
if(InitializePPPOEPacketForRecved(pPacket))
{
// process it
ProcessRecvPacket(pBindContext,pPacket);
}
// dereference it
DereferencePacket(pPacket);
NdisAcquireSpinLock(&pBindContext->m_lockSelf);
}
pBindContext->m_bProcessingRecvPacket = FALSE;
}
NdisReleaseSpinLock(&pBindContext->m_lockSelf);
}
// status complete
VOID protocolStatusComplete(PBIND_CONTEXT pBindContext)
{
return;
}
// status
VOID protocolStatus(PBIND_CONTEXT pBindContext,NDIS_STATUS generalStatus,PVOID pStatusBuffer,UINT uStatusBufferSize)
{
if(generalStatus == NDIS_STATUS_MEDIA_DISCONNECT)
{
NotifyBindingRemoval(pBindContext);
}
}
// receive
NDIS_STATUS protocolReceive(PBIND_CONTEXT pBindContext,NDIS_HANDLE MacReceiveContext,PVOID pHeaderBuffer,UINT uHeaderBufferSize,
PVOID pLookAheadBuffer,UINT uLookaheadBufferSize,UINT uPacketSize)
{
// always accept the packect
NDIS_STATUS status = NDIS_STATUS_NOT_ACCEPTED;
// check pppoe frame
if(!FastCheckIsPPPOEFrame(static_cast<PPPPOE_FRAME>(pHeaderBuffer),uHeaderBufferSize))
return NDIS_STATUS_NOT_ACCEPTED;
// check buffer size
if( uHeaderBufferSize + uPacketSize > PPPOE_MAX_ETH_FRAME_SIZE ||
uHeaderBufferSize < PPPOE_MIN_ETH_FRAME_SIZE)
return NDIS_STATUS_NOT_ACCEPTED;
// create a pppoe packet
PPPPOE_PACKET pPPPOEPacket = GetSimplePPPOEPacket();
if(!pPPPOEPacket)
return NDIS_STATUS_NOT_ACCEPTED;
// check full buffer received
if(uLookaheadBufferSize < uPacketSize)
{
// move head buffer to the end first
NdisMoveMemory(pPPPOEPacket->m_pucFrame + PPPOE_MAX_FRAME_SIZE,pHeaderBuffer,uHeaderBufferSize);
NdisTransferData(&status,pBindContext->m_pOpenBlock,MacReceiveContext,0,uPacketSize,
pPPPOEPacket->m_pNdisPacket,&uPacketSize);
pPPPOEPacket->m_ulFlags |= PPPOE_PACKET_BUFFER_REVERSED;
}
else
{
// copy head buffer
NdisMoveMemory(pPPPOEPacket->m_pFrame,pHeaderBuffer,uHeaderBufferSize);
// copy lookahead buffer
NdisMoveMemory(pPPPOEPacket->m_pucFrame + uHeaderBufferSize,pLookAheadBuffer,uLookaheadBufferSize);
status = NDIS_STATUS_SUCCESS;
}
if(status != NDIS_STATUS_PENDING)
protocolTransferDataComplete(pBindContext,pPPPOEPacket->m_pNdisPacket,status,uPacketSize);
return status;
}
// receive packet
INT protocolReceivePacket(PBIND_CONTEXT pBindContext,PNDIS_PACKET pPacket)
{
BOOLEAN bNeedCallReturn = FALSE;
PPPPOE_PACKET pPPPOEPacket = NdisPacket2PPPOEPacket(pBindContext,pPacket,&bNeedCallReturn);
if(!pPPPOEPacket)
return 0;
NdisInterlockedInsertTailList(&pBindContext->m_ltRecvPacket,&pPPPOEPacket->m_ltPackets,&pBindContext->m_lockSelf);
return bNeedCallReturn;
}
// bind adapter
VOID protocolBindAdapter(PNDIS_STATUS pStatus,NDIS_HANDLE hBindContext,PNDIS_STRING pDeviceName,PVOID pSys1,PVOID pSys2)
{
DbgEnterFunction();
PBIND_CONTEXT pBind = NULL;
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
NDIS_STATUS openErrorStatus;
__try
{
NdisAcquireSpinLock(&g_lockBind);
if(!g_bIsTimeToBind)
{
*pStatus = status = NDIS_STATUS_FAILURE;
NdisReleaseSpinLock(&g_lockBind);
__leave;
}
NdisReleaseSpinLock(&g_lockBind);
// create bind
pBind = CreateBind();
// open lower miniport
NDIS_MEDIUM mediumArray[1] ={NdisMedium802_3};
UINT selMedium;
NdisOpenAdapter(&status,&openErrorStatus,&pBind->m_pOpenBlock,&selMedium,mediumArray,
sizeof(mediumArray)/sizeof(NDIS_MEDIUM),g_hProtocolHandle,pBind,pDeviceName,0,NULL);
if(status != NDIS_STATUS_PENDING)
{
protocolOpenAdapterComplete(pBind,status,openErrorStatus);
}
NdisWaitEvent(&pBind->m_evCallback,0);
NdisResetEvent(&pBind->m_evCallback);
status = pBind->m_statusCallback;
if(status != NDIS_STATUS_SUCCESS || mediumArray[selMedium] != NdisMedium802_3)
ExRaiseStatus(status);
// query lower miniport for current address
QueryLowerMiniportForCurrentAddress(pBind);
// query lower miniport for current address
QueryLowerMiniportForLinkSpeed(pBind);
// query lower miniport for max frame size
QueryLowerMiniportForMaxFrameSize(pBind);
// set packet filter
if(g_bSetFilterAtBind)
SetLowerMiniportPacketFilter(pBind,TRUE);
// add bind to list
NdisInterlockedInsertHeadList(&g_ltBinds,&pBind->m_ltBinds,&g_lockBind);
pBind->m_ulBindState = BIND_LOWER_MINIPORT_OPENED;
pBind->m_ulFlags |= BIND_CONTEXT_BINDED;
status = NDIS_STATUS_SUCCESS;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
if(pBind)
{
if(pBind->m_pOpenBlock)
{
NdisCloseAdapter(&openErrorStatus,pBind->m_pOpenBlock);
if(openErrorStatus == NDIS_STATUS_PENDING)
{
NdisWaitEvent(&pBind->m_evCallback,0);
NdisResetEvent(&pBind->m_evCallback);
}
}
FreeBind(pBind);
}
}
*pStatus = status;
DbgLeaveFunctionWithStatus(status);
}
// unbind
VOID protocolUnbindAdapter(OUT PNDIS_STATUS pStatus,PBIND_CONTEXT pBindContext,NDIS_HANDLE hUnbindContext)
{
DbgEnterFunction();
NdisAcquireSpinLock(&pBindContext->m_lockSelf);
if(pBindContext->m_ulBindState == BIND_LOWER_MINIPORT_CLOSING)
{
NdisReleaseSpinLock(&pBindContext->m_lockSelf);
NdisMSleep(10000);
NdisAcquireSpinLock(&pBindContext->m_lockSelf);
}
pBindContext->m_ulBindState = BIND_ROMOVING;
NdisReleaseSpinLock(&pBindContext->m_lockSelf);
NotifyBindingRemoval(pBindContext);
NdisAcquireSpinLock(&g_lockBind);
RemoveEntryList(&pBindContext->m_ltBinds);
NdisReleaseSpinLock(&g_lockBind);
DereferenceBind(pBindContext);
NdisWaitEvent(&pBindContext->m_evRemove,0);
while(pBindContext->m_lPacketNeedReturn > 0)
NdisMSleep(10000);
NdisCloseAdapter(pStatus,pBindContext->m_pOpenBlock);
if(*pStatus != NDIS_STATUS_PENDING)
{
protocolCloseAdapterComplete(pBindContext,*pStatus);
}
NdisWaitEvent(&pBindContext->m_evCallback,0);
NdisResetEvent(&pBindContext->m_evCallback);
pBindContext->m_ulBindState = BIND_FREEING;
FreeBind(pBindContext);
*pStatus = NDIS_STATUS_SUCCESS;
DbgLeaveFunctionWithStatus(*pStatus);
}
// unload
VOID protocolUnload()
{
}
// pnp event
NDIS_STATUS protocolPnPEvent(PBIND_CONTEXT pBindContext,PNET_PNP_EVENT pNetPnPEvent)
{
if(pNetPnPEvent->NetEvent == NetEventSetPower)
{
NdisAcquireSpinLock(&pBindContext->m_lockSelf);
NDIS_DEVICE_POWER_STATE newState = *static_cast<PNDIS_DEVICE_POWER_STATE>(pNetPnPEvent->Buffer);
if(newState != NdisDeviceStateD0)
{
BOOLEAN bNeedClose = FALSE;
if(pBindContext->m_ulBindState == BIND_LOWER_MINIPORT_OPENED)
{
pBindContext->m_ulBindState = BIND_LOWER_MINIPORT_CLOSING;
bNeedClose = TRUE;
}
NdisReleaseSpinLock(&pBindContext->m_lockSelf);
if(bNeedClose)
NotifyBindingRemoval(pBindContext);
NdisAcquireSpinLock(&pBindContext->m_lockSelf);
while(pBindContext->m_lRefCount > 1)
{
NdisReleaseSpinLock(&pBindContext->m_lockSelf);
NdisMSleep(10000);
}
pBindContext->m_ulBindState = BIND_LOWER_MINIPORT_CLOSED;
NdisReleaseSpinLock(&pBindContext->m_lockSelf);
}
else
{
if(pBindContext->m_ulBindState == BIND_LOWER_MINIPORT_CLOSED)
pBindContext->m_ulBindState = BIND_LOWER_MINIPORT_OPENED;
NdisReleaseSpinLock(&pBindContext->m_lockSelf);
}
}
return NDIS_STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -