504 lines
9.7 KiB
C
504 lines
9.7 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1995 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
routing\ip\rtrmgr\close.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Function related to shutdown
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
Gurdeep Singh Pall 6/14/95 Created
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "allinc.h"
|
||
|
|
||
|
VOID
|
||
|
ReinstallOldRoutes(
|
||
|
);
|
||
|
|
||
|
|
||
|
VOID
|
||
|
RouterManagerCleanup(
|
||
|
VOID
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description
|
||
|
|
||
|
The main cleanup function
|
||
|
|
||
|
Locks
|
||
|
|
||
|
None
|
||
|
|
||
|
Arguments
|
||
|
|
||
|
None
|
||
|
|
||
|
Return Value
|
||
|
|
||
|
None
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
HANDLE hRtmHandle;
|
||
|
DWORD i;
|
||
|
|
||
|
TraceEnter("RouterManagerCleanup");
|
||
|
|
||
|
DeleteAllInterfaces();
|
||
|
|
||
|
UnloadRoutingProtocols();
|
||
|
|
||
|
UnInitHashTables();
|
||
|
|
||
|
CloseIPDriver();
|
||
|
|
||
|
CloseMcastDriver();
|
||
|
|
||
|
MIBCleanup();
|
||
|
|
||
|
CloseIpIpKey();
|
||
|
|
||
|
if (!RouterRoleLanOnly)
|
||
|
{
|
||
|
//
|
||
|
// WAN related cleanups
|
||
|
//
|
||
|
|
||
|
CloseWanArp() ;
|
||
|
|
||
|
if (g_bEnableNetbtBcastFrowarding)
|
||
|
{
|
||
|
RestoreNetbtBcastForwardingMode();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(g_hMprConfig isnot NULL)
|
||
|
{
|
||
|
MprConfigServerDisconnect(g_hMprConfig);
|
||
|
}
|
||
|
|
||
|
MgmDeInitialize ();
|
||
|
|
||
|
if (g_hNotification isnot NULL)
|
||
|
{
|
||
|
RtmDeregisterFromChangeNotification(g_hLocalRoute,
|
||
|
g_hNotification);
|
||
|
|
||
|
g_hNotification = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
if (g_hDefaultRouteNotification isnot NULL)
|
||
|
{
|
||
|
RtmDeregisterFromChangeNotification(g_hNetMgmtRoute,
|
||
|
g_hDefaultRouteNotification);
|
||
|
|
||
|
g_hDefaultRouteNotification = NULL;
|
||
|
}
|
||
|
|
||
|
// Cleanup and deregister all RTM registrations
|
||
|
|
||
|
for(i = 0;
|
||
|
i < sizeof(g_rgRtmHandles)/sizeof(RTM_HANDLE_INFO);
|
||
|
i++)
|
||
|
{
|
||
|
hRtmHandle = g_rgRtmHandles[i].hRouteHandle;
|
||
|
|
||
|
if (hRtmHandle isnot NULL)
|
||
|
{
|
||
|
// Delete all routes added by this regn
|
||
|
DeleteRtmRoutes(hRtmHandle, 0, TRUE);
|
||
|
|
||
|
// Delete all nexthops added by this regn
|
||
|
DeleteRtmNexthops(hRtmHandle, 0, TRUE);
|
||
|
|
||
|
// Deregister this registration from RTM
|
||
|
RtmDeregisterEntity(hRtmHandle);
|
||
|
|
||
|
g_rgRtmHandles[i].dwProtoId = 0;
|
||
|
g_rgRtmHandles[i].hRouteHandle = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Null out the aliases to the above regn handles
|
||
|
|
||
|
g_hLocalRoute = NULL;
|
||
|
g_hAutoStaticRoute = NULL;
|
||
|
g_hStaticRoute = NULL;
|
||
|
g_hNonDodRoute = NULL;
|
||
|
g_hNetMgmtRoute = NULL;
|
||
|
|
||
|
//
|
||
|
// When last entity deregisters, the route table is automatically deleted
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// Before closing the handle to the TCP driver, reinstall all the routes
|
||
|
// that existed before we started. The memory was from route heap so will
|
||
|
// get freed
|
||
|
//
|
||
|
|
||
|
if(!IsListEmpty(&g_leStackRoutesToRestore))
|
||
|
{
|
||
|
ReinstallOldRoutes();
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Close handles used for notification
|
||
|
//
|
||
|
|
||
|
if(g_hDemandDialEvent isnot NULL)
|
||
|
{
|
||
|
CloseHandle(g_hDemandDialEvent) ;
|
||
|
g_hDemandDialEvent = NULL;
|
||
|
}
|
||
|
|
||
|
if(g_hIpInIpEvent isnot NULL)
|
||
|
{
|
||
|
CloseHandle(g_hIpInIpEvent);
|
||
|
g_hIpInIpEvent = NULL;
|
||
|
}
|
||
|
|
||
|
if(g_hSetForwardingEvent isnot NULL)
|
||
|
{
|
||
|
CloseHandle(g_hSetForwardingEvent);
|
||
|
g_hSetForwardingEvent = NULL;
|
||
|
}
|
||
|
|
||
|
if(g_hForwardingChangeEvent isnot NULL)
|
||
|
{
|
||
|
CloseHandle(g_hForwardingChangeEvent);
|
||
|
|
||
|
g_hForwardingChangeEvent = NULL;
|
||
|
}
|
||
|
|
||
|
if(g_hStackChangeEvent isnot NULL)
|
||
|
{
|
||
|
CloseHandle(g_hStackChangeEvent);
|
||
|
g_hStackChangeEvent = NULL;
|
||
|
}
|
||
|
|
||
|
if(g_hRoutingProtocolEvent isnot NULL)
|
||
|
{
|
||
|
CloseHandle(g_hRoutingProtocolEvent) ;
|
||
|
g_hRoutingProtocolEvent = NULL;
|
||
|
}
|
||
|
|
||
|
if(g_hStopRouterEvent isnot NULL)
|
||
|
{
|
||
|
CloseHandle(g_hStopRouterEvent) ;
|
||
|
g_hStopRouterEvent = NULL;
|
||
|
}
|
||
|
|
||
|
if(g_hRtrDiscSocketEvent isnot NULL)
|
||
|
{
|
||
|
CloseHandle(g_hRtrDiscSocketEvent);
|
||
|
g_hRtrDiscSocketEvent = NULL;
|
||
|
}
|
||
|
|
||
|
if(g_hMcMiscSocketEvent isnot NULL)
|
||
|
{
|
||
|
CloseHandle(g_hMcMiscSocketEvent);
|
||
|
g_hMcMiscSocketEvent = NULL;
|
||
|
}
|
||
|
|
||
|
if(g_hRtrDiscTimer isnot NULL)
|
||
|
{
|
||
|
CloseHandle(g_hRtrDiscTimer);
|
||
|
g_hRtrDiscTimer = NULL;
|
||
|
}
|
||
|
|
||
|
for(i = 0; i < NUM_MCAST_IRPS; i++)
|
||
|
{
|
||
|
if(g_hMcastEvents[i] isnot NULL)
|
||
|
{
|
||
|
CloseHandle(g_hMcastEvents[i]);
|
||
|
|
||
|
g_hMcastEvents[i] = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for(i = 0; i < NUM_ROUTE_CHANGE_IRPS; i++)
|
||
|
{
|
||
|
if(g_hRouteChangeEvents[i] isnot NULL)
|
||
|
{
|
||
|
CloseHandle(g_hRouteChangeEvents[i]);
|
||
|
|
||
|
g_hRouteChangeEvents[i] = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
if(WSACleanup() isnot NO_ERROR)
|
||
|
{
|
||
|
Trace1(ERR,
|
||
|
"RouterManagerCleanup: WSACleanup returned %d",
|
||
|
WSAGetLastError());
|
||
|
}
|
||
|
|
||
|
for(i = 0; i < NUM_LOCKS; i++)
|
||
|
{
|
||
|
RtlDeleteResource(&g_LockTable[i]);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// This cleans out the interface structures, since they are all
|
||
|
// allocated from this heap
|
||
|
//
|
||
|
|
||
|
if(IPRouterHeap isnot NULL)
|
||
|
{
|
||
|
HeapDestroy (IPRouterHeap) ;
|
||
|
IPRouterHeap = NULL;
|
||
|
}
|
||
|
|
||
|
Trace0(GLOBAL, "IP Router Manager cleanup done");
|
||
|
|
||
|
TraceLeave("RouterManagerCleanup");
|
||
|
|
||
|
TraceDeregister (TraceHandle) ;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
ReinstallOldRoutes(
|
||
|
)
|
||
|
{
|
||
|
DWORD dwResult;
|
||
|
PROUTE_LIST_ENTRY prl;
|
||
|
|
||
|
TraceEnter("ReinstallOldRoutes");
|
||
|
|
||
|
while (!IsListEmpty(&g_leStackRoutesToRestore))
|
||
|
{
|
||
|
prl = (PROUTE_LIST_ENTRY) RemoveHeadList(
|
||
|
&g_leStackRoutesToRestore
|
||
|
);
|
||
|
|
||
|
TraceRoute2(
|
||
|
ROUTE, "%d.%d.%d.%d/%d.%d.%d.%d",
|
||
|
PRINT_IPADDR( prl->mibRoute.dwForwardDest ),
|
||
|
PRINT_IPADDR( prl->mibRoute.dwForwardMask )
|
||
|
);
|
||
|
|
||
|
dwResult = SetIpForwardEntryToStack(&(prl->mibRoute));
|
||
|
|
||
|
if (dwResult isnot NO_ERROR)
|
||
|
{
|
||
|
Trace2(ERR,
|
||
|
"ReinstallOldRoutes: Failed to add route to %x from "
|
||
|
" init table. Error %x",
|
||
|
prl->mibRoute.dwForwardDest,
|
||
|
dwResult);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
TraceLeave("ReinstallOldRoutes");
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
MIBCleanup(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
TraceEnter("MIBCleanup");
|
||
|
|
||
|
if(g_hIfHeap isnot NULL)
|
||
|
{
|
||
|
HeapDestroy(g_hIfHeap);
|
||
|
g_hIfHeap = NULL;
|
||
|
}
|
||
|
|
||
|
if(g_hUdpHeap isnot NULL)
|
||
|
{
|
||
|
HeapDestroy(g_hUdpHeap);
|
||
|
g_hUdpHeap = NULL;
|
||
|
}
|
||
|
|
||
|
if(g_hIpAddrHeap isnot NULL)
|
||
|
{
|
||
|
HeapDestroy(g_hIpAddrHeap);
|
||
|
g_hIpAddrHeap = NULL;
|
||
|
}
|
||
|
|
||
|
if(g_hIpForwardHeap isnot NULL)
|
||
|
{
|
||
|
HeapDestroy(g_hIpForwardHeap);
|
||
|
g_hIpForwardHeap = NULL;
|
||
|
}
|
||
|
|
||
|
if(g_hIpNetHeap isnot NULL)
|
||
|
{
|
||
|
HeapDestroy(g_hIpNetHeap);
|
||
|
g_hIpNetHeap = NULL;
|
||
|
}
|
||
|
|
||
|
TraceLeave("MIBCleanup");
|
||
|
}
|
||
|
|
||
|
//* UnloadRoutingProtocols()
|
||
|
//
|
||
|
// Function: 1. Calls stopprotocol for each routing protocol
|
||
|
// 2. Waits for protocols to stop
|
||
|
// 3. Unloads the routing protocol dlls.
|
||
|
//
|
||
|
// Returns: Nothing.
|
||
|
//*
|
||
|
VOID
|
||
|
UnloadRoutingProtocols()
|
||
|
{
|
||
|
PLIST_ENTRY currentlist ;
|
||
|
PPROTO_CB protptr ;
|
||
|
|
||
|
TraceEnter("UnloadRoutingProtocols");
|
||
|
|
||
|
while (!IsListEmpty(&g_leProtoCbList))
|
||
|
{
|
||
|
|
||
|
currentlist = RemoveHeadList(&g_leProtoCbList);
|
||
|
|
||
|
protptr = CONTAINING_RECORD (currentlist, PROTO_CB, leList) ;
|
||
|
|
||
|
//
|
||
|
// relenquish CPU to enable DLL threads to finish
|
||
|
//
|
||
|
Sleep(0);
|
||
|
|
||
|
FreeLibrary (protptr->hiHInstance) ; // unload dll
|
||
|
|
||
|
HeapFree (IPRouterHeap, 0, protptr) ; // free cb
|
||
|
|
||
|
}
|
||
|
|
||
|
TraceLeave("UnloadRoutingProtocols");
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
CloseIPDriver(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
TraceEnter("CloseIPDriver");
|
||
|
|
||
|
if(g_hIpDevice isnot NULL)
|
||
|
{
|
||
|
CloseHandle(g_hIpDevice) ;
|
||
|
}
|
||
|
|
||
|
if (g_hIpRouteChangeDevice isnot NULL)
|
||
|
{
|
||
|
CloseHandle(g_hIpRouteChangeDevice);
|
||
|
}
|
||
|
|
||
|
TraceLeave("CloseIPDriver");
|
||
|
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
CloseMcastDriver(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
TraceEnter("CloseMcastDriver");
|
||
|
|
||
|
if(g_hMcastDevice isnot NULL)
|
||
|
{
|
||
|
CloseHandle(g_hMcastDevice);
|
||
|
}
|
||
|
|
||
|
TraceLeave("CloseMcastDriver");
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
StopDriverAndCloseHandle(
|
||
|
PCHAR pszServiceName,
|
||
|
HANDLE hDevice
|
||
|
)
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
UNICODE_STRING nameString;
|
||
|
IO_STATUS_BLOCK ioStatusBlock;
|
||
|
OBJECT_ATTRIBUTES objectAttributes;
|
||
|
SC_HANDLE schSCManager, schService;
|
||
|
DWORD dwErr;
|
||
|
SERVICE_STATUS ssStatus;
|
||
|
|
||
|
TraceEnter("StopDriverAndCloseHandle");
|
||
|
|
||
|
if(hDevice isnot NULL)
|
||
|
{
|
||
|
CloseHandle(hDevice);
|
||
|
}
|
||
|
|
||
|
schSCManager = OpenSCManager(NULL,
|
||
|
NULL,
|
||
|
SC_MANAGER_ALL_ACCESS);
|
||
|
|
||
|
if(schSCManager is NULL)
|
||
|
{
|
||
|
dwErr = GetLastError();
|
||
|
|
||
|
Trace2(ERR,
|
||
|
"StopDriver: Error %d opening service controller for %s",
|
||
|
dwErr,
|
||
|
pszServiceName);
|
||
|
|
||
|
TraceLeave("StopDriver");
|
||
|
|
||
|
return dwErr;
|
||
|
}
|
||
|
|
||
|
schService = OpenService(schSCManager,
|
||
|
pszServiceName,
|
||
|
SERVICE_ALL_ACCESS);
|
||
|
|
||
|
if(schService is NULL)
|
||
|
{
|
||
|
dwErr = GetLastError();
|
||
|
|
||
|
Trace2(ERR,
|
||
|
"StopDriver: Error %d opening %s",
|
||
|
dwErr,
|
||
|
pszServiceName);
|
||
|
|
||
|
CloseServiceHandle(schSCManager);
|
||
|
|
||
|
TraceLeave("StopDriver");
|
||
|
|
||
|
return dwErr;
|
||
|
}
|
||
|
|
||
|
if(!ControlService(schService,
|
||
|
SERVICE_CONTROL_STOP,
|
||
|
&ssStatus))
|
||
|
{
|
||
|
dwErr = GetLastError();
|
||
|
|
||
|
Trace2(ERR,
|
||
|
"StopDriver: Error %d stopping %s",
|
||
|
dwErr,
|
||
|
pszServiceName);
|
||
|
|
||
|
TraceLeave("StopDriver");
|
||
|
|
||
|
return dwErr;
|
||
|
}
|
||
|
|
||
|
TraceLeave("StopDriver");
|
||
|
|
||
|
return NO_ERROR ;
|
||
|
}
|
||
|
|