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

📄 bind.cpp

📁 pppoe client
💻 CPP
字号:

//********************************************************************
//	日期:	2004/08/14 - 14:8:2004   8:27
//	名前:	tiamo
//	描述:	bind
//*********************************************************************

#include "stdafx.h"

BOOLEAN g_bSetFilterAtBind;

// create bind
PBIND_CONTEXT CreateBind()
{
	PBIND_CONTEXT pRet = NULL;

	NDIS_STATUS status = NdisAllocateMemoryWithTag(reinterpret_cast<PVOID *>(&pRet),sizeof(BIND_CONTEXT),0);
	NdisZeroMemory(pRet,sizeof(BIND_CONTEXT));

	pRet->m_ulSig = 'BIND';
	pRet->m_lRefCount = 1;
	pRet->m_ulBindState = BIND_ALLOCATED;
	NdisInitializeEvent(&pRet->m_evRemove);
	NdisInitializeEvent(&pRet->m_evCallback);
	NdisAllocateSpinLock(&pRet->m_lockSelf);
	NdisInitializeListHead(&pRet->m_ltRecvPacket);

	return pRet;
}

// free bind
VOID FreeBind(PBIND_CONTEXT pBind)
{
	NdisFreeMemory(pBind,sizeof(BIND_CONTEXT),0);
}

// reference bind
VOID ReferenceBind(PBIND_CONTEXT pBind,BOOLEAN bAcquireSpinLock)
{
	if(bAcquireSpinLock)
		NdisAcquireSpinLock(&pBind->m_lockSelf);

	pBind->m_lRefCount ++;

	if(bAcquireSpinLock)
		NdisReleaseSpinLock(&pBind->m_lockSelf);
}

// dereference bind
VOID DereferenceBind(PBIND_CONTEXT pBind)
{
	NdisAcquireSpinLock(&pBind->m_lockSelf);

	LONG lCount = -- pBind->m_lRefCount;

	NdisReleaseSpinLock(&pBind->m_lockSelf);

	// set remove event;
	if(!lCount)
		NdisSetEvent(&pBind->m_evRemove);
}


// query lower miniport for current address
VOID QueryLowerMiniportForCurrentAddress(PBIND_CONTEXT pBind)
{
	NdisZeroMemory(&pBind->m_ndisRequest,sizeof(NDIS_REQUEST));

	pBind->m_ndisRequest.RequestType = NdisRequestQueryInformation;
	pBind->m_ndisRequest.DATA.QUERY_INFORMATION.Oid = OID_802_3_CURRENT_ADDRESS;
	pBind->m_ndisRequest.DATA.QUERY_INFORMATION.InformationBuffer = static_cast<PVOID>(pBind->m_macAddress);
	pBind->m_ndisRequest.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(pBind->m_macAddress);

	NDIS_STATUS status;
	NdisRequest(&status,pBind->m_pOpenBlock,&pBind->m_ndisRequest);

	if(status == NDIS_STATUS_PENDING)
	{
		NdisWaitEvent(&pBind->m_evCallback,0);
		NdisResetEvent(&pBind->m_evCallback);
	}
	else
		protocolRequestComplete(pBind,&pBind->m_ndisRequest,status);
}

// query lower miniport for current address
VOID QueryLowerMiniportForLinkSpeed(PBIND_CONTEXT pBind)
{
	NdisZeroMemory(&pBind->m_ndisRequest,sizeof(NDIS_REQUEST));

	pBind->m_ndisRequest.RequestType = NdisRequestQueryInformation;
	pBind->m_ndisRequest.DATA.QUERY_INFORMATION.Oid = OID_GEN_LINK_SPEED;
	pBind->m_ndisRequest.DATA.QUERY_INFORMATION.InformationBuffer = static_cast<PVOID>(&pBind->m_ulLinkSpeed);
	pBind->m_ndisRequest.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(pBind->m_ulLinkSpeed);

	NDIS_STATUS status;
	NdisRequest(&status,pBind->m_pOpenBlock,&pBind->m_ndisRequest);

	if(status == NDIS_STATUS_PENDING)
	{
		NdisWaitEvent(&pBind->m_evCallback,0);
		NdisResetEvent(&pBind->m_evCallback);
	}
	else
		protocolRequestComplete(pBind,&pBind->m_ndisRequest,status);
}

// query lower miniport for current address
VOID QueryLowerMiniportForMaxFrameSize(PBIND_CONTEXT pBind)
{
	NdisZeroMemory(&pBind->m_ndisRequest,sizeof(NDIS_REQUEST));

	pBind->m_ndisRequest.RequestType = NdisRequestQueryInformation;
	pBind->m_ndisRequest.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_FRAME_SIZE;
	pBind->m_ndisRequest.DATA.QUERY_INFORMATION.InformationBuffer = static_cast<PVOID>(&pBind->m_ulMaxFrameSize);
	pBind->m_ndisRequest.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(pBind->m_ulMaxFrameSize);

	NDIS_STATUS status;
	NdisRequest(&status,pBind->m_pOpenBlock,&pBind->m_ndisRequest);

	if(status == NDIS_STATUS_PENDING)
	{
		NdisWaitEvent(&pBind->m_evCallback,0);
		NdisResetEvent(&pBind->m_evCallback);
	}
	else
		protocolRequestComplete(pBind,&pBind->m_ndisRequest,status);
}

// change lower miniport packet filter
VOID ChangeLowerMiniportPacketFilter(BOOLEAN bSetAtBind)
{
	NdisAcquireSpinLock(&g_lockBind);

	g_bSetFilterAtBind = bSetAtBind;

	PLIST_ENTRY pEntry = g_ltBinds.Flink;
	for(;pEntry != &g_ltBinds;pEntry = pEntry->Flink)
	{
		PBIND_CONTEXT pBind = CONTAINING_RECORD(pEntry,BIND_CONTEXT,m_ltBinds);

		NdisAcquireSpinLock(&pBind->m_lockSelf);

		if(pBind->m_ulBindState == BIND_LOWER_MINIPORT_OPENED)
		{
			pBind->m_ulFlags |= BIND_CONTEXT_PACKET_FILTER_SET_NEEDED;
			pBind->m_lRefCount ++;
		}

		NdisReleaseSpinLock(&pBind->m_lockSelf);
	}

	pEntry = g_ltBinds.Flink;

	for(;pEntry != &g_ltBinds;pEntry = pEntry->Flink)
	{
		PBIND_CONTEXT pBind = CONTAINING_RECORD(pEntry,BIND_CONTEXT,m_ltBinds);
		if(pBind->m_ulFlags & BIND_CONTEXT_PACKET_FILTER_SET_NEEDED)
		{
			NdisReleaseSpinLock(&g_lockBind);

			SetLowerMiniportPacketFilter(pBind,bSetAtBind);

			pBind->m_ulFlags &= ~BIND_CONTEXT_PACKET_FILTER_SET_NEEDED;

			DereferenceBind(pBind);
			
			NdisAcquireSpinLock(&g_lockBind);
		}
	}

	NdisReleaseSpinLock(&g_lockBind);
}

// set packet filter
VOID SetLowerMiniportPacketFilter(PBIND_CONTEXT pBind,BOOLEAN bSetOrRemove)
{
	// if set then only can remove
	if(pBind->m_ulFlags & BIND_CONTEXT_PACKET_FILTER_SET)
	{
		if(!bSetOrRemove)
		{
			pBind->m_ulPacketFilter =  0;

			bSetOrRemove = TRUE;
		}
	}
	else
	{
		if(bSetOrRemove)
			pBind->m_ulPacketFilter = NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_DIRECTED;
	}

	if(bSetOrRemove)
	{
		NdisZeroMemory(&pBind->m_ndisRequest,sizeof(NDIS_REQUEST));

		pBind->m_ndisRequest.RequestType = NdisRequestSetInformation;
		pBind->m_ndisRequest.DATA.SET_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;

		pBind->m_ndisRequest.DATA.SET_INFORMATION.InformationBuffer = static_cast<PVOID>(&pBind->m_ulPacketFilter);
		pBind->m_ndisRequest.DATA.SET_INFORMATION.InformationBufferLength = sizeof(pBind->m_ulPacketFilter);

		NDIS_STATUS status;
		NdisRequest(&status,pBind->m_pOpenBlock,&pBind->m_ndisRequest);

		if(status == NDIS_STATUS_PENDING)
		{
			NdisWaitEvent(&pBind->m_evCallback,0);
			NdisResetEvent(&pBind->m_evCallback);
		}
		else
			protocolRequestComplete(pBind,&pBind->m_ndisRequest,status);
	}
}

// reEnumerate bind
VOID ExecReEnumerateBindForMakeCall(PPPPOE_WORK_ITEM pItem,PPPPOE_WORK_ITEM_PARAM pParam,PVOID pAdditionalParam)
{
	NdisAcquireSpinLock(&g_lockBind);

	g_bIsTimeToBind = TRUE;

	NdisReleaseSpinLock(&g_lockBind);

	NdisReEnumerateProtocolBindings(g_hProtocolHandle);

	ChangeLowerMiniportPacketFilter(TRUE);

	NdisMQueryInformationComplete(g_pAdapter->m_hMiniportAdapter,NDIS_STATUS_SUCCESS);

	ScheduleWorkItem(pParam->MakeCallReEnumerateBindFormat.m_pFsmMakeCall);
}

// notify bind remove
VOID NotifyBindingRemoval(PBIND_CONTEXT pBind)
{
	if(!g_pAdapter)
		return;

	__try
	{
		NdisAcquireSpinLock(&g_pAdapter->m_lockSelf);

		if(ADAPTER_IN_WRONG_STATE(g_pAdapter))
		{
			NdisReleaseSpinLock(&g_pAdapter->m_lockSelf);
			__leave;
		}

		if(PROVIDER_IN_WRONG_STATE(g_pAdapter))
		{
			NdisReleaseSpinLock(&g_pAdapter->m_lockSelf);
			__leave;
		}

		ReferenceTspiProvider(g_pAdapter,FALSE);

		NdisReleaseSpinLock(&g_pAdapter->m_lockSelf);

		protocolReceiveComplete(pBind);

		NdisAcquireSpinLock(&g_pAdapter->m_lockSelf);

		ULONG ulCalls = g_pAdapter->m_ulEndPoints * g_pAdapter->m_ulNumLineDevs;

		USHORT usCallIndex = 0;

		for(; usCallIndex < ulCalls; usCallIndex ++)
		{
			PCALL_INFO pCall = GetCallPtrFromHandleTableIndex(g_pAdapter->m_pCallHandleTable,usCallIndex);

			if(pCall)
			{
				NdisAcquireSpinLock(&pCall->m_lockSelf);

				if(pCall->m_pBindContext == pBind)
				{
					ReferenceCall(pCall,FALSE);

					NdisReleaseSpinLock(&pCall->m_lockSelf);

					NdisReleaseSpinLock(&g_pAdapter->m_lockSelf);

					NDIS_TAPI_DROP drop;
					drop.hdCall = pCall->m_hdCall;

					TspiDrop(g_pAdapter,&drop,LINEDISCONNECTMODE_UNREACHABLE);

					DereferenceCall(pCall);

					NdisAcquireSpinLock(&g_pAdapter->m_lockSelf);
				}
				else
					NdisReleaseSpinLock(&pCall->m_lockSelf);
			}
		}

		NdisReleaseSpinLock(&g_pAdapter->m_lockSelf);

		DereferenceTspiProvider(g_pAdapter);
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -