DeleteInterface Sample

[This is preliminary documentation and subject to change.]

DWORD
APIENTRY
DeleteInterface(
    IN DWORD dwIndex
    )
/*++
  Routine Description
      Called by the IP Router Manager to delete an interface. 
      If the interface is running we shut it down and free all the
      resources used by it.

  Arguments
      dwIndex   The index of the interface to be deleted

  Return Value
      ERROR_INVALID_PARAMETER   Interface with the given index not found
      NO_ERROR

--*/
{
    PNT_IF      pIf;
    PLIST_ENTRY pleNode;
    PINTRNL_IF  pBind;

    
    EnterProtocolApi();
    
    TraceEnter("DeleteInterface");
    
    Trace1(ERR,
           "DeleteInterface: Called for interface %d",
           dwIndex);
    
    EnterCriticalSection(&g_csIfListLock);
    
    pIf = GetIfBlockGivenIndex(dwIndex);
    
    if(pIf == NULL)
    {
        //
        // Did not have an interface corresponding to
        // this index
        //

        LeaveCriticalSection(&g_csIfListLock);
        
        Trace1(ERR,
               "DeleteInterface: Interface %d does not exist",
               dwIndex);

        TraceLeave("DeleteInterface");

        ExitProtocolApi();

        return ERROR_INVALID_PARAMETER;
    }

    //
    // Remove it from the list of NT Interfaces
    //
    
    RemoveEntryList(&(pIf->leNtIfLink));
    
    ASSERT(pIf->dwNtIndex == dwIndex);
    ASSERT(pIf->pwszIfName);
    
    //
    // Shut down each binding on the interface. We may have already
    // gotten Unbind() calls so they may have already been shut down
    //

    pleNode = pIf->leInternalIfHead.Flink;
    
    while(pleNode != &(pIf->leInternalIfHead))
    {
        pBind = CONTAINING_RECORD(pleNode, INTRNL_IF, leInternalIfLink);

        pleNode = pleNode->Flink;
        
        if(pBind->dwState == BINDING_UP)
        {
            //
            // So we did not get an unbind or disable for this
            //

            ASSERT(pBind->sSocket != INVALID_SOCKET);

            if(closesocket(pBind->sSocket) != NO_ERROR)
            {
                Trace3(ERR,
                       "DeleteInterface: Error %d closing socket %d on interface %S",
                       WSAGetLastError(),
                       pBind->sSocket,
                       pIf->pwszIfName);
            }
        }

        HeapFree(g_hPrivateHeap,
                 0,
                 pBind);
    }
            
    //
    // Free other resources
    //

    HeapFree(g_hPrivateHeap,
             0,
             pIf->pwszIfName);


    //
    // Lastly free the interface itself
    //
    
    HeapFree(g_hPrivateHeap,
             0,
             pIf);
    

    LeaveCriticalSection(&g_csIfListLock);

    TraceLeave("AddInterface");

    ExitProtocolApi();
        
    return NO_ERROR;
}