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.

858 lines
25 KiB

  1. //
  2. // N W C L I O B J . C P P
  3. //
  4. // Implementation of the CNWClient notify object model
  5. //
  6. #include "pch.h"
  7. #pragma hdrstop
  8. #include "ncerror.h"
  9. #include "ncperms.h"
  10. #include "ncreg.h"
  11. #include "ncsetup.h"
  12. #include "ncsvc.h"
  13. #include "nwcliobj.h"
  14. #include <ncshell.h>
  15. extern const WCHAR c_szAfNWCWorkstationParameters[];
  16. extern const WCHAR c_szAfNWCWorkstationShares[];
  17. extern const WCHAR c_szAfNWCWorkstationDrives[];
  18. extern const WCHAR c_szInfId_MS_NWIPX[];
  19. extern const WCHAR c_szInfId_MS_Server[];
  20. //---[ Constants ]-------------------------------------------------------------
  21. static const WCHAR c_szNWClientParamPath[] = L"System\\CurrentControlSet\\Services\\NWCWorkstation\\Parameters";
  22. static const WCHAR c_szNWClientSharesPath[] = L"System\\CurrentControlSet\\Services\\NWCWorkstation\\Shares";
  23. static const WCHAR c_szNWClientDrivesPath[] = L"System\\CurrentControlSet\\Services\\NWCWorkstation\\Drives";
  24. static const WCHAR c_szLMServerParamPath[] = L"System\\CurrentControlSet\\Services\\LanmanServer\\Parameters";
  25. static const WCHAR c_szLMServerLinkagePath[] = L"System\\CurrentControlSet\\Services\\LanmanServer\\Linkage";
  26. static const WCHAR c_szEnableSharedNetDrives[] = L"EnableSharedNetDrives";
  27. static const WCHAR c_szOtherDependencies[] = L"OtherDependencies";
  28. static const WCHAR c_szGWEnabledValue[] = L"GatewayEnabled";
  29. extern const WCHAR c_szSvcLmServer[]; // L"LanmanServer";
  30. extern const WCHAR c_szSvcNWCWorkstation[]; // L"NWCWorkstation";
  31. HRESULT HrRefreshEntireNetwork();
  32. HRESULT HrGetEntireNetworkPidl(LPITEMIDLIST *ppidlFolder);
  33. //
  34. // Constructor
  35. //
  36. CNWClient::CNWClient()
  37. {
  38. // Initialize member variables.
  39. m_pnc = NULL;
  40. m_pncc = NULL;
  41. m_eInstallAction = eActUnknown;
  42. m_hlibConfig = NULL;
  43. m_fUpgrade = FALSE;
  44. // Get the product flavor (PF_WORKSTATION or PF_SERVER). Use this
  45. // to decide whether or not we need to install the "server" component.
  46. //
  47. GetProductFlavor(NULL, &m_pf);
  48. }
  49. CNWClient::~CNWClient()
  50. {
  51. ReleaseObj(m_pncc);
  52. ReleaseObj(m_pnc);
  53. // Release KEY handles here.
  54. }
  55. //
  56. // INetCfgNotify
  57. //
  58. STDMETHODIMP CNWClient::Initialize( INetCfgComponent * pnccItem,
  59. INetCfg* pnc,
  60. BOOL fInstalling)
  61. {
  62. Validate_INetCfgNotify_Initialize(pnccItem, pnc, fInstalling);
  63. TraceTag(ttidNWClientCfg, "CNWClient::Initialize");
  64. m_pncc = pnccItem;
  65. m_pnc = pnc;
  66. AssertSz(m_pncc, "m_pncc NULL in CNWClient::Initialize");
  67. AssertSz(m_pnc, "m_pnc NULL in CNWClient::Initialize");
  68. // Addref the config objects
  69. //
  70. AddRefObj(m_pncc);
  71. AddRefObj(m_pnc);
  72. return S_OK;
  73. }
  74. //+---------------------------------------------------------------------------
  75. //
  76. // Member: CNWClient::HrRestoreRegistry
  77. //
  78. // Purpose: Restores the contents of the registry for this component
  79. //
  80. // Arguments:
  81. // (none)
  82. //
  83. // Returns: Win32 error if failed, otherwise S_OK
  84. //
  85. // Author: jeffspr 13 Aug 1997
  86. //
  87. // Notes:
  88. //
  89. HRESULT CNWClient::HrRestoreRegistry()
  90. {
  91. HRESULT hr = S_OK;
  92. HKEY hkey = NULL;
  93. TOKEN_PRIVILEGES * ptpRestore = NULL;
  94. DWORD dwDisp = 0;
  95. static const WCHAR c_szSvcDLLName[] = L"%SystemRoot%\\System32\\nwwks.dll";
  96. static const WCHAR c_szServiceDll[] = L"ServiceDll";
  97. TraceTag(ttidNWClientCfg, "CNWClient::HrRestoreRegistry");
  98. if (!m_strParamsRestoreFile.empty() ||
  99. !m_strDrivesRestoreFile.empty() ||
  100. !m_strSharesRestoreFile.empty())
  101. {
  102. hr = HrEnableAllPrivileges(&ptpRestore);
  103. }
  104. if (SUCCEEDED(hr) && !m_strParamsRestoreFile.empty())
  105. {
  106. // Ensure key is there by creating it
  107. hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, c_szNWClientParamPath, 0,
  108. KEY_ALL_ACCESS, NULL, &hkey, &dwDisp);
  109. if (SUCCEEDED(hr))
  110. {
  111. hr = HrRegRestoreKey(hkey, m_strParamsRestoreFile.c_str(), 0);
  112. if (FAILED(hr))
  113. {
  114. TraceError("CNWClient::HrRestoreRegistry - HrRestoreRegistry for "
  115. "Parameters", hr);
  116. hr = S_OK;
  117. }
  118. //
  119. // Bug 182442. HrRegRestoreKey above overwrites the ServiceDll value added
  120. // from the inf file. So, we manually save it.
  121. //
  122. hr = HrRegSetValueEx(hkey, c_szServiceDll, REG_EXPAND_SZ,
  123. (const BYTE *)c_szSvcDLLName,
  124. (wcslen(c_szSvcDLLName) + 1) * sizeof(WCHAR));
  125. if (FAILED(hr))
  126. {
  127. TraceError("CNWClient::HrRestoreRegistry - HrRestoreRegistry for "
  128. "ServiceDll", hr);
  129. hr = S_OK;
  130. }
  131. RegCloseKey(hkey);
  132. hkey = NULL;
  133. }
  134. }
  135. if (!m_strSharesRestoreFile.empty())
  136. {
  137. // Ensure key is there by creating it
  138. hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, c_szNWClientSharesPath, 0,
  139. KEY_ALL_ACCESS, NULL, &hkey, &dwDisp);
  140. if (SUCCEEDED(hr))
  141. {
  142. hr = HrRegRestoreKey(hkey, m_strSharesRestoreFile.c_str(), 0);
  143. if (FAILED(hr))
  144. {
  145. TraceError("CNWClient::HrRestoreRegistry - HrRestoreRegistry for "
  146. "Shares", hr);
  147. hr = S_OK;
  148. }
  149. RegCloseKey(hkey);
  150. hkey = NULL;
  151. }
  152. }
  153. if (!m_strDrivesRestoreFile.empty())
  154. {
  155. // Ensure key is there by creating it
  156. hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, c_szNWClientDrivesPath, 0,
  157. KEY_ALL_ACCESS, NULL, &hkey, &dwDisp);
  158. if (SUCCEEDED(hr))
  159. {
  160. hr = HrRegRestoreKey(hkey, m_strDrivesRestoreFile.c_str(), 0);
  161. if (FAILED(hr))
  162. {
  163. TraceError("CNWClient::HrRestoreRegistry - HrRestoreRegistry for "
  164. "Drives", hr);
  165. hr = S_OK;
  166. }
  167. RegCloseKey(hkey);
  168. hkey = NULL;
  169. }
  170. }
  171. if (ptpRestore)
  172. {
  173. hr = HrRestorePrivileges(ptpRestore);
  174. delete [] reinterpret_cast<BYTE *>(ptpRestore);
  175. }
  176. TraceError("CNWClient::HrRestoreRegistry", hr);
  177. return hr;
  178. }
  179. static const WCHAR c_szDefaultLocation[] = L"DefaultLocation";
  180. static const WCHAR c_szDefaultScriptOptions[] = L"DefaultScriptOptions";
  181. HRESULT CNWClient::HrWriteAnswerFileParams()
  182. {
  183. HRESULT hr = S_OK;
  184. TraceTag(ttidNWClientCfg, "CNWClient::HrWriteAnswerFileParams");
  185. // Don't do anything if we don't have anything to write to the
  186. // registry
  187. if (!m_strDefaultLocation.empty() || (m_dwLogonScript != 0xFFFFFFFF))
  188. {
  189. HKEY hkey;
  190. DWORD dwDisp;
  191. // Ensure key is there by creating it
  192. hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, c_szNWClientParamPath, 0,
  193. KEY_ALL_ACCESS, NULL, &hkey, &dwDisp);
  194. if (SUCCEEDED(hr))
  195. {
  196. if (!m_strDefaultLocation.empty())
  197. {
  198. hr = HrRegSetString(hkey, c_szDefaultLocation,
  199. m_strDefaultLocation);
  200. if (FAILED(hr))
  201. {
  202. TraceError("CNWClient::HrWriteAnswerFileParams - Couldn't"
  203. " set DefaultLocation", hr);
  204. hr = S_OK;
  205. }
  206. }
  207. if (m_dwLogonScript != 0xFFFFFFFF)
  208. {
  209. // 0x3 is combination of the following:
  210. //
  211. // #define NW_LOGONSCRIPT_DISABLED 0x00000000
  212. // #define NW_LOGONSCRIPT_ENABLED 0x00000001
  213. // #define NW_LOGONSCRIPT_4X_ENABLED 0x00000002
  214. //
  215. hr = HrRegSetDword(hkey, c_szDefaultScriptOptions,
  216. m_dwLogonScript ? 0x3 : 0x0);
  217. if (FAILED(hr))
  218. {
  219. TraceError("CNWClient::HrWriteAnswerFileParams - Couldn't"
  220. " set DefaultLocation", hr);
  221. hr = S_OK;
  222. }
  223. }
  224. RegCloseKey(hkey);
  225. }
  226. }
  227. TraceError("CNWClient::HrWriteAnswerFileParams", hr);
  228. return hr;
  229. }
  230. static const WCHAR c_szPreferredServer[] = L"PreferredServer";
  231. static const WCHAR c_szDefaultTree[] = L"DefaultTree";
  232. static const WCHAR c_szDefaultContext[] = L"DefaultContext";
  233. static const WCHAR c_szLogonScript[] = L"LogonScript";
  234. //+---------------------------------------------------------------------------
  235. //
  236. // Member: CNWClient::HrProcessAnswerFile
  237. //
  238. // Purpose: Handles necessary processing of contents of the answer file.
  239. //
  240. // Arguments:
  241. // pszAnswerFile [in] Filename of answer file for upgrade.
  242. // pszAnswerSection [in] Comma-separated list of sections in the
  243. // file appropriate to this component.
  244. //
  245. // Returns: S_OK if successful, setup API error otherwise.
  246. //
  247. // Author: jeffspr 8 May 1997
  248. //
  249. // Notes:
  250. //
  251. HRESULT CNWClient::HrProcessAnswerFile( PCWSTR pszAnswerFile,
  252. PCWSTR pszAnswerSection)
  253. {
  254. HRESULT hr;
  255. CSetupInfFile csif;
  256. TraceTag(ttidNWClientCfg, "CNWClient::HrProcessAnswerFile");
  257. // Open the answer file.
  258. hr = csif.HrOpen(pszAnswerFile, NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
  259. if (FAILED(hr))
  260. {
  261. hr = S_OK;
  262. goto Exit;
  263. }
  264. // Restore portions of the registry based on file names from the answer
  265. // file
  266. // Get restore file for "Parameters" key
  267. hr = csif.HrGetString(pszAnswerSection, c_szAfNWCWorkstationParameters,
  268. &m_strParamsRestoreFile);
  269. if (FAILED(hr))
  270. {
  271. TraceError("CNWClient::HrProcessAnswerFile - Error restoring "
  272. "Parameters key", hr);
  273. // oh well, just continue
  274. hr = S_OK;
  275. }
  276. // Get restore file for "Shares" key
  277. hr = csif.HrGetString(pszAnswerSection, c_szAfNWCWorkstationShares,
  278. &m_strSharesRestoreFile);
  279. if (FAILED(hr))
  280. {
  281. TraceError("CNWClient::HrProcessAnswerFile - Error restoring "
  282. "Shares key", hr);
  283. // oh well, just continue
  284. hr = S_OK;
  285. }
  286. // Get restore file for "Drives" key
  287. hr = csif.HrGetString(pszAnswerSection, c_szAfNWCWorkstationDrives,
  288. &m_strDrivesRestoreFile);
  289. if (FAILED(hr))
  290. {
  291. TraceError("CNWClient::HrProcessAnswerFile - Error restoring "
  292. "Drives key", hr);
  293. // oh well, just continue
  294. hr = S_OK;
  295. }
  296. //
  297. // Read answer file parameters (these are all optional so no errors are
  298. // saved)
  299. //
  300. TraceTag(ttidNWClientCfg, "Reading PreferredServer from answer file");
  301. // Read contents of PreferredServer key.
  302. if (FAILED(csif.HrGetString(pszAnswerSection, c_szPreferredServer,
  303. &m_strDefaultLocation)))
  304. {
  305. // Couldn't read PreferredServer key, so we must assume that the other
  306. // two values are present
  307. tstring strDefaultTree;
  308. tstring strDefaultContext;
  309. TraceTag(ttidNWClientCfg, "PreferredServer not found so trying "
  310. "DefaultTree and DefaultContext instead");
  311. // Read contents of DefaultTree key.
  312. if (SUCCEEDED(csif.HrGetString(pszAnswerSection, c_szDefaultTree,
  313. &strDefaultTree)))
  314. {
  315. TraceTag(ttidNWClientCfg, "Got DefaultTree ok: %S",
  316. strDefaultTree.c_str());
  317. // Read contents of DefaultContext key.
  318. hr = csif.HrGetString(pszAnswerSection, c_szDefaultContext,
  319. &strDefaultContext);
  320. if (SUCCEEDED(hr))
  321. {
  322. TraceTag(ttidNWClientCfg, "Got DefaultContext ok: %S",
  323. strDefaultContext.c_str());
  324. // Munge the DefaultLocation value with the DefaultTree and
  325. // DefaultContext values read from the answer file
  326. m_strDefaultLocation = L"*";
  327. m_strDefaultLocation += strDefaultTree;
  328. m_strDefaultLocation += L"\\";
  329. m_strDefaultLocation += strDefaultContext;
  330. TraceTag(ttidNWClientCfg, "DefaultLocation is: %S",
  331. m_strDefaultLocation.c_str());
  332. }
  333. else
  334. {
  335. TraceError("CNWClient::HrProcessAnswerFile - error reading "
  336. "DefaultContext", hr);
  337. hr = S_OK;
  338. }
  339. }
  340. }
  341. else
  342. {
  343. TraceTag(ttidNWClientCfg, "DefaultLocation is: %S",
  344. m_strDefaultLocation.c_str());
  345. }
  346. // Init to impossible value so we know whether we read it or not
  347. m_dwLogonScript = 0xFFFFFFFF;
  348. // Read contents of LogonScript key.
  349. (VOID) csif.HrGetStringAsBool(pszAnswerSection, c_szLogonScript,
  350. reinterpret_cast<BOOL *>(&m_dwLogonScript));
  351. TraceTag(ttidNWClientCfg, "LogonScript is: %ld", m_dwLogonScript);
  352. Exit:
  353. TraceError("CNWClient::HrProcessAnswerFile", hr);
  354. return hr;
  355. }
  356. STDMETHODIMP CNWClient::Upgrade(DWORD dwSetupFlags, DWORD dwUpgradeFromBuildNo)
  357. {
  358. return S_FALSE;
  359. }
  360. STDMETHODIMP CNWClient::ReadAnswerFile(PCWSTR pszAnswerFile,
  361. PCWSTR pszAnswerSection)
  362. {
  363. Validate_INetCfgNotify_ReadAnswerFile(pszAnswerFile,
  364. pszAnswerSection);
  365. TraceTag(ttidNWClientCfg, "CNWClient::ReadAnswerFile");
  366. m_eInstallAction = eActInstall;
  367. // If we're not already installed, do the work.
  368. //
  369. if (pszAnswerFile && pszAnswerSection)
  370. {
  371. HRESULT hr = HrProcessAnswerFile(pszAnswerFile, pszAnswerSection);
  372. if (FAILED(hr))
  373. {
  374. TraceError("CNWClient::NetworkInstall - Answer file has errors. Defaulting "
  375. "all information as if answer file did not exist.",
  376. hr);
  377. }
  378. }
  379. return S_OK;
  380. }
  381. STDMETHODIMP CNWClient::Install(DWORD dw)
  382. {
  383. Validate_INetCfgNotify_Install(dw);
  384. TraceTag(ttidNWClientCfg, "CNWClient::Install");
  385. m_eInstallAction = eActInstall;
  386. // Install the NWLink sub-component
  387. HRESULT hr = HrInstallComponentOboComponent(m_pnc, NULL,
  388. GUID_DEVCLASS_NETTRANS,
  389. c_szInfId_MS_NWIPX,
  390. m_pncc,
  391. NULL);
  392. if (SUCCEEDED(hr))
  393. {
  394. // If we're NT Server, we DO need to install it, as what we're
  395. // installing is GSNW, not CSNW (and therefore, since we're sharing
  396. // resources, we need to use the server service)
  397. //
  398. if (PF_SERVER == m_pf)
  399. {
  400. NETWORK_INSTALL_PARAMS nip;
  401. nip.dwSetupFlags = dw;
  402. nip.dwUpgradeFromBuildNo = -1;
  403. nip.pszAnswerFile = NULL;
  404. nip.pszAnswerSection = NULL;
  405. // Install Server
  406. hr = HrInstallComponentOboComponent(m_pnc, &nip,
  407. GUID_DEVCLASS_NETSERVICE,
  408. c_szInfId_MS_Server,
  409. m_pncc,
  410. NULL);
  411. }
  412. }
  413. TraceError("CNWClient::Install", hr);
  414. return hr;
  415. }
  416. STDMETHODIMP CNWClient::Removing()
  417. {
  418. TraceTag(ttidNWClientCfg, "CNWClient::Removing");
  419. m_eInstallAction = eActRemove;
  420. // Remove the NWLink service
  421. //
  422. HRESULT hr = HrRemoveComponentOboComponent(m_pnc,
  423. GUID_DEVCLASS_NETTRANS,
  424. c_szInfId_MS_NWIPX,
  425. m_pncc);
  426. if (SUCCEEDED(hr))
  427. {
  428. if (PF_SERVER == m_pf)
  429. {
  430. // Remove our reference of the Server service
  431. //
  432. hr = HrRemoveComponentOboComponent(m_pnc,
  433. GUID_DEVCLASS_NETSERVICE,
  434. c_szInfId_MS_Server,
  435. m_pncc);
  436. }
  437. }
  438. if (hr == NETCFG_S_STILL_REFERENCED)
  439. {
  440. // If services are still in use, that's OK, I just needed to make
  441. // sure that I released my reference.
  442. //
  443. hr = S_OK;
  444. }
  445. Validate_INetCfgNotify_Removing_Return(hr);
  446. TraceError("CNWClient::Removing()", hr);
  447. return hr;
  448. }
  449. STDMETHODIMP CNWClient::Validate()
  450. {
  451. return S_OK;
  452. }
  453. STDMETHODIMP CNWClient::CancelChanges()
  454. {
  455. return S_OK;
  456. }
  457. STDMETHODIMP CNWClient::ApplyRegistryChanges()
  458. {
  459. HRESULT hr = S_OK;
  460. TraceTag(ttidNWClientCfg, "CNWClient::ApplyRegistryChanges");
  461. if (m_eInstallAction == eActRemove)
  462. {
  463. hr = HrRemoveCodeFromOldINF();
  464. }
  465. else if (m_eInstallAction == eActInstall)
  466. {
  467. hr = HrRestoreRegistry();
  468. if (FAILED(hr))
  469. {
  470. TraceError("CNWClient::ApplyRegistryChanges - HrRestoreRegistry non-fatal error",
  471. hr);
  472. hr = S_OK;
  473. }
  474. hr = HrWriteAnswerFileParams();
  475. if (FAILED(hr))
  476. {
  477. TraceError("CNWClient::ApplyRegistryChanges - HrWriteAnswerFileParams "
  478. "non-fatal error", hr);
  479. hr = S_OK;
  480. }
  481. // If gateway is enabled, modify lanmanserver appropriately
  482. // Ignore the return code other than to trace it.
  483. //
  484. hr = HrEnableGatewayIfNeeded();
  485. if (FAILED(hr))
  486. {
  487. TraceError("CNWClient::ApplyRegistryChanges - HrEnableGatewayIfNeeded non-fatal error", hr);
  488. }
  489. hr = HrInstallCodeFromOldINF();
  490. }
  491. Validate_INetCfgNotify_Apply_Return(hr);
  492. TraceError("CNWClient::ApplyRegistryChanges",
  493. (hr == S_FALSE) ? S_OK : hr);
  494. return hr;
  495. }
  496. STDMETHODIMP CNWClient::ApplyPnpChanges (
  497. INetCfgPnpReconfigCallback* pICallback)
  498. {
  499. HRESULT hr;
  500. hr = HrRefreshEntireNetwork();
  501. if (FAILED(hr))
  502. {
  503. TraceError("CNWClient::ApplyPnpChanges - HrRefreshEntireNetwork"
  504. "non-fatal error", hr);
  505. hr = S_OK;
  506. }
  507. // GlennC can't do the work to make NW Client PnP so we're forced to
  508. // prompt for a reboot for any change.
  509. //
  510. return NETCFG_S_REBOOT;
  511. }
  512. // Note -- Don't convert this to a constant. We need copies of it within the
  513. // functions because ParseDisplayName actually mangles the string.
  514. //
  515. #define ENTIRE_NETWORK_PATH L"::{208D2C60-3AEA-1069-A2D7-08002B30309D}\\EntireNetwork"
  516. //+---------------------------------------------------------------------------
  517. //
  518. // Function: HrGetEntireNetworkPidl
  519. //
  520. // Purpose: Get the pidl for "Entire Network". Used in places where we're
  521. // not folder specific, but we still need to update folder
  522. // entries.
  523. //
  524. // Arguments:
  525. // ppidlFolder [out] Return parameter for the folder pidl
  526. //
  527. // Returns:
  528. //
  529. // Author: anbrad 08 Jun 1999
  530. // jeffspr 13 Jun 1998
  531. //
  532. // Notes:
  533. //
  534. HRESULT HrGetEntireNetworkPidl(LPITEMIDLIST *ppidlFolder)
  535. {
  536. HRESULT hr = S_OK;
  537. LPSHELLFOLDER pshf = NULL;
  538. LPITEMIDLIST pidlFolder = NULL;
  539. Assert(ppidlFolder);
  540. WCHAR szEntireNetworkPath[] = ENTIRE_NETWORK_PATH;
  541. // Get the desktop folder, so we can parse the display name and get
  542. // the UI object of the connections folder
  543. //
  544. hr = SHGetDesktopFolder(&pshf);
  545. if (SUCCEEDED(hr))
  546. {
  547. ULONG chEaten;
  548. hr = pshf->ParseDisplayName(NULL, 0, (WCHAR *) szEntireNetworkPath,
  549. &chEaten, &pidlFolder, NULL);
  550. ReleaseObj(pshf);
  551. }
  552. // If succeeded, fill in the return param.
  553. //
  554. if (SUCCEEDED(hr))
  555. {
  556. *ppidlFolder = pidlFolder;
  557. }
  558. else
  559. {
  560. // If we failed, then delete the pidl if we already got it.
  561. //
  562. if (pidlFolder)
  563. SHFree(pidlFolder);
  564. }
  565. TraceHr(ttidNWClientCfg, FAL, hr, FALSE, "HrGetEntireNetworkPidl");
  566. return hr;
  567. }
  568. //+---------------------------------------------------------------------------
  569. //
  570. // Function: HrRefreshEntireNetwork
  571. //
  572. // Purpose: Update the "Entire Network" portion of the shell due to
  573. // the addition of a new networking client (NWClient)
  574. //
  575. // Arguments:
  576. // (none)
  577. //
  578. // Returns:
  579. //
  580. // Author: anbrad 08 Jun 1999
  581. //
  582. // Notes:
  583. //
  584. HRESULT HrRefreshEntireNetwork()
  585. {
  586. HRESULT hr = S_OK;
  587. HCURSOR hcWait = SetCursor(LoadCursor(NULL, IDC_WAIT));
  588. LPITEMIDLIST pidlFolder = NULL;;
  589. hr = HrGetEntireNetworkPidl(&pidlFolder);
  590. // If we now have a pidl, send the GenerateEvent to update the item
  591. //
  592. if (SUCCEEDED(hr))
  593. {
  594. Assert(pidlFolder);
  595. // SHCNE_UPDATEDIR?ITEM
  596. GenerateEvent(SHCNE_UPDATEDIR, pidlFolder, NULL, NULL);
  597. }
  598. if (hcWait)
  599. {
  600. SetCursor(hcWait);
  601. }
  602. if (pidlFolder)
  603. {
  604. SHFree(pidlFolder);
  605. }
  606. TraceHr(ttidError, FAL, hr, FALSE, "HrRefreshEntireNetwork");
  607. return hr;
  608. }
  609. //+---------------------------------------------------------------------------
  610. //
  611. // Function: HrEnableGatewayIfNeeded
  612. //
  613. // Purpose: Update the Lanman dependencies, if appropriate (meaning if
  614. // gateway is enabled).
  615. //
  616. // Arguments:
  617. // (none)
  618. //
  619. // Returns:
  620. //
  621. // Author: jeffspr 19 Aug 1999
  622. //
  623. // Notes:
  624. //
  625. HRESULT CNWClient::HrEnableGatewayIfNeeded()
  626. {
  627. HRESULT hr = S_OK;
  628. HKEY hKey = NULL;
  629. DWORD dwValue = 0;
  630. CServiceManager sm;
  631. CService svc;
  632. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE,
  633. c_szNWClientParamPath,
  634. KEY_READ,
  635. &hKey);
  636. if (FAILED(hr))
  637. {
  638. TraceError("Couldn't open NWClient param key", hr);
  639. goto Exit;
  640. }
  641. hr = HrRegQueryDword(hKey,
  642. c_szGWEnabledValue,
  643. &dwValue);
  644. if (FAILED(hr))
  645. {
  646. if (hr != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
  647. {
  648. TraceError("Couldn't query the GWEnabled Value", hr);
  649. goto Exit;
  650. }
  651. else
  652. {
  653. dwValue = 0;
  654. }
  655. }
  656. else
  657. {
  658. // Normalize to bool
  659. //
  660. dwValue = !!dwValue;
  661. }
  662. RegSafeCloseKey(hKey);
  663. hKey = NULL;
  664. // If there are gateway services present, then add the dependencies
  665. // to LanmanServer
  666. //
  667. if (dwValue > 0)
  668. {
  669. // Set the value in the registry for the server paramaters.
  670. //
  671. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE,
  672. c_szLMServerParamPath,
  673. KEY_WRITE,
  674. &hKey);
  675. if (SUCCEEDED(hr))
  676. {
  677. hr = HrRegSetDword(hKey,
  678. c_szEnableSharedNetDrives,
  679. dwValue);
  680. RegSafeCloseKey(hKey);
  681. hKey = NULL;
  682. }
  683. hr = sm.HrOpen();
  684. if (SUCCEEDED(hr))
  685. {
  686. hr = sm.HrOpenService(&svc, c_szSvcLmServer, NO_LOCK);
  687. if (SUCCEEDED(hr))
  688. {
  689. // Add dependency of NWC Workstation to Server
  690. //
  691. hr = sm.HrAddServiceDependency(c_szSvcLmServer,
  692. c_szSvcNWCWorkstation);
  693. if (SUCCEEDED(hr))
  694. {
  695. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE,
  696. c_szLMServerLinkagePath,
  697. KEY_READ | KEY_WRITE,
  698. &hKey);
  699. if (SUCCEEDED(hr))
  700. {
  701. // Add the "OtherDependencies" to LanmanServer for legacy reasons
  702. //
  703. hr = HrRegAddStringToMultiSz(c_szSvcNWCWorkstation,
  704. hKey,
  705. NULL,
  706. c_szOtherDependencies,
  707. STRING_FLAG_ENSURE_AT_END | STRING_FLAG_DONT_MODIFY_IF_PRESENT,
  708. 0);
  709. RegSafeCloseKey(hKey);
  710. hKey = NULL;
  711. }
  712. }
  713. }
  714. else
  715. {
  716. TraceError("Failed to open LanmanServer service for dependency mods", hr);
  717. }
  718. }
  719. else
  720. {
  721. TraceError("Failed to open service control manager", hr);
  722. }
  723. }
  724. Exit:
  725. TraceHr(ttidNWClientCfg, FAL, hr, FALSE, "HrEnableGatewayIfNeeded");
  726. return hr;
  727. }