[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;
}