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)
{
}