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

📄 protocol.cpp

📁 pppoe client
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			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;
}

// unbind
VOID protocolUnbindAdapter(OUT PNDIS_STATUS pStatus,PBIND_CONTEXT pBindContext,NDIS_HANDLE hUnbindContext)
{
	NdisAcquireSpinLock(&pBindContext->m_lockSelf);

	if(pBindContext->m_ulBindState == BIND_LOWER_MINIPORT_CLOSING)
	{
		NdisReleaseSpinLock(&pBindContext->m_lockSelf);

		DebugInfo(("waiting for close adapter complete.\n"));
		NdisMSleep(10000);

		NdisAcquireSpinLock(&pBindContext->m_lockSelf);
	}

	pBindContext->m_ulBindState = BIND_ROMOVING;

	NdisReleaseSpinLock(&pBindContext->m_lockSelf);

	NotifyBindingRemoval(pBindContext);

	NdisAcquireSpinLock(&g_lockBind);

	RemoveEntryList(&pBindContext->m_ltBindAnchor);

	NdisReleaseSpinLock(&g_lockBind);

	DereferenceBind(pBindContext);

	DebugInfo(("waiting for bind remove event,ref = %d\n",pBindContext->m_lRefCount));
	NdisWaitEvent(&pBindContext->m_evRemove,0);

	DebugInfo(("waiting for return lower packets,count = %d\n",pBindContext->m_lPacketNeedReturn));
	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;
}

// 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;
}

// init bind system
VOID InitializeBindSystem()
{
	NdisInitializeListHead(&g_ltBindsHead);

	NdisAllocateSpinLock(&g_lockBind);
}

// shut down bind system
VOID ShutdownBindSystem()
{
	NdisFreeSpinLock(&g_lockBind);
}

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

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

	pRet->m_ulSig = BIND_CONTEXT_SIG;
	pRet->m_lRefCount = 1;
	pRet->m_ulBindState = BIND_ALLOCATED;
	NdisInitializeEvent(&pRet->m_evRemove);
	NdisInitializeEvent(&pRet->m_evCallback);
	NdisAllocateSpinLock(&pRet->m_lockSelf);
	NdisInitializeListHead(&pRet->m_ltRecvPacketHead);

	return pRet;
}

// free bind
VOID FreeBind(PBIND_CONTEXT pBind)
{
	ASSERT(pBind && pBind->m_ulSig == BIND_CONTEXT_SIG && pBind->m_lRefCount == 0);

	FreeMemory(pBind,sizeof(BIND_CONTEXT));
}

// reference bind
VOID ReferenceBind(PBIND_CONTEXT pBind,BOOLEAN bAcquireSpinLock)
{
	ASSERT(pBind && pBind->m_ulSig == BIND_CONTEXT_SIG && pBind->m_lRefCount > 0);

	if(bAcquireSpinLock)
		NdisAcquireSpinLock(&pBind->m_lockSelf);

	pBind->m_lRefCount ++;

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

// dereference bind
VOID DereferenceBind(PBIND_CONTEXT pBind)
{
	ASSERT(pBind && pBind->m_ulSig == BIND_CONTEXT_SIG && pBind->m_lRefCount > 0);

	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)
{
	ASSERT(pBind && pBind->m_ulSig == BIND_CONTEXT_SIG && pBind->m_lRefCount > 0);

	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 link speed
VOID QueryLowerMiniportForLinkSpeed(PBIND_CONTEXT pBind)
{
	ASSERT(pBind && pBind->m_ulSig == BIND_CONTEXT_SIG && pBind->m_lRefCount > 0);

	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 max frame size
VOID QueryLowerMiniportForMaxFrameSize(PBIND_CONTEXT pBind)
{
	ASSERT(pBind && pBind->m_ulSig == BIND_CONTEXT_SIG && pBind->m_lRefCount > 0);

	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_ltBindsHead.Flink;
	for(;pEntry != &g_ltBindsHead;pEntry = pEntry->Flink)
	{
		PBIND_CONTEXT pBind = CONTAINING_RECORD(pEntry,BIND_CONTEXT,m_ltBindAnchor);

		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_ltBindsHead.Flink;

	for(;pEntry != &g_ltBindsHead;pEntry = pEntry->Flink)
	{
		PBIND_CONTEXT pBind = CONTAINING_RECORD(pEntry,BIND_CONTEXT,m_ltBindAnchor);
		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)
{
	ASSERT(pBind && pBind->m_ulSig == BIND_CONTEXT_SIG && pBind->m_lRefCount > 0);

	// 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);
	}
}

// notify bind remove DISPATCH_LEVEL
VOID NotifyBindingRemoval(PBIND_CONTEXT pBind)
{

}

⌨️ 快捷键说明

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