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.

914 lines
25 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. RegCloseKey(hkey);
  511. }
  512. }
  513. hr = HrRestorePrivileges(ptpRestore);
  514. delete [] reinterpret_cast<BYTE *>(ptpRestore);
  515. }
  516. }
  517. TraceError("CMSClient::HrRestoreRegistry", hr);
  518. return hr;
  519. }
  520. //+---------------------------------------------------------------------------
  521. //
  522. // Member: CMSClient::HrProcessAnswerFile
  523. //
  524. // Purpose: Processes the answer file. Any parameters that have been set
  525. // are read into our in-memory state.
  526. //
  527. // Arguments:
  528. // pszAnswerFile [in] Filename of answer file.
  529. // pszAnswerSection [in] Comma-separated list of sections in the
  530. // file appropriate to this component.
  531. //
  532. // Returns: S_OK if successful, NETCFG error code otherwise.
  533. //
  534. // Author: danielwe 22 Feb 1997
  535. //
  536. // Notes: Errors returned from this function should be ignored so as to
  537. // prevent blocking the rest of network install.
  538. //
  539. HRESULT CMSClient::HrProcessAnswerFile(PCWSTR pszAnswerFile,
  540. PCWSTR pszAnswerSection)
  541. {
  542. HRESULT hr = S_OK;
  543. CSetupInfFile csif;
  544. PWSTR mszDomainList = NULL;
  545. AssertSz(pszAnswerFile, "Answer file string is NULL!");
  546. AssertSz(pszAnswerSection, "Answer file sections string is NULL!");
  547. // Open the answer file.
  548. hr = csif.HrOpen(pszAnswerFile, NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
  549. if (FAILED(hr))
  550. goto err;
  551. if (m_fUpgrade)
  552. {
  553. // Restore portions of the registry based on file names from the answer
  554. // file
  555. // Get restore file for "Parameters" key
  556. hr = csif.HrGetString(pszAnswerSection, c_szNetLogonParams,
  557. &m_strNetLogonParamsRestoreFile);
  558. if (FAILED(hr))
  559. {
  560. TraceError("CMSClient::HrProcessAnswerFile - Error reading "
  561. "NetLogon.Parameters from answer file", hr);
  562. // oh well, just continue
  563. hr = S_OK;
  564. }
  565. // Get restore file for "Parameters" key
  566. hr = csif.HrGetString(pszAnswerSection, c_szBrowserParams,
  567. &m_strBrowserParamsRestoreFile);
  568. if (FAILED(hr))
  569. {
  570. TraceError("CMSClient::HrProcessAnswerFile - Error reading "
  571. "Browser.Parameters from answer file", hr);
  572. // oh well, just continue
  573. hr = S_OK;
  574. }
  575. }
  576. // Get the BrowseDomains field.
  577. hr = HrSetupGetFirstMultiSzFieldWithAlloc(csif.Hinf(),
  578. pszAnswerSection,
  579. c_szBrowseDomains,
  580. &mszDomainList);
  581. if (FAILED(hr))
  582. {
  583. // ignore line not found errors
  584. if (hr == HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND))
  585. {
  586. hr = S_OK;
  587. }
  588. TraceError("HrProcessAnswerFile - Error on BrowseDomains field. "
  589. "Using default value", hr);
  590. }
  591. else
  592. {
  593. // Set the new domain list.
  594. SetBrowserDomainList(mszDomainList);
  595. }
  596. // Get the NameServiceNetworkAddress value
  597. hr = csif.HrGetString(pszAnswerSection,
  598. c_szNameServiceNetAddr,
  599. &m_rpcData.strNetAddr);
  600. if (FAILED(hr))
  601. {
  602. // ignore line not found errors
  603. if (hr == HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND))
  604. {
  605. hr = S_OK;
  606. }
  607. TraceError("HrProcessAnswerFile - Error on NetworkAddress field. "
  608. "Defaulting value", hr);
  609. m_rpcData.strNetAddr = c_szDefNetAddr;
  610. }
  611. else
  612. {
  613. m_fRPCChanges = TRUE;
  614. }
  615. // Get the NameServiceProtocol value.
  616. hr = csif.HrGetString(pszAnswerSection,
  617. c_szNameServiceProt,
  618. &m_rpcData.strProt);
  619. if (FAILED(hr))
  620. {
  621. // ignore line not found errors
  622. if (hr == HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND))
  623. {
  624. hr = S_OK;
  625. }
  626. TraceError("HrProcessAnswerFile - Error on NameServiceProtocol field. "
  627. "Defaulting value", hr);
  628. m_rpcData.strProt = c_szProtWinNT;
  629. }
  630. else
  631. {
  632. m_fRPCChanges = TRUE;
  633. }
  634. err:
  635. TraceError("CMSClient::HrProcessAnswerFile", hr);
  636. return hr;
  637. }
  638. //
  639. // INetCfgProperties
  640. //
  641. //+---------------------------------------------------------------------------
  642. //
  643. // Member: CMSClient::MergePropPages
  644. //
  645. // Purpose: Called when this component's properties are about to be
  646. // brought up.
  647. //
  648. // Arguments:
  649. // pdwDefPages [out] Number of default pages to show.
  650. // pahpspPrivate [out] Array of property sheet handles to pages that this
  651. // component will show.
  652. // pcPrivate [out] Number of pages in array.
  653. // hwndParent [in] Parent window for any UI.
  654. // pszStartPage [out] Pointer to start page.
  655. //
  656. // Returns: HRESULT, Error code.
  657. //
  658. // Author: danielwe 22 Feb 1997
  659. //
  660. // Notes:
  661. //
  662. STDMETHODIMP CMSClient::MergePropPages(
  663. IN OUT DWORD* pdwDefPages,
  664. OUT LPBYTE* pahpspPrivate,
  665. OUT UINT* pcPages,
  666. IN HWND hwndParent,
  667. OUT PCWSTR* pszStartPage)
  668. {
  669. Validate_INetCfgProperties_MergePropPages (
  670. pdwDefPages, pahpspPrivate, pcPages, hwndParent, pszStartPage);
  671. HPROPSHEETPAGE *ahpsp = NULL;
  672. HRESULT hr = HrSetupPropSheets(&ahpsp, c_cPages);
  673. if (SUCCEEDED(hr))
  674. {
  675. *pahpspPrivate = (LPBYTE)ahpsp;
  676. // We don't want any default pages to be shown
  677. *pdwDefPages = 0;
  678. *pcPages = c_cPages;
  679. }
  680. Validate_INetCfgProperties_MergePropPages_Return(hr);
  681. TraceError("CMSClient::MergePropPages", hr);
  682. return hr;
  683. }
  684. STDMETHODIMP CMSClient::ValidateProperties(HWND hwndSheet)
  685. {
  686. return S_OK;
  687. }
  688. STDMETHODIMP CMSClient::CancelProperties()
  689. {
  690. return S_OK;
  691. }
  692. STDMETHODIMP CMSClient::ApplyProperties()
  693. {
  694. return S_OK;
  695. }
  696. //
  697. // INetCfgSystemNotify
  698. //
  699. STDMETHODIMP CMSClient::GetSupportedNotifications (DWORD* pdwNotificationFlag)
  700. {
  701. Validate_INetCfgSystemNotify_GetSupportedNotifications(pdwNotificationFlag);
  702. *pdwNotificationFlag = NCN_NETTRANS | NCN_NETSERVICE |
  703. NCN_ENABLE | NCN_DISABLE |
  704. NCN_ADD | NCN_REMOVE;
  705. return S_OK;
  706. }
  707. STDMETHODIMP CMSClient::SysQueryBindingPath (DWORD dwChangeFlag,
  708. INetCfgBindingPath* pncbp)
  709. {
  710. return S_OK;
  711. }
  712. STDMETHODIMP CMSClient::SysQueryComponent (DWORD dwChangeFlag,
  713. INetCfgComponent* pncc)
  714. {
  715. return S_OK;
  716. }
  717. STDMETHODIMP CMSClient::SysNotifyBindingPath (DWORD dwChangeFlag,
  718. INetCfgBindingPath* pncbpItem)
  719. {
  720. return S_FALSE;
  721. }
  722. STDMETHODIMP CMSClient::SysNotifyComponent(DWORD dwChangeFlag,
  723. INetCfgComponent* pncc)
  724. {
  725. HRESULT hr;
  726. Validate_INetCfgSystemNotify_SysNotifyComponent(dwChangeFlag, pncc);
  727. // Assume we won't be dirty as a result of this notification.
  728. //
  729. hr = S_FALSE;
  730. if (dwChangeFlag & (NCN_ADD | NCN_REMOVE))
  731. {
  732. if (FIsComponentId(c_szInfId_MS_Server, pncc))
  733. {
  734. if (dwChangeFlag & NCN_ADD)
  735. {
  736. m_eSrvState = eSrvEnable;
  737. hr = S_OK;
  738. }
  739. else if (dwChangeFlag & NCN_REMOVE)
  740. {
  741. m_eSrvState = eSrvDisable;
  742. hr = S_OK;
  743. }
  744. }
  745. }
  746. return hr;
  747. }
  748. HRESULT CMSClient::HrSetNetLogonDependencies(VOID)
  749. {
  750. static const WCHAR c_szLanmanServer[] = L"LanmanServer";
  751. static const WCHAR c_szNetLogon[] = L"NetLogon";
  752. HRESULT hr = S_OK;
  753. NT_PRODUCT_TYPE ProductType;
  754. if (RtlGetNtProductType(&ProductType))
  755. {
  756. if (NtProductLanManNt == ProductType)
  757. {
  758. // If domain controller, make NetLogon wait for LanmanServer
  759. CServiceManager sm;
  760. CService svc;
  761. hr = sm.HrOpen();
  762. if (SUCCEEDED(hr))
  763. {
  764. hr = sm.HrAddServiceDependency(c_szNetLogon, c_szLanmanServer);
  765. sm.Close();
  766. }
  767. if (FAILED(hr))
  768. {
  769. TraceError("CMSClient::HrSetNetLogonDependencies - "
  770. "Creating dependency of NetLogon on LanmanServer",
  771. hr);
  772. }
  773. }
  774. }
  775. if (SUCCEEDED(hr))
  776. {
  777. LSA_HANDLE h=0;
  778. POLICY_PRIMARY_DOMAIN_INFO* ppdi;
  779. LSA_OBJECT_ATTRIBUTES loa;
  780. ZeroMemory (&loa, sizeof(loa));
  781. loa.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
  782. NTSTATUS ntstatus;
  783. ntstatus = LsaOpenPolicy(NULL, &loa, POLICY_VIEW_LOCAL_INFORMATION, &h);
  784. if (FALSE != LSA_SUCCESS(ntstatus))
  785. {
  786. ntstatus = LsaQueryInformationPolicy(h, PolicyPrimaryDomainInformation, (VOID **) &ppdi);
  787. if (LSA_SUCCESS(ntstatus))
  788. {
  789. if (ppdi->Sid > 0) // Domain Member
  790. {
  791. hr = HrChangeServiceStartType(c_szNetLogon, SERVICE_AUTO_START);
  792. if (FAILED(hr))
  793. {
  794. TraceError("CMSClient::HrSetNetLogonDependencies - "
  795. "Install for Start - NetLogon",
  796. hr);
  797. }
  798. }
  799. LsaFreeMemory(ppdi);
  800. }
  801. LsaClose(h);
  802. }
  803. }
  804. TraceError("CMSClient::HrSetNetLogonDependencies",hr);
  805. return hr;
  806. }