📄 misc.c
字号:
/*++
Copyright (c) 1990-1998 Microsoft Corporation, All Rights Reserved.
Module Name:
misc.c
Abstract:
This module contains several miscellaneous routines like, ReferenceVC
dereferenceVC etc.
Author:
Anil Francis Thomas (10/98)
Environment:
Kernel
Revision History:
DChen 092499 Remove try/except block in VerifyRecvOpenContext
--*/
#include "precomp.h"
#pragma hdrstop
#define MODULE_ID MODULE_MISC
NDIS_STATUS AtmSmAllocVc(
IN PATMSM_ADAPTER pAdapt,
OUT PATMSM_VC *ppVc,
IN ULONG VcType,
IN NDIS_HANDLE NdisVcHandle
)
/*++
Routine Description:
This routine is used to create a VC structure and link to an adapter
Arguments:
pAdapt - Adapter structure
ppVc - pointer to a pointer of Vc
VcType - Type of VC to allocate (incoming, pmp outgoing etc)
Return Value:
NDIS_STATUS_SUCCESS if we could create a VC
NDIS_STATUS_RESOURCES no resources
NDIS_STATUS_CLOSING if we couldn't reference the adapter
--*/
{
PATMSM_VC pVc;
NDIS_STATUS Status;
*ppVc = NULL;
//
// Add a reference to the adapter for the VC (see if the adapter
// is closing)
//
if(!AtmSmReferenceAdapter(pAdapt))
return NDIS_STATUS_CLOSING;
//
// Allocate a Vc, initialize it and link it into the Adapter
//
AtmSmAllocMem(&pVc, PATMSM_VC, sizeof(ATMSM_VC));
if(NULL != pVc)
{
NdisZeroMemory(pVc, sizeof(ATMSM_VC));
pVc->ulSignature = atmsm_vc_signature;
pVc->NdisVcHandle = NdisVcHandle;
pVc->pAdapt = pAdapt;
pVc->ulRefCount = 1; // Dereferenced when DeleteVc is called.
pVc->VcType = VcType;
pVc->MaxSendSize = pAdapt->MaxPacketSize; // default
ATMSM_SET_VC_STATE(pVc, ATMSM_VC_IDLE);
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
InsertHeadList(&pAdapt->InactiveVcHead, &pVc->List);
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
Status = NDIS_STATUS_SUCCESS;
DbgInfo(("CreateVc: Created Vc %x\n", pVc));
}
else
{
// Not enough resources, hence remove the reference we added above
AtmSmDereferenceAdapter(pAdapt);
Status = NDIS_STATUS_RESOURCES;
DbgErr(("CreateVc: Failed - No resources\n"));
}
*ppVc = pVc;
return Status;
}
BOOLEAN AtmSmReferenceVc(
IN PATMSM_VC pVc
)
/*++
Routine Description:
Reference the VC.
Arguments:
pVc Pointer to the VC.
Return Value:
TRUE Referenced
FALSE Interface is closing, cannot reference.
--*/
{
PATMSM_ADAPTER pAdapt = pVc->pAdapt;
BOOLEAN rc = FALSE;
DbgInfo(("AtmSmReferenceVc - VC - 0x%X\n", pVc));
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
if(ATMSM_GET_VC_STATE(pVc) != ATMSM_VC_CLOSING)
{
pVc->ulRefCount ++;
rc = TRUE;
}
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
return rc;
}
ULONG AtmSmDereferenceVc(
IN PATMSM_VC pVc
)
/*++
Routine Description:
Dereference the VC. This could result in the VC to be deallocated.
Arguments:
pVc Pointer to the VC.
Return Value:
Reference count
--*/
{
PATMSM_ADAPTER pAdapt = pVc->pAdapt;
ULONG ulRet;
TraceIn(AtmSmDereferenceVc);
DbgInfo(("AtmSmDereferenceVc - VC - 0x%X\n", pVc));
ASSERT(pVc->ulRefCount > 0);
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
ulRet = --pVc->ulRefCount;
if(0 == pVc->ulRefCount)
{
PIRP pIrp;
ULONG VcType = pVc->VcType;
NDIS_HANDLE NdisVcHandle = pVc->NdisVcHandle;
ASSERT (ATMSM_GET_VC_STATE(pVc) != ATMSM_VC_ACTIVE);
ASSERT (0 == pVc->ulNumTotalMembers);
// cleanup a connectIrp if it exists
pIrp = pVc->pConnectIrp;
pVc->pConnectIrp = NULL;
if(pIrp)
{
pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NETWORK_INCREMENT);
}
// Remove any send packets pending on the Vc
while(pVc->pSendPktNext)
{
PPROTO_RSVD pPRsvd;
PNDIS_PACKET pPacket;
pPacket = pVc->pSendPktNext;
pPRsvd = GET_PROTO_RSVD(pPacket);
pVc->pSendPktNext = pPRsvd->pPktNext;
// this is the last packet
if(pVc->pSendLastPkt == pPacket)
pVc->pSendLastPkt = NULL;
pVc->ulSendPktsCount--;
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
AtmSmCoSendComplete(NDIS_STATUS_CLOSING, (NDIS_HANDLE)pVc, pPacket);
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
}
RemoveEntryList(&pVc->List);
// this is important - since memory is not cleared
pVc->ulSignature = atmsm_dead_vc_signature;
pVc->pAdapt = NULL;
AtmSmFreeMem(pVc);
// Release the lock on the adapter
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
if(((VC_TYPE_PP_OUTGOING == VcType) ||
(VC_TYPE_PMP_OUTGOING == VcType)) &&
NdisVcHandle != NULL)
{
(VOID)NdisCoDeleteVc(NdisVcHandle);
}
// dereference the adapter (to remove the VC reference)
// should be done after releasing the lock
AtmSmDereferenceAdapter(pAdapt);
}
else
{
// Release the lock on the adapter
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
}
TraceOut(AtmSmDereferenceVc);
return ulRet;
}
BOOLEAN DeleteMemberInfoFromVc(
IN PATMSM_VC pVc,
IN PATMSM_PMP_MEMBER pMemberToRemove
)
/*++
Routine Description:
The specified member structure is removed from the VC and the
structure is freed.
Arguments:
pVc Pointer to the VC.
Return Value:
TRUE - if removed
FALSE - otherwise
--*/
{
PATMSM_ADAPTER pAdapt = pVc->pAdapt;
PATMSM_PMP_MEMBER pMember;
PATMSM_PMP_MEMBER pPrevMember = NULL;
TraceIn(DeleteMemberInfoFromVc);
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
for(pMember = pVc->pPMPMembers; pMember;
pPrevMember = pMember, pMember = pMember->pNext)
if(pMember == pMemberToRemove)
break;
ASSERT(pMember);
if(!pMember)
{
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
return FALSE;
}
if(!pPrevMember)
{
pVc->pPMPMembers = pMember->pNext;
}
else
{
pPrevMember->pNext = pMember->pNext;
}
AtmSmFreeMem(pMember);
pVc->ulNumTotalMembers--;
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
// Now dereference the VC
AtmSmDereferenceVc(pVc);
TraceOut(DeleteMemberInfoFromVc);
return TRUE;
}
VOID AtmSmDisconnectVc(
IN PATMSM_VC pVc
)
/*++
Routine Description:
This routine can be used to disconnect a P-P VC or disconnect
all members of a PMP Vc
Arguments:
pVc - Pointer to the VC.
Return Value:
NONE
--*/
{
NDIS_STATUS Status;
PATMSM_ADAPTER pAdapt = pVc->pAdapt;
TraceIn(AtmSmDisconnectVc);
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
if(VC_TYPE_PMP_OUTGOING != pVc->VcType)
{
//
// This is a PP VC
//
if((ATMSM_GET_VC_STATE(pVc) == ATMSM_VC_SETUP_IN_PROGRESS) ||
(ATMSM_GET_VC_STATE(pVc) == ATMSM_VC_ACTIVE))
{
ATMSM_SET_VC_STATE(pVc, ATMSM_VC_CLOSING);
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
Status = NdisClCloseCall(
pVc->NdisVcHandle,
NULL, // No party Handle
NULL, // No Buffer
0 // Size of above
);
if(NDIS_STATUS_PENDING != Status)
{
AtmSmCloseCallComplete(
Status,
(NDIS_HANDLE)pVc,
(NDIS_HANDLE)NULL
);
}
}
else
{
if(ATMSM_GET_VC_STATE(pVc) == ATMSM_VC_IDLE)
{
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
// remove the reference added to the VC while creating
AtmSmDereferenceVc(pVc);
}
else
{
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
}
}
}
else
{
PATMSM_PMP_MEMBER pMember;
// this is a PMP VC
//
// Find a member that we haven't tried drop on.
//
while(TRUE)
{
for(pMember = pVc->pPMPMembers; pMember != NULL;
pMember = pMember->pNext)
{
if(0 == (pMember->ulFlags & ATMSM_MEMBER_DROP_TRIED))
{
break;
}
}
if(!pMember) // we are done with all members
break;
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
AtmSmDropMemberFromVc(pVc, pMember);
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
}
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
// remove the reference added to the VC while creating
AtmSmDereferenceVc(pVc);
}
TraceOut(AtmSmDisconnectVc);
}
VOID AtmSmDropMemberFromVc(
IN PATMSM_VC pVc,
IN PATMSM_PMP_MEMBER pMemberToDrop
)
/*++
Routine Description:
This is used to drop a member from a PMP VC. This could be
called as a result of incoming Drop request, or we are
initiating a drop request.
Handle all cases
(a) Not connected to PMP Vc
(b) Connection being setup (MakeCall or AddParty in progress)
(c) Connected to PMP Vc
Arguments:
pVc - Pointer to the VC.
pMemberToDrop - pointer to a member that is being dropped
Return Value:
NONE
--*/
{
PATMSM_ADAPTER pAdapt = (PATMSM_ADAPTER)pVc->pAdapt;
BOOLEAN bLockReleased = FALSE;
NDIS_STATUS Status;
NDIS_HANDLE NdisVcHandle;
NDIS_HANDLE NdisPartyHandle;
TraceIn(AtmSmDropMemberFromVc);
DbgInfo(("pAdapt %x, pVc %x pMember %x, ConnSt %x, PartyHandle %x\n",
pAdapt, pVc, pMemberToDrop, ATMSM_GET_MEMBER_STATE(pMemberToDrop),
pMemberToDrop->NdisPartyHandle));
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
pMemberToDrop->ulFlags |= ATMSM_MEMBER_DROP_TRIED;
switch(ATMSM_GET_MEMBER_STATE(pMemberToDrop))
{
case ATMSM_MEMBER_CONNECTED:
NdisPartyHandle = pMemberToDrop->NdisPartyHandle;
ASSERT(NdisPartyHandle != NULL);
if((pVc->ulNumActiveMembers + pVc->ulNumConnectingMembers)
> 1)
{
//
// This is not the last member in connected or connecting
// state. Hence use DropParty.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -