⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 protocol.cpp

📁 pppoe client
💻 CPP
📖 第 1 页 / 共 2 页
字号:

//********************************************************************
//	日期:	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 + -