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

📄 misc.c

📁 驱动开发,经过测试可以直接编译后使用,编译使用DDK中的build工具
💻 C
📖 第 1 页 / 共 3 页
字号:
/*++

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 + -