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.

386 lines
13 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. // Create key name: "SOFTWARE\Microsoft\<AgentName>
  173. strKeyAgentName = c_szSoftwareKey;
  174. strKeyAgentName.append(c_szBackslash);
  175. strKeyAgentName.append(pszAgentName);
  176. // Create key name: "SNMP\Parameters\\<AgentName>
  177. strKeyAgentNameParams = c_szSNMPParams;
  178. strKeyAgentNameParams.append(c_szBackslash);
  179. strKeyAgentNameParams.append(pszAgentName);
  180. // Create key name: "SOFTWARE\Microsoft\<AgentName>\CurrentVersion
  181. // Start with "SOFTWARE\Microsoft\<AgentName> and append a
  182. // backslash and then the constant "CurrentVersion"
  183. strKeyAgentNameCurVer = strKeyAgentName;
  184. strKeyAgentNameCurVer.append(c_szBackslash);
  185. strKeyAgentNameCurVer.append(c_szCurrentVersion);
  186. static const WCHAR c_szFmt[] = L"%lu";
  187. WCHAR szAgentNumber[64];
  188. wsprintfW(szAgentNumber, c_szFmt, dwNum);
  189. srd.pszExtAgentValueName = strKeyAgentNameCurVer.c_str();
  190. REGBATCH rbSNMPData[] =
  191. {
  192. { // Software\Microsoft\AgentName
  193. HKEY_LOCAL_MACHINE,
  194. strKeyAgentName.c_str(),
  195. c_szEmpty,
  196. REG_CREATE, // Only create the key
  197. offsetof(SNMP_REG_DATA, pszEmpty),
  198. NULL
  199. },
  200. { // Software\Microsoft\AgentName\CurrentVersion
  201. HKEY_LOCAL_MACHINE,
  202. strKeyAgentNameCurVer.c_str(),
  203. c_szPathName,
  204. REG_EXPAND_SZ,
  205. offsetof(SNMP_REG_DATA, pszAgentPath),
  206. NULL
  207. },
  208. { // SNMP\Parameters\ExtensionAgents
  209. HKLM_SVCS,
  210. c_szAgentsKey,
  211. szAgentNumber,
  212. REG_SZ,
  213. offsetof(SNMP_REG_DATA, pszExtAgentValueName),
  214. NULL
  215. },
  216. };
  217. hr = HrRegWriteValues(celems(rbSNMPData),
  218. reinterpret_cast<const REGBATCH *>
  219. (&rbSNMPData),
  220. reinterpret_cast<const BYTE *>(&srd),
  221. 0, KEY_READ_WRITE);
  222. RegCloseKey(hkeyService);
  223. }
  224. else
  225. {
  226. if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  227. {
  228. // Ok if Service key does not exist. Means it is not
  229. // installed so we do nothing and return S_OK;
  230. hr = S_OK;
  231. }
  232. }
  233. }
  234. RegCloseKey(hkeySNMP);
  235. }
  236. else
  237. {
  238. if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  239. {
  240. // Ok if SNMP key does not exist. Means it is not installed
  241. // so we do nothing and return S_OK;
  242. hr = S_OK;
  243. }
  244. }
  245. RegCloseKey(hkeyServices);
  246. }
  247. if (SUCCEEDED(hr))
  248. {
  249. hr = S_OK;
  250. }
  251. TraceError("HrAddSNMPAgent", hr);
  252. return hr;
  253. }
  254. //+---------------------------------------------------------------------------
  255. //
  256. // Function: HrRemoveSNMPAgent
  257. //
  258. // Purpose: Removes a component as an SNMP agent
  259. //
  260. // Arguments:
  261. // pszAgentName [in] Name of agent to remove (i.e. WINSMibAgent)
  262. //
  263. // Returns: S_OK for success, WIN32 error otherwise
  264. //
  265. // Author: danielwe 28 Apr 1997
  266. //
  267. // Notes: Note that *ALL* entries related to this agent are removed, not
  268. // just the first one.
  269. //
  270. HRESULT HrRemoveSNMPAgent(PCWSTR pszAgentName)
  271. {
  272. HRESULT hr = S_OK;
  273. tstring strKeyAgentName;
  274. tstring strKeyAgentNameParams;
  275. // Create key name: "SOFTWARE\Microsoft\<AgentName>
  276. strKeyAgentName = c_szSoftwareKey;
  277. strKeyAgentName.append(c_szBackslash);
  278. strKeyAgentName.append(pszAgentName);
  279. // Delete entire registry tree under SOFTWARE\Microsoft\<agent name>
  280. hr = HrRegDeleteKeyTree(HKEY_LOCAL_MACHINE, strKeyAgentName.c_str());
  281. if (SUCCEEDED(hr))
  282. {
  283. // Delete key:
  284. // "SYSTEM\CurrentControlSet\Services\SNMP\Parameters\\<AgentName>
  285. strKeyAgentNameParams = c_szParamsKeyAbs;
  286. strKeyAgentNameParams.append(c_szBackslash);
  287. strKeyAgentNameParams.append(pszAgentName);
  288. hr = HrRegDeleteKey(HKEY_LOCAL_MACHINE, strKeyAgentNameParams.c_str());
  289. if (SUCCEEDED(hr))
  290. {
  291. HKEY hkeyEnum;
  292. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szAgentsKeyAbs,
  293. KEY_READ_WRITE_DELETE, &hkeyEnum);
  294. if (SUCCEEDED(hr))
  295. {
  296. DWORD dwIndex = 0;
  297. // Enumerate all values.
  298. do
  299. {
  300. WCHAR szValueName [_MAX_PATH];
  301. DWORD cchValueName = celems (szValueName);
  302. DWORD dwType;
  303. WCHAR szValueData[_MAX_PATH];
  304. DWORD cchValueData = celems (szValueData);
  305. hr = HrRegEnumValue(hkeyEnum, dwIndex,
  306. szValueName, &cchValueName,
  307. &dwType,
  308. reinterpret_cast<LPBYTE>(szValueData),
  309. &cchValueData);
  310. if (SUCCEEDED(hr))
  311. {
  312. // It's type should be REG_SZ
  313. AssertSz(REG_SZ == dwType,
  314. "HrGetNextAgentNumber: Expected a type of "
  315. "REG_SZ.");
  316. if (FIsSubstr(pszAgentName, szValueData))
  317. {
  318. // Delete value if the agent name is found in the
  319. // data. Don't break though, because there may be
  320. // duplicates for some reason so this will delete
  321. // those as well.
  322. hr = HrRegDeleteValue(hkeyEnum, szValueName);
  323. }
  324. }
  325. else if (HRESULT_FROM_WIN32 (ERROR_NO_MORE_ITEMS) == hr)
  326. {
  327. hr = S_OK;
  328. break;
  329. }
  330. dwIndex++;
  331. }
  332. while (SUCCEEDED(hr));
  333. RegCloseKey(hkeyEnum);
  334. }
  335. }
  336. }
  337. if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  338. {
  339. // Ignore any errors about registry keys or values missing. We don't
  340. // want them there anyway so if they're not, who cares!?!?
  341. hr = S_OK;
  342. }
  343. TraceError("HrRemoveSNMPAgent", hr);
  344. return hr;
  345. }