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.

712 lines
21 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: S R V R O B J . C P P
  7. //
  8. // Contents: Implementation of CSrvrcfg and helper functions.
  9. //
  10. // Notes:
  11. //
  12. // Author: danielwe 5 Mar 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "srvrobj.h"
  18. #include "ncerror.h"
  19. #include "ncperms.h"
  20. #include "ncreg.h"
  21. #include "ncsetup.h"
  22. #include "ncsvc.h"
  23. #include "afilestr.h"
  24. static const WCHAR c_szRegKeyServerParams[] = L"System\\CurrentControlSet\\Services\\LanmanServer\\Parameters";
  25. static const WCHAR c_szRegKeyServerShares[] = L"System\\CurrentControlSet\\Services\\LanmanServer\\Shares";
  26. static const WCHAR c_szRegKeyServerAutoTuned[] = L"System\\CurrentControlSet\\Services\\LanmanServer\\AutotunedParameters";
  27. //+---------------------------------------------------------------------------
  28. //
  29. // Member: CSrvrcfg::CSrvrcfg
  30. //
  31. // Purpose: Constructs the CSrvrcfg object.
  32. //
  33. // Arguments:
  34. // (none)
  35. //
  36. // Returns: Nothing.
  37. //
  38. // Author: danielwe 5 Mar 1997
  39. //
  40. // Notes:
  41. //
  42. CSrvrcfg::CSrvrcfg()
  43. :
  44. m_hkeyMM(NULL),
  45. m_fDirty(FALSE),
  46. m_pncc(NULL),
  47. m_fOneTimeInstall(FALSE),
  48. m_fRestoredRegistry(FALSE),
  49. m_fUpgradeFromWks(FALSE),
  50. m_fUpgrade(FALSE)
  51. {
  52. ZeroMemory(&m_apspObj, sizeof(m_apspObj));
  53. ZeroMemory(&m_sdd, sizeof(m_sdd));
  54. }
  55. //
  56. // INetCfgComponentControl
  57. //
  58. //+---------------------------------------------------------------------------
  59. //
  60. // Member: CSrvrcfg::Initialize
  61. //
  62. // Purpose: Called when we are initialized.
  63. //
  64. // Arguments:
  65. // pnccItem [in] Component we belong to.
  66. // pnc [in] INetCfg master object if we need it.
  67. // fInstalling [in] TRUE if we are being installed, FALSE otherwise.
  68. //
  69. // Returns: HRESULT, Error code.
  70. //
  71. // Author: danielwe 22 Mar 1997
  72. //
  73. // Notes:
  74. //
  75. STDMETHODIMP CSrvrcfg::Initialize(INetCfgComponent* pnccItem, INetCfg *pnc,
  76. BOOL fInstalling)
  77. {
  78. Validate_INetCfgNotify_Initialize(pnccItem, pnc, fInstalling);
  79. m_pncc = pnccItem;
  80. AddRefObj(m_pncc);
  81. GetProductFlavor(NULL, &m_pf);
  82. HRESULT hr = HrOpenRegKeys(pnc);
  83. if (SUCCEEDED(hr))
  84. {
  85. hr = HrGetRegistryInfo(fInstalling);
  86. }
  87. Validate_INetCfgNotify_Initialize_Return(hr);
  88. TraceError("CSrvrcfg::Initialize", hr);
  89. return hr;
  90. }
  91. STDMETHODIMP CSrvrcfg::Validate()
  92. {
  93. return S_OK;
  94. }
  95. STDMETHODIMP CSrvrcfg::CancelChanges()
  96. {
  97. return S_OK;
  98. }
  99. //+---------------------------------------------------------------------------
  100. //
  101. // Member: CSrvrcfg::Apply
  102. //
  103. // Purpose: Called when changes to this component should be applied.
  104. //
  105. // Arguments:
  106. // (none)
  107. //
  108. // Returns: HRESULT, Error code.
  109. //
  110. // Author: danielwe 5 Mar 1997
  111. //
  112. // Notes:
  113. //
  114. STDMETHODIMP CSrvrcfg::ApplyRegistryChanges()
  115. {
  116. HRESULT hr = S_OK;
  117. static const WCHAR c_szLicenseSvc[] = L"LicenseService";
  118. if (m_fUpgrade)
  119. {
  120. TraceTag(ttidSrvrCfg, "Upgrading MS_SERVER");
  121. if (!m_fRestoredRegistry)
  122. {
  123. TraceTag(ttidSrvrCfg, "Restoring registry");
  124. hr = HrRestoreRegistry();
  125. if (FAILED(hr))
  126. {
  127. TraceError("CSrvrcfg::ApplyRegistryChanges - HrRestoreRegistry - non-fatal",
  128. hr);
  129. hr = S_OK;
  130. }
  131. }
  132. }
  133. if (SUCCEEDED(hr))
  134. {
  135. if (m_fDirty)
  136. {
  137. hr = HrSetRegistryInfo();
  138. }
  139. if (SUCCEEDED(hr))
  140. {
  141. if (m_fOneTimeInstall)
  142. {
  143. /*
  144. hr = HrChangeServiceStartTypeOptional(c_szLicenseSvc,
  145. SERVICE_AUTO_START);
  146. if (SUCCEEDED(hr))
  147. {
  148. hr = S_OK;
  149. m_fDirty = FALSE;
  150. m_fOneTimeInstall = FALSE;
  151. }
  152. */
  153. }
  154. }
  155. }
  156. Validate_INetCfgNotify_Apply_Return(hr);
  157. TraceError("CSrvrcfg::ApplyRegistryChanges",
  158. (hr == S_FALSE) ? S_OK : hr);
  159. return hr;
  160. }
  161. //
  162. // INetCfgComponentSetup
  163. //
  164. //+---------------------------------------------------------------------------
  165. //
  166. // Member: CSrvrcfg::Install
  167. //
  168. // Purpose: Called when this component is being installed
  169. //
  170. // Arguments:
  171. // dwSetupFlags [in] Flags that describe the type of setup
  172. //
  173. // Returns: HRESULT, Error code.
  174. //
  175. // Author: danielwe 5 Mar 1997
  176. //
  177. // Notes:
  178. //
  179. STDMETHODIMP CSrvrcfg::Install(DWORD dwSetupFlags)
  180. {
  181. m_fDirty = TRUE;
  182. m_fOneTimeInstall = TRUE;
  183. if (dwSetupFlags & NSF_WINNT_WKS_UPGRADE)
  184. {
  185. m_fUpgrade = TRUE;
  186. m_fUpgradeFromWks = TRUE;
  187. }
  188. else if ((dwSetupFlags & NSF_WINNT_SVR_UPGRADE) ||
  189. (dwSetupFlags & NSF_WINNT_SBS_UPGRADE))
  190. {
  191. m_fUpgrade = TRUE;
  192. }
  193. return S_OK;
  194. }
  195. STDMETHODIMP CSrvrcfg::Upgrade(DWORD dwSetupFlags,
  196. DWORD dwUpgradeFomBuildNo)
  197. {
  198. return S_FALSE;
  199. }
  200. //+---------------------------------------------------------------------------
  201. //
  202. // Member: CSrvrcfg::ReadAnswerFile
  203. //
  204. // Purpose: Reads the appropriate fields from the given answer file into
  205. // our in-memory state.
  206. //
  207. // Arguments:
  208. // pszAnswerFile [in] File name of answer file
  209. // pszAnswerSection [in] Section of answer file to look in
  210. //
  211. // Returns: S_OK if successful, OLE or Win32 error otherwise
  212. //
  213. // Author: danielwe 30 Oct 1997
  214. //
  215. // Notes:
  216. //
  217. STDMETHODIMP CSrvrcfg::ReadAnswerFile(PCWSTR pszAnswerFile,
  218. PCWSTR pszAnswerSection)
  219. {
  220. HRESULT hr = S_OK;
  221. if (pszAnswerSection && pszAnswerFile)
  222. {
  223. // There's an answer file. We must process it now.
  224. hr = HrProcessAnswerFile(pszAnswerFile, pszAnswerSection);
  225. if (FAILED(hr))
  226. {
  227. TraceError("CSrvrcfg::ReadAnswerFile- Answer file has "
  228. "errors. Defaulting all information as if "
  229. "answer file did not exist.",
  230. NETSETUP_E_ANS_FILE_ERROR);
  231. hr = S_OK;
  232. }
  233. }
  234. TraceError("CSrvrcfg::ReadAnswerFile", hr);
  235. return hr;
  236. }
  237. STDMETHODIMP CSrvrcfg::Removing()
  238. {
  239. return S_OK;
  240. }
  241. //+---------------------------------------------------------------------------
  242. //
  243. // Member: CSrvrcfg::HrRestoreRegistry
  244. //
  245. // Purpose: Restores the contents of the registry for this component
  246. //
  247. // Arguments:
  248. // (none)
  249. //
  250. // Returns: Win32 error if failed, otherwise S_OK
  251. //
  252. // Author: danielwe 8 Aug 1997
  253. //
  254. // Notes:
  255. //
  256. HRESULT CSrvrcfg::HrRestoreRegistry()
  257. {
  258. HRESULT hr = S_OK;
  259. HKEY hkey;
  260. TOKEN_PRIVILEGES * ptpRestore = NULL;
  261. BOOL fRestoreSucceeded = FALSE;
  262. if (!m_strParamsRestoreFile.empty() ||
  263. !m_strSharesRestoreFile.empty() ||
  264. !m_strAutoTunedRestoreFile.empty())
  265. {
  266. hr = HrEnableAllPrivileges(&ptpRestore);
  267. if (SUCCEEDED(hr))
  268. {
  269. if (!m_strParamsRestoreFile.empty())
  270. {
  271. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyServerParams,
  272. KEY_ALL_ACCESS, &hkey);
  273. if (SUCCEEDED(hr))
  274. {
  275. hr = HrRegRestoreKey(hkey, m_strParamsRestoreFile.c_str(),
  276. 0);
  277. if (FAILED(hr))
  278. {
  279. TraceError("CSrvrcfg::HrRestoreRegistry - HrRestoreRegistry for "
  280. "Parameters", hr);
  281. hr = S_OK;
  282. }
  283. else
  284. {
  285. fRestoreSucceeded = TRUE;
  286. }
  287. RegCloseKey(hkey);
  288. }
  289. }
  290. if (fRestoreSucceeded)
  291. {
  292. // if the restore succeeded, rewrite the values that were blown
  293. // away by the restore
  294. static const WCHAR c_szSvcDLLName[] = L"%SystemRoot%\\System32\\srvsvc.dll";
  295. static const WCHAR c_szServiceDll[] = L"ServiceDll";
  296. HKEY hkResult = NULL;
  297. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyServerParams, KEY_ALL_ACCESS, &hkResult);
  298. if SUCCEEDED(hr)
  299. {
  300. hr = HrRegSetValueEx(hkResult, c_szServiceDll, REG_EXPAND_SZ, (const BYTE *)c_szSvcDLLName, CbOfMultiSzAndTermSafe(c_szSvcDLLName));
  301. }
  302. if FAILED(hr)
  303. {
  304. TraceError("CSrvrcfg::HrRestoreRegistry - HrRestoreRegistry for "
  305. "ServiceDll", hr);
  306. hr = S_OK;
  307. }
  308. //
  309. // The following key has to be set here because of new changes introduced
  310. // by SCE (Security Configuration Engine). SCE runs early in GUI mode setup to
  311. // set out-of-the-box security by setting some registry values. During NT4
  312. // upgrades we don't see those registry values set because during NT4 upgrades,
  313. // some services including Lanmanserver and Netlogon gets deleted and reinstalled
  314. // for PnP requirements. To maintain the services configuration between deleting
  315. // and reinstalling, some of their Keys including the "Parameters" keys for
  316. // LanManServer and Netlogon get backed up early during upgrade and restored
  317. // later with the service installation. This backing up and restoring action
  318. // happens through the services own notify objects (like this one). The problem
  319. // is, backing up of the Keys happens before SCE sets the values in those keys and
  320. // they get restored after SCE sets the values. So we lose the values set. So, we
  321. // are setting those keys here separately to the secure values.
  322. // See Windows Raid bug #691952 for more details.
  323. //
  324. static const WCHAR c_szRestrictNullSessAccess[] = L"RestrictNullSessAccess";
  325. DWORD value = 1;
  326. hr = HrRegSetValueEx(hkey, c_szRestrictNullSessAccess, REG_DWORD, (const BYTE *)&value, 4);
  327. if (FAILED(hr))
  328. {
  329. TraceError("CSrvrcfg::HrRestoreRegistry - setting RestrictNullSessAccess to DWORD 1 failed", hr);
  330. hr = S_OK;
  331. }
  332. RegSafeCloseKey(hkResult);
  333. static const WCHAR c_szTrkWks[] = L"TrkWks";
  334. static const WCHAR c_szTrkSrv[] = L"TrkSrv";
  335. static const WCHAR c_szNullSession[] = L"NullSessionPipes";
  336. hr = HrRegAddStringToMultiSz(c_szTrkWks,
  337. HKEY_LOCAL_MACHINE,
  338. c_szRegKeyServerParams,
  339. c_szNullSession,
  340. STRING_FLAG_ENSURE_AT_END,
  341. 0);
  342. if (SUCCEEDED(hr))
  343. {
  344. hr = HrRegAddStringToMultiSz(c_szTrkSrv,
  345. HKEY_LOCAL_MACHINE,
  346. c_szRegKeyServerParams,
  347. c_szNullSession,
  348. STRING_FLAG_ENSURE_AT_END,
  349. 0);
  350. }
  351. if (FAILED(hr))
  352. {
  353. TraceError("CSrvrcfg::HrRestoreRegistry - Error replacing "
  354. "values for Parameters", hr);
  355. hr = S_OK;
  356. }
  357. }
  358. if (!m_strSharesRestoreFile.empty())
  359. {
  360. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyServerShares,
  361. KEY_ALL_ACCESS, &hkey);
  362. if (SUCCEEDED(hr))
  363. {
  364. hr = HrRegRestoreKey(hkey, m_strSharesRestoreFile.c_str(),
  365. 0);
  366. if (FAILED(hr))
  367. {
  368. TraceError("CSrvrcfg::HrRestoreRegistry - HrRestoreRegistry for "
  369. "Shares", hr);
  370. hr = S_OK;
  371. }
  372. RegCloseKey(hkey);
  373. }
  374. }
  375. if (!m_strAutoTunedRestoreFile.empty())
  376. {
  377. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyServerAutoTuned,
  378. KEY_ALL_ACCESS, &hkey);
  379. if (SUCCEEDED(hr))
  380. {
  381. hr = HrRegRestoreKey(hkey, m_strAutoTunedRestoreFile.c_str(),
  382. 0);
  383. if (FAILED(hr))
  384. {
  385. TraceError("CSrvrcfg::HrRestoreRegistry - HrRestoreRegistry for "
  386. "AutotunedParameters", hr);
  387. hr = S_OK;
  388. }
  389. RegCloseKey(hkey);
  390. }
  391. }
  392. hr = HrRestorePrivileges(ptpRestore);
  393. delete [] reinterpret_cast<BYTE *>(ptpRestore);
  394. // Set a flag so we don't do this again if we are applied again
  395. m_fRestoredRegistry = TRUE;
  396. }
  397. }
  398. else
  399. {
  400. TraceTag(ttidSrvrCfg, "WARNING: HrRestoreRegistry() was called without"
  401. " ReadAnswerFile() being called!");
  402. }
  403. TraceError("CSrvrcfg::HrRestoreRegistry", hr);
  404. return hr;
  405. }
  406. //+---------------------------------------------------------------------------
  407. //
  408. // Member: CSrvrcfg::HrProcessAnswerFile
  409. //
  410. // Purpose: Handles necessary processing of contents of the answer file.
  411. //
  412. // Arguments:
  413. // pszAnswerFile [in] Filename of answer file for upgrade.
  414. // pszAnswerSection [in] Comma-separated list of sections in the
  415. // file appropriate to this component.
  416. //
  417. // Returns: S_OK if successful, setup API error otherwise.
  418. //
  419. // Author: danielwe 8 May 1997
  420. //
  421. // Notes:
  422. //
  423. HRESULT CSrvrcfg::HrProcessAnswerFile(PCWSTR pszAnswerFile,
  424. PCWSTR pszAnswerSection)
  425. {
  426. HRESULT hr = S_OK;
  427. tstring strOpt;
  428. PCWSTR szOptDefault;
  429. CSetupInfFile csif;
  430. if (m_pf == PF_SERVER)
  431. {
  432. szOptDefault = c_szAfMaxthroughputforfilesharing;
  433. }
  434. else
  435. {
  436. szOptDefault = c_szAfMinmemoryused;
  437. }
  438. // Open the answer file.
  439. hr = csif.HrOpen(pszAnswerFile, NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
  440. if (FAILED(hr))
  441. {
  442. hr = S_OK;
  443. goto err;
  444. }
  445. if (m_fUpgrade)
  446. {
  447. // Restore portions of the registry based on file names from the answer
  448. // file
  449. // Get restore file for "Parameters" key
  450. hr = csif.HrGetString(pszAnswerSection, c_szAfLmServerParameters,
  451. &m_strParamsRestoreFile);
  452. if (FAILED(hr))
  453. {
  454. TraceError("CSrvrcfg::HrProcessAnswerFile - Error restoring "
  455. "Parameters key", hr);
  456. // oh well, just continue
  457. hr = S_OK;
  458. }
  459. // Get restore file for "Shares" key
  460. hr = csif.HrGetString(pszAnswerSection, c_szAfLmServerShares,
  461. &m_strSharesRestoreFile);
  462. if (FAILED(hr))
  463. {
  464. TraceError("CSrvrcfg::HrProcessAnswerFile - Error restoring "
  465. "Shares key", hr);
  466. // oh well, just continue
  467. hr = S_OK;
  468. }
  469. // Get restore file for "AutotunedParameters" key
  470. hr = csif.HrGetString(pszAnswerSection,
  471. c_szAfLmServerAutotunedParameters,
  472. &m_strAutoTunedRestoreFile);
  473. if (FAILED(hr))
  474. {
  475. TraceError("CSrvrcfg::HrProcessAnswerFile - Error restoring "
  476. "AutotunedParameters key", hr);
  477. // oh well, just continue
  478. hr = S_OK;
  479. }
  480. }
  481. // Read contents Opimitzation key
  482. hr = csif.HrGetString(pszAnswerSection, c_szAfLmServerOptimization,
  483. &strOpt);
  484. if (SUCCEEDED(hr))
  485. {
  486. m_fDirty = TRUE;
  487. if (!lstrcmpiW(strOpt.c_str(), c_szAfMinmemoryused))
  488. {
  489. m_sdd.dwSize = 1;
  490. }
  491. else if (!lstrcmpiW(strOpt.c_str(), c_szAfBalance))
  492. {
  493. m_sdd.dwSize = 2;
  494. }
  495. else if (!lstrcmpiW(strOpt.c_str(), c_szAfMaxthroughputforfilesharing))
  496. {
  497. m_sdd.dwSize = 3;
  498. m_sdd.fLargeCache = TRUE;
  499. }
  500. else if (!lstrcmpiW(strOpt.c_str(), c_szAfMaxthrouputfornetworkapps))
  501. {
  502. m_sdd.dwSize = 3;
  503. m_sdd.fLargeCache = FALSE;
  504. }
  505. #ifdef DBG
  506. else
  507. {
  508. // NOTE: Default values for dwSize and fLargeCache will have been set
  509. // already by registry reading function.
  510. TraceTag(ttidSrvrCfg, "Unknown Optimization value '%S'. Using default "
  511. "'%S'.", strOpt.c_str(), szOptDefault);
  512. }
  513. #endif
  514. }
  515. // Read contents of BroadcastsToLanman2Clients key.
  516. hr = csif.HrGetStringAsBool(pszAnswerSection, c_szAfBroadcastToClients,
  517. &m_sdd.fAnnounce);
  518. if (FAILED(hr))
  519. {
  520. TraceError("CSrvrcfg::HrProcessAnswerFile - Error restoring "
  521. "BroadcastsToLanman2Clients key. Using default value"
  522. " of FALSE.", hr);
  523. // oh well, just continue
  524. hr = S_OK;
  525. }
  526. err:
  527. TraceError("CSrvrcfg::HrProcessAnswerFile", hr);
  528. return hr;
  529. }
  530. //
  531. // INetCfgProperties
  532. //
  533. //+---------------------------------------------------------------------------
  534. //
  535. // Member: CSrvrcfg::MergePropPages
  536. //
  537. // Purpose: Called when this component's properties are about to be
  538. // brought up.
  539. //
  540. // Arguments:
  541. // pdwDefPages [out] Number of default pages to show.
  542. // pahpspPrivate [out] Array of property sheet handles to pages that this
  543. // component will show.
  544. // pcPrivate [out] Number of pages in array.
  545. // hwndParent [in] Parent window for any UI.
  546. // pszStartPage [out] Pointer to start page.
  547. //
  548. // Returns: HRESULT, Error code.
  549. //
  550. // Author: danielwe 22 Feb 1997
  551. //
  552. // Notes:
  553. //
  554. STDMETHODIMP CSrvrcfg::MergePropPages(DWORD *pdwDefPages,
  555. LPBYTE *pahpspPrivate,
  556. UINT *pcPrivate, HWND hwndParent,
  557. PCWSTR *pszStartPage)
  558. {
  559. HRESULT hr = S_OK;
  560. HPROPSHEETPAGE *ahpsp = NULL;
  561. Validate_INetCfgProperties_MergePropPages(pdwDefPages, pahpspPrivate,
  562. pcPrivate, hwndParent,
  563. pszStartPage);
  564. // We don't want any default pages to be shown
  565. *pdwDefPages = 0;
  566. if (m_pf == PF_WORKSTATION)
  567. {
  568. // On workstation product, UI is not shown.
  569. *pcPrivate = 0;
  570. }
  571. else
  572. {
  573. hr = HrSetupPropSheets(&ahpsp, c_cPages);
  574. if (SUCCEEDED(hr))
  575. {
  576. *pahpspPrivate = (LPBYTE)ahpsp;
  577. *pcPrivate = c_cPages;
  578. }
  579. }
  580. Validate_INetCfgProperties_MergePropPages_Return(hr);
  581. TraceError("CSrvrcfg::MergePropPages", hr);
  582. return hr;
  583. }
  584. STDMETHODIMP CSrvrcfg::ValidateProperties(HWND hwndSheet)
  585. {
  586. return S_OK;
  587. }
  588. STDMETHODIMP CSrvrcfg::CancelProperties()
  589. {
  590. return S_OK;
  591. }
  592. STDMETHODIMP CSrvrcfg::ApplyProperties()
  593. {
  594. return S_OK;
  595. }
  596. //+---------------------------------------------------------------------------
  597. //
  598. // Member: CSrvrcfg::~CSrvrcfg
  599. //
  600. // Purpose: Destroys the CSrvrcfg object.
  601. //
  602. // Arguments:
  603. // (none)
  604. //
  605. // Returns: Nothing.
  606. //
  607. // Author: danielwe 5 Mar 1997
  608. //
  609. // Notes:
  610. //
  611. CSrvrcfg::~CSrvrcfg()
  612. {
  613. ReleaseObj(m_pncc);
  614. RegSafeCloseKey(m_hkeyMM);
  615. CleanupPropPages();
  616. #ifdef DBG
  617. {
  618. INT ipage;
  619. for (ipage = 0; ipage < c_cPages; ipage++)
  620. {
  621. AssertSz(!m_apspObj[ipage], "Prop page object should be NULL!");
  622. }
  623. }
  624. #endif
  625. }