Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

866 lines
23 KiB

/*++
Copyright (c) 1990-1997 Microsoft Corporation
Module Name:
cl.c
Abstract:
This file contains the functions that implement the ndiswan
NDIS 5.0 client interface. These functions are used to interface
with NDIS 5.0 miniports/call managers.
Author:
Tony Bell (TonyBe) January 9, 1997
Environment:
Kernel Mode
Revision History:
TonyBe 01/09/97 Created
--*/
//
// We want to initialize all of the global variables now!
//
#include "wan.h"
#include "atm.h"
#define __FILE_SIG__ CL_FILESIG
NDIS_STATUS
ClCreateVc(
IN NDIS_HANDLE ProtocolAfContext,
IN NDIS_HANDLE NdisVcHandle,
OUT PNDIS_HANDLE ProtocolVcContext
)
{
PCL_AFSAPCB AfSapCB = (PCL_AFSAPCB)ProtocolAfContext;
POPENCB OpenCB = AfSapCB->OpenCB;
PLINKCB LinkCB;
PBUNDLECB BundleCB;
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClCreateVc: Enter"));
//
// Get a linkcb
//
LinkCB = NdisWanAllocateLinkCB(OpenCB, 0);
if (LinkCB == NULL) {
//
// Error getting LinkCB!
//
return (NDIS_STATUS_RESOURCES);
}
LinkCB->NdisLinkHandle = NdisVcHandle;
LinkCB->ConnectionWrapperID = NdisVcHandle;
LinkCB->AfSapCB = AfSapCB;
//
// Set some default values
//
LinkCB->RFlowSpec.PeakBandwidth =
LinkCB->SFlowSpec.PeakBandwidth = 28800 / 8;
LinkCB->SendWindow = OpenCB->WanInfo.MaxTransmit;
//
// Get a bundlecb
//
BundleCB = NdisWanAllocateBundleCB();
if (BundleCB == NULL) {
NdisWanFreeLinkCB(LinkCB);
//
// Error getting BundleCB!
//
return (NDIS_STATUS_RESOURCES);
}
//
// Add LinkCB to BundleCB
//
AcquireBundleLock(BundleCB);
AddLinkToBundle(BundleCB, LinkCB);
ReleaseBundleLock(BundleCB);
//
// Place BundleCB in active connection table
//
if (NULL == InsertBundleInConnectionTable(BundleCB)) {
//
// Error inserting link in ConnectionTable
//
RemoveLinkFromBundle(BundleCB, LinkCB, FALSE);
NdisWanFreeLinkCB(LinkCB);
return (NDIS_STATUS_RESOURCES);
}
//
// Place LinkCB in active connection table
//
if (NULL == InsertLinkInConnectionTable(LinkCB)) {
//
// Error inserting bundle in connectiontable
//
RemoveLinkFromBundle(BundleCB, LinkCB, FALSE);
NdisWanFreeLinkCB(LinkCB);
return (NDIS_STATUS_RESOURCES);
}
*ProtocolVcContext = LinkCB->hLinkHandle;
NdisAcquireSpinLock(&AfSapCB->Lock);
REF_CLAFSAPCB(AfSapCB);
NdisReleaseSpinLock(&AfSapCB->Lock);
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClCreateVc: Exit"));
return (NDIS_STATUS_SUCCESS);
}
NDIS_STATUS
ClDeleteVc(
IN NDIS_HANDLE ProtocolVcContext
)
{
PLINKCB LinkCB;
PBUNDLECB BundleCB;
PCL_AFSAPCB AfSapCB;
if (!IsLinkValid(ProtocolVcContext, FALSE, &LinkCB)) {
NdisWanDbgOut(DBG_FAILURE, DBG_CL,
("NDISWAN: Possible double delete of VcContext %x\n",
ProtocolVcContext));
return (NDIS_STATUS_FAILURE);
}
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClDeleteVc: Enter %p", LinkCB));
NdisAcquireSpinLock(&LinkCB->Lock);
AfSapCB = LinkCB->AfSapCB;
//
// For the ref applied in IsLinkValid. We
// don't have to use the full deref code here as we know the ref
// applied at CreateVc will keep the link around.
//
LinkCB->RefCount--;
//
// For the createvc reference
//
DEREF_LINKCB_LOCKED(LinkCB);
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClDeleteVc: Exit"));
DEREF_CLAFSAPCB(AfSapCB);
return(NDIS_STATUS_SUCCESS);
}
VOID
ClOpenAfComplete(
IN NDIS_STATUS Status,
IN NDIS_HANDLE ProtocolAfContext,
IN NDIS_HANDLE NdisAfHandle
)
{
PCL_AFSAPCB AfSapCB = (PCL_AFSAPCB)ProtocolAfContext;
POPENCB OpenCB = AfSapCB->OpenCB;
PCO_SAP Sap;
NDIS_HANDLE SapHandle;
UCHAR SapBuffer[CLSAP_BUFFERSIZE];
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClOpenAfComplete: Enter %p %x", AfSapCB, Status));
NdisAcquireSpinLock(&AfSapCB->Lock);
AfSapCB->Flags &= ~(AF_OPENING);
if (Status == NDIS_STATUS_SUCCESS) {
AfSapCB->Flags |=
(AF_OPENED | SAP_REGISTERING);
AfSapCB->AfHandle = NdisAfHandle;
NdisReleaseSpinLock(&AfSapCB->Lock);
//
// If we successfully opened the AddressFamily we
// need to register our SAP.
//
NdisAcquireSpinLock(&OpenCB->Lock);
InsertHeadList(&OpenCB->AfSapCBList,
&AfSapCB->Linkage);
NdisReleaseSpinLock(&OpenCB->Lock);
Sap = (PCO_SAP)SapBuffer;
//
// Register our SAP
//
Sap->SapType = SAP_TYPE_NDISWAN_PPP;
Sap->SapLength = sizeof(DEVICECLASS_NDISWAN_SAP);
NdisMoveMemory(Sap->Sap,
DEVICECLASS_NDISWAN_SAP,
sizeof(DEVICECLASS_NDISWAN_SAP));
Status =
NdisClRegisterSap(AfSapCB->AfHandle,
AfSapCB,
Sap,
&SapHandle);
if (Status != NDIS_STATUS_PENDING) {
ClRegisterSapComplete(Status, AfSapCB, Sap, SapHandle);
}
NdisWanDbgOut(DBG_TRACE, DBG_PROTOCOL,
("ClRegisterSap SapHandle 0x%x status: 0x%x", SapHandle, Status));
} else {
AfSapCB->Flags |= AF_OPEN_FAILED;
NdisReleaseSpinLock(&AfSapCB->Lock);
//
// We failed to register the address family so free
// associated memory.
//
NdisWanFreeClAfSapCB(AfSapCB);
//
// Since the open af was initiated from the notification
// of a new af from ndis we have to decrement the af
// registering count.
//
NdisAcquireSpinLock(&OpenCB->Lock);
if (--OpenCB->AfRegisteringCount == 0) {
NdisWanSetNotificationEvent(&OpenCB->AfRegisteringEvent);
}
NdisReleaseSpinLock(&OpenCB->Lock);
}
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClOpenAfComplete: Exit"));
}
VOID
ClCloseAfComplete(
IN NDIS_STATUS Status,
IN NDIS_HANDLE ProtocolAfContext
)
{
PCL_AFSAPCB AfSapCB = (PCL_AFSAPCB)ProtocolAfContext;
POPENCB OpenCB = AfSapCB->OpenCB;
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClCloseAfComplete: Enter %p %x", AfSapCB, Status));
//
// BUG 494260
// NDIS should not be invoking this deregister handler at a raised
// IRQL (i.e while holding a spinlock). Bug 494260 documents this
// this issue.
//
// This assert has been commented out to prevent breaks on checked build.
// When 494260 is fixed, this ASSERT should be uncommented.
//
// ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
do {
//
// If the close attempt failed there must be another
// thread that is already doing the close. Let the
// other thread cleanup the afsapcb.
//
if (Status != NDIS_STATUS_SUCCESS) {
break;
}
NdisAcquireSpinLock(&AfSapCB->Lock);
AfSapCB->Flags &= ~(AF_CLOSING);
AfSapCB->Flags |= (AF_CLOSED);
NdisReleaseSpinLock(&AfSapCB->Lock);
NdisAcquireSpinLock(&OpenCB->Lock);
RemoveEntryList(&AfSapCB->Linkage);
NdisReleaseSpinLock(&OpenCB->Lock);
NdisWanFreeClAfSapCB(AfSapCB);
} while (FALSE);
//
// Refer comment above
//
// ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClCloseAfComplete: Exit"));
}
VOID
ClRegisterSapComplete(
IN NDIS_STATUS Status,
IN NDIS_HANDLE ProtocolSapContext,
IN PCO_SAP Sap,
IN NDIS_HANDLE NdisSapHandle
)
{
PCL_AFSAPCB AfSapCB = (PCL_AFSAPCB)ProtocolSapContext;
POPENCB OpenCB = AfSapCB->OpenCB;
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClRegisterSapComplete: Enter %p %x", AfSapCB, Status));
NdisAcquireSpinLock(&AfSapCB->Lock);
AfSapCB->Flags &= ~(SAP_REGISTERING);
if (Status == NDIS_STATUS_SUCCESS) {
AfSapCB->Flags |= SAP_REGISTERED;
AfSapCB->SapHandle = NdisSapHandle;
NdisReleaseSpinLock(&AfSapCB->Lock);
} else {
//
// We failed to register our sap so close the address family
//
AfSapCB->Flags &= ~(AF_OPENED);
AfSapCB->Flags |=
(SAP_REGISTER_FAILED | AF_CLOSING);
NdisReleaseSpinLock(&AfSapCB->Lock);
NdisAcquireSpinLock(&OpenCB->Lock);
RemoveEntryList(&AfSapCB->Linkage);
InsertTailList(&OpenCB->AfSapCBClosing, &AfSapCB->Linkage);
NdisReleaseSpinLock(&OpenCB->Lock);
NdisClCloseAddressFamily(AfSapCB->AfHandle);
if (Status != NDIS_STATUS_PENDING) {
ClCloseAfComplete(Status, AfSapCB);
}
}
//
// Since the open af was initiated from the notification
// of a new af from ndis we have to decrement the af
// registering count.
//
NdisAcquireSpinLock(&OpenCB->Lock);
if (--OpenCB->AfRegisteringCount == 0) {
NdisWanSetNotificationEvent(&OpenCB->AfRegisteringEvent);
}
NdisReleaseSpinLock(&OpenCB->Lock);
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClRegisterSapComplete: Exit"));
}
VOID
ClDeregisterSapComplete(
IN NDIS_STATUS Status,
IN NDIS_HANDLE ProtocolSapContext
)
{
PCL_AFSAPCB AfSapCB = (PCL_AFSAPCB)ProtocolSapContext;
POPENCB OpenCB = AfSapCB->OpenCB;
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClDeregisterSapComplete: Enter %p %x", AfSapCB, Status));
//
// BUG 494260
// NDIS should not be invoking this deregister handler at a raised
// IRQL (i.e while holding a spinlock). Bug 494260 documents this
// this issue.
//
// This assert has been commented out to prevent breaks on checked build.
// When 494260 is fixed, this ASSERT should be uncommented.
//
// ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
NdisAcquireSpinLock(&AfSapCB->Lock);
ASSERT(AfSapCB->Flags & AF_OPENED);
AfSapCB->Flags &= ~(AF_OPENED | SAP_DEREGISTERING);
AfSapCB->Flags |= (AF_CLOSING);
NdisReleaseSpinLock(&AfSapCB->Lock);
Status =
NdisClCloseAddressFamily(AfSapCB->AfHandle);
if (Status != NDIS_STATUS_PENDING) {
ClCloseAfComplete(Status, AfSapCB);
}
//
// Refer comment above
//
// ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClDeregisterSapComplete: Exit"));
}
VOID
ClMakeCallComplete(
IN NDIS_STATUS Status,
IN NDIS_HANDLE ProtocolVcContext,
IN NDIS_HANDLE NdisPartyHandle OPTIONAL,
IN PCO_CALL_PARAMETERS CallParameters
)
{
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClMakeCallComplete: Enter %p %x", ProtocolVcContext, Status));
DbgBreakPoint();
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClMakeCallComplete: Exit"));
}
VOID
ClModifyQoSComplete(
IN NDIS_STATUS Status,
IN NDIS_HANDLE ProtocolVcContext,
IN PCO_CALL_PARAMETERS CallParameters
)
{
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClModifyQoSComplete: Enter %p %x", ProtocolVcContext, Status));
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClModifyQoSComplete: Exit"));
}
VOID
ClCloseCallComplete(
IN NDIS_STATUS Status,
IN NDIS_HANDLE ProtocolVcContext,
IN NDIS_HANDLE ProtocolPartyContext OPTIONAL
)
{
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClCloseCallComplete: Enter %p %x", ProtocolVcContext, Status));
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClCloseCallComplete: Exit"));
}
NDIS_STATUS
ClIncomingCall(
IN NDIS_HANDLE ProtocolSapContext,
IN NDIS_HANDLE ProtocolVcContext,
IN OUT PCO_CALL_PARAMETERS CallParameters
)
{
PCL_AFSAPCB AfSapCB = (PCL_AFSAPCB)ProtocolSapContext;
PLINKCB LinkCB;
POPENCB OpenCB = AfSapCB->OpenCB;
PBUNDLECB BundleCB;
BOOLEAN AtmUseLLC = FALSE;
BOOLEAN MediaBroadband = FALSE;
PWAN_LINK_INFO LinkInfo;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClIncomingCall: Enter %p %p", AfSapCB, ProtocolVcContext));
do {
if (!AreLinkAndBundleValid(ProtocolVcContext,
TRUE,
&LinkCB,
&BundleCB)) {
Status = NDIS_STATUS_FAILURE;
break;
}
NdisAcquireSpinLock(&LinkCB->Lock);
LinkCB->ClCallState = CL_CALL_CONNECTED;
NdisReleaseSpinLock(&LinkCB->Lock);
AcquireBundleLock(BundleCB);
NdisMoveMemory(&LinkCB->SFlowSpec,
&CallParameters->CallMgrParameters->Transmit,
sizeof(FLOWSPEC));
NdisMoveMemory(&LinkCB->RFlowSpec,
&CallParameters->CallMgrParameters->Receive,
sizeof(FLOWSPEC));
if (LinkCB->SFlowSpec.PeakBandwidth == 0) {
LinkCB->SFlowSpec.PeakBandwidth = 28800 / 8;
}
if (LinkCB->RFlowSpec.PeakBandwidth == 0) {
LinkCB->RFlowSpec.PeakBandwidth = LinkCB->SFlowSpec.PeakBandwidth;
}
LinkInfo = &LinkCB->LinkInfo;
//
// Assume all CoNDIS miniports support PPP framing
//
LinkInfo->SendFramingBits =
LinkInfo->RecvFramingBits = PPP_FRAMING;
LinkCB->RecvHandler = ReceivePPP;
if (OpenCB->MediumType == NdisMediumAtm ||
(OpenCB->MediumType == NdisMediumWan &&
(OpenCB->MediumSubType == NdisWanMediumAtm ||
OpenCB->MediumSubType == NdisWanMediumPppoe)) ||
(OpenCB->MediumType == NdisMediumCoWan &&
(OpenCB->MediumSubType == NdisWanMediumAtm ||
OpenCB->MediumSubType == NdisWanMediumPppoe))) {
MediaBroadband = TRUE;
LinkCB->RecvHandler = DetectBroadbandFraming;
}
if (MediaBroadband) {
if (CallParameters->Flags & PERMANENT_VC) {
//
// Per TomF we are going to use NULL encap as
// our default PVC encapsulation
//
if (gbAtmUseLLCOnPVC) {
AtmUseLLC = TRUE;
}
} else {
//
// If this is an ATM SVC we need to see
// if the SVC needs LLC framing or not
//
if (gbAtmUseLLCOnSVC) {
AtmUseLLC = TRUE;
} else {
ULONG IeCount;
Q2931_IE UNALIGNED *Ie;
ATM_BLLI_IE UNALIGNED *Bli;
Q2931_CALLMGR_PARAMETERS *cmparams;
cmparams = (Q2931_CALLMGR_PARAMETERS*)
&(CallParameters->CallMgrParameters->CallMgrSpecific.Parameters[0]);
Bli = NULL;
Ie = (Q2931_IE UNALIGNED *)&cmparams->InfoElements[0];
for (IeCount = 0;
IeCount < cmparams->InfoElementCount;
IeCount++) {
if (Ie->IEType == IE_BLLI) {
Bli = (ATM_BLLI_IE UNALIGNED*)&Ie->IE[0];
break;
}
Ie = (Q2931_IE UNALIGNED *)((ULONG_PTR)Ie + Ie->IELength);
}
if (Bli != NULL) {
AtmUseLLC = (Bli->Layer2Protocol == BLLI_L2_LLC);
}
}
}
if (AtmUseLLC) {
LinkInfo->SendFramingBits |= LLC_ENCAPSULATION;
LinkInfo->RecvFramingBits |= LLC_ENCAPSULATION;
LinkCB->RecvHandler = ReceiveLLC;
}
if (!(LinkInfo->SendFramingBits & LLC_ENCAPSULATION)) {
LinkInfo->SendFramingBits |= PPP_COMPRESS_ADDRESS_CONTROL;
LinkInfo->RecvFramingBits |= PPP_COMPRESS_ADDRESS_CONTROL;
}
}
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("SPeakBandwidth %d SendWindow %d",
LinkCB->SFlowSpec.PeakBandwidth,
LinkCB->SendWindow));
if (CallParameters->Flags & PERMANENT_VC) {
//
// This is a PVC so we will disable idle data detection
// thus allowing the connection to remain active
//
BundleCB->Flags |= DISABLE_IDLE_DETECT;
}
BundleCB->FramingInfo.RecvFramingBits =
BundleCB->FramingInfo.SendFramingBits = PPP_FRAMING;
UpdateBundleInfo(BundleCB);
//
// Deref for the ref applied by AreLinkAndBundleValid. This
// will release the BundleCB->Lock!
//
DEREF_BUNDLECB_LOCKED(BundleCB);
//
// Deref for the ref applied by AreLinkAndBundleValid.
//
DEREF_LINKCB(LinkCB);
} while (0);
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClIncomingCall: Exit"));
return (Status);
}
VOID
ClIncomingCallQoSChange(
IN NDIS_HANDLE ProtocolVcContext,
IN PCO_CALL_PARAMETERS CallParameters
)
{
PLINKCB LinkCB;
PBUNDLECB BundleCB;
POPENCB OpenCB;
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClIncomingCallQoSChange: Enter %p", ProtocolVcContext));
do {
if (!AreLinkAndBundleValid(ProtocolVcContext,
TRUE,
&LinkCB,
&BundleCB)) {
break;
}
AcquireBundleLock(BundleCB);
OpenCB = LinkCB->OpenCB;
//
// Do I need to pass this info to 5.0 Clients?????
//
NdisMoveMemory(&LinkCB->SFlowSpec,
&CallParameters->CallMgrParameters->Transmit,
sizeof(FLOWSPEC));
NdisMoveMemory(&LinkCB->RFlowSpec,
&CallParameters->CallMgrParameters->Receive,
sizeof(FLOWSPEC));
if (LinkCB->SFlowSpec.PeakBandwidth == 0) {
LinkCB->SFlowSpec.PeakBandwidth = 28800 / 8;
}
if (LinkCB->RFlowSpec.PeakBandwidth == 0) {
LinkCB->RFlowSpec.PeakBandwidth = LinkCB->SFlowSpec.PeakBandwidth;
}
UpdateBundleInfo(BundleCB);
//
// Deref for the ref applied by AreLinkAndBundleValid. This will
// release the BundleCB->Lock.
//
DEREF_BUNDLECB_LOCKED(BundleCB);
//
// Deref for the ref applied by AreLinkAndBundleValid.
//
DEREF_LINKCB(LinkCB);
} while (0);
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClIncomingCallQoSChange: Exit"));
}
VOID
ClIncomingCloseCall(
IN NDIS_STATUS CloseStatus,
IN NDIS_HANDLE ProtocolVcContext,
IN PVOID CloseData OPTIONAL,
IN UINT Size OPTIONAL
)
{
PLINKCB LinkCB;
PBUNDLECB BundleCB;
PRECV_DESC RecvDesc;
NDIS_STATUS Status;
ULONG i;
BOOLEAN FreeBundle = FALSE;
BOOLEAN FreeLink = FALSE;
NdisWanDbgOut(DBG_TRACE, DBG_CL,
("ClIncomingCloseCall: Enter %p %x", ProtocolVcContext, CloseStatus));
do {
if (!AreLinkAndBundleValid(ProtocolVcContext,
TRUE,
&LinkCB,
&BundleCB)) {
#if DBG
DbgPrint("NDISWAN: CloseCall after link has gone down VcContext %x\n",
ProtocolVcContext);
DbgBreakPoint();
#endif
break;
}
NdisAcquireSpinLock(&LinkCB->Lock);
//
// Link is now going down
//
LinkCB->State = LINK_GOING_DOWN;
if (LinkCB->VcRefCount == 0) {
LinkCB->ClCallState = CL_CALL_CLOSED;
NdisReleaseSpinLock(&LinkCB->Lock);
Status =
NdisClCloseCall(LinkCB->NdisLinkHandle,
NULL,
NULL,
0);
if (Status != NDIS_STATUS_PENDING) {
ClCloseCallComplete(Status,
LinkCB,
NULL);
}
} else {
LinkCB->ClCallState = CL_CALL_CLOSE_PENDING;
NdisReleaseSpinLock(&LinkCB->Lock);
}
NdisAcquireSpinLock(&IoRecvList.Lock);
RecvDesc = (PRECV_DESC)IoRecvList.DescList.Flink;
while ((PVOID)RecvDesc != (PVOID)&IoRecvList.DescList) {
PRECV_DESC Next;
Next = (PRECV_DESC)RecvDesc->Linkage.Flink;
if (RecvDesc->LinkCB == LinkCB) {
RemoveEntryList(&RecvDesc->Linkage);
LinkCB->RecvDescCount--;
IoRecvList.ulDescCount--;
NdisWanFreeRecvDesc(RecvDesc);
}
RecvDesc = Next;
}
NdisReleaseSpinLock(&IoRecvList.Lock);
//
// Flush the Bundle's fragment send queues that
// have sends pending on this link
//
AcquireBundleLock(BundleCB);
for (i = 0; i < MAX_MCML; i++) {
PSEND_DESC SendDesc;
PSEND_FRAG_INFO FragInfo;
FragInfo = &BundleCB->SendFragInfo[i];
SendDesc = (PSEND_DESC)FragInfo->FragQueue.Flink;
while ((PVOID)SendDesc != (PVOID)&FragInfo->FragQueue) {
if (SendDesc->LinkCB == LinkCB) {
PSEND_DESC NextSendDesc;
NextSendDesc = (PSEND_DESC)SendDesc->Linkage.Flink;
RemoveEntryList(&SendDesc->Linkage);
FragInfo->FragQueueDepth--;
(*LinkCB->SendHandler)(SendDesc);
SendDesc = NextSendDesc;
} else {
SendDesc = (PSEND_DESC)SendDesc->Linkage.Flink;
}
}
}
UpdateBundleInfo(BundleCB);
ReleaseBundleLock(BundleCB);
//
// Deref's for the refs applied by AreLinkAndBundleValid.
//
DEREF_LINKCB(LinkCB);
DEREF_BUNDLECB(BundleCB);
} while (0);
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClIncomingCloseCall: Exit"));
}
VOID
ClCallConnected(
IN NDIS_HANDLE ProtocolVcContext
)
{
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClCallConnected: Enter %p", ProtocolVcContext));
NdisWanDbgOut(DBG_TRACE, DBG_CL, ("ClCallConnected: Exit"));
}