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.

390 lines
10 KiB

  1. /*++
  2. Copyright (c) 1992-1999 Microsoft Corporation
  3. Module Name:
  4. regthrd.c
  5. Abstract:
  6. Contains routines for thread listening to registry changes.
  7. Environment:
  8. User Mode - Win32
  9. Revision History:
  10. Rajat Goel -- 24 Feb 1999
  11. - Creation
  12. --*/
  13. ///////////////////////////////////////////////////////////////////////////////
  14. // //
  15. // Include files //
  16. // //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. #include "globals.h"
  19. #include "contexts.h"
  20. #include "regions.h"
  21. #include "snmpmgrs.h"
  22. #include "trapmgrs.h"
  23. #include "trapthrd.h"
  24. #include "network.h"
  25. #include "varbinds.h"
  26. #include "snmpmgmt.h"
  27. #include "registry.h"
  28. #include <stdio.h>
  29. ///////////////////////////////////////////////////////////////////////////////
  30. // //
  31. // Private procedures //
  32. // //
  33. ///////////////////////////////////////////////////////////////////////////////
  34. DWORD
  35. ProcessSubagentChanges(
  36. )
  37. /*++
  38. Routine Description:
  39. Procedure for checking for any changes in the Extension Agents parameter in
  40. the registry
  41. Arguments:
  42. Return Values:
  43. Returns true if successful.
  44. --*/
  45. {
  46. DWORD retval;
  47. DWORD cnt;
  48. HKEY hExAgentsKey = NULL;
  49. // Open the ..SNMP\Parameters\ExtensionAgents key
  50. retval = RegOpenKeyEx(
  51. HKEY_LOCAL_MACHINE,
  52. REG_KEY_EXTENSION_AGENTS,
  53. 0,
  54. KEY_READ,
  55. &hExAgentsKey
  56. );
  57. cnt = 0;
  58. if (retval != ERROR_SUCCESS)
  59. {
  60. LPTSTR pszKey = REG_KEY_EXTENSION_AGENTS;
  61. ReportSnmpEvent(
  62. SNMP_EVENT_INVALID_REGISTRY_KEY,
  63. 1,
  64. &pszKey,
  65. retval);
  66. }
  67. while (retval == ERROR_SUCCESS)
  68. {
  69. DWORD dwNameSize;
  70. DWORD dwValueSize;
  71. DWORD dwValueType;
  72. DWORD dwPathSize;
  73. HKEY hAgentKey = NULL;
  74. TCHAR szName[MAX_PATH];
  75. TCHAR szValue[MAX_PATH];
  76. CHAR szPath[MAX_PATH];
  77. CHAR szExpPath[MAX_PATH];
  78. PSUBAGENT_LIST_ENTRY pSLE = NULL;
  79. dwNameSize = sizeof(szName) / sizeof(szName[0]); // size in number of TCHARs
  80. dwValueSize = sizeof(szValue); // size in number of bytes
  81. dwPathSize = sizeof(szPath);
  82. // Retrieve the registry path for the Extension Agent DLL key
  83. retval = RegEnumValue(
  84. hExAgentsKey,
  85. cnt,
  86. szName,
  87. &dwNameSize,
  88. NULL,
  89. &dwValueType,
  90. (LPBYTE)szValue,
  91. &dwValueSize
  92. );
  93. // if failed to Enum the registry value, this is serious enough to break the loop
  94. if (retval != ERROR_SUCCESS)
  95. break;
  96. // Open the registry key for the current extension agent
  97. if (RegOpenKeyEx(
  98. HKEY_LOCAL_MACHINE,
  99. szValue,
  100. 0,
  101. KEY_READ,
  102. &hAgentKey) == ERROR_SUCCESS)
  103. {
  104. // get the full pathname of the extension agent DLL
  105. if (RegQueryValueExA(
  106. hAgentKey,
  107. REG_VALUE_SUBAGENT_PATH,
  108. NULL,
  109. &dwValueType,
  110. szPath,
  111. &dwPathSize
  112. ) == ERROR_SUCCESS)
  113. {
  114. // Expand path
  115. ExpandEnvironmentStringsA(
  116. szPath,
  117. szExpPath,
  118. sizeof(szExpPath));
  119. // Check if the DLL has already been loaded. If it has,
  120. // mark it. If not load it.
  121. if (FindSubagent(&pSLE, szExpPath))
  122. {
  123. // If this extension agent already exists in the list,
  124. // mark it such that it is not removed further
  125. pSLE->uchFlags |= FLG_SLE_KEEP;
  126. }
  127. else
  128. {
  129. // This is a new DLL, add it to the list and mark it to be kept
  130. // while looking for the extension agents to be removed
  131. if (!AddSubagentByDll(szExpPath, FLG_SLE_KEEP))
  132. {
  133. SNMPDBG((
  134. SNMP_LOG_ERROR,
  135. "SNMP: SVC: unable to load extension agent '%s'.\n",
  136. szExpPath
  137. ));
  138. }
  139. }
  140. }
  141. else
  142. {
  143. // we couldn't open the registry key which provides the full path to the DLL.
  144. // report the error but don't break the loop as there might be more subagents to handle
  145. SNMPDBG((
  146. SNMP_LOG_ERROR,
  147. "SNMP: SVC: unable to retrieve extension agent '%s' value.\n",
  148. REG_VALUE_SUBAGENT_PATH
  149. ));
  150. }
  151. RegCloseKey(hAgentKey);
  152. }
  153. else
  154. {
  155. LPTSTR pSzValue = szValue;
  156. SNMPDBG((
  157. SNMP_LOG_ERROR,
  158. "SNMP: SVC: unable to open extension agent %s key.\n", szValue
  159. ));
  160. ReportSnmpEvent(
  161. SNMP_EVENT_INVALID_EXTENSION_AGENT_KEY,
  162. 1,
  163. &pSzValue,
  164. retval);
  165. }
  166. cnt++;
  167. }
  168. // Go through the list of subagents. Unload any DLL's that were not marked
  169. // in the previous loop
  170. {
  171. PLIST_ENTRY pLE;
  172. PSUBAGENT_LIST_ENTRY pSLE;
  173. pLE = g_Subagents.Flink;
  174. while (pLE != &g_Subagents)
  175. {
  176. pSLE = CONTAINING_RECORD(pLE, SUBAGENT_LIST_ENTRY, Link);
  177. if (!(pSLE->uchFlags & FLG_SLE_KEEP))
  178. {
  179. RemoveEntryList(&(pSLE->Link));
  180. pLE = pLE->Flink;
  181. FreeSLE(pSLE);
  182. continue;
  183. }
  184. else
  185. {
  186. // reset the flag for next updates
  187. pSLE->uchFlags ^= FLG_SLE_KEEP;
  188. }
  189. pLE = pLE->Flink;
  190. }
  191. }
  192. if (retval == ERROR_NO_MORE_ITEMS)
  193. retval = ERROR_SUCCESS;
  194. if (hExAgentsKey != NULL)
  195. RegCloseKey(hExAgentsKey);
  196. return retval;
  197. }
  198. ///////////////////////////////////////////////////////////////////////////////
  199. // //
  200. // Public procedures //
  201. // //
  202. ///////////////////////////////////////////////////////////////////////////////
  203. DWORD
  204. ProcessRegistryMessage(
  205. PVOID pParam
  206. )
  207. /*++
  208. Routine Description:
  209. Thread procedure for processing Registry Changes
  210. Arguments:
  211. pParam - unused.
  212. Return Values:
  213. Returns true if successful.
  214. --*/
  215. {
  216. DWORD retval = ERROR_SUCCESS;
  217. do
  218. {
  219. DWORD evntIndex;
  220. BOOL bEvntSetOk;
  221. // Wait for registry change or Main thread termination
  222. evntIndex = WaitOnRegNotification();
  223. // for one change into the registry several notifications occur (key renaming, value addition,
  224. // value change, etc). In order to avoid useless (and counterproductive) notifications, wait
  225. // here for half of SHUTDOWN_WAIT_HINT.
  226. Sleep(SHUTDOWN_WAIT_HINT/2);
  227. // first thing to do is to re initialize the registry notifiers
  228. // otherwise we might miss some changes
  229. InitRegistryNotifiers();
  230. if (evntIndex == WAIT_FAILED)
  231. {
  232. retval = GetLastError();
  233. break;
  234. }
  235. if (evntIndex == WAIT_OBJECT_0)
  236. {
  237. // termination was signaled
  238. SNMPDBG((
  239. SNMP_LOG_TRACE,
  240. "SNMP: SVC: shutting down the registry listener thread.\n"
  241. ));
  242. break;
  243. }
  244. //
  245. // unload and reload the registry parameters
  246. //
  247. // Used in ProcessSnmpMessages->RecvCompletionRoutine
  248. EnterCriticalSection(&g_RegCriticalSectionA);
  249. // Used in ProcessSubagentEvents
  250. EnterCriticalSection(&g_RegCriticalSectionB);
  251. // Used in GenerateTrap
  252. EnterCriticalSection(&g_RegCriticalSectionC);
  253. UnloadPermittedManagers();
  254. UnloadTrapDestinations();
  255. UnloadValidCommunities();
  256. UnloadSupportedRegions();
  257. // start reloading the registry with scalar parameters first
  258. // this is needed in order to know how to perform the name resolution
  259. // when loading PermittedManagers and TrapDestinations.
  260. LoadScalarParameters();
  261. // Check for subagent changes (extension agent dll's)
  262. if (ProcessSubagentChanges() != ERROR_SUCCESS)
  263. SNMPDBG((
  264. SNMP_LOG_TRACE,
  265. "SNMP: SVC: an error occured while trying to track registry subagent changes.\n"
  266. ));
  267. LoadSupportedRegions();
  268. LoadPermittedManagers(FALSE);
  269. LoadTrapDestinations(FALSE);
  270. // don't direct dynamic update for the ValidCommunities at this point!
  271. // if a REG_SZ entry occurs at this time, then it should be left as it is.
  272. LoadValidCommunities(FALSE);
  273. SetEvent(g_hRegistryEvent);
  274. LeaveCriticalSection(&g_RegCriticalSectionC);
  275. LeaveCriticalSection(&g_RegCriticalSectionB);
  276. LeaveCriticalSection(&g_RegCriticalSectionA);
  277. SNMPDBG((
  278. SNMP_LOG_TRACE,
  279. "SNMP: SVC: a registry change was detected.\n"
  280. ));
  281. ReportSnmpEvent(
  282. SNMP_EVENT_CONFIGURATION_UPDATED,
  283. 0,
  284. NULL,
  285. 0);
  286. } while(retval == ERROR_SUCCESS);
  287. if (retval != ERROR_SUCCESS)
  288. {
  289. SNMPDBG((
  290. SNMP_LOG_ERROR,
  291. "SNMP: SVC: ** Failed in listening for registry changes **.\n"
  292. ));
  293. // log an event to system log file - SNMP service is going on but will not update on registry changes
  294. ReportSnmpEvent(
  295. SNMP_EVENT_REGNOTIFY_THREAD_FAILED,
  296. 0,
  297. NULL,
  298. retval);
  299. }
  300. return retval;
  301. }