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.

420 lines
15 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: N C S N M P . C P P
  7. //
  8. // Contents: Functions for adding a service as an SNMP agent.
  9. //
  10. // Notes:
  11. //
  12. // Author: danielwe 8 Apr 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "ncsnmp.h"
  18. #include "ncreg.h"
  19. extern const WCHAR c_szBackslash[];
  20. extern const WCHAR c_szEmpty[];
  21. extern const WCHAR c_szRegKeyServices[];
  22. static const WCHAR c_szSNMP[] = L"SNMP";
  23. static const WCHAR c_szSNMPParams[] = L"SNMP\\Parameters";
  24. static const WCHAR c_szSoftwareKey[] = L"SOFTWARE\\Microsoft";
  25. static const WCHAR c_szAgentsKey[] = L"SNMP\\Parameters\\ExtensionAgents";
  26. static const WCHAR c_szAgentsKeyAbs[] = L"System\\CurrentControlSet\\Services\\SNMP\\Parameters\\ExtensionAgents";
  27. static const WCHAR c_szParamsKeyAbs[] = L"System\\CurrentControlSet\\Services\\SNMP\\Parameters";
  28. static const WCHAR c_szCurrentVersion[]= L"CurrentVersion";
  29. static const WCHAR c_szPathName[] = L"Pathname";
  30. struct SNMP_REG_DATA
  31. {
  32. PCWSTR pszAgentPath;
  33. PCWSTR pszExtAgentValueName;
  34. PCWSTR pszEmpty;
  35. };
  36. //+---------------------------------------------------------------------------
  37. //
  38. // Function: HrGetNextAgentNumber
  39. //
  40. // Purpose: Obtains the next agent number to use as a value name.
  41. //
  42. // Arguments:
  43. // pszAgentName [in] Name of agent being added
  44. // pdwNumber [out] New agent number to use.
  45. //
  46. // Returns: S_OK if successful, S_FALSE if agent already exists, or
  47. // WIN32 error code otherwise.
  48. //
  49. // Author: danielwe 8 Apr 1997
  50. //
  51. // Notes:
  52. //
  53. HRESULT HrGetNextAgentNumber(PCWSTR pszAgentName, DWORD *pdwNumber)
  54. {
  55. HRESULT hr = S_OK;
  56. HKEY hkeyEnum;
  57. DWORD dwIndex = 0;
  58. Assert(pdwNumber);
  59. *pdwNumber = 0;
  60. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szAgentsKeyAbs, KEY_READ,
  61. &hkeyEnum);
  62. if (S_OK == hr)
  63. {
  64. // Enumerate all values.
  65. do
  66. {
  67. WCHAR szValueName [_MAX_PATH];
  68. DWORD cchValueName = celems (szValueName);
  69. DWORD dwType;
  70. hr = HrRegEnumValue(hkeyEnum, dwIndex,
  71. szValueName, &cchValueName,
  72. &dwType, NULL, 0);
  73. if (S_OK == hr)
  74. {
  75. // Verify the type. If it's not correct, though,
  76. // we'll ignore the key. No sense failing the entire install
  77. // (RAID 370702)
  78. //
  79. if (REG_SZ == dwType)
  80. {
  81. tstring strAgent;
  82. hr = HrRegQueryString(hkeyEnum, szValueName, &strAgent);
  83. if (S_OK == hr)
  84. {
  85. if (strAgent.find(pszAgentName, 0) != tstring::npos)
  86. {
  87. hr = S_FALSE;
  88. }
  89. }
  90. }
  91. else
  92. {
  93. // No sense failing the install, but it's still wrong, so
  94. // assert
  95. //
  96. AssertSz(REG_SZ == dwType,
  97. "HrGetNextAgentNumber: Expected a type of REG_SZ.");
  98. }
  99. }
  100. else if (HRESULT_FROM_WIN32 (ERROR_NO_MORE_ITEMS) == hr)
  101. {
  102. hr = S_OK;
  103. break;
  104. }
  105. dwIndex++;
  106. }
  107. while (hr == S_OK);
  108. RegCloseKey(hkeyEnum);
  109. }
  110. else if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
  111. {
  112. // danielwe: 403774 - If key doesn't exist, SNMP isn't installed so
  113. // we should not continue.
  114. hr = S_FALSE;
  115. }
  116. if (S_OK == hr)
  117. {
  118. *pdwNumber = dwIndex + 1;
  119. }
  120. TraceError("HrGetNextAgentNumber", (S_FALSE == hr) ? S_OK : hr);
  121. return hr;
  122. }
  123. //+---------------------------------------------------------------------------
  124. //
  125. // Function: HrAddSNMPAgent
  126. //
  127. // Purpose: Adds a service as an SNMP agent.
  128. //
  129. // Arguments:
  130. // pszServiceName [in] Name of service to add (i.e. "WINS")
  131. // pszAgentName [in] Name of the agent to add (i.e. "WINSMibAgent")
  132. // pszAgentPath [in] Path to where the agent DLL lives.
  133. // (i.e. "%SystemRoot%\System32\winsmib.dll")
  134. //
  135. // Returns: S_OK if successful, WIN32 error code otherwise.
  136. //
  137. // Author: danielwe 8 Apr 1997
  138. //
  139. // Notes:
  140. //
  141. HRESULT HrAddSNMPAgent(PCWSTR pszServiceName, PCWSTR pszAgentName,
  142. PCWSTR pszAgentPath)
  143. {
  144. HRESULT hr = S_OK;
  145. HKEY hkeySNMP;
  146. HKEY hkeyService;
  147. HKEY hkeyServices;
  148. DWORD dwNum;
  149. SNMP_REG_DATA srd = {pszAgentPath, const_cast<PCWSTR>(c_szEmpty),
  150. const_cast<PCWSTR>(c_szEmpty)};
  151. tstring strKeyAgentName;
  152. tstring strKeyAgentNameCurVer;
  153. tstring strKeyAgentNameParams;
  154. // Open HKEY_LOCAL_MACHINE\System\CCS\Services key
  155. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyServices,
  156. KEY_READ_WRITE, &hkeyServices);
  157. if (SUCCEEDED(hr))
  158. {
  159. // Open Services\SNMP key
  160. hr = HrRegOpenKeyEx(hkeyServices, c_szSNMP, KEY_READ_WRITE,
  161. &hkeySNMP);
  162. if (SUCCEEDED(hr))
  163. {
  164. hr = HrGetNextAgentNumber(pszAgentName, &dwNum);
  165. if (S_OK == hr)
  166. {
  167. // Open the Services\szService key
  168. hr = HrRegOpenKeyEx(hkeyServices, pszServiceName,
  169. KEY_READ_WRITE, &hkeyService);
  170. if (SUCCEEDED(hr))
  171. {
  172. try
  173. {
  174. // Create key name: "SOFTWARE\Microsoft\<AgentName>
  175. strKeyAgentName = c_szSoftwareKey;
  176. strKeyAgentName.append(c_szBackslash);
  177. strKeyAgentName.append(pszAgentName);
  178. // Create key name: "SNMP\Parameters\\<AgentName>
  179. strKeyAgentNameParams = c_szSNMPParams;
  180. strKeyAgentNameParams.append(c_szBackslash);
  181. strKeyAgentNameParams.append(pszAgentName);
  182. // Create key name: "SOFTWARE\Microsoft\<AgentName>\CurrentVersion
  183. // Start with "SOFTWARE\Microsoft\<AgentName> and append a
  184. // backslash and then the constant "CurrentVersion"
  185. strKeyAgentNameCurVer = strKeyAgentName;
  186. strKeyAgentNameCurVer.append(c_szBackslash);
  187. strKeyAgentNameCurVer.append(c_szCurrentVersion);
  188. }
  189. catch (bad_alloc)
  190. {
  191. hr = E_OUTOFMEMORY;
  192. }
  193. if (SUCCEEDED(hr))
  194. {
  195. static const WCHAR c_szFmt[] = L"%lu";
  196. WCHAR szAgentNumber[64];
  197. wsprintfW(szAgentNumber, c_szFmt, dwNum);
  198. srd.pszExtAgentValueName = strKeyAgentNameCurVer.c_str();
  199. REGBATCH rbSNMPData[] =
  200. {
  201. { // Software\Microsoft\AgentName
  202. HKEY_LOCAL_MACHINE,
  203. strKeyAgentName.c_str(),
  204. c_szEmpty,
  205. REG_CREATE, // Only create the key
  206. offsetof(SNMP_REG_DATA, pszEmpty),
  207. NULL
  208. },
  209. { // Software\Microsoft\AgentName\CurrentVersion
  210. HKEY_LOCAL_MACHINE,
  211. strKeyAgentNameCurVer.c_str(),
  212. c_szPathName,
  213. REG_EXPAND_SZ,
  214. offsetof(SNMP_REG_DATA, pszAgentPath),
  215. NULL
  216. },
  217. { // SNMP\Parameters\ExtensionAgents
  218. HKLM_SVCS,
  219. c_szAgentsKey,
  220. szAgentNumber,
  221. REG_SZ,
  222. offsetof(SNMP_REG_DATA, pszExtAgentValueName),
  223. NULL
  224. },
  225. };
  226. hr = HrRegWriteValues(celems(rbSNMPData),
  227. reinterpret_cast<const REGBATCH *>
  228. (&rbSNMPData),
  229. reinterpret_cast<const BYTE *>(&srd),
  230. 0, KEY_READ_WRITE);
  231. }
  232. RegCloseKey(hkeyService);
  233. }
  234. else
  235. {
  236. if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  237. {
  238. // Ok if Service key does not exist. Means it is not
  239. // installed so we do nothing and return S_OK;
  240. hr = S_OK;
  241. }
  242. }
  243. }
  244. RegCloseKey(hkeySNMP);
  245. }
  246. else
  247. {
  248. if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  249. {
  250. // Ok if SNMP key does not exist. Means it is not installed
  251. // so we do nothing and return S_OK;
  252. hr = S_OK;
  253. }
  254. }
  255. RegCloseKey(hkeyServices);
  256. }
  257. if (SUCCEEDED(hr))
  258. {
  259. hr = S_OK;
  260. }
  261. TraceError("HrAddSNMPAgent", hr);
  262. return hr;
  263. }
  264. //+---------------------------------------------------------------------------
  265. //
  266. // Function: HrRemoveSNMPAgent
  267. //
  268. // Purpose: Removes a component as an SNMP agent
  269. //
  270. // Arguments:
  271. // pszAgentName [in] Name of agent to remove (i.e. WINSMibAgent)
  272. //
  273. // Returns: S_OK for success, WIN32 error otherwise
  274. //
  275. // Author: danielwe 28 Apr 1997
  276. //
  277. // Notes: Note that *ALL* entries related to this agent are removed, not
  278. // just the first one.
  279. //
  280. HRESULT HrRemoveSNMPAgent(PCWSTR pszAgentName)
  281. {
  282. HRESULT hr = S_OK;
  283. tstring strKeyAgentName;
  284. tstring strKeyAgentNameParams;
  285. try
  286. {
  287. // Create key name: "SOFTWARE\Microsoft\<AgentName>
  288. strKeyAgentName = c_szSoftwareKey;
  289. strKeyAgentName.append(c_szBackslash);
  290. strKeyAgentName.append(pszAgentName);
  291. }
  292. catch (bad_alloc)
  293. {
  294. hr = E_OUTOFMEMORY;
  295. }
  296. if (SUCCEEDED(hr))
  297. {
  298. // Delete entire registry tree under SOFTWARE\Microsoft\<agent name>
  299. hr = HrRegDeleteKeyTree(HKEY_LOCAL_MACHINE, strKeyAgentName.c_str());
  300. if (SUCCEEDED(hr) || (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)))
  301. {
  302. try
  303. {
  304. // Delete key:
  305. // "SYSTEM\CurrentControlSet\Services\SNMP\Parameters\\<AgentName>
  306. strKeyAgentNameParams = c_szParamsKeyAbs;
  307. strKeyAgentNameParams.append(c_szBackslash);
  308. strKeyAgentNameParams.append(pszAgentName);
  309. }
  310. catch (bad_alloc)
  311. {
  312. hr = E_OUTOFMEMORY;
  313. }
  314. if (SUCCEEDED(hr) || (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)))
  315. {
  316. // BUG# 510726, Ignore any errors about registry keys or values
  317. // missing. We still want to continue to cleanup this subagent's
  318. // configuration in the registry.
  319. hr = HrRegDeleteKey(HKEY_LOCAL_MACHINE, strKeyAgentNameParams.c_str());
  320. if ((hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) || SUCCEEDED(hr))
  321. {
  322. HKEY hkeyEnum;
  323. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szAgentsKeyAbs,
  324. KEY_READ_WRITE_DELETE, &hkeyEnum);
  325. if (SUCCEEDED(hr))
  326. {
  327. DWORD dwIndex = 0;
  328. // Enumerate all values.
  329. do
  330. {
  331. WCHAR szValueName [_MAX_PATH];
  332. DWORD cchValueName = celems (szValueName);
  333. DWORD dwType;
  334. WCHAR szValueData[_MAX_PATH];
  335. DWORD cchValueData = celems (szValueData);
  336. hr = HrRegEnumValue(hkeyEnum, dwIndex,
  337. szValueName, &cchValueName,
  338. &dwType,
  339. reinterpret_cast<LPBYTE>(szValueData),
  340. &cchValueData);
  341. if (SUCCEEDED(hr))
  342. {
  343. // It's type should be REG_SZ
  344. AssertSz(REG_SZ == dwType,
  345. "HrGetNextAgentNumber: Expected a type of "
  346. "REG_SZ.");
  347. if (FIsSubstr(pszAgentName, szValueData))
  348. {
  349. // Delete value if the agent name is found in the
  350. // data. Don't break though, because there may be
  351. // duplicates for some reason so this will delete
  352. // those as well.
  353. hr = HrRegDeleteValue(hkeyEnum, szValueName);
  354. }
  355. }
  356. else if (HRESULT_FROM_WIN32 (ERROR_NO_MORE_ITEMS) == hr)
  357. {
  358. hr = S_OK;
  359. break;
  360. }
  361. dwIndex++;
  362. }
  363. while (SUCCEEDED(hr));
  364. RegCloseKey(hkeyEnum);
  365. }
  366. }
  367. }
  368. }
  369. }
  370. if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  371. {
  372. // Ignore any errors about registry keys or values missing. We don't
  373. // want them there anyway so if they're not, who cares!?!?
  374. hr = S_OK;
  375. }
  376. TraceError("HrRemoveSNMPAgent", hr);
  377. return hr;
  378. }