www.pudn.com > PPPOE.rar > 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(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(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(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) 
		{ 
			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(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(&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(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(&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(&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(&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) 
{ 
 
}