Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

503 lines
9.7 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. routing\ip\rtrmgr\close.c
  5. Abstract:
  6. Function related to shutdown
  7. Revision History:
  8. Gurdeep Singh Pall 6/14/95 Created
  9. --*/
  10. #include "allinc.h"
  11. VOID
  12. ReinstallOldRoutes(
  13. );
  14. VOID
  15. RouterManagerCleanup(
  16. VOID
  17. )
  18. /*++
  19. Routine Description
  20. The main cleanup function
  21. Locks
  22. None
  23. Arguments
  24. None
  25. Return Value
  26. None
  27. --*/
  28. {
  29. HANDLE hRtmHandle;
  30. DWORD i;
  31. TraceEnter("RouterManagerCleanup");
  32. DeleteAllInterfaces();
  33. UnloadRoutingProtocols();
  34. UnInitHashTables();
  35. CloseIPDriver();
  36. CloseMcastDriver();
  37. MIBCleanup();
  38. CloseIpIpKey();
  39. if (!RouterRoleLanOnly)
  40. {
  41. //
  42. // WAN related cleanups
  43. //
  44. CloseWanArp() ;
  45. if (g_bEnableNetbtBcastFrowarding)
  46. {
  47. RestoreNetbtBcastForwardingMode();
  48. }
  49. }
  50. if(g_hMprConfig isnot NULL)
  51. {
  52. MprConfigServerDisconnect(g_hMprConfig);
  53. }
  54. MgmDeInitialize ();
  55. if (g_hNotification isnot NULL)
  56. {
  57. RtmDeregisterFromChangeNotification(g_hLocalRoute,
  58. g_hNotification);
  59. g_hNotification = NULL;
  60. }
  61. if (g_hDefaultRouteNotification isnot NULL)
  62. {
  63. RtmDeregisterFromChangeNotification(g_hNetMgmtRoute,
  64. g_hDefaultRouteNotification);
  65. g_hDefaultRouteNotification = NULL;
  66. }
  67. // Cleanup and deregister all RTM registrations
  68. for(i = 0;
  69. i < sizeof(g_rgRtmHandles)/sizeof(RTM_HANDLE_INFO);
  70. i++)
  71. {
  72. hRtmHandle = g_rgRtmHandles[i].hRouteHandle;
  73. if (hRtmHandle isnot NULL)
  74. {
  75. // Delete all routes added by this regn
  76. DeleteRtmRoutes(hRtmHandle, 0, TRUE);
  77. // Delete all nexthops added by this regn
  78. DeleteRtmNexthops(hRtmHandle, 0, TRUE);
  79. // Deregister this registration from RTM
  80. RtmDeregisterEntity(hRtmHandle);
  81. g_rgRtmHandles[i].dwProtoId = 0;
  82. g_rgRtmHandles[i].hRouteHandle = NULL;
  83. }
  84. }
  85. // Null out the aliases to the above regn handles
  86. g_hLocalRoute = NULL;
  87. g_hAutoStaticRoute = NULL;
  88. g_hStaticRoute = NULL;
  89. g_hNonDodRoute = NULL;
  90. g_hNetMgmtRoute = NULL;
  91. //
  92. // When last entity deregisters, the route table is automatically deleted
  93. //
  94. //
  95. // Before closing the handle to the TCP driver, reinstall all the routes
  96. // that existed before we started. The memory was from route heap so will
  97. // get freed
  98. //
  99. if(!IsListEmpty(&g_leStackRoutesToRestore))
  100. {
  101. ReinstallOldRoutes();
  102. }
  103. //
  104. // Close handles used for notification
  105. //
  106. if(g_hDemandDialEvent isnot NULL)
  107. {
  108. CloseHandle(g_hDemandDialEvent) ;
  109. g_hDemandDialEvent = NULL;
  110. }
  111. if(g_hIpInIpEvent isnot NULL)
  112. {
  113. CloseHandle(g_hIpInIpEvent);
  114. g_hIpInIpEvent = NULL;
  115. }
  116. if(g_hSetForwardingEvent isnot NULL)
  117. {
  118. CloseHandle(g_hSetForwardingEvent);
  119. g_hSetForwardingEvent = NULL;
  120. }
  121. if(g_hForwardingChangeEvent isnot NULL)
  122. {
  123. CloseHandle(g_hForwardingChangeEvent);
  124. g_hForwardingChangeEvent = NULL;
  125. }
  126. if(g_hStackChangeEvent isnot NULL)
  127. {
  128. CloseHandle(g_hStackChangeEvent);
  129. g_hStackChangeEvent = NULL;
  130. }
  131. if(g_hRoutingProtocolEvent isnot NULL)
  132. {
  133. CloseHandle(g_hRoutingProtocolEvent) ;
  134. g_hRoutingProtocolEvent = NULL;
  135. }
  136. if(g_hStopRouterEvent isnot NULL)
  137. {
  138. CloseHandle(g_hStopRouterEvent) ;
  139. g_hStopRouterEvent = NULL;
  140. }
  141. if(g_hRtrDiscSocketEvent isnot NULL)
  142. {
  143. CloseHandle(g_hRtrDiscSocketEvent);
  144. g_hRtrDiscSocketEvent = NULL;
  145. }
  146. if(g_hMcMiscSocketEvent isnot NULL)
  147. {
  148. CloseHandle(g_hMcMiscSocketEvent);
  149. g_hMcMiscSocketEvent = NULL;
  150. }
  151. if(g_hRtrDiscTimer isnot NULL)
  152. {
  153. CloseHandle(g_hRtrDiscTimer);
  154. g_hRtrDiscTimer = NULL;
  155. }
  156. for(i = 0; i < NUM_MCAST_IRPS; i++)
  157. {
  158. if(g_hMcastEvents[i] isnot NULL)
  159. {
  160. CloseHandle(g_hMcastEvents[i]);
  161. g_hMcastEvents[i] = NULL;
  162. }
  163. }
  164. for(i = 0; i < NUM_ROUTE_CHANGE_IRPS; i++)
  165. {
  166. if(g_hRouteChangeEvents[i] isnot NULL)
  167. {
  168. CloseHandle(g_hRouteChangeEvents[i]);
  169. g_hRouteChangeEvents[i] = NULL;
  170. }
  171. }
  172. if(WSACleanup() isnot NO_ERROR)
  173. {
  174. Trace1(ERR,
  175. "RouterManagerCleanup: WSACleanup returned %d",
  176. WSAGetLastError());
  177. }
  178. for(i = 0; i < NUM_LOCKS; i++)
  179. {
  180. RtlDeleteResource(&g_LockTable[i]);
  181. }
  182. //
  183. // This cleans out the interface structures, since they are all
  184. // allocated from this heap
  185. //
  186. if(IPRouterHeap isnot NULL)
  187. {
  188. HeapDestroy (IPRouterHeap) ;
  189. IPRouterHeap = NULL;
  190. }
  191. Trace0(GLOBAL, "IP Router Manager cleanup done");
  192. TraceLeave("RouterManagerCleanup");
  193. TraceDeregister (TraceHandle) ;
  194. }
  195. VOID
  196. ReinstallOldRoutes(
  197. )
  198. {
  199. DWORD dwResult;
  200. PROUTE_LIST_ENTRY prl;
  201. TraceEnter("ReinstallOldRoutes");
  202. while (!IsListEmpty(&g_leStackRoutesToRestore))
  203. {
  204. prl = (PROUTE_LIST_ENTRY) RemoveHeadList(
  205. &g_leStackRoutesToRestore
  206. );
  207. TraceRoute2(
  208. ROUTE, "%d.%d.%d.%d/%d.%d.%d.%d",
  209. PRINT_IPADDR( prl->mibRoute.dwForwardDest ),
  210. PRINT_IPADDR( prl->mibRoute.dwForwardMask )
  211. );
  212. dwResult = SetIpForwardEntryToStack(&(prl->mibRoute));
  213. if (dwResult isnot NO_ERROR)
  214. {
  215. Trace2(ERR,
  216. "ReinstallOldRoutes: Failed to add route to %x from "
  217. " init table. Error %x",
  218. prl->mibRoute.dwForwardDest,
  219. dwResult);
  220. }
  221. }
  222. TraceLeave("ReinstallOldRoutes");
  223. }
  224. VOID
  225. MIBCleanup(
  226. VOID
  227. )
  228. {
  229. TraceEnter("MIBCleanup");
  230. if(g_hIfHeap isnot NULL)
  231. {
  232. HeapDestroy(g_hIfHeap);
  233. g_hIfHeap = NULL;
  234. }
  235. if(g_hUdpHeap isnot NULL)
  236. {
  237. HeapDestroy(g_hUdpHeap);
  238. g_hUdpHeap = NULL;
  239. }
  240. if(g_hIpAddrHeap isnot NULL)
  241. {
  242. HeapDestroy(g_hIpAddrHeap);
  243. g_hIpAddrHeap = NULL;
  244. }
  245. if(g_hIpForwardHeap isnot NULL)
  246. {
  247. HeapDestroy(g_hIpForwardHeap);
  248. g_hIpForwardHeap = NULL;
  249. }
  250. if(g_hIpNetHeap isnot NULL)
  251. {
  252. HeapDestroy(g_hIpNetHeap);
  253. g_hIpNetHeap = NULL;
  254. }
  255. TraceLeave("MIBCleanup");
  256. }
  257. //* UnloadRoutingProtocols()
  258. //
  259. // Function: 1. Calls stopprotocol for each routing protocol
  260. // 2. Waits for protocols to stop
  261. // 3. Unloads the routing protocol dlls.
  262. //
  263. // Returns: Nothing.
  264. //*
  265. VOID
  266. UnloadRoutingProtocols()
  267. {
  268. PLIST_ENTRY currentlist ;
  269. PPROTO_CB protptr ;
  270. TraceEnter("UnloadRoutingProtocols");
  271. while (!IsListEmpty(&g_leProtoCbList))
  272. {
  273. currentlist = RemoveHeadList(&g_leProtoCbList);
  274. protptr = CONTAINING_RECORD (currentlist, PROTO_CB, leList) ;
  275. //
  276. // relenquish CPU to enable DLL threads to finish
  277. //
  278. Sleep(0);
  279. FreeLibrary (protptr->hiHInstance) ; // unload dll
  280. HeapFree (IPRouterHeap, 0, protptr) ; // free cb
  281. }
  282. TraceLeave("UnloadRoutingProtocols");
  283. }
  284. VOID
  285. CloseIPDriver(
  286. VOID
  287. )
  288. {
  289. TraceEnter("CloseIPDriver");
  290. if(g_hIpDevice isnot NULL)
  291. {
  292. CloseHandle(g_hIpDevice) ;
  293. }
  294. if (g_hIpRouteChangeDevice isnot NULL)
  295. {
  296. CloseHandle(g_hIpRouteChangeDevice);
  297. }
  298. TraceLeave("CloseIPDriver");
  299. }
  300. VOID
  301. CloseMcastDriver(
  302. VOID
  303. )
  304. {
  305. TraceEnter("CloseMcastDriver");
  306. if(g_hMcastDevice isnot NULL)
  307. {
  308. CloseHandle(g_hMcastDevice);
  309. }
  310. TraceLeave("CloseMcastDriver");
  311. }
  312. DWORD
  313. StopDriverAndCloseHandle(
  314. PCHAR pszServiceName,
  315. HANDLE hDevice
  316. )
  317. {
  318. NTSTATUS status;
  319. UNICODE_STRING nameString;
  320. IO_STATUS_BLOCK ioStatusBlock;
  321. OBJECT_ATTRIBUTES objectAttributes;
  322. SC_HANDLE schSCManager, schService;
  323. DWORD dwErr;
  324. SERVICE_STATUS ssStatus;
  325. TraceEnter("StopDriverAndCloseHandle");
  326. if(hDevice isnot NULL)
  327. {
  328. CloseHandle(hDevice);
  329. }
  330. schSCManager = OpenSCManager(NULL,
  331. NULL,
  332. SC_MANAGER_ALL_ACCESS);
  333. if(schSCManager is NULL)
  334. {
  335. dwErr = GetLastError();
  336. Trace2(ERR,
  337. "StopDriver: Error %d opening service controller for %s",
  338. dwErr,
  339. pszServiceName);
  340. TraceLeave("StopDriver");
  341. return dwErr;
  342. }
  343. schService = OpenService(schSCManager,
  344. pszServiceName,
  345. SERVICE_ALL_ACCESS);
  346. if(schService is NULL)
  347. {
  348. dwErr = GetLastError();
  349. Trace2(ERR,
  350. "StopDriver: Error %d opening %s",
  351. dwErr,
  352. pszServiceName);
  353. CloseServiceHandle(schSCManager);
  354. TraceLeave("StopDriver");
  355. return dwErr;
  356. }
  357. if(!ControlService(schService,
  358. SERVICE_CONTROL_STOP,
  359. &ssStatus))
  360. {
  361. dwErr = GetLastError();
  362. Trace2(ERR,
  363. "StopDriver: Error %d stopping %s",
  364. dwErr,
  365. pszServiceName);
  366. TraceLeave("StopDriver");
  367. return dwErr;
  368. }
  369. TraceLeave("StopDriver");
  370. return NO_ERROR ;
  371. }