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.

650 lines
17 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: N E T O C X . C P P
  7. //
  8. // Contents: Custom installation functions for various optional
  9. // components.
  10. //
  11. // Notes:
  12. //
  13. // Author: danielwe 19 Jun 1997
  14. //
  15. //----------------------------------------------------------------------------
  16. #include "pch.h"
  17. #pragma hdrstop
  18. #include "netoc.h"
  19. #include "netocx.h"
  20. #include "ncmisc.h"
  21. #include "ncreg.h"
  22. #include "ncsetup.h"
  23. #include "ncsvc.h"
  24. #include "snmpocx.h"
  25. static const WCHAR c_szFileSpec[] = L"*.*";
  26. static const WCHAR c_szWinsPath[] = L"\\wins";
  27. static const WCHAR c_szRegKeyWinsParams[] = L"System\\CurrentControlSet\\Services\\WINS\\Parameters";
  28. static const WCHAR c_szRegValWinsBackupDir[] = L"BackupDirPath";
  29. //+---------------------------------------------------------------------------
  30. //
  31. // Function: HrOcExtWINS
  32. //
  33. // Purpose: NetOC external message handler
  34. //
  35. // Arguments:
  36. // pnocd []
  37. // uMsg []
  38. // wParam []
  39. // lParam []
  40. //
  41. // Returns:
  42. //
  43. // Author: danielwe 17 Sep 1998
  44. //
  45. // Notes:
  46. //
  47. HRESULT HrOcExtWINS(PNETOCDATA pnocd, UINT uMsg,
  48. WPARAM wParam, LPARAM lParam)
  49. {
  50. HRESULT hr = S_OK;
  51. Assert(pnocd);
  52. switch (uMsg)
  53. {
  54. case NETOCM_POST_INSTALL:
  55. hr = HrOcWinsOnInstall(pnocd);
  56. break;
  57. }
  58. TraceError("HrOcExtWINS", hr);
  59. return hr;
  60. }
  61. //+---------------------------------------------------------------------------
  62. //
  63. // Function: HrOcExtDNS
  64. //
  65. // Purpose: NetOC external message handler
  66. //
  67. // Arguments:
  68. // pnocd []
  69. // uMsg []
  70. // wParam []
  71. // lParam []
  72. //
  73. // Returns:
  74. //
  75. // Author: danielwe 17 Sep 1998
  76. //
  77. // Notes:
  78. //
  79. HRESULT HrOcExtDNS(PNETOCDATA pnocd, UINT uMsg,
  80. WPARAM wParam, LPARAM lParam)
  81. {
  82. HRESULT hr = S_OK;
  83. Assert(pnocd);
  84. switch (uMsg)
  85. {
  86. case NETOCM_POST_INSTALL:
  87. hr = HrOcDnsOnInstall(pnocd);
  88. break;
  89. }
  90. TraceError("HrOcExtDNS", hr);
  91. return hr;
  92. }
  93. //+---------------------------------------------------------------------------
  94. //
  95. // Function: HrOcExtSNMP
  96. //
  97. // Purpose: NetOC external message handler
  98. //
  99. // Arguments:
  100. // pnocd []
  101. // uMsg []
  102. // wParam []
  103. // lParam []
  104. //
  105. // Returns:
  106. //
  107. // Author: danielwe 17 Sep 1998
  108. //
  109. // Notes:
  110. //
  111. HRESULT HrOcExtSNMP(PNETOCDATA pnocd, UINT uMsg,
  112. WPARAM wParam, LPARAM lParam)
  113. {
  114. HRESULT hr = S_OK;
  115. Assert(pnocd);
  116. switch (uMsg)
  117. {
  118. case NETOCM_POST_INSTALL:
  119. hr = HrOcSnmpOnInstall(pnocd);
  120. break;
  121. }
  122. TraceError("HrOcExtSNMP", hr);
  123. return hr;
  124. }
  125. //+---------------------------------------------------------------------------
  126. //
  127. // Function: HrSetWinsServiceRecoveryOption
  128. //
  129. // Purpose: Sets the recovery options for the WINS service
  130. //
  131. // Arguments:
  132. // pnocd [in] Pointer to NETOC data.
  133. //
  134. // Returns: S_OK if successful, Win32 error otherwise.
  135. //
  136. // Author: danielwe 26 May 1999
  137. //
  138. // Notes:
  139. //
  140. HRESULT HrSetWinsServiceRecoveryOption(PNETOCDATA pnocd)
  141. {
  142. CServiceManager sm;
  143. CService service;
  144. HRESULT hr = S_OK;
  145. SC_ACTION sra [4] =
  146. {
  147. { SC_ACTION_RESTART, 15*1000 }, // restart after 15 seconds
  148. { SC_ACTION_RESTART, 15*1000 }, // restart after 15 seconds
  149. { SC_ACTION_RESTART, 15*1000 }, // restart after 15 seconds
  150. { SC_ACTION_NONE, 30*1000 },
  151. };
  152. SERVICE_FAILURE_ACTIONS sfa =
  153. {
  154. 60 * 60, // dwResetPeriod is 1 hr
  155. L"", // no reboot message
  156. L"", // no command to execute
  157. 4, // 3 attempts to restart the server and stop after that
  158. sra
  159. };
  160. hr = sm.HrOpenService(&service, L"WINS");
  161. if (S_OK == hr)
  162. {
  163. hr = service.HrSetServiceRestartRecoveryOption(&sfa);
  164. }
  165. TraceError("HrSetWinsServiceRecoveryOption", hr);
  166. return hr;
  167. }
  168. //+---------------------------------------------------------------------------
  169. //
  170. // Function: HrOcWinsOnInstall
  171. //
  172. // Purpose: Called by optional components installer code to handle
  173. // additional installation requirements for WINS Server.
  174. //
  175. // Arguments:
  176. // pnocd [in] Pointer to NETOC data.
  177. //
  178. // Returns: S_OK if successful, Win32 error otherwise.
  179. //
  180. // Author: danielwe 19 Jun 1997
  181. //
  182. // Notes:
  183. //
  184. HRESULT HrOcWinsOnInstall(PNETOCDATA pnocd)
  185. {
  186. HRESULT hr = S_OK;
  187. if (pnocd->eit == IT_INSTALL)
  188. {
  189. hr = HrHandleStaticIpDependency(pnocd);
  190. if (SUCCEEDED(hr))
  191. {
  192. hr = HrSetWinsServiceRecoveryOption(pnocd);
  193. }
  194. }
  195. else if (pnocd->eit == IT_UPGRADE)
  196. {
  197. HKEY hkey;
  198. // Upgrade the BackupDirPath value from whatever it was to
  199. // REG_EXPAND_SZ
  200. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyWinsParams,
  201. KEY_ALL_ACCESS, &hkey);
  202. if (SUCCEEDED(hr))
  203. {
  204. DWORD dwType;
  205. LPBYTE pbData = NULL;
  206. DWORD cbData;
  207. hr = HrRegQueryValueWithAlloc(hkey, c_szRegValWinsBackupDir,
  208. &dwType, &pbData, &cbData);
  209. if (SUCCEEDED(hr))
  210. {
  211. switch (dwType)
  212. {
  213. case REG_MULTI_SZ:
  214. case REG_SZ:
  215. PWSTR pszNew;
  216. // This cast will give us the first string of the MULTI_SZ
  217. pszNew = reinterpret_cast<PWSTR>(pbData);
  218. TraceTag(ttidNetOc, "Resetting %S to %S",
  219. c_szRegValWinsBackupDir, pszNew);
  220. hr = HrRegSetSz(hkey, c_szRegValWinsBackupDir, pszNew);
  221. break;
  222. }
  223. MemFree(pbData);
  224. }
  225. RegCloseKey(hkey);
  226. }
  227. // This process is non-fatal
  228. TraceError("HrOcWinsOnInstall - Failed to upgrade BackupDirPath - "
  229. "non-fatal", hr);
  230. // overwrite hr on purpose
  231. hr = HrSetWinsServiceRecoveryOption(pnocd);
  232. }
  233. else if (pnocd->eit == IT_REMOVE)
  234. {
  235. WCHAR szWinDir[MAX_PATH];
  236. if (GetSystemDirectory(szWinDir, celems(szWinDir)))
  237. {
  238. lstrcatW(szWinDir, c_szWinsPath);
  239. // szWinDir should now be something like c:\winnt\system32\wins
  240. hr = HrDeleteFileSpecification(c_szFileSpec, szWinDir);
  241. }
  242. else
  243. {
  244. hr = HrFromLastWin32Error();
  245. }
  246. if (FAILED(hr))
  247. {
  248. TraceError("HrOcWinsOnInstall: failed to delete files, continuing...",
  249. hr);
  250. hr = S_OK;
  251. }
  252. }
  253. TraceError("HrOcWinsOnInstall", hr);
  254. return hr;
  255. }
  256. //+---------------------------------------------------------------------------
  257. //
  258. // Function: HrOcDnsOnInstall
  259. //
  260. // Purpose: Called by optional components installer code to handle
  261. // additional installation requirements for DNS Server.
  262. //
  263. // Arguments:
  264. // pnocd [in] Pointer to NETOC data.
  265. //
  266. // Returns: S_OK if successful, Win32 error otherwise.
  267. //
  268. // Author: danielwe 19 Jun 1997
  269. //
  270. // Notes:
  271. //
  272. HRESULT HrOcDnsOnInstall(PNETOCDATA pnocd)
  273. {
  274. HRESULT hr = S_OK;
  275. if (pnocd->eit == IT_INSTALL)
  276. {
  277. hr = HrHandleStaticIpDependency(pnocd);
  278. }
  279. TraceError("HrOcDnsOnInstall", hr);
  280. return hr;
  281. }
  282. //+---------------------------------------------------------------------------
  283. //
  284. // Function: HrOcSnmpAgent
  285. //
  286. // Purpose: Installs the SNMP agent parameters
  287. //
  288. // Arguments:
  289. // pnocd [in] Pointer to NETOC data.
  290. //
  291. // Returns: S_OK if successful, Win32 error otherwise.
  292. //
  293. // Author: FlorinT 10/05/1998
  294. //
  295. // Notes:
  296. //
  297. HRESULT HrOcSnmpAgent(PNETOCDATA pnocd)
  298. {
  299. tstring tstrVariable;
  300. PWSTR pTstrArray = NULL;
  301. HRESULT hr;
  302. // Read SNMP answer file params and save them to the registry
  303. //-------- read the 'Contact Name' parameter
  304. hr = HrSetupGetFirstString(g_ocmData.hinfAnswerFile,
  305. AF_SECTION,
  306. AF_SYSNAME,
  307. &tstrVariable);
  308. if (hr == S_OK)
  309. {
  310. hr = SnmpRegWriteTstring(REG_KEY_AGENT,
  311. SNMP_CONTACT,
  312. tstrVariable);
  313. }
  314. if (hr == S_OK || hr == HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND))
  315. {
  316. //-------- read the 'Location' parameter
  317. hr = HrSetupGetFirstString(g_ocmData.hinfAnswerFile,
  318. AF_SECTION,
  319. AF_SYSLOCATION,
  320. &tstrVariable);
  321. }
  322. if (hr == S_OK)
  323. {
  324. hr = SnmpRegWriteTstring(REG_KEY_AGENT,
  325. SNMP_LOCATION,
  326. tstrVariable);
  327. }
  328. if (hr == S_OK || hr == HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND))
  329. {
  330. //-------- read the 'Service' parameter
  331. hr = HrSetupGetFirstMultiSzFieldWithAlloc(g_ocmData.hinfAnswerFile,
  332. AF_SECTION,
  333. AF_SYSSERVICES,
  334. &pTstrArray);
  335. }
  336. if (hr == S_OK)
  337. {
  338. DWORD dwServices = SnmpStrArrayToServices(pTstrArray);
  339. delete pTstrArray;
  340. hr = SnmpRegWriteDword(REG_KEY_AGENT,
  341. SNMP_SERVICES,
  342. dwServices);
  343. }
  344. return (hr == HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND)) ? S_OK : hr;
  345. }
  346. //+---------------------------------------------------------------------------
  347. //
  348. // Function: HrOcSnmpTraps
  349. //
  350. // Purpose: Installs the traps SNMP parameters defined in the answer file
  351. //
  352. // Arguments:
  353. // pnocd [in] Pointer to NETOC data.
  354. //
  355. // Returns: S_OK if successful, Win32 error otherwise.
  356. //
  357. // Author: FlorinT 10/05/1998
  358. //
  359. // Notes:
  360. //
  361. HRESULT HrOcSnmpTraps(PNETOCDATA pnocd)
  362. {
  363. tstring tstrVariable;
  364. PWSTR pTstrArray = NULL;
  365. HRESULT hr;
  366. // Read SNMP answer file params and save them to the registry
  367. //-------- read the 'Trap community' parameter
  368. hr = HrSetupGetFirstString(g_ocmData.hinfAnswerFile,
  369. AF_SECTION,
  370. AF_TRAPCOMMUNITY,
  371. &tstrVariable);
  372. if (hr == S_OK)
  373. {
  374. //-------- read the 'Trap destinations' parameter
  375. HrSetupGetFirstMultiSzFieldWithAlloc(g_ocmData.hinfAnswerFile,
  376. AF_SECTION,
  377. AF_TRAPDEST,
  378. &pTstrArray);
  379. hr = SnmpRegWriteTraps(tstrVariable, pTstrArray);
  380. delete pTstrArray;
  381. }
  382. return (hr == HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND)) ? S_OK : hr;
  383. }
  384. // bitmask values for 'pFlag' parameter for HrOcSnmpSecurity()
  385. // they indicate which of the SNMP SECuritySETtings were defined through
  386. // the answerfile.
  387. #define SNMP_SECSET_COMMUNITIES 0x00000001
  388. #define SNMP_SECSET_AUTHFLAG 0x00000002
  389. #define SNMP_SECSET_PERMMGR 0x00000004
  390. //+---------------------------------------------------------------------------
  391. //
  392. // Function: HrOcSnmpSecurituy
  393. //
  394. // Purpose: Installs the security SNMP parameters defined in the answer file
  395. //
  396. // Arguments:
  397. // pnocd [in] Pointer to NETOC data.
  398. //
  399. // Returns: S_OK if successful, Win32 error otherwise.
  400. //
  401. // Author: FlorinT 10/05/1998
  402. //
  403. // Notes:
  404. //
  405. HRESULT HrOcSnmpSecurity(PNETOCDATA pnocd, DWORD *pFlags)
  406. {
  407. BOOL bVariable = FALSE;
  408. PWSTR pTstrArray = NULL;
  409. HRESULT hr;
  410. // Read SNMP answer file params and save them to the registry
  411. //-------- read the 'Accepted communities' parameter
  412. hr = HrSetupGetFirstMultiSzFieldWithAlloc(g_ocmData.hinfAnswerFile,
  413. AF_SECTION,
  414. AF_ACCEPTCOMMNAME,
  415. &pTstrArray);
  416. if (hr == S_OK)
  417. {
  418. if (pFlags)
  419. (*pFlags) |= SNMP_SECSET_COMMUNITIES;
  420. hr = SnmpRegWriteCommunities(pTstrArray);
  421. delete pTstrArray;
  422. }
  423. if (hr == S_OK || hr == HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND))
  424. {
  425. //-------- read the 'EnableAuthenticationTraps' parameter
  426. hr = HrSetupGetFirstStringAsBool(g_ocmData.hinfAnswerFile,
  427. AF_SECTION,
  428. AF_SENDAUTH,
  429. &bVariable);
  430. if (hr == S_OK)
  431. {
  432. if (pFlags)
  433. (*pFlags) |= SNMP_SECSET_AUTHFLAG;
  434. hr = SnmpRegWriteDword(REG_KEY_SNMP_PARAMETERS,
  435. REG_VALUE_AUTHENTICATION_TRAPS,
  436. bVariable);
  437. }
  438. }
  439. if (hr == S_OK || hr == HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND))
  440. {
  441. //-------- read the 'Permitted Managers' parameter
  442. hr = HrSetupGetFirstStringAsBool(g_ocmData.hinfAnswerFile,
  443. AF_SECTION,
  444. AF_ANYHOST,
  445. &bVariable);
  446. }
  447. if (hr == S_OK)
  448. {
  449. pTstrArray = NULL;
  450. // if not 'any host', get the list of hosts from the inf file
  451. if (bVariable == FALSE)
  452. {
  453. hr = HrSetupGetFirstMultiSzFieldWithAlloc(g_ocmData.hinfAnswerFile,
  454. AF_SECTION,
  455. AF_LIMITHOST,
  456. &pTstrArray);
  457. }
  458. // at least clear up the 'permitted managers' list (bVariable = TRUE)
  459. // at most, write the allowed managers to the registry
  460. if (hr == S_OK)
  461. {
  462. if (pFlags)
  463. (*pFlags) |= SNMP_SECSET_PERMMGR;
  464. hr = SnmpRegWritePermittedMgrs(bVariable, pTstrArray);
  465. }
  466. if (pTstrArray != NULL)
  467. delete pTstrArray;
  468. }
  469. return (hr == HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND)) ? S_OK : hr;
  470. }
  471. //+---------------------------------------------------------------------------
  472. //
  473. // Function: HrOcSnmpDefCommunity
  474. //
  475. // Purpose: Installs the default SNMP community.
  476. //
  477. // Arguments:
  478. // pnocd [in] Pointer to NETOC data.
  479. //
  480. // Returns: S_OK if successful, Win32 error otherwise.
  481. //
  482. // Author: FlorinT 10/05/1998
  483. //
  484. // Notes:
  485. //
  486. HRESULT HrOcSnmpDefCommunity(PNETOCDATA pnocd)
  487. {
  488. HRESULT hr = S_OK;
  489. hr = SnmpRegWriteDefCommunity();
  490. return hr;
  491. }
  492. //+---------------------------------------------------------------------------
  493. //
  494. // Function: HrOcSnmpUpgParams
  495. //
  496. // Purpose: makes all the registry changes needed when upgrading to Win2K
  497. //
  498. // Arguments:
  499. // pnocd [in] Pointer to NETOC data.
  500. //
  501. // Returns: S_OK if successful, Win32 error otherwise.
  502. //
  503. // Author: FlorinT 10/05/1998
  504. //
  505. // Notes:
  506. //
  507. HRESULT HrOcSnmpUpgParams(PNETOCDATA pnocd)
  508. {
  509. HRESULT hr = S_OK;
  510. hr = SnmpRegUpgEnableAuthTraps();
  511. return hr;
  512. }
  513. //+---------------------------------------------------------------------------
  514. //
  515. // Function: HrOcSnmpOnInstall
  516. //
  517. // Purpose: Called by optional components installer code to handle
  518. // additional installation requirements for SNMP.
  519. //
  520. // Arguments:
  521. // pnocd [in] Pointer to NETOC data.
  522. //
  523. // Returns: S_OK if successful, Win32 error otherwise.
  524. //
  525. // Author: danielwe 15 Sep 1998
  526. //
  527. // Notes:
  528. //
  529. HRESULT HrOcSnmpOnInstall(PNETOCDATA pnocd)
  530. {
  531. HRESULT hr = S_OK;
  532. DWORD secFlags = 0;
  533. if ((pnocd->eit == IT_INSTALL) | (pnocd->eit == IT_UPGRADE))
  534. {
  535. // --ft:10/14/98-- bug #237203 - success if there is no answer file!
  536. if (g_ocmData.hinfAnswerFile != NULL)
  537. {
  538. hr = HrOcSnmpSecurity(pnocd, &secFlags);
  539. if (hr == S_OK)
  540. hr = HrOcSnmpTraps(pnocd);
  541. if (hr == S_OK)
  542. hr = HrOcSnmpAgent(pnocd);
  543. }
  544. }
  545. // configure the 'public' community as a read-only community only if:
  546. // fresh installing and (there is no answer_file or there is an answer_file but it doesn't
  547. // configure any community)
  548. if (hr == S_OK && pnocd->eit == IT_INSTALL && !(secFlags & SNMP_SECSET_COMMUNITIES))
  549. {
  550. hr = HrOcSnmpDefCommunity(pnocd);
  551. }
  552. // on upgrade only look at the old EnableAuthTraps value and copy it to the new location
  553. if (hr == S_OK && pnocd->eit == IT_UPGRADE)
  554. {
  555. // don't care here about the return code. The upgrade from W2K to W2K fail here and we
  556. // don't need to fail in this case. Any failure in upgrading the setting from NT4 to W2K
  557. // will result in having the default parameter.
  558. HrOcSnmpUpgParams(pnocd);
  559. }
  560. if (hr == S_OK && (pnocd->eit == IT_INSTALL || pnocd->eit == IT_UPGRADE) )
  561. {
  562. // set admin dacl to ValidCommunities subkey
  563. hr = SnmpAddAdminAclToKey(REG_KEY_VALID_COMMUNITIES);
  564. if (hr == S_OK)
  565. {
  566. // set admin dacl to PermittedManagers subkey
  567. hr = SnmpAddAdminAclToKey(REG_KEY_PERMITTED_MANAGERS);
  568. }
  569. }
  570. TraceError("HrOcSnmpOnInstall", hr);
  571. return (hr == HRESULT_FROM_SETUPAPI(ERROR_SECTION_NOT_FOUND)) ? S_OK : hr;
  572. }