📄 protocol.cpp
字号:
//********************************************************************
// 日期: 2004/08/25 - 25:8:2004 16:08
// 名前: tiamo
// 描述: protocol
//*********************************************************************
#include "stdafx.h"
#define __ulFILE__ MAKE_SIG('B','I','N','D')
// lock
NDIS_SPIN_LOCK g_lockBind;
// bind time
BOOLEAN g_bIsTimeToBind;
// set filter
BOOLEAN g_bSetFilterAtBind;
// list head
LIST_ENTRY g_ltBindsHead;
// open complete
VOID protocolOpenAdapterComplete(PBIND_CONTEXT pBindContext,NDIS_STATUS status,NDIS_STATUS openErrorStatus)
{
PAGED_CODE();
ASSERT(pBindContext && pBindContext->m_ulSig == BIND_CONTEXT_SIG && pBindContext->m_lRefCount > 0);
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)
{
PAGED_CODE();
ASSERT(pBindContext && pBindContext->m_ulSig == BIND_CONTEXT_SIG);
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)
{
ASSERT(pBindContext && pBindContext->m_ulSig == BIND_CONTEXT_SIG && pBindContext->m_lRefCount > 0);
PPACKET pMyPacket = reinterpret_cast<PPROTOCOL_RESERVED>(pPacket->ProtocolReserved)->m_pPacket;
pMyPacket->m_status = status;
// ref by miniportCoSendPackets
DereferencePacket(pMyPacket);
// ref by miniportCoSendPackets
DereferenceBind(pMyPacket->m_pBindContext);
}
// transfer data complete
VOID protocolTransferDataComplete(PBIND_CONTEXT pBindContext,PNDIS_PACKET pPacket,NDIS_STATUS status,UINT uByteTransferred)
{
ASSERT(pBindContext && pBindContext->m_ulSig == BIND_CONTEXT_SIG && pBindContext->m_lRefCount > 0);
PPACKET pMyPacket = reinterpret_cast<PPROTOCOL_RESERVED>(pPacket->ProtocolReserved)->m_pPacket;
if(status != NDIS_STATUS_SUCCESS)
{
DereferencePacket(pMyPacket);
return;
}
// reversed data,so convert it
if(pMyPacket->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,pMyPacket->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,pMyPacket->m_pucFrame + lCurrentOffset,lCopyLen);
// copy back
NdisMoveMemory(pMyPacket->m_pucFrame + lCurrentOffset + PPPOE_MIN_ETH_FRAME_SIZE,temp,lCopyLen);
}
NdisMoveMemory(pMyPacket->m_pucFrame,ucHead,PPPOE_MIN_ETH_FRAME_SIZE);
pMyPacket->m_ulFlags &= ~PPPOE_PACKET_BUFFER_REVERSED;
}
// insert to the list
NdisInterlockedInsertTailList(&pBindContext->m_ltRecvPacketHead,&pMyPacket->m_ltPacketAnchor,&pBindContext->m_lockSelf);
}
// request complete
VOID protocolRequestComplete(PBIND_CONTEXT pBindContext,PNDIS_REQUEST pRequest,NDIS_STATUS status)
{
ASSERT(pBindContext && pBindContext->m_ulSig == BIND_CONTEXT_SIG && pBindContext->m_lRefCount > 0);
__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)
{
ASSERT(pBindContext && pBindContext->m_ulSig == BIND_CONTEXT_SIG && pBindContext->m_lRefCount > 0);
NdisAcquireSpinLock(&pBindContext->m_lockSelf);
if(!pBindContext->m_bProcessingRecvPacket)
{
pBindContext->m_bProcessingRecvPacket = TRUE;
while(!IsListEmpty(&pBindContext->m_ltRecvPacketHead))
{
PLIST_ENTRY pEntry = RemoveHeadList(&pBindContext->m_ltRecvPacketHead);
NdisReleaseSpinLock(&pBindContext->m_lockSelf);
// get packet
PPACKET pPacket = CONTAINING_RECORD(pEntry,PACKET,m_ltPacketAnchor);
// initialize packet member value
if(InitializePacketForRecved(pPacket))
{
// process it
ProcessRecvedPacket(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)
{
}
// status
VOID protocolStatus(PBIND_CONTEXT pBindContext,NDIS_STATUS generalStatus,PVOID pStatusBuffer,UINT uStatusBufferSize)
{
ASSERT(pBindContext && pBindContext->m_ulSig == BIND_CONTEXT_SIG && pBindContext->m_lRefCount > 0);
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)
{
ASSERT(pBindContext && pBindContext->m_ulSig == BIND_CONTEXT_SIG && pBindContext->m_lRefCount > 0);
// always not 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
PPACKET pPacket = GetSimplePacket();
if(!pPacket)
return NDIS_STATUS_NOT_ACCEPTED;
// check full buffer received
if(uLookaheadBufferSize < uPacketSize)
{
// move head buffer to the end first
NdisMoveMemory(pPacket->m_pucFrame + PPPOE_MAX_FRAME_SIZE,pHeaderBuffer,uHeaderBufferSize);
NdisTransferData(&status,pBindContext->m_pOpenBlock,MacReceiveContext,0,uPacketSize,
pPacket->m_pNdisPacket,&uPacketSize);
pPacket->m_ulFlags |= PPPOE_PACKET_BUFFER_REVERSED;
}
else
{
// copy head buffer
NdisMoveMemory(pPacket->m_pFrame,pHeaderBuffer,uHeaderBufferSize);
// copy lookahead buffer
NdisMoveMemory(pPacket->m_pucFrame + uHeaderBufferSize,pLookAheadBuffer,uLookaheadBufferSize);
status = NDIS_STATUS_SUCCESS;
}
if(status != NDIS_STATUS_PENDING)
protocolTransferDataComplete(pBindContext,pPacket->m_pNdisPacket,status,uPacketSize);
return status;
}
// receive packet
INT protocolReceivePacket(PBIND_CONTEXT pBindContext,PNDIS_PACKET pPacket)
{
BOOLEAN bNeedCallReturn = FALSE;
PPACKET pMyPacket = ConvertRecvedNdisPacket(pBindContext,pPacket,&bNeedCallReturn);
if(!pMyPacket)
return 0;
NdisInterlockedInsertTailList(&pBindContext->m_ltRecvPacketHead,&pMyPacket->m_ltPacketAnchor,&pBindContext->m_lockSelf);
return bNeedCallReturn;
}
// bind adapter
VOID protocolBindAdapter(PNDIS_STATUS pStatus,NDIS_HANDLE hBindContext,PNDIS_STRING pDeviceName,PVOID pSys1,PVOID pSys2)
{
PBIND_CONTEXT pBind = NULL;
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
NDIS_STATUS openErrorStatus;
__try
{
NdisAcquireSpinLock(&g_lockBind);
if(!g_bIsTimeToBind)
{
DebugInfo(("it is not the time to bind.\n"));
*pStatus = status = NDIS_STATUS_FAILURE;
NdisReleaseSpinLock(&g_lockBind);
__leave;
}
NdisReleaseSpinLock(&g_lockBind);
// create bind
pBind = CreateBind();
DebugInfo(("create bind 0x%x\n",pBind));
// open lower miniport
NDIS_MEDIUM mediumArray[1] ={NdisMedium802_3};
UINT selMedium;
DebugInfo(("open adapter %Z\n",pDeviceName));
NdisOpenAdapter(&status,&openErrorStatus,&pBind->m_pOpenBlock,&selMedium,mediumArray,
sizeof(mediumArray)/sizeof(NDIS_MEDIUM),g_hNdisProtocolHandle,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)
{
DebugError(("open adapter %Z,error 0x%x\n",pDeviceName,status));
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_ltBindsHead,&pBind->m_ltBindAnchor,&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)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -