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.

399 lines
9.8 KiB

  1. /*++
  2. Copyright (c) 1992-1997 Microsoft Corporation
  3. Module Name:
  4. startup.c
  5. Abstract:
  6. Contains routines for starting SNMP master agent.
  7. Environment:
  8. User Mode - Win32
  9. Revision History:
  10. 10-Feb-1997 DonRyan
  11. Rewrote to implement SNMPv2 support.
  12. --*/
  13. ///////////////////////////////////////////////////////////////////////////////
  14. // //
  15. // Include files //
  16. // //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. #include "globals.h"
  19. #include "startup.h"
  20. #include "network.h"
  21. #include "registry.h"
  22. #include "snmpthrd.h"
  23. #include "regthrd.h"
  24. #include "trapthrd.h"
  25. #include "args.h"
  26. #include "mem.h"
  27. #include "snmpmgmt.h"
  28. ///////////////////////////////////////////////////////////////////////////////
  29. // //
  30. // Global variables //
  31. // //
  32. ///////////////////////////////////////////////////////////////////////////////
  33. HANDLE g_hAgentThread = NULL;
  34. HANDLE g_hRegistryThread = NULL; // Used to track registry changes
  35. CRITICAL_SECTION g_RegCriticalSectionA;
  36. CRITICAL_SECTION g_RegCriticalSectionB;
  37. CRITICAL_SECTION g_RegCriticalSectionC; // protect the generation of trap from
  38. // registry changes
  39. ///////////////////////////////////////////////////////////////////////////////
  40. // //
  41. // Private procedures //
  42. // //
  43. ///////////////////////////////////////////////////////////////////////////////
  44. BOOL
  45. LoadWinsock(
  46. )
  47. /*++
  48. Routine Description:
  49. Startup winsock.
  50. Arguments:
  51. None.
  52. Return Values:
  53. Returns true if successful.
  54. --*/
  55. {
  56. WSADATA WsaData;
  57. WORD wVersionRequested = MAKEWORD(2,0);
  58. INT nStatus;
  59. // attempt to startup winsock
  60. nStatus = WSAStartup(wVersionRequested, &WsaData);
  61. // validate return code
  62. if (nStatus == SOCKET_ERROR) {
  63. SNMPDBG((
  64. SNMP_LOG_ERROR,
  65. "SNMP: SVC: error %d starting winsock.\n",
  66. WSAGetLastError()
  67. ));
  68. // failure
  69. return FALSE;
  70. }
  71. // success
  72. return TRUE;
  73. }
  74. BOOL
  75. UnloadWinsock(
  76. )
  77. /*++
  78. Routine Description:
  79. Shutdown winsock.
  80. Arguments:
  81. None.
  82. Return Values:
  83. Returns true if successful.
  84. --*/
  85. {
  86. INT nStatus;
  87. // cleanup
  88. nStatus = WSACleanup();
  89. // validate return code
  90. if (nStatus == SOCKET_ERROR) {
  91. SNMPDBG((
  92. SNMP_LOG_ERROR,
  93. "SNMP: SVC: error %d stopping winsock.\n",
  94. WSAGetLastError()
  95. ));
  96. // failure
  97. return FALSE;
  98. }
  99. // success
  100. return TRUE;
  101. }
  102. ///////////////////////////////////////////////////////////////////////////////
  103. // //
  104. // Public procedures //
  105. // //
  106. ///////////////////////////////////////////////////////////////////////////////
  107. BOOL
  108. StartupAgent(
  109. )
  110. /*++
  111. Routine Description:
  112. Performs essential initialization of master agent.
  113. Arguments:
  114. None.
  115. Return Values:
  116. Returns true if successful.
  117. --*/
  118. {
  119. BOOL fOk = TRUE;
  120. DWORD dwThreadId = 0;
  121. DWORD regThreadId = 0;
  122. INT nCSOk = 0; // counts the number of CS that were successfully initialized
  123. // initialize management variables
  124. mgmtInit();
  125. // initialize list heads
  126. InitializeListHead(&g_Subagents);
  127. InitializeListHead(&g_SupportedRegions);
  128. InitializeListHead(&g_ValidCommunities);
  129. InitializeListHead(&g_TrapDestinations);
  130. InitializeListHead(&g_PermittedManagers);
  131. InitializeListHead(&g_IncomingTransports);
  132. InitializeListHead(&g_OutgoingTransports);
  133. __try
  134. {
  135. InitializeCriticalSection(&g_RegCriticalSectionA); nCSOk++;
  136. InitializeCriticalSection(&g_RegCriticalSectionB); nCSOk++;
  137. InitializeCriticalSection(&g_RegCriticalSectionC); nCSOk++;
  138. }
  139. __except(EXCEPTION_EXECUTE_HANDLER)
  140. {
  141. if (nCSOk == 1)
  142. DeleteCriticalSection(&g_RegCriticalSectionA);
  143. if (nCSOk == 2)
  144. {
  145. DeleteCriticalSection(&g_RegCriticalSectionA);
  146. DeleteCriticalSection(&g_RegCriticalSectionB);
  147. }
  148. // nCSOk can't be 3 as far as we are here
  149. fOk = FALSE;
  150. }
  151. SNMPDBG((
  152. SNMP_LOG_TRACE,
  153. "SNMP: SVC: Initialize critical sections...%s\n", fOk? "Ok" : "Failed"));
  154. fOk = fOk &&
  155. (g_hRegistryEvent = CreateEvent(NULL, FALSE, TRUE, NULL)) != NULL;
  156. g_dwUpTimeReference = SnmpSvcInitUptime();
  157. // retreive system uptime reference
  158. SNMPDBG((
  159. SNMP_LOG_TRACE,
  160. "SNMP: SVC: Getting system uptime...%d\n", g_dwUpTimeReference));
  161. // allocate essentials
  162. fOk = fOk && AgentHeapCreate();
  163. SNMPDBG((
  164. SNMP_LOG_TRACE,
  165. "SNMP: SVC: Creating agent heap...%s\n", fOk? "Ok" : "Failed"));
  166. fOk = fOk && LoadWinsock();
  167. SNMPDBG((
  168. SNMP_LOG_TRACE,
  169. "SNMP: SVC: Loading Winsock stack...%s\n", fOk? "Ok" : "Failed"));
  170. fOk = fOk && LoadIncomingTransports();
  171. SNMPDBG((
  172. SNMP_LOG_TRACE,
  173. "SNMP: SVC: Loading Incoming transports...%s\n", fOk? "Ok" : "Failed"));
  174. fOk = fOk && LoadOutgoingTransports();
  175. SNMPDBG((
  176. SNMP_LOG_TRACE,
  177. "SNMP: SVC: Loading Outgoing transports...%s\n", fOk? "Ok" : "Failed"));
  178. fOk = fOk &&
  179. // attempt to start main thread
  180. (g_hAgentThread = CreateThread(
  181. NULL, // lpThreadAttributes
  182. 0, // dwStackSize
  183. ProcessSnmpMessages,
  184. NULL, // lpParameter
  185. CREATE_SUSPENDED, // dwCreationFlags
  186. &dwThreadId
  187. )) != NULL;
  188. SNMPDBG((
  189. SNMP_LOG_TRACE,
  190. "SNMP: SVC: Starting ProcessSnmpMessages thread...%s\n", fOk? "Ok" : "Failed"));
  191. fOk = fOk &&
  192. // attempt to start registry listener thread
  193. (g_hRegistryThread = CreateThread(
  194. NULL,
  195. 0,
  196. ProcessRegistryMessage,
  197. NULL,
  198. CREATE_SUSPENDED,
  199. &regThreadId)) != NULL;
  200. SNMPDBG((
  201. SNMP_LOG_TRACE,
  202. "SNMP: SVC: Starting ProcessRegistryMessages thread...%s\n", fOk? "Ok" : "Failed"));
  203. return fOk;
  204. }
  205. BOOL
  206. ShutdownAgent(
  207. )
  208. /*++
  209. Routine Description:
  210. Performs final cleanup of master agent.
  211. Arguments:
  212. None.
  213. Return Values:
  214. Returns true if successful.
  215. --*/
  216. {
  217. BOOL fOk;
  218. DWORD dwStatus;
  219. // make sure shutdown signalled
  220. fOk = SetEvent(g_hTerminationEvent);
  221. if (!fOk) {
  222. SNMPDBG((
  223. SNMP_LOG_ERROR,
  224. "SNMP: SVC: error %d signalling termination.\n",
  225. GetLastError()
  226. ));
  227. }
  228. // check if thread created
  229. if ((g_hAgentThread != NULL) && (g_hRegistryThread != NULL)) {
  230. HANDLE hEvntArray[2];
  231. hEvntArray[0] = g_hAgentThread;
  232. hEvntArray[1] = g_hRegistryThread;
  233. dwStatus = WaitForMultipleObjects(2, hEvntArray, TRUE, SHUTDOWN_WAIT_HINT);
  234. // validate return status
  235. if ((dwStatus != WAIT_OBJECT_0) &&
  236. (dwStatus != WAIT_OBJECT_0 + 1) &&
  237. (dwStatus != WAIT_TIMEOUT)) {
  238. SNMPDBG((
  239. SNMP_LOG_ERROR,
  240. "SNMP: SVC: error %d waiting for thread(s) termination.\n",
  241. GetLastError()
  242. ));
  243. }
  244. } else if (g_hAgentThread != NULL) {
  245. // wait for pdu processing thread to terminate
  246. dwStatus = WaitForSingleObject(g_hAgentThread, SHUTDOWN_WAIT_HINT);
  247. // validate return status
  248. if ((dwStatus != WAIT_OBJECT_0) &&
  249. (dwStatus != WAIT_TIMEOUT)) {
  250. SNMPDBG((
  251. SNMP_LOG_ERROR,
  252. "SNMP: SVC: error %d waiting for main thread termination.\n",
  253. GetLastError()
  254. ));
  255. }
  256. } else if (g_hRegistryThread != NULL) {
  257. // wait for registry processing thread to terminate
  258. dwStatus = WaitForSingleObject(g_hRegistryThread, SHUTDOWN_WAIT_HINT);
  259. // validate return status
  260. if ((dwStatus != WAIT_OBJECT_0) &&
  261. (dwStatus != WAIT_TIMEOUT)) {
  262. SNMPDBG((
  263. SNMP_LOG_ERROR,
  264. "SNMP: SVC: error %d waiting for registry thread termination.\n",
  265. GetLastError()
  266. ));
  267. }
  268. }
  269. // unload incoming transports
  270. UnloadIncomingTransports();
  271. // unload outgoing transports
  272. UnloadOutgoingTransports();
  273. // unload registry info
  274. UnloadRegistryParameters();
  275. // unload the winsock stack
  276. UnloadWinsock();
  277. // cleanup the internal management buffers
  278. mgmtCleanup();
  279. // nuke private heap
  280. AgentHeapDestroy();
  281. // clean up critical section resources
  282. DeleteCriticalSection(&g_RegCriticalSectionA);
  283. DeleteCriticalSection(&g_RegCriticalSectionB);
  284. DeleteCriticalSection(&g_RegCriticalSectionC);
  285. ReportSnmpEvent(
  286. SNMP_EVENT_SERVICE_STOPPED,
  287. 0,
  288. NULL,
  289. 0);
  290. return TRUE;
  291. }