Leaked source code of windows server 2003
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.

547 lines
11 KiB

  1. /*++
  2. Copyright (c) 1996-1997 Microsoft Corporation
  3. Module Name:
  4. init.c
  5. Abstract:
  6. This module contains initialization code for traffic.DLL.
  7. Author:
  8. Jim Stewart ( jstew ) July 28, 1996
  9. Revision History:
  10. Ofer Bar (oferbar) Oct 1, 1997
  11. --*/
  12. #include "precomp.h"
  13. //#pragma hdrstop
  14. //#include "oscode.h"
  15. //
  16. // global data
  17. //
  18. ULONG DebugMask = 0;
  19. BOOL NTPlatform = FALSE;
  20. //LPWSCONTROL WsCtrl = NULL;
  21. PGLOBAL_STRUC pGlobals = NULL;
  22. DWORD InitializationStatus = NO_ERROR;
  23. static BOOL _init_rpc = FALSE;
  24. static PUSHORT _RpcStringBinding;
  25. //
  26. // 258218 changes
  27. //
  28. TRAFFIC_LOCK NotificationListLock;
  29. LIST_ENTRY NotificationListHead;
  30. TRAFFIC_LOCK ClientRegDeregLock;
  31. HANDLE GpcCancelEvent = INVALID_HANDLE_VALUE;
  32. PVOID hinstTrafficDll;
  33. VOID
  34. CloseAll(VOID);
  35. #if DBG
  36. TCHAR *TC_States[] = {
  37. TEXT("INVALID"),
  38. TEXT("INSTALLING"), // structures were allocated.
  39. TEXT("OPEN"), // Open for business
  40. TEXT("USERCLOSED_KERNELCLOSEPENDING"), // the user component has closed it, we are awaiting a kernel close
  41. TEXT("FORCED_KERNELCLOSE"), // the kernel component has forced a close.
  42. TEXT("KERNELCOSED_USERCLEANUP"), // Kernel has closed it, we are ready to delete this obj.
  43. TEXT("REMOVED"), // Its gone (being freed - remember that the handle has to be freed before removing)
  44. TEXT("EXIT_CLEANUP"), // We are going away and need to be cleanedup
  45. TEXT("MAX_STATES")
  46. };
  47. #endif
  48. BOOL
  49. Initialize (
  50. IN PVOID DllHandle,
  51. IN ULONG Reason,
  52. IN PVOID Context OPTIONAL
  53. )
  54. /*++
  55. Description:
  56. This is the DLL entry point, called when a process
  57. attaches or a thread is created
  58. Arguments:
  59. DllHandle - a handle to the DLL
  60. Reason - why the dll entry point is being called
  61. Context - additional information about call reason
  62. Return Value:
  63. TRUE or FALSE
  64. --*/
  65. {
  66. HANDLE Handle;
  67. DWORD Error;
  68. //
  69. // On a thread detach, set up the context param so that all
  70. // necessary deallocations will occur. On a FreeLibrary call Context
  71. // will be NULL and that is the case that we DO want to cleanup.
  72. //
  73. if ( Reason == DLL_THREAD_DETACH ) {
  74. Context = NULL;
  75. }
  76. switch ( Reason ) {
  77. case DLL_PROCESS_ATTACH:
  78. // Save the DLL handle as it is used to change ref count on this DLL
  79. hinstTrafficDll = DllHandle;
  80. //
  81. // disable the DLL_THREAD_ATTACH event
  82. //
  83. DisableThreadLibraryCalls( DllHandle );
  84. SETUP_DEBUG_INFO();
  85. IF_DEBUG(INIT) {
  86. WSPRINT(( "Initialize: DLL Process Attach \n" ));
  87. }
  88. INIT_DBG_MEMORY();
  89. if (!InitializeGlobalData()) {
  90. CLOSE_DEBUG();
  91. return FALSE;
  92. }
  93. IF_DEBUG(INIT) {
  94. WSPRINT(("traffic.dll Version %d\n", CURRENT_TCI_VERSION));
  95. }
  96. InitializationStatus = InitializeOsSpecific();
  97. if (ERROR_FAILED(InitializationStatus)) {
  98. WSPRINT(("\tInitialize: Failed OS specific initialization!\n"));
  99. CLOSE_DEBUG();
  100. //
  101. // we return TRUE to succedd DLL loading into the process
  102. // all other TCI calls will check this and fail...
  103. //
  104. return TRUE;
  105. } else {
  106. #if 0
  107. InitializeWmi();
  108. //
  109. // call to internally enumerate the interfaces
  110. //
  111. EnumAllInterfaces();
  112. #endif
  113. }
  114. //InitializeIpRouteTab();
  115. break;
  116. case DLL_PROCESS_DETACH:
  117. if ( Context )
  118. {
  119. // As per MSDN a non-zero Context means process is
  120. // terminating. Do not do any cleanup
  121. break;
  122. }
  123. IF_DEBUG(SHUTDOWN) {
  124. WSPRINT(( "Shutdown: Process Detach, Context = %X\n",Context ));
  125. }
  126. //DUMP_MEM_ALLOCATIONS();
  127. //
  128. // Only clean up resources if we're being called because of a
  129. // FreeLibrary(). If this is because of process termination,
  130. // do not clean up, as the system will do it for us. However
  131. // we must still clear all flows and filters with the kernel
  132. // since the system will not clean these up on termination.
  133. //
  134. //
  135. // don't want to get WMI notifications
  136. //
  137. DeInitializeWmi();
  138. //
  139. // close all flows and filters with the kernel and deregister from GPC
  140. //
  141. CloseAll();
  142. //
  143. // close the kernel file handle
  144. //
  145. DeInitializeOsSpecific();
  146. //
  147. // release all allocated resources
  148. //
  149. DeInitializeGlobalData();
  150. //
  151. // dump allocated memory, before and after we cleanup to
  152. // help track any leaks
  153. DUMP_MEM_ALLOCATIONS();
  154. DEINIT_DBG_MEMORY();
  155. CLOSE_DEBUG();
  156. break;
  157. case DLL_THREAD_DETACH:
  158. IF_DEBUG(SHUTDOWN) {
  159. WSPRINT(( "Shutdown: thread detach\n" ));
  160. }
  161. break;
  162. case DLL_THREAD_ATTACH:
  163. break;
  164. default:
  165. ASSERT( FALSE );
  166. break;
  167. }
  168. return TRUE;
  169. }
  170. VOID
  171. CloseAll()
  172. /*++
  173. Description:
  174. Close all interfaces, all flows and all filters.
  175. Also deregister GPC clients and release all TC ineterfaces.
  176. Arguments:
  177. none
  178. Return Value:
  179. none
  180. --*/
  181. {
  182. DWORD Status;
  183. PLIST_ENTRY pEntry;
  184. PINTERFACE_STRUC pInterface;
  185. PCLIENT_STRUC pClient;
  186. PGPC_CLIENT pGpcClient;
  187. PTC_IFC pTcIfc;
  188. IF_DEBUG(SHUTDOWN) {
  189. WSPRINT(( "CloseAll: Attempting to close any open interface\n" ));
  190. }
  191. while (!IsListEmpty( &pGlobals->ClientList )) {
  192. pClient = CONTAINING_RECORD( pGlobals->ClientList.Flink,
  193. CLIENT_STRUC,
  194. Linkage );
  195. IF_DEBUG(SHUTDOWN) {
  196. WSPRINT(( "CloseAll: Closing client=0x%X\n",
  197. PtrToUlong(pClient)));
  198. }
  199. while (!IsListEmpty( &pClient->InterfaceList )) {
  200. pInterface = CONTAINING_RECORD( pClient->InterfaceList.Flink,
  201. INTERFACE_STRUC,
  202. Linkage );
  203. //
  204. // remove all flows/filters and close the interface
  205. //
  206. IF_DEBUG(SHUTDOWN) {
  207. WSPRINT(( "CloseAll: Closing interface=0x%X\n",
  208. PtrToUlong(pInterface)));
  209. }
  210. MarkAllNodesForClosing(pInterface, EXIT_CLEANUP);
  211. CloseInterface(pInterface, TRUE);
  212. }
  213. //
  214. // deregister the client
  215. //
  216. IF_DEBUG(SHUTDOWN) {
  217. WSPRINT(( "CloseAll: Deregistring TC client\n"));
  218. }
  219. TcDeregisterClient(pClient->ClHandle);
  220. }
  221. //
  222. // Deregister GPC clients
  223. //
  224. while (!IsListEmpty( &pGlobals->GpcClientList )) {
  225. pEntry = pGlobals->GpcClientList.Flink;
  226. pGpcClient = CONTAINING_RECORD( pEntry,
  227. GPC_CLIENT,
  228. Linkage );
  229. IF_DEBUG(SHUTDOWN) {
  230. WSPRINT(( "CloseAll: Deregistring GPC client\n"));
  231. }
  232. IoDeregisterClient(pGpcClient);
  233. RemoveEntryList(pEntry);
  234. FreeMem(pGpcClient);
  235. }
  236. //
  237. // Remove TC interfaces
  238. //
  239. while (!IsListEmpty( &pGlobals->TcIfcList )) {
  240. pEntry = pGlobals->TcIfcList.Flink;
  241. pTcIfc = CONTAINING_RECORD( pEntry,
  242. TC_IFC,
  243. Linkage );
  244. ASSERT( IsListEmpty( &pTcIfc->ClIfcList ) );
  245. IF_DEBUG(SHUTDOWN) {
  246. WSPRINT(( "CloseAll: Remove TC (%x) interface from list\n", pTcIfc));
  247. }
  248. REFDEL(&pTcIfc->RefCount, 'KIFC');
  249. }
  250. IF_DEBUG(SHUTDOWN) {
  251. WSPRINT(( "<==CloseAll: exit...\n"));
  252. }
  253. }
  254. DWORD
  255. InitializeGlobalData(VOID)
  256. /*++
  257. Description:
  258. This routine initializes the global data.
  259. Arguments:
  260. none
  261. Return Value:
  262. none
  263. --*/
  264. {
  265. DWORD Status;
  266. //
  267. // allocate memory for the globals
  268. //
  269. AllocMem(&pGlobals, sizeof(GLOBAL_STRUC));
  270. if (pGlobals == NULL) {
  271. return FALSE;
  272. }
  273. RtlZeroMemory(pGlobals, sizeof(GLOBAL_STRUC));
  274. __try {
  275. InitLock( pGlobals->Lock );
  276. InitLock( NotificationListLock);
  277. InitLock( ClientRegDeregLock );
  278. } __except (EXCEPTION_EXECUTE_HANDLER) {
  279. Status = GetExceptionCode();
  280. IF_DEBUG(ERRORS) {
  281. WSPRINT(("TcRegisterClient: Exception Error: = 0x%X\n", Status ));
  282. }
  283. FreeMem(pGlobals);
  284. return FALSE;
  285. }
  286. //
  287. // initialize the handle table
  288. //
  289. NEW_HandleFactory(pGlobals->pHandleTbl);
  290. if (pGlobals->pHandleTbl == NULL) {
  291. FreeMem(pGlobals);
  292. return FALSE;
  293. }
  294. if (constructHandleFactory(pGlobals->pHandleTbl) != 0) {
  295. //
  296. // failed to construct the handle table, exit
  297. //
  298. FreeHandleFactory(pGlobals->pHandleTbl);
  299. FreeMem(pGlobals);
  300. return FALSE;
  301. }
  302. InitializeListHead( &pGlobals->ClientList );
  303. InitializeListHead( &pGlobals->TcIfcList );
  304. InitializeListHead( &pGlobals->GpcClientList );
  305. InitializeListHead( &NotificationListHead ); // 258218
  306. ASSERT(sizeof(IP_PATTERN) == sizeof(GPC_IP_PATTERN));
  307. ASSERT(FIELD_OFFSET(IP_PATTERN,SrcAddr) ==
  308. FIELD_OFFSET(GPC_IP_PATTERN,SrcAddr));
  309. ASSERT(FIELD_OFFSET(IP_PATTERN,ProtocolId) ==
  310. FIELD_OFFSET(GPC_IP_PATTERN,ProtocolId));
  311. return TRUE;
  312. }
  313. VOID
  314. DeInitializeGlobalData(VOID)
  315. /*++
  316. Description:
  317. This routine de-initializes the global data.
  318. Arguments:
  319. none
  320. Return Value:
  321. none
  322. --*/
  323. {
  324. PLIST_ENTRY pEntry;
  325. PTC_IFC pTcIfc;
  326. PNOTIFICATION_ELEMENT pNotifyElem;
  327. IF_DEBUG(SHUTDOWN) {
  328. WSPRINT(( "DeInitializeGlobalData: cleanup global data\n"));
  329. }
  330. destructHandleFactory(pGlobals->pHandleTbl);
  331. FreeHandleFactory(pGlobals->pHandleTbl);
  332. #if 0
  333. //
  334. // clear the TC interface structures
  335. //
  336. while (!IsListEmpty(&pGlobals->TcIfcList)) {
  337. pEntry = RemoveHeadList(&pGlobals->TcIfcList);
  338. pTcIfc = (PTC_IFC)CONTAINING_RECORD(pEntry, TC_IFC, Linkage);
  339. FreeMem(pTcIfc);
  340. }
  341. #endif
  342. DeleteLock( pGlobals->Lock );
  343. //
  344. // Free the notification elements (258218)
  345. //
  346. while (!IsListEmpty(&NotificationListHead)) {
  347. pEntry = RemoveHeadList(&NotificationListHead);
  348. pNotifyElem = (PNOTIFICATION_ELEMENT)CONTAINING_RECORD(pEntry, NOTIFICATION_ELEMENT, Linkage.Flink);
  349. FreeMem(pNotifyElem);
  350. }
  351. DeleteLock( NotificationListLock);
  352. DeleteLock( ClientRegDeregLock );
  353. FreeMem(pGlobals);
  354. IF_DEBUG(SHUTDOWN) {
  355. WSPRINT(( "<==DeInitializeGlobalData: exit\n"));
  356. }
  357. }