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