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.

680 lines
19 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. hr = HrChangeServiceStartTypeOptional(c_szLicenseSvc,
  144. SERVICE_AUTO_START);
  145. if (SUCCEEDED(hr))
  146. {
  147. hr = S_OK;
  148. m_fDirty = FALSE;
  149. m_fOneTimeInstall = FALSE;
  150. }
  151. }
  152. }
  153. }
  154. Validate_INetCfgNotify_Apply_Return(hr);
  155. TraceError("CSrvrcfg::ApplyRegistryChanges",
  156. (hr == S_FALSE) ? S_OK : hr);
  157. return hr;
  158. }
  159. //
  160. // INetCfgComponentSetup
  161. //
  162. //+---------------------------------------------------------------------------
  163. //
  164. // Member: CSrvrcfg::Install
  165. //
  166. // Purpose: Called when this component is being installed
  167. //
  168. // Arguments:
  169. // dwSetupFlags [in] Flags that describe the type of setup
  170. //
  171. // Returns: HRESULT, Error code.
  172. //
  173. // Author: danielwe 5 Mar 1997
  174. //
  175. // Notes:
  176. //
  177. STDMETHODIMP CSrvrcfg::Install(DWORD dwSetupFlags)
  178. {
  179. m_fDirty = TRUE;
  180. m_fOneTimeInstall = TRUE;
  181. if (dwSetupFlags & NSF_WINNT_WKS_UPGRADE)
  182. {
  183. m_fUpgrade = TRUE;
  184. m_fUpgradeFromWks = TRUE;
  185. }
  186. else if ((dwSetupFlags & NSF_WINNT_SVR_UPGRADE) ||
  187. (dwSetupFlags & NSF_WINNT_SBS_UPGRADE))
  188. {
  189. m_fUpgrade = TRUE;
  190. }
  191. return S_OK;
  192. }
  193. STDMETHODIMP CSrvrcfg::Upgrade(DWORD dwSetupFlags,
  194. DWORD dwUpgradeFomBuildNo)
  195. {
  196. return S_FALSE;
  197. }
  198. //+---------------------------------------------------------------------------
  199. //
  200. // Member: CSrvrcfg::ReadAnswerFile
  201. //
  202. // Purpose: Reads the appropriate fields from the given answer file into
  203. // our in-memory state.
  204. //
  205. // Arguments:
  206. // pszAnswerFile [in] File name of answer file
  207. // pszAnswerSection [in] Section of answer file to look in
  208. //
  209. // Returns: S_OK if successful, OLE or Win32 error otherwise
  210. //
  211. // Author: danielwe 30 Oct 1997
  212. //
  213. // Notes:
  214. //
  215. STDMETHODIMP CSrvrcfg::ReadAnswerFile(PCWSTR pszAnswerFile,
  216. PCWSTR pszAnswerSection)
  217. {
  218. HRESULT hr = S_OK;
  219. if (pszAnswerSection && pszAnswerFile)
  220. {
  221. // There's an answer file. We must process it now.
  222. hr = HrProcessAnswerFile(pszAnswerFile, pszAnswerSection);
  223. if (FAILED(hr))
  224. {
  225. TraceError("CSrvrcfg::ReadAnswerFile- Answer file has "
  226. "errors. Defaulting all information as if "
  227. "answer file did not exist.",
  228. NETSETUP_E_ANS_FILE_ERROR);
  229. hr = S_OK;
  230. }
  231. }
  232. TraceError("CSrvrcfg::ReadAnswerFile", hr);
  233. return hr;
  234. }
  235. STDMETHODIMP CSrvrcfg::Removing()
  236. {
  237. return S_OK;
  238. }
  239. //+---------------------------------------------------------------------------
  240. //
  241. // Member: CSrvrcfg::HrRestoreRegistry
  242. //
  243. // Purpose: Restores the contents of the registry for this component
  244. //
  245. // Arguments:
  246. // (none)
  247. //
  248. // Returns: Win32 error if failed, otherwise S_OK
  249. //
  250. // Author: danielwe 8 Aug 1997
  251. //
  252. // Notes:
  253. //
  254. HRESULT CSrvrcfg::HrRestoreRegistry()
  255. {
  256. HRESULT hr = S_OK;
  257. HKEY hkey;
  258. TOKEN_PRIVILEGES * ptpRestore = NULL;
  259. BOOL fRestoreSucceeded = FALSE;
  260. if (!m_strParamsRestoreFile.empty() ||
  261. !m_strSharesRestoreFile.empty() ||
  262. !m_strAutoTunedRestoreFile.empty())
  263. {
  264. hr = HrEnableAllPrivileges(&ptpRestore);
  265. if (SUCCEEDED(hr))
  266. {
  267. if (!m_strParamsRestoreFile.empty())
  268. {
  269. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyServerParams,
  270. KEY_ALL_ACCESS, &hkey);
  271. if (SUCCEEDED(hr))
  272. {
  273. hr = HrRegRestoreKey(hkey, m_strParamsRestoreFile.c_str(),
  274. 0);
  275. if (FAILED(hr))
  276. {
  277. TraceError("CSrvrcfg::HrRestoreRegistry - HrRestoreRegistry for "
  278. "Parameters", hr);
  279. hr = S_OK;
  280. }
  281. else
  282. {
  283. fRestoreSucceeded = TRUE;
  284. }
  285. RegCloseKey(hkey);
  286. }
  287. }
  288. if (fRestoreSucceeded)
  289. {
  290. // if the restore succeeded, rewrite the values that were blown
  291. // away by the restore
  292. static const WCHAR c_szSvcDLLName[] = L"%SystemRoot%\\System32\\srvsvc.dll";
  293. static const WCHAR c_szServiceDll[] = L"ServiceDll";
  294. HKEY hkResult = NULL;
  295. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyServerParams, KEY_ALL_ACCESS, &hkResult);
  296. if SUCCEEDED(hr)
  297. {
  298. hr = HrRegSetValueEx(hkResult, c_szServiceDll, REG_EXPAND_SZ, (const BYTE *)c_szSvcDLLName, CbOfMultiSzAndTermSafe(c_szSvcDLLName));
  299. RegSafeCloseKey(hkResult);
  300. }
  301. if FAILED(hr)
  302. {
  303. TraceError("CSrvrcfg::HrRestoreRegistry - HrRestoreRegistry for "
  304. "ServiceDll", hr);
  305. hr = S_OK;
  306. }
  307. static const WCHAR c_szTrkWks[] = L"TrkWks";
  308. static const WCHAR c_szTrkSrv[] = L"TrkSrv";
  309. static const WCHAR c_szNullSession[] = L"NullSessionPipes";
  310. hr = HrRegAddStringToMultiSz(c_szTrkWks,
  311. HKEY_LOCAL_MACHINE,
  312. c_szRegKeyServerParams,
  313. c_szNullSession,
  314. STRING_FLAG_ENSURE_AT_END,
  315. 0);
  316. if (SUCCEEDED(hr))
  317. {
  318. hr = HrRegAddStringToMultiSz(c_szTrkSrv,
  319. HKEY_LOCAL_MACHINE,
  320. c_szRegKeyServerParams,
  321. c_szNullSession,
  322. STRING_FLAG_ENSURE_AT_END,
  323. 0);
  324. }
  325. if (FAILED(hr))
  326. {
  327. TraceError("CSrvrcfg::HrRestoreRegistry - Error replacing "
  328. "values for Parameters", hr);
  329. hr = S_OK;
  330. }
  331. }
  332. if (!m_strSharesRestoreFile.empty())
  333. {
  334. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyServerShares,
  335. KEY_ALL_ACCESS, &hkey);
  336. if (SUCCEEDED(hr))
  337. {
  338. hr = HrRegRestoreKey(hkey, m_strSharesRestoreFile.c_str(),
  339. 0);
  340. if (FAILED(hr))
  341. {
  342. TraceError("CSrvrcfg::HrRestoreRegistry - HrRestoreRegistry for "
  343. "Shares", hr);
  344. hr = S_OK;
  345. }
  346. RegCloseKey(hkey);
  347. }
  348. }
  349. if (!m_strAutoTunedRestoreFile.empty())
  350. {
  351. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyServerAutoTuned,
  352. KEY_ALL_ACCESS, &hkey);
  353. if (SUCCEEDED(hr))
  354. {
  355. hr = HrRegRestoreKey(hkey, m_strAutoTunedRestoreFile.c_str(),
  356. 0);
  357. if (FAILED(hr))
  358. {
  359. TraceError("CSrvrcfg::HrRestoreRegistry - HrRestoreRegistry for "
  360. "AutotunedParameters", hr);
  361. hr = S_OK;
  362. }
  363. RegCloseKey(hkey);
  364. }
  365. }
  366. hr = HrRestorePrivileges(ptpRestore);
  367. delete [] reinterpret_cast<BYTE *>(ptpRestore);
  368. // Set a flag so we don't do this again if we are applied again
  369. m_fRestoredRegistry = TRUE;
  370. }
  371. }
  372. else
  373. {
  374. TraceTag(ttidSrvrCfg, "WARNING: HrRestoreRegistry() was called without"
  375. " ReadAnswerFile() being called!");
  376. }
  377. TraceError("CSrvrcfg::HrRestoreRegistry", hr);
  378. return hr;
  379. }
  380. //+---------------------------------------------------------------------------
  381. //
  382. // Member: CSrvrcfg::HrProcessAnswerFile
  383. //
  384. // Purpose: Handles necessary processing of contents of the answer file.
  385. //
  386. // Arguments:
  387. // pszAnswerFile [in] Filename of answer file for upgrade.
  388. // pszAnswerSection [in] Comma-separated list of sections in the
  389. // file appropriate to this component.
  390. //
  391. // Returns: S_OK if successful, setup API error otherwise.
  392. //
  393. // Author: danielwe 8 May 1997
  394. //
  395. // Notes:
  396. //
  397. HRESULT CSrvrcfg::HrProcessAnswerFile(PCWSTR pszAnswerFile,
  398. PCWSTR pszAnswerSection)
  399. {
  400. HRESULT hr = S_OK;
  401. tstring strOpt;
  402. PCWSTR szOptDefault;
  403. CSetupInfFile csif;
  404. if (m_pf == PF_SERVER)
  405. {
  406. szOptDefault = c_szAfMaxthroughputforfilesharing;
  407. }
  408. else
  409. {
  410. szOptDefault = c_szAfMinmemoryused;
  411. }
  412. // Open the answer file.
  413. hr = csif.HrOpen(pszAnswerFile, NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
  414. if (FAILED(hr))
  415. {
  416. hr = S_OK;
  417. goto err;
  418. }
  419. if (m_fUpgrade)
  420. {
  421. // Restore portions of the registry based on file names from the answer
  422. // file
  423. // Get restore file for "Parameters" key
  424. hr = csif.HrGetString(pszAnswerSection, c_szAfLmServerParameters,
  425. &m_strParamsRestoreFile);
  426. if (FAILED(hr))
  427. {
  428. TraceError("CSrvrcfg::HrProcessAnswerFile - Error restoring "
  429. "Parameters key", hr);
  430. // oh well, just continue
  431. hr = S_OK;
  432. }
  433. // Get restore file for "Shares" key
  434. hr = csif.HrGetString(pszAnswerSection, c_szAfLmServerShares,
  435. &m_strSharesRestoreFile);
  436. if (FAILED(hr))
  437. {
  438. TraceError("CSrvrcfg::HrProcessAnswerFile - Error restoring "
  439. "Shares key", hr);
  440. // oh well, just continue
  441. hr = S_OK;
  442. }
  443. // Get restore file for "AutotunedParameters" key
  444. hr = csif.HrGetString(pszAnswerSection,
  445. c_szAfLmServerAutotunedParameters,
  446. &m_strAutoTunedRestoreFile);
  447. if (FAILED(hr))
  448. {
  449. TraceError("CSrvrcfg::HrProcessAnswerFile - Error restoring "
  450. "AutotunedParameters key", hr);
  451. // oh well, just continue
  452. hr = S_OK;
  453. }
  454. }
  455. // Read contents Opimitzation key
  456. hr = csif.HrGetString(pszAnswerSection, c_szAfLmServerOptimization,
  457. &strOpt);
  458. if (SUCCEEDED(hr))
  459. {
  460. m_fDirty = TRUE;
  461. if (!lstrcmpiW(strOpt.c_str(), c_szAfMinmemoryused))
  462. {
  463. m_sdd.dwSize = 1;
  464. }
  465. else if (!lstrcmpiW(strOpt.c_str(), c_szAfBalance))
  466. {
  467. m_sdd.dwSize = 2;
  468. }
  469. else if (!lstrcmpiW(strOpt.c_str(), c_szAfMaxthroughputforfilesharing))
  470. {
  471. m_sdd.dwSize = 3;
  472. m_sdd.fLargeCache = TRUE;
  473. }
  474. else if (!lstrcmpiW(strOpt.c_str(), c_szAfMaxthrouputfornetworkapps))
  475. {
  476. m_sdd.dwSize = 3;
  477. m_sdd.fLargeCache = FALSE;
  478. }
  479. #ifdef DBG
  480. else
  481. {
  482. // NOTE: Default values for dwSize and fLargeCache will have been set
  483. // already by registry reading function.
  484. TraceTag(ttidSrvrCfg, "Unknown Optimization value '%S'. Using default "
  485. "'%S'.", strOpt.c_str(), szOptDefault);
  486. }
  487. #endif
  488. }
  489. // Read contents of BroadcastsToLanman2Clients key.
  490. hr = csif.HrGetStringAsBool(pszAnswerSection, c_szAfBroadcastToClients,
  491. &m_sdd.fAnnounce);
  492. if (FAILED(hr))
  493. {
  494. TraceError("CSrvrcfg::HrProcessAnswerFile - Error restoring "
  495. "BroadcastsToLanman2Clients key. Using default value"
  496. " of FALSE.", hr);
  497. // oh well, just continue
  498. hr = S_OK;
  499. }
  500. err:
  501. TraceError("CSrvrcfg::HrProcessAnswerFile", hr);
  502. return hr;
  503. }
  504. //
  505. // INetCfgProperties
  506. //
  507. //+---------------------------------------------------------------------------
  508. //
  509. // Member: CSrvrcfg::MergePropPages
  510. //
  511. // Purpose: Called when this component's properties are about to be
  512. // brought up.
  513. //
  514. // Arguments:
  515. // pdwDefPages [out] Number of default pages to show.
  516. // pahpspPrivate [out] Array of property sheet handles to pages that this
  517. // component will show.
  518. // pcPrivate [out] Number of pages in array.
  519. // hwndParent [in] Parent window for any UI.
  520. // pszStartPage [out] Pointer to start page.
  521. //
  522. // Returns: HRESULT, Error code.
  523. //
  524. // Author: danielwe 22 Feb 1997
  525. //
  526. // Notes:
  527. //
  528. STDMETHODIMP CSrvrcfg::MergePropPages(DWORD *pdwDefPages,
  529. LPBYTE *pahpspPrivate,
  530. UINT *pcPrivate, HWND hwndParent,
  531. PCWSTR *pszStartPage)
  532. {
  533. HRESULT hr = S_OK;
  534. HPROPSHEETPAGE *ahpsp = NULL;
  535. Validate_INetCfgProperties_MergePropPages(pdwDefPages, pahpspPrivate,
  536. pcPrivate, hwndParent,
  537. pszStartPage);
  538. // We don't want any default pages to be shown
  539. *pdwDefPages = 0;
  540. if (m_pf == PF_WORKSTATION)
  541. {
  542. // On workstation product, UI is not shown.
  543. *pcPrivate = 0;
  544. }
  545. else
  546. {
  547. hr = HrSetupPropSheets(&ahpsp, c_cPages);
  548. if (SUCCEEDED(hr))
  549. {
  550. *pahpspPrivate = (LPBYTE)ahpsp;
  551. *pcPrivate = c_cPages;
  552. }
  553. }
  554. Validate_INetCfgProperties_MergePropPages_Return(hr);
  555. TraceError("CSrvrcfg::MergePropPages", hr);
  556. return hr;
  557. }
  558. STDMETHODIMP CSrvrcfg::ValidateProperties(HWND hwndSheet)
  559. {
  560. return S_OK;
  561. }
  562. STDMETHODIMP CSrvrcfg::CancelProperties()
  563. {
  564. return S_OK;
  565. }
  566. STDMETHODIMP CSrvrcfg::ApplyProperties()
  567. {
  568. return S_OK;
  569. }
  570. //+---------------------------------------------------------------------------
  571. //
  572. // Member: CSrvrcfg::~CSrvrcfg
  573. //
  574. // Purpose: Destroys the CSrvrcfg object.
  575. //
  576. // Arguments:
  577. // (none)
  578. //
  579. // Returns: Nothing.
  580. //
  581. // Author: danielwe 5 Mar 1997
  582. //
  583. // Notes:
  584. //
  585. CSrvrcfg::~CSrvrcfg()
  586. {
  587. ReleaseObj(m_pncc);
  588. RegSafeCloseKey(m_hkeyMM);
  589. CleanupPropPages();
  590. #ifdef DBG
  591. {
  592. INT ipage;
  593. for (ipage = 0; ipage < c_cPages; ipage++)
  594. {
  595. AssertSz(!m_apspObj[ipage], "Prop page object should be NULL!");
  596. }
  597. }
  598. #endif
  599. }