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.

942 lines
28 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997-1999.
  5. //
  6. // File: M S C L I O B J . C P P
  7. //
  8. // Contents: Implementation of the CMSClient notify object model
  9. //
  10. // Notes:
  11. //
  12. // Author: danielwe 22 Feb 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include <ncxbase.h>
  18. #include <ncsvc.h>
  19. #include "mscliobj.h"
  20. #include "nb30.h"
  21. #include "ncerror.h"
  22. #include "ncperms.h"
  23. #include "ncreg.h"
  24. #include "ncsetup.h"
  25. #include "ncsvc.h"
  26. #include <ntsecapi.h>
  27. #include <lm.h>
  28. static const WCHAR c_szBrowseDomains[] = L"BrowseDomains";
  29. static const WCHAR c_szNameServiceNetAddr[] = L"NameServiceNetworkAddress";
  30. static const WCHAR c_szNameServiceProt[] = L"NameServiceProtocol";
  31. extern const WCHAR c_szInfId_MS_NetBIOS[];
  32. extern const WCHAR c_szInfId_MS_Server[];
  33. // Defined in rpcdlg.cpp
  34. extern const WCHAR c_szDefNetAddr[];
  35. extern const WCHAR c_szProtWinNT[];
  36. // Registry paths
  37. static const WCHAR c_szRegKeyBrowser[] = L"System\\CurrentControlSet\\Services\\Browser\\Parameters";
  38. static const WCHAR c_szRegKeyNetLogon[] = L"System\\CurrentControlSet\\Services\\NetLogon\\Parameters";
  39. // Answer file constants
  40. static const WCHAR c_szNetLogonParams[] = L"NetLogon.Parameters";
  41. static const WCHAR c_szBrowserParams[] = L"Browser.Parameters";
  42. //+---------------------------------------------------------------------------
  43. //
  44. // Member: CMSClient::CMSClient
  45. //
  46. // Purpose: Constructs the CMSClient object.
  47. //
  48. // Arguments:
  49. // (none)
  50. //
  51. // Returns: Nothing.
  52. //
  53. // Author: danielwe 22 Feb 1997
  54. //
  55. // Notes:
  56. //
  57. CMSClient::CMSClient()
  58. : m_pncc(NULL),
  59. m_pnc(NULL),
  60. m_fBrowserChanges(FALSE),
  61. m_fRPCChanges(FALSE),
  62. m_fOneTimeInstall(FALSE),
  63. m_fUpgrade(FALSE),
  64. m_fRemoving(FALSE),
  65. m_hkeyRPCName(NULL),
  66. m_eSrvState(eSrvNone),
  67. m_fUpgradeFromWks(FALSE),
  68. m_szDomainList(NULL)
  69. {
  70. ZeroMemory(&m_rpcData, sizeof(RPC_CONFIG_DATA));
  71. ZeroMemory(&m_apspObj, sizeof(m_apspObj));
  72. }
  73. //+---------------------------------------------------------------------------
  74. //
  75. // Member: CMSClient::~CMSClient
  76. //
  77. // Purpose: Destructs the CMSClient object.
  78. //
  79. // Arguments:
  80. // (none)
  81. //
  82. // Returns: Nothing.
  83. //
  84. // Author: danielwe 22 Feb 1997
  85. //
  86. // Notes:
  87. //
  88. CMSClient::~CMSClient()
  89. {
  90. ReleaseObj(m_pncc);
  91. ReleaseObj(m_pnc);
  92. RegSafeCloseKey(m_hkeyRPCName);
  93. m_rpcData.strProt.erase();
  94. m_rpcData.strNetAddr.erase();
  95. m_rpcData.strEndPoint.erase();
  96. CleanupPropPages();
  97. #ifdef DBG
  98. {
  99. INT ipage;
  100. for (ipage = 0; ipage < c_cPages; ipage++)
  101. {
  102. AssertSz(!m_apspObj[ipage], "Prop page object not cleaned up!");
  103. }
  104. }
  105. #endif
  106. delete [] m_szDomainList;
  107. }
  108. //
  109. // INetCfgComponentControl
  110. //
  111. //+---------------------------------------------------------------------------
  112. //
  113. // Member: CMSClient::Initialize
  114. //
  115. // Purpose: Initializes the notify object.
  116. //
  117. // Arguments:
  118. // pnccItem [in] INetCfgComponent that we are handling
  119. // notifications for.
  120. // pnc [in] INetCfg master object.
  121. // fInstalling [in] TRUE if we are being installed, FALSE if not.
  122. //
  123. // Returns: HRESULT, Error code.
  124. //
  125. // Author: danielwe 22 Feb 1997
  126. //
  127. // Notes:
  128. //
  129. STDMETHODIMP CMSClient::Initialize(INetCfgComponent *pnccItem, INetCfg *pnc,
  130. BOOL fInstalling)
  131. {
  132. HRESULT hr = S_OK;
  133. INetCfgComponent * pnccServer = NULL;
  134. Validate_INetCfgNotify_Initialize(pnccItem, pnc, fInstalling);
  135. m_pncc = pnccItem;
  136. m_pnc = pnc;
  137. AssertSz(m_pncc, "Component object is NULL!");
  138. AssertSz(m_pnc, "INetCfg object is NULL!");
  139. // We're hanging on to these, so AddRef 'em.
  140. AddRefObj(m_pncc);
  141. AddRefObj(m_pnc);
  142. // Check to see if MS_SERVER is installed. If not, set the browser service
  143. // to be disabled.
  144. //
  145. hr = m_pnc->FindComponent(c_szInfId_MS_Server, &pnccServer);
  146. if (S_FALSE == hr)
  147. {
  148. // Server component is not present. Set browser to be disabled on
  149. // apply
  150. m_eSrvState = eSrvDisable;
  151. }
  152. else if (S_OK == hr)
  153. {
  154. ReleaseObj(pnccServer);
  155. }
  156. if (SUCCEEDED(hr))
  157. {
  158. // Read in data for the RPC config dialog from the registry
  159. hr = HrGetRPCRegistryInfo();
  160. if (SUCCEEDED(hr))
  161. {
  162. // Read in data for the browser config dialog from the registry
  163. hr = HrGetBrowserRegistryInfo();
  164. }
  165. }
  166. Validate_INetCfgNotify_Initialize_Return(hr);
  167. TraceError("CMSClient::Initialize", hr);
  168. return hr;
  169. }
  170. STDMETHODIMP CMSClient::Validate()
  171. {
  172. return S_OK;
  173. }
  174. STDMETHODIMP CMSClient::CancelChanges()
  175. {
  176. return S_OK;
  177. }
  178. //+---------------------------------------------------------------------------
  179. //
  180. // Member: CMSClient::ApplyRegistryChanges
  181. //
  182. // Purpose: Called when changes to this component should be applied.
  183. //
  184. // Arguments:
  185. // (none)
  186. //
  187. // Returns: S_OK if successful, S_FALSE if no changes occurred,
  188. // NETCFG_S_REBOOT if a reboot is required, otherwise a NETCFG_E
  189. // error code.
  190. //
  191. // Author: danielwe 22 Feb 1997
  192. //
  193. // Notes:
  194. //
  195. STDMETHODIMP CMSClient::ApplyRegistryChanges()
  196. {
  197. TraceFileFunc(ttidMSCliCfg);
  198. HRESULT hr = S_OK;
  199. if (m_fUpgrade)
  200. {
  201. m_fUpgrade = FALSE;
  202. hr = HrRestoreRegistry();
  203. if (FAILED(hr))
  204. {
  205. TraceError("CMSClient::ApplyRegistryChanges - HrRestoreRegistry - non-fatal",
  206. hr);
  207. hr = S_OK;
  208. }
  209. }
  210. // Do we need to enable or disable the browser service??
  211. //
  212. switch (m_eSrvState)
  213. {
  214. case eSrvEnable:
  215. TraceTag(ttidMSCliCfg, "Enabling the Browser service...");
  216. hr = HrEnableBrowserService();
  217. if (FAILED(hr))
  218. {
  219. TraceError("CMSClient::ApplyRegistryChanges - HrEnableBrowserService failed."
  220. " non-fatal.", hr);
  221. hr = S_OK;
  222. }
  223. break;
  224. case eSrvDisable:
  225. TraceTag(ttidMSCliCfg, "Disabling the Browser service...");
  226. hr = HrDisableBrowserService();
  227. if (FAILED(hr))
  228. {
  229. TraceError("CMSClient::ApplyRegistryChanges - HrDisableBrowserService failed."
  230. " non-fatal.", hr);
  231. hr = S_OK;
  232. }
  233. break;
  234. }
  235. if (m_fRPCChanges || m_fBrowserChanges ||
  236. m_fOneTimeInstall || m_fUpgradeFromWks)
  237. {
  238. hr = HrApplyChanges();
  239. if (SUCCEEDED(hr))
  240. {
  241. m_fRPCChanges = FALSE;
  242. m_fBrowserChanges = FALSE;
  243. m_fOneTimeInstall = FALSE;
  244. // Make NetLogon dependend on LanmanServer for Domain Controllers, and Automatic start for Domain Members
  245. hr = HrSetNetLogonDependencies();
  246. }
  247. }
  248. else
  249. {
  250. // No relevant changes were detected (netbios changes do not affect
  251. // netcfg so we can return S_FALSE even if things changed
  252. hr = S_FALSE;
  253. }
  254. Validate_INetCfgNotify_Apply_Return(hr);
  255. TraceError("CMSClient::ApplyRegistryChanges", (hr == S_FALSE) ? S_OK : hr);
  256. return hr;
  257. }
  258. STDMETHODIMP
  259. CMSClient::ApplyPnpChanges (
  260. IN INetCfgPnpReconfigCallback* pICallback)
  261. {
  262. HRESULT hr;
  263. hr = S_OK;
  264. if (m_fRemoving)
  265. {
  266. // Make sure Mrxsmb and Rdbss have been removed. (They are stopped
  267. // when LanmanWorkstation stops, but the binding engine has no idea
  268. // that Mrxsmb and Rdbss are part of this component. Hence, the
  269. // status of the DeleteService that is performed as part of the INF
  270. // is not communicated back out.) We make sure that these services
  271. // do not exist here, and if they do, we report that we need a
  272. // reboot.
  273. //
  274. CServiceManager scm;
  275. CService svc;
  276. TraceTag(ttidMSCliCfg, "Checking to see that Mrxsmb and Rdbss "
  277. "are stopped and removed");
  278. hr = scm.HrOpenService (&svc, L"Mrxsmb",
  279. NO_LOCK, SC_MANAGER_CONNECT, SERVICE_QUERY_STATUS);
  280. if (HRESULT_FROM_WIN32(ERROR_SERVICE_DOES_NOT_EXIST) != hr)
  281. {
  282. TraceHr(ttidMSCliCfg, FAL, hr, FALSE, "OpenService(MrxSmb)");
  283. TraceTag(ttidMSCliCfg, "Mrxsmb still exists");
  284. hr = NETCFG_S_REBOOT;
  285. }
  286. else
  287. {
  288. // Mrxsmb does not exist. Now check Rdbss.
  289. //
  290. hr = scm.HrOpenService (&svc, L"Rdbss",
  291. NO_LOCK, SC_MANAGER_CONNECT, SERVICE_QUERY_STATUS);
  292. if (HRESULT_FROM_WIN32(ERROR_SERVICE_DOES_NOT_EXIST) != hr)
  293. {
  294. TraceHr(ttidMSCliCfg, FAL, hr, FALSE, "OpenService(Rdbss)");
  295. TraceTag(ttidMSCliCfg, "Rdbss still exists");
  296. hr = NETCFG_S_REBOOT;
  297. }
  298. else
  299. {
  300. // Rdbss does not exist. This is good.
  301. //
  302. hr = S_OK;
  303. }
  304. }
  305. }
  306. return hr;
  307. }
  308. //
  309. // INetCfgComponentSetup
  310. //
  311. //+---------------------------------------------------------------------------
  312. //
  313. // Member: CMSClient::Install
  314. //
  315. // Purpose: Called when this component is being installed
  316. //
  317. // Arguments:
  318. // dwSetupFlags [in] Flags that describe the type of setup
  319. //
  320. // Returns: S_OK if success, OLE or Win32 error otherwise
  321. //
  322. // Author: danielwe 30 Oct 1997
  323. //
  324. // Notes:
  325. //
  326. STDMETHODIMP CMSClient::Install(DWORD dwSetupFlags)
  327. {
  328. HRESULT hr;
  329. Validate_INetCfgNotify_Install (dwSetupFlags);
  330. m_fRPCChanges = TRUE;
  331. m_fBrowserChanges = TRUE;
  332. m_fOneTimeInstall = TRUE;
  333. if ((NSF_WINNT_WKS_UPGRADE & dwSetupFlags) ||
  334. (NSF_WINNT_SBS_UPGRADE & dwSetupFlags) ||
  335. (NSF_WINNT_SVR_UPGRADE & dwSetupFlags))
  336. {
  337. m_fUpgrade = TRUE;
  338. }
  339. // Install the NetBIOS sub-component
  340. hr = HrInstallComponentOboComponent(m_pnc, NULL,
  341. GUID_DEVCLASS_NETSERVICE,
  342. c_szInfId_MS_NetBIOS,
  343. m_pncc,
  344. NULL);
  345. TraceError("CMSClient::Install", hr);
  346. return hr;
  347. }
  348. //+---------------------------------------------------------------------------
  349. //
  350. // Member: CMSClient::Upgrade
  351. //
  352. // Purpose: Called when this component is upgraded
  353. //
  354. // Arguments:
  355. // dwSetupFlags [in] Flags describing setup
  356. // dwUpgradeFomBuildNo [in] Build number from which we are upgrading
  357. //
  358. // Returns: S_OK if success, OLE or Win32 error otherwise
  359. //
  360. // Author: danielwe 30 Oct 1997
  361. //
  362. // Notes:
  363. //
  364. STDMETHODIMP CMSClient::Upgrade(DWORD dwSetupFlags,
  365. DWORD dwUpgradeFomBuildNo)
  366. {
  367. if (dwSetupFlags & NSF_WINNT_WKS_UPGRADE)
  368. {
  369. TraceTag(ttidMSCliCfg, "Upgrading from workstation...");
  370. m_fUpgradeFromWks = TRUE;
  371. }
  372. return S_OK;
  373. }
  374. //+---------------------------------------------------------------------------
  375. //
  376. // Member: CMSClient::ReadAnswerFile
  377. //
  378. // Purpose: Reads the appropriate fields from the given answer file into
  379. // our in-memory state.
  380. //
  381. // Arguments:
  382. // pszAnswerFile [in] File name of answer file
  383. // pszAnswerSection [in] Section of answer file to look in
  384. //
  385. // Returns: S_OK if successful, OLE or Win32 error otherwise
  386. //
  387. // Author: danielwe 30 Oct 1997
  388. //
  389. // Notes: IMPORTANT: During install or upgrade, this MUST be called
  390. // *before* Upgrade() or Install()! (see bug #100995)
  391. //
  392. STDMETHODIMP CMSClient::ReadAnswerFile(PCWSTR pszAnswerFile,
  393. PCWSTR pszAnswerSection)
  394. {
  395. HRESULT hr = S_OK;
  396. if (pszAnswerSection && pszAnswerFile)
  397. {
  398. // There's an answer file. We must process it now.
  399. hr = HrProcessAnswerFile(pszAnswerFile, pszAnswerSection);
  400. if (FAILED(hr))
  401. {
  402. TraceError("CMSClient::ReadAnswerFile- Answer file has "
  403. "errors. Defaulting all information as if "
  404. "answer file did not exist.",
  405. NETSETUP_E_ANS_FILE_ERROR);
  406. hr = S_OK;
  407. }
  408. }
  409. TraceError("CMSClient::ReadAnswerFile", hr);
  410. return hr;
  411. }
  412. //+---------------------------------------------------------------------------
  413. //
  414. // Member: CMSClient::Removing
  415. //
  416. // Purpose: Called whent this component is being removed
  417. //
  418. // Arguments:
  419. // (none)
  420. //
  421. // Returns: S_OK of success, OLE or Win32 error otherwise
  422. //
  423. // Author: danielwe 30 Oct 1997
  424. //
  425. // Notes:
  426. //
  427. STDMETHODIMP CMSClient::Removing()
  428. {
  429. m_fRemoving = TRUE;
  430. // Remove the NetBIOS service. This doesn't actually remove the
  431. // component, it simply marks it as needing to be removed, and in
  432. // Apply() it will be fully removed.
  433. HRESULT hr = HrRemoveComponentOboComponent(m_pnc,
  434. GUID_DEVCLASS_NETSERVICE,
  435. c_szInfId_MS_NetBIOS,
  436. m_pncc);
  437. TraceError("CMSClient::Removing", hr);
  438. return hr;
  439. }
  440. //+---------------------------------------------------------------------------
  441. //
  442. // Member: CMSClient::HrRestoreRegistry
  443. //
  444. // Purpose: Restores the registry settings for various services on upgrade
  445. //
  446. // Arguments:
  447. // (none)
  448. //
  449. // Returns: S_OK if success, WIN32 error otherwise
  450. //
  451. // Author: danielwe 8 Aug 1997
  452. //
  453. // Notes:
  454. //
  455. HRESULT CMSClient::HrRestoreRegistry()
  456. {
  457. HRESULT hr = S_OK;
  458. HKEY hkey;
  459. TOKEN_PRIVILEGES * ptpRestore = NULL;
  460. static const WCHAR c_szSvcDLLName[] = L"%SystemRoot%\\System32\\browser.dll";
  461. static const WCHAR c_szServiceDll[] = L"ServiceDll";
  462. if (!m_strBrowserParamsRestoreFile.empty() ||
  463. !m_strNetLogonParamsRestoreFile.empty())
  464. {
  465. hr = HrEnableAllPrivileges(&ptpRestore);
  466. if (SUCCEEDED(hr))
  467. {
  468. if (!m_strBrowserParamsRestoreFile.empty())
  469. {
  470. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyBrowser,
  471. KEY_ALL_ACCESS, &hkey);
  472. if (SUCCEEDED(hr))
  473. {
  474. hr = HrRegRestoreKey(hkey,
  475. m_strBrowserParamsRestoreFile.c_str(),
  476. 0);
  477. if (FAILED(hr))
  478. {
  479. TraceError("CMSClient::HrRestoreRegistry - "
  480. "HrRestoreRegistry for Browser Parameters",
  481. hr);
  482. hr = S_OK;
  483. }
  484. hr = HrRegSetValueEx(hkey, c_szServiceDll, REG_EXPAND_SZ, (const BYTE *)c_szSvcDLLName, (wcslen(c_szSvcDLLName) + 1) * sizeof(TCHAR));
  485. if (FAILED(hr))
  486. {
  487. TraceError("CMSClient::HrRestoreRegistry - HrRestoreRegistry for "
  488. "ServiceDll", hr);
  489. hr = S_OK;
  490. }
  491. RegSafeCloseKey(hkey);
  492. }
  493. }
  494. if (!m_strNetLogonParamsRestoreFile.empty())
  495. {
  496. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyNetLogon,
  497. KEY_ALL_ACCESS, &hkey);
  498. if (SUCCEEDED(hr))
  499. {
  500. hr = HrRegRestoreKey(hkey,
  501. m_strNetLogonParamsRestoreFile.c_str(),
  502. 0);
  503. if (FAILED(hr))
  504. {
  505. TraceError("CMSClient::HrRestoreRegistry - "
  506. "HrRestoreRegistry for NetLogon Parameters",
  507. hr);
  508. hr = S_OK;
  509. }
  510. //
  511. // The following key has to be set here because of new changes introduced
  512. // by SCE (Security Configuration Engine). SCE runs early in GUI mode setup to
  513. // set out-of-the-box security by setting some registry values. During NT4
  514. // upgrades we don't see those registry values set because during NT4 upgrades,
  515. // some services including Lanmanserver and Netlogon gets deleted and reinstalled
  516. // for PnP requirements. To maintain the services configuration between deleting
  517. // and reinstalling, some of their Keys including the "Parameters" keys for
  518. // LanManServer and Netlogon get backed up early during upgrade and restored
  519. // later with the service installation. This backing up and restoring action
  520. // happens through the services own notify objects (like this one). The problem
  521. // is, backing up of the Keys happens before SCE sets the values in those keys and
  522. // they get restored after SCE sets the values. So we lose the values set. So, we
  523. // are setting those keys here separately to the secure values.
  524. // See Windows Raid bug #691952 for more details.
  525. //
  526. static const WCHAR c_szRequireSignOrSeal[] = L"RequireSignOrSeal";
  527. DWORD value = 1;
  528. hr = HrRegSetValueEx(hkey, c_szRequireSignOrSeal, REG_DWORD, (const BYTE *)&value, 4);
  529. if (FAILED(hr))
  530. {
  531. TraceError("CMSClicfg::HrRestoreRegistry - setting RequireSignOrSeal to DWORD 1 failed", hr);
  532. hr = S_OK;
  533. }
  534. RegCloseKey(hkey);
  535. }
  536. }
  537. hr = HrRestorePrivileges(ptpRestore);
  538. delete [] reinterpret_cast<BYTE *>(ptpRestore);
  539. }
  540. }
  541. TraceError("CMSClient::HrRestoreRegistry", hr);
  542. return hr;
  543. }
  544. //+---------------------------------------------------------------------------
  545. //
  546. // Member: CMSClient::HrProcessAnswerFile
  547. //
  548. // Purpose: Processes the answer file. Any parameters that have been set
  549. // are read into our in-memory state.
  550. //
  551. // Arguments:
  552. // pszAnswerFile [in] Filename of answer file.
  553. // pszAnswerSection [in] Comma-separated list of sections in the
  554. // file appropriate to this component.
  555. //
  556. // Returns: S_OK if successful, NETCFG error code otherwise.
  557. //
  558. // Author: danielwe 22 Feb 1997
  559. //
  560. // Notes: Errors returned from this function should be ignored so as to
  561. // prevent blocking the rest of network install.
  562. //
  563. HRESULT CMSClient::HrProcessAnswerFile(PCWSTR pszAnswerFile,
  564. PCWSTR pszAnswerSection)
  565. {
  566. HRESULT hr = S_OK;
  567. CSetupInfFile csif;
  568. PWSTR mszDomainList = NULL;
  569. AssertSz(pszAnswerFile, "Answer file string is NULL!");
  570. AssertSz(pszAnswerSection, "Answer file sections string is NULL!");
  571. // Open the answer file.
  572. hr = csif.HrOpen(pszAnswerFile, NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
  573. if (FAILED(hr))
  574. goto err;
  575. if (m_fUpgrade)
  576. {
  577. // Restore portions of the registry based on file names from the answer
  578. // file
  579. // Get restore file for "Parameters" key
  580. hr = csif.HrGetString(pszAnswerSection, c_szNetLogonParams,
  581. &m_strNetLogonParamsRestoreFile);
  582. if (FAILED(hr))
  583. {
  584. TraceError("CMSClient::HrProcessAnswerFile - Error reading "
  585. "NetLogon.Parameters from answer file", hr);
  586. // oh well, just continue
  587. hr = S_OK;
  588. }
  589. // Get restore file for "Parameters" key
  590. hr = csif.HrGetString(pszAnswerSection, c_szBrowserParams,
  591. &m_strBrowserParamsRestoreFile);
  592. if (FAILED(hr))
  593. {
  594. TraceError("CMSClient::HrProcessAnswerFile - Error reading "
  595. "Browser.Parameters from answer file", hr);
  596. // oh well, just continue
  597. hr = S_OK;
  598. }
  599. }
  600. // Get the BrowseDomains field.
  601. hr = HrSetupGetFirstMultiSzFieldWithAlloc(csif.Hinf(),
  602. pszAnswerSection,
  603. c_szBrowseDomains,
  604. &mszDomainList);
  605. if (FAILED(hr))
  606. {
  607. // ignore line not found errors
  608. if (hr == HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND))
  609. {
  610. hr = S_OK;
  611. }
  612. TraceError("HrProcessAnswerFile - Error on BrowseDomains field. "
  613. "Using default value", hr);
  614. }
  615. else
  616. {
  617. // Set the new domain list.
  618. SetBrowserDomainList(mszDomainList);
  619. }
  620. // Get the NameServiceNetworkAddress value
  621. hr = csif.HrGetString(pszAnswerSection,
  622. c_szNameServiceNetAddr,
  623. &m_rpcData.strNetAddr);
  624. if (FAILED(hr))
  625. {
  626. // ignore line not found errors
  627. if (hr == HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND))
  628. {
  629. hr = S_OK;
  630. }
  631. TraceError("HrProcessAnswerFile - Error on NetworkAddress field. "
  632. "Defaulting value", hr);
  633. m_rpcData.strNetAddr = c_szDefNetAddr;
  634. }
  635. else
  636. {
  637. m_fRPCChanges = TRUE;
  638. }
  639. // Get the NameServiceProtocol value.
  640. hr = csif.HrGetString(pszAnswerSection,
  641. c_szNameServiceProt,
  642. &m_rpcData.strProt);
  643. if (FAILED(hr))
  644. {
  645. // ignore line not found errors
  646. if (hr == HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND))
  647. {
  648. hr = S_OK;
  649. }
  650. TraceError("HrProcessAnswerFile - Error on NameServiceProtocol field. "
  651. "Defaulting value", hr);
  652. m_rpcData.strProt = c_szProtWinNT;
  653. }
  654. else
  655. {
  656. m_fRPCChanges = TRUE;
  657. }
  658. err:
  659. TraceError("CMSClient::HrProcessAnswerFile", hr);
  660. return hr;
  661. }
  662. //
  663. // INetCfgProperties
  664. //
  665. //+---------------------------------------------------------------------------
  666. //
  667. // Member: CMSClient::MergePropPages
  668. //
  669. // Purpose: Called when this component's properties are about to be
  670. // brought up.
  671. //
  672. // Arguments:
  673. // pdwDefPages [out] Number of default pages to show.
  674. // pahpspPrivate [out] Array of property sheet handles to pages that this
  675. // component will show.
  676. // pcPrivate [out] Number of pages in array.
  677. // hwndParent [in] Parent window for any UI.
  678. // pszStartPage [out] Pointer to start page.
  679. //
  680. // Returns: HRESULT, Error code.
  681. //
  682. // Author: danielwe 22 Feb 1997
  683. //
  684. // Notes:
  685. //
  686. STDMETHODIMP CMSClient::MergePropPages(
  687. IN OUT DWORD* pdwDefPages,
  688. OUT LPBYTE* pahpspPrivate,
  689. OUT UINT* pcPages,
  690. IN HWND hwndParent,
  691. OUT PCWSTR* pszStartPage)
  692. {
  693. Validate_INetCfgProperties_MergePropPages (
  694. pdwDefPages, pahpspPrivate, pcPages, hwndParent, pszStartPage);
  695. HPROPSHEETPAGE *ahpsp = NULL;
  696. HRESULT hr = HrSetupPropSheets(&ahpsp, c_cPages);
  697. if (SUCCEEDED(hr))
  698. {
  699. *pahpspPrivate = (LPBYTE)ahpsp;
  700. // We don't want any default pages to be shown
  701. *pdwDefPages = 0;
  702. *pcPages = c_cPages;
  703. }
  704. Validate_INetCfgProperties_MergePropPages_Return(hr);
  705. TraceError("CMSClient::MergePropPages", hr);
  706. return hr;
  707. }
  708. STDMETHODIMP CMSClient::ValidateProperties(HWND hwndSheet)
  709. {
  710. return S_OK;
  711. }
  712. STDMETHODIMP CMSClient::CancelProperties()
  713. {
  714. return S_OK;
  715. }
  716. STDMETHODIMP CMSClient::ApplyProperties()
  717. {
  718. return S_OK;
  719. }
  720. //
  721. // INetCfgSystemNotify
  722. //
  723. STDMETHODIMP CMSClient::GetSupportedNotifications (DWORD* pdwNotificationFlag)
  724. {
  725. Validate_INetCfgSystemNotify_GetSupportedNotifications(pdwNotificationFlag);
  726. *pdwNotificationFlag = NCN_NETTRANS | NCN_NETSERVICE |
  727. NCN_ENABLE | NCN_DISABLE |
  728. NCN_ADD | NCN_REMOVE;
  729. return S_OK;
  730. }
  731. STDMETHODIMP CMSClient::SysQueryBindingPath (DWORD dwChangeFlag,
  732. INetCfgBindingPath* pncbp)
  733. {
  734. return S_OK;
  735. }
  736. STDMETHODIMP CMSClient::SysQueryComponent (DWORD dwChangeFlag,
  737. INetCfgComponent* pncc)
  738. {
  739. return S_OK;
  740. }
  741. STDMETHODIMP CMSClient::SysNotifyBindingPath (DWORD dwChangeFlag,
  742. INetCfgBindingPath* pncbpItem)
  743. {
  744. return S_FALSE;
  745. }
  746. STDMETHODIMP CMSClient::SysNotifyComponent(DWORD dwChangeFlag,
  747. INetCfgComponent* pncc)
  748. {
  749. HRESULT hr;
  750. Validate_INetCfgSystemNotify_SysNotifyComponent(dwChangeFlag, pncc);
  751. // Assume we won't be dirty as a result of this notification.
  752. //
  753. hr = S_FALSE;
  754. if (dwChangeFlag & (NCN_ADD | NCN_REMOVE))
  755. {
  756. if (FIsComponentId(c_szInfId_MS_Server, pncc))
  757. {
  758. if (dwChangeFlag & NCN_ADD)
  759. {
  760. m_eSrvState = eSrvEnable;
  761. hr = S_OK;
  762. }
  763. else if (dwChangeFlag & NCN_REMOVE)
  764. {
  765. m_eSrvState = eSrvDisable;
  766. hr = S_OK;
  767. }
  768. }
  769. }
  770. return hr;
  771. }
  772. HRESULT CMSClient::HrSetNetLogonDependencies(VOID)
  773. {
  774. static const WCHAR c_szLanmanServer[] = L"LanmanServer";
  775. static const WCHAR c_szNetLogon[] = L"NetLogon";
  776. HRESULT hr = S_OK;
  777. NT_PRODUCT_TYPE ProductType;
  778. if (RtlGetNtProductType(&ProductType))
  779. {
  780. if (NtProductLanManNt == ProductType)
  781. {
  782. // If domain controller, make NetLogon wait for LanmanServer
  783. CServiceManager sm;
  784. CService svc;
  785. hr = sm.HrOpen();
  786. if (SUCCEEDED(hr))
  787. {
  788. hr = sm.HrAddServiceDependency(c_szNetLogon, c_szLanmanServer);
  789. sm.Close();
  790. }
  791. if (FAILED(hr))
  792. {
  793. TraceError("CMSClient::HrSetNetLogonDependencies - "
  794. "Creating dependency of NetLogon on LanmanServer",
  795. hr);
  796. }
  797. }
  798. }
  799. if (SUCCEEDED(hr))
  800. {
  801. LSA_HANDLE h=0;
  802. POLICY_PRIMARY_DOMAIN_INFO* ppdi;
  803. LSA_OBJECT_ATTRIBUTES loa;
  804. ZeroMemory (&loa, sizeof(loa));
  805. loa.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
  806. NTSTATUS ntstatus;
  807. ntstatus = LsaOpenPolicy(NULL, &loa, POLICY_VIEW_LOCAL_INFORMATION, &h);
  808. if (FALSE != LSA_SUCCESS(ntstatus))
  809. {
  810. ntstatus = LsaQueryInformationPolicy(h, PolicyPrimaryDomainInformation, (VOID **) &ppdi);
  811. if (LSA_SUCCESS(ntstatus))
  812. {
  813. if (ppdi->Sid > 0) // Domain Member
  814. {
  815. hr = HrChangeServiceStartType(c_szNetLogon, SERVICE_AUTO_START);
  816. if (FAILED(hr))
  817. {
  818. TraceError("CMSClient::HrSetNetLogonDependencies - "
  819. "Install for Start - NetLogon",
  820. hr);
  821. }
  822. }
  823. LsaFreeMemory(ppdi);
  824. }
  825. LsaClose(h);
  826. }
  827. }
  828. TraceError("CMSClient::HrSetNetLogonDependencies",hr);
  829. return hr;
  830. }