UnBindInterface Sample

[This is preliminary documentation and subject to change.]

DWORD
APIENTRY
UnBindInterface(
    IN DWORD dwIndex
    )
/*++
  Routine Description
      Called when the interface loses its IP Address(es). This may
      happen when the interface is shutting down. It may be because an
      admin Disabled the interface with IP (as opposed to just disabling
      or protocol on the interface). It can happen when the admin
      releases a DHCP acquired interface or when a dial up link
      disconnects. We see if we were running on the binding and if so,
      we shut it down. We dont release any memory associated with the
      binding because we can get bound again.

  Arguments
      dwIndex   The index of the interface being unbound

  Return Value
      ERROR_INVALID_PARAMETER
      NO_ERROR

--*/
{
    PNT_IF      pIf;
    PLIST_ENTRY pleNode;
    PINTRNL_IF  pBind;
    DWORD       dwResult;
    
    
    EnterProtocolApi();

    TraceEnter("UnbindInterface");
    
    EnterCriticalSection(&g_csIfListLock);

    pIf = GetIfBlockGivenIndex(dwIndex);

    if(pIf == NULL)
    {
        LeaveCriticalSection(&g_csIfListLock);
        
        Trace1(ERR,
               "UnbindInterface: Interface %d does not exist",
               dwIndex);

        TraceLeave("UnbindInterface");

        ExitProtocolApi();

        return ERROR_INVALID_PARAMETER;
    }

    if(!IsNtBound(pIf))
    {
        //
        // Nothing new happening
        //
        
        Trace1(INTF,
               "UnbindInterface: Unbind received for %S which was never bound",
               pIf->pwszIfName);

        LeaveCriticalSection(&g_csIfListLock);
        
        TraceLeave("UnbindInterface");

        ExitProtocolApi();

        return NO_ERROR;
    }
    
    ClearNtBound(pIf);

    if(IsNtEnabled(pIf))
    {
        //
        // Since it is enabled and was bound, deactivate the
        // bindings
        //
        
        for(pleNode  = pIf->leInternalIfHead.Flink;
            pleNode != &pIf->leInternalIfHead;
            pleNode  = pleNode->Flink)
        {
            pBind = CONTAINING_RECORD(pleNode, INTRNL_IF, leInternalIfLink);

            if(pBind->dwState == BINDING_UP)
            {
                //
                // This binding had been successfully activated
                //
                
                dwResult = DeactivateBinding(pBind);
                
                if(dwResult != NO_ERROR)
                {
                    Trace2(ERR,
                           "UnbindInterface: Unable to deactivate %d.%d.%d.%d over %S",
                           PRINT_ADDRESS(pBind->dwAddress),
                           pIf->pwszIfName);
                }
            }
        }

        if(pIf->ulNumBindings == 1)
        {
            //
            // Clear out the old address
            //

            pBind = CONTAINING_RECORD(pIf->leInternalIfHead.Flink,
                                      INTRNL_IF,
                                      leInternalIfLink);

            pBind->dwAddress = 0x00000000;
            pBind->dwMask    = 0x00000000;
        }
    }

    LeaveCriticalSection(&g_csIfListLock);
    
    TraceLeave("UnbindInterface");

    ExitProtocolApi();

    return NO_ERROR;
    
}