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.

973 lines
26 KiB

  1. /****************************************************************************
  2. *
  3. * icfg32.cpp
  4. *
  5. * Microsoft Confidential
  6. * Copyright (c) Microsoft Corporation 1992-1997
  7. * All rights reserved
  8. *
  9. * This module provides the implementation of the methods for
  10. * the NT specific functionality of inetcfg
  11. *
  12. * 6/5/97 ChrisK Inherited from AmnonH
  13. * 7/3/97 ShaunCo Modfied for NT5
  14. * 5/1/98 donaldm Brought over from NT tree to ICW tree as part of NTCFG95.DLL
  15. ***************************************************************************/
  16. #define INITGUID
  17. #include <wtypes.h>
  18. #include <cfgapi.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <setupapi.h>
  22. #include <basetyps.h>
  23. #include <devguid.h>
  24. #include <lmsname.h>
  25. #include "debug.h"
  26. #include "icwunicd.h"
  27. #include <netcfgx.h>
  28. #define REG_DATA_EXTRA_SPACE 255
  29. DWORD g_dwLastError = ERROR_SUCCESS;
  30. ULONG ReleaseObj
  31. (
  32. IUnknown* punk
  33. )
  34. {
  35. return (punk) ? punk->Release () : 0;
  36. }
  37. //+---------------------------------------------------------------------------
  38. //
  39. // Function: HrCreateAndInitializeINetCfg
  40. //
  41. // Purpose: Cocreate and initialize the root INetCfg object. This will
  42. // optionally initialize COM for the caller too.
  43. //
  44. // Arguments:
  45. // pfInitCom [in,out] TRUE to call CoInitialize before creating.
  46. // returns TRUE if COM was successfully
  47. // initialized FALSE if not. If NULL, means
  48. // don't initialize COM.
  49. // ppnc [out] The returned INetCfg object.
  50. // fGetWriteLock [in] TRUE if a writable INetCfg is needed
  51. // cmsTimeout [in] See INetCfg::AcquireWriteLock
  52. // szwClientDesc [in] See INetCfg::AcquireWriteLock
  53. // ppszwClientDesc [out] See INetCfg::AcquireWriteLock
  54. //
  55. // Returns: S_OK or an error code.
  56. //
  57. // Author: shaunco 7 May 1997
  58. //
  59. // Notes:
  60. //
  61. HRESULT HrCreateAndInitializeINetCfg
  62. (
  63. BOOL* pfInitCom,
  64. INetCfg** ppnc,
  65. BOOL fGetWriteLock,
  66. DWORD cmsTimeout,
  67. LPCWSTR szwClientDesc,
  68. LPWSTR* ppszwClientDesc
  69. )
  70. {
  71. Assert (ppnc);
  72. // Initialize the output parameter.
  73. *ppnc = NULL;
  74. if (ppszwClientDesc)
  75. {
  76. *ppszwClientDesc = NULL;
  77. }
  78. // Initialize COM if the caller requested.
  79. HRESULT hr = S_OK;
  80. if (pfInitCom && *pfInitCom)
  81. {
  82. hr = CoInitializeEx( NULL,
  83. COINIT_DISABLE_OLE1DDE | COINIT_MULTITHREADED );
  84. if (RPC_E_CHANGED_MODE == hr)
  85. {
  86. hr = S_OK;
  87. if (pfInitCom)
  88. {
  89. *pfInitCom = FALSE;
  90. }
  91. }
  92. }
  93. if (SUCCEEDED(hr))
  94. {
  95. // Create the object implementing INetCfg.
  96. //
  97. INetCfg* pnc;
  98. hr = CoCreateInstance(CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER,
  99. IID_INetCfg, reinterpret_cast<void**>(&pnc));
  100. if (SUCCEEDED(hr))
  101. {
  102. INetCfgLock * pnclock = NULL;
  103. if (fGetWriteLock)
  104. {
  105. // Get the locking interface
  106. hr = pnc->QueryInterface(IID_INetCfgLock,
  107. reinterpret_cast<LPVOID *>(&pnclock));
  108. if (SUCCEEDED(hr))
  109. {
  110. // Attempt to lock the INetCfg for read/write
  111. hr = pnclock->AcquireWriteLock(cmsTimeout, szwClientDesc,
  112. ppszwClientDesc);
  113. if (S_FALSE == hr)
  114. {
  115. // Couldn't acquire the lock
  116. hr = NETCFG_E_NO_WRITE_LOCK;
  117. }
  118. }
  119. }
  120. if (SUCCEEDED(hr))
  121. {
  122. // Initialize the INetCfg object.
  123. //
  124. hr = pnc->Initialize(NULL);
  125. if (SUCCEEDED(hr))
  126. {
  127. *ppnc = pnc;
  128. pnc->AddRef ();
  129. }
  130. else
  131. {
  132. if (pnclock)
  133. {
  134. pnclock->ReleaseWriteLock();
  135. }
  136. }
  137. // Transfer reference to caller.
  138. }
  139. ReleaseObj(pnclock);
  140. ReleaseObj(pnc);
  141. }
  142. // If we failed anything above, and we've initialized COM,
  143. // be sure an uninitialize it.
  144. //
  145. if (FAILED(hr) && pfInitCom && *pfInitCom)
  146. {
  147. CoUninitialize ();
  148. }
  149. }
  150. return hr;
  151. }
  152. //+---------------------------------------------------------------------------
  153. //
  154. // Function: HrUninitializeAndUnlockINetCfg
  155. //
  156. // Purpose: Uninitializes and unlocks the INetCfg object
  157. //
  158. // Arguments:
  159. // pnc [in] INetCfg to uninitialize and unlock
  160. //
  161. // Returns: S_OK if success, OLE or Win32 error otherwise
  162. //
  163. // Author: danielwe 13 Nov 1997
  164. //
  165. // Notes:
  166. //
  167. //+---------------------------------------------------------------------------
  168. HRESULT HrUninitializeAndUnlockINetCfg
  169. (
  170. INetCfg* pnc
  171. )
  172. {
  173. HRESULT hr = S_OK;
  174. hr = pnc->Uninitialize();
  175. if (SUCCEEDED(hr))
  176. {
  177. INetCfgLock * pnclock;
  178. // Get the locking interface
  179. hr = pnc->QueryInterface(IID_INetCfgLock,
  180. reinterpret_cast<LPVOID *>(&pnclock));
  181. if (SUCCEEDED(hr))
  182. {
  183. // Attempt to lock the INetCfg for read/write
  184. hr = pnclock->ReleaseWriteLock();
  185. ReleaseObj(pnclock);
  186. }
  187. }
  188. return hr;
  189. }
  190. //+---------------------------------------------------------------------------
  191. //
  192. // Function: HrUninitializeAndReleaseINetCfg
  193. //
  194. // Purpose: Unintialize and release an INetCfg object. This will
  195. // optionally uninitialize COM for the caller too.
  196. //
  197. // Arguments:
  198. // fUninitCom [in] TRUE to uninitialize COM after the INetCfg is
  199. // uninitialized and released.
  200. // pnc [in] The INetCfg object.
  201. // fHasLock [in] TRUE if the INetCfg was locked for write and
  202. // must be unlocked.
  203. //
  204. // Returns: S_OK or an error code.
  205. //
  206. // Author: shaunco 7 May 1997
  207. //
  208. // Notes: The return value is the value returned from
  209. // INetCfg::Uninitialize. Even if this fails, the INetCfg
  210. // is still released. Therefore, the return value is for
  211. // informational purposes only. You can't touch the INetCfg
  212. // object after this call returns.
  213. //
  214. //+---------------------------------------------------------------------------
  215. HRESULT HrUninitializeAndReleaseINetCfg
  216. (
  217. BOOL fUninitCom,
  218. INetCfg* pnc,
  219. BOOL fHasLock
  220. )
  221. {
  222. Assert (pnc);
  223. HRESULT hr = S_OK;
  224. if (fHasLock)
  225. {
  226. hr = HrUninitializeAndUnlockINetCfg(pnc);
  227. }
  228. else
  229. {
  230. hr = pnc->Uninitialize ();
  231. }
  232. ReleaseObj (pnc);
  233. if (fUninitCom)
  234. {
  235. CoUninitialize ();
  236. }
  237. return hr;
  238. }
  239. //+---------------------------------------------------------------------------
  240. //
  241. // Function: HrInstallComponent
  242. //
  243. // Purpose: Install the component with a specified id.
  244. //
  245. // Arguments:
  246. // pnc [in] INetCfg pointer.
  247. // pguidClass [in] Class guid of the component to install.
  248. // pszwComponentId [in] Component id to install.
  249. // ppncc [out] (Optional) Returned component that was
  250. // installed.
  251. //
  252. // Returns: S_OK or an error code.
  253. //
  254. // Author: shaunco 4 Jan 1998
  255. //
  256. // Notes:
  257. //
  258. //+---------------------------------------------------------------------------
  259. HRESULT HrInstallComponent
  260. (
  261. INetCfg* pnc,
  262. const GUID* pguidClass,
  263. LPCWSTR pszwComponentId,
  264. INetCfgComponent** ppncc
  265. )
  266. {
  267. Assert (pnc);
  268. Assert (pszwComponentId);
  269. // Initialize output parameter.
  270. //
  271. if (ppncc)
  272. {
  273. *ppncc = NULL;
  274. }
  275. // Get the class setup object.
  276. //
  277. INetCfgClassSetup* pncclasssetup;
  278. HRESULT hr = pnc->QueryNetCfgClass (pguidClass, IID_INetCfgClassSetup,
  279. reinterpret_cast<void**>(&pncclasssetup));
  280. if (SUCCEEDED(hr))
  281. {
  282. OBO_TOKEN OboToken;
  283. ZeroMemory (&OboToken, sizeof(OboToken));
  284. OboToken.Type = OBO_USER;
  285. hr = pncclasssetup->Install (pszwComponentId,
  286. &OboToken, 0, 0, NULL, NULL, ppncc);
  287. ReleaseObj (pncclasssetup);
  288. }
  289. return hr;
  290. }
  291. //+----------------------------------------------------------------------------
  292. //
  293. // Function: IcfgSetInstallSourcePath
  294. //
  295. // Synopsis: Set the path that will be used to install system components
  296. //
  297. // Arguments: lpszSourcePath - path to be used as install source (ANSI)
  298. //
  299. // Returns: HRESULT - S_OK is success
  300. //
  301. // History: 6/5/97 ChrisK Inherited
  302. //
  303. //-----------------------------------------------------------------------------
  304. HRESULT WINAPI IcfgSetInstallSourcePath(LPTSTR lpszSourcePath)
  305. {
  306. TraceMsg(TF_GENERAL, "ICFGNT: IcfgSetInstallSourcePath\n");
  307. return(ERROR_SUCCESS);
  308. }
  309. //+----------------------------------------------------------------------------
  310. //
  311. // Function: ValidateProductSuite
  312. //
  313. // Synopsis: Check registry for a particular Product Suite string
  314. //
  315. // Arguments: SuiteName - name of product suite to look for
  316. //
  317. // Returns: TRUE - the suite exists
  318. //
  319. // History: 6/5/97 ChrisK Inherited
  320. //
  321. //-----------------------------------------------------------------------------
  322. BOOL
  323. ValidateProductSuite(LPTSTR SuiteName)
  324. {
  325. BOOL rVal = FALSE;
  326. LONG Rslt;
  327. HKEY hKey = NULL;
  328. DWORD Type = 0;
  329. DWORD Size = 0;
  330. LPTSTR ProductSuite = NULL;
  331. LPTSTR p;
  332. TraceMsg(TF_GENERAL, "ICFGNT: ValidateProductSuite\n");
  333. //
  334. // Determine the size required to read registry values
  335. //
  336. Rslt = RegOpenKeyA(
  337. HKEY_LOCAL_MACHINE,
  338. "System\\CurrentControlSet\\Control\\ProductOptions",
  339. &hKey
  340. );
  341. if (Rslt != ERROR_SUCCESS)
  342. {
  343. goto exit;
  344. }
  345. Rslt = RegQueryValueExA(
  346. hKey,
  347. "ProductSuite",
  348. NULL,
  349. &Type,
  350. NULL,
  351. &Size
  352. );
  353. if (Rslt != ERROR_SUCCESS)
  354. {
  355. goto exit;
  356. }
  357. if (!Size)
  358. {
  359. goto exit;
  360. }
  361. ProductSuite = (LPTSTR) GlobalAlloc( GPTR, Size );
  362. if (!ProductSuite)
  363. {
  364. goto exit;
  365. }
  366. //
  367. // Read ProductSuite information
  368. //
  369. Rslt = RegQueryValueExA(
  370. hKey,
  371. "ProductSuite",
  372. NULL,
  373. &Type,
  374. (LPBYTE) ProductSuite,
  375. &Size
  376. );
  377. if (Rslt != ERROR_SUCCESS)
  378. {
  379. goto exit;
  380. }
  381. if (Type != REG_MULTI_SZ)
  382. {
  383. goto exit;
  384. }
  385. //
  386. // Look for a particular string in the data returned
  387. // Note: data is terminiated with two NULLs
  388. //
  389. p = ProductSuite;
  390. while (*p) {
  391. if (_tcsstr( p, SuiteName ))
  392. {
  393. rVal = TRUE;
  394. break;
  395. }
  396. p += (lstrlen( p ) + 1);
  397. }
  398. exit:
  399. if (ProductSuite)
  400. {
  401. GlobalFree( ProductSuite );
  402. }
  403. if (hKey)
  404. {
  405. RegCloseKey( hKey );
  406. }
  407. return rVal;
  408. }
  409. //+----------------------------------------------------------------------------
  410. //
  411. // Function: GetRegValue
  412. //
  413. // Synopsis: Dynamically allocate memory and read value from registry
  414. //
  415. // Arguments: hKey - handle to key to be read
  416. // lpValueName - pointer to value name to be read
  417. // lpData - pointer to pointer to data
  418. //
  419. // Returns: Win32 error, ERROR_SUCCESS is it worked
  420. //
  421. // History: 6/5/97 ChrisK Inherited
  422. //
  423. //-----------------------------------------------------------------------------
  424. inline LONG GetRegValue(HKEY hKey, LPTSTR lpValueName, LPBYTE *lpData)
  425. {
  426. LONG dwError;
  427. DWORD cbData;
  428. TraceMsg(TF_GENERAL, "ICFGNT: GetRegValue\n");
  429. dwError = RegQueryValueEx(hKey,
  430. lpValueName,
  431. NULL,
  432. NULL,
  433. NULL,
  434. &cbData);
  435. if(dwError != ERROR_SUCCESS)
  436. {
  437. return(dwError);
  438. }
  439. //
  440. // Allocate space and buffer incase we need to add more info later
  441. // see turn off the printing binding
  442. //
  443. *lpData = (LPBYTE) GlobalAlloc(GPTR,cbData + REG_DATA_EXTRA_SPACE);
  444. if(*lpData == 0)
  445. {
  446. return(ERROR_OUTOFMEMORY);
  447. }
  448. dwError = RegQueryValueEx(hKey,
  449. lpValueName,
  450. NULL,
  451. NULL,
  452. *lpData,
  453. &cbData);
  454. if(dwError != ERROR_SUCCESS)
  455. {
  456. GlobalFree(*lpData);
  457. }
  458. return(dwError);
  459. }
  460. //+----------------------------------------------------------------------------
  461. //
  462. // Function: CallModemInstallWizard
  463. //
  464. // Synopsis: Invoke modem install wizard via SetupDi interfaces
  465. //
  466. // Arguments: hwnd - handle to parent window
  467. //
  468. // Returns: TRUE - success, FALSE - failed
  469. //
  470. // History: 6/5/97 ChrisK Inherited
  471. //
  472. //-----------------------------------------------------------------------------
  473. //
  474. // The following code was stolen from RAS
  475. //
  476. BOOL
  477. CallModemInstallWizard(HWND hwnd)
  478. /* call the Modem.Cpl install wizard to enable the user to install one or
  479. ** more modems
  480. **
  481. ** Return TRUE if the wizard was successfully invoked, FALSE otherwise
  482. **
  483. */
  484. {
  485. HDEVINFO hdi;
  486. BOOL fReturn = FALSE;
  487. // Create a modem DeviceInfoSet
  488. TraceMsg(TF_GENERAL, "ICFGNT: CallModemInstallWizard\n");
  489. hdi = SetupDiCreateDeviceInfoList((LPGUID)&GUID_DEVCLASS_MODEM, hwnd);
  490. if (hdi)
  491. {
  492. SP_INSTALLWIZARD_DATA iwd;
  493. // Initialize the InstallWizardData
  494. ZeroMemory(&iwd, sizeof(iwd));
  495. iwd.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
  496. iwd.ClassInstallHeader.InstallFunction = DIF_INSTALLWIZARD;
  497. iwd.hwndWizardDlg = hwnd;
  498. // Set the InstallWizardData as the ClassInstallParams
  499. if (SetupDiSetClassInstallParams(hdi, NULL,
  500. (PSP_CLASSINSTALL_HEADER)&iwd, sizeof(iwd)))
  501. {
  502. // Call the class installer to invoke the installation
  503. // wizard.
  504. if (SetupDiCallClassInstaller(DIF_INSTALLWIZARD, hdi, NULL))
  505. {
  506. // Success. The wizard was invoked and finished.
  507. // Now cleanup.
  508. fReturn = TRUE;
  509. SetupDiCallClassInstaller(DIF_DESTROYWIZARDDATA, hdi, NULL);
  510. }
  511. }
  512. // Clean up
  513. SetupDiDestroyDeviceInfoList(hdi);
  514. }
  515. return fReturn;
  516. }
  517. //+----------------------------------------------------------------------------
  518. //
  519. // Function: IcfgNeedModem
  520. //
  521. // Synopsis: Check system configuration to determine if there is at least
  522. // one physical modem installed
  523. //
  524. // Arguments: dwfOptions - currently not used
  525. //
  526. // Returns: HRESULT - S_OK if successfull
  527. // lpfNeedModem - TRUE if no modems are available
  528. //
  529. // History: 6/5/97 ChrisK Inherited
  530. //
  531. //-----------------------------------------------------------------------------
  532. HRESULT WINAPI
  533. IcfgNeedModem (DWORD dwfOptions, LPBOOL lpfNeedModem)
  534. {
  535. //
  536. // Ras is installed, and ICW wants to know if it needs to
  537. // install a modem.
  538. //
  539. *lpfNeedModem = TRUE;
  540. // Get the device info set for modems.
  541. //
  542. HDEVINFO hdevinfo = SetupDiGetClassDevs((GUID*)&GUID_DEVCLASS_MODEM,
  543. NULL,
  544. NULL,
  545. DIGCF_PRESENT);
  546. if (hdevinfo)
  547. {
  548. SP_DEVINFO_DATA diData;
  549. diData.cbSize = sizeof(diData);
  550. // Look for at least one modem.
  551. //
  552. if (SetupDiEnumDeviceInfo(hdevinfo, 0, &diData))
  553. {
  554. *lpfNeedModem = FALSE;
  555. }
  556. SetupDiDestroyDeviceInfoList (hdevinfo);
  557. }
  558. return(ERROR_SUCCESS);
  559. }
  560. //+----------------------------------------------------------------------------
  561. //
  562. // Function: IcfgInstallModem
  563. //
  564. // Synopsis:
  565. // This function is called when ICW verified that RAS is installed,
  566. // but no modems are avilable. It needs to make sure a modem is availble.
  567. // There are two possible scenarios:
  568. //
  569. // a. There are no modems installed. This happens when someone deleted
  570. // a modem after installing RAS. In this case we need to run the modem
  571. // install wizard, and configure the newly installed modem to be a RAS
  572. // dialout device.
  573. //
  574. // b. There are modems installed, but non of them is configured as a dial out
  575. // device. In this case, we silently convert them to be DialInOut devices,
  576. // so ICW can use them.
  577. //
  578. // Arguments: hwndParent - handle to parent window
  579. // dwfOptions - not used
  580. //
  581. // Returns: lpfNeedsStart - not used
  582. //
  583. // History: 6/5/97 ChrisK Inherited
  584. //
  585. //-----------------------------------------------------------------------------
  586. HRESULT WINAPI
  587. IcfgInstallModem (HWND hwndParent, DWORD dwfOptions, LPBOOL lpfNeedsStart)
  588. {
  589. //$ BUGBUG (shaunco) 3 Jul 1997: See if we need to install a modem, or
  590. // just install it?
  591. //
  592. // Fire up the modem install wizard
  593. //
  594. if (!CallModemInstallWizard(hwndParent))
  595. {
  596. return(g_dwLastError = GetLastError());
  597. }
  598. return(ERROR_SUCCESS);
  599. }
  600. //+----------------------------------------------------------------------------
  601. //
  602. // Function: IcfgNeedInetComponets
  603. //
  604. // Synopsis: Check to see if the components marked in the options are
  605. // installed on the system
  606. //
  607. // Arguements: dwfOptions - set of bit flag indicating which components to
  608. // check for
  609. //
  610. // Returns; HRESULT - S_OK if successfull
  611. // lpfNeedComponents - TRUE is some components are not installed
  612. //
  613. // History: 6/5/97 ChrisK Inherited
  614. //
  615. //-----------------------------------------------------------------------------
  616. HRESULT WINAPI
  617. IcfgNeedInetComponents(DWORD dwfOptions, LPBOOL lpfNeedComponents)
  618. {
  619. TraceMsg(TF_GENERAL, "ICFGNT: IcfgNeedInetComponents\n");
  620. //
  621. // Assume we have what we need.
  622. //
  623. *lpfNeedComponents = FALSE;
  624. HRESULT hr = S_OK;
  625. INetCfg* pnc = NULL;
  626. BOOL fInitCom = TRUE;
  627. // If the optiona are such that we need an INetCfg interface pointer,
  628. // get one.
  629. //
  630. if ((dwfOptions & ICFG_INSTALLTCP) ||
  631. (dwfOptions & ICFG_INSTALLRAS))
  632. {
  633. hr = HrCreateAndInitializeINetCfg (&fInitCom, &pnc,
  634. FALSE, 0, NULL, NULL);
  635. }
  636. // Look for TCP/IP using the INetCfg interface.
  637. //
  638. if (SUCCEEDED(hr) && (dwfOptions & ICFG_INSTALLTCP))
  639. {
  640. Assert (pnc);
  641. hr = pnc->FindComponent (NETCFG_TRANS_CID_MS_TCPIP, NULL);
  642. if (S_FALSE == hr)
  643. {
  644. *lpfNeedComponents = TRUE;
  645. }
  646. }
  647. // We no longer need the INetCfg interface pointer, so release it.
  648. //
  649. if (pnc)
  650. {
  651. (void) HrUninitializeAndReleaseINetCfg (fInitCom, pnc, FALSE);
  652. }
  653. if (dwfOptions & ICFG_INSTALLMAIL)
  654. {
  655. // How do we do this?
  656. Assert (0);
  657. }
  658. // Normalize the HRESULT.
  659. if (SUCCEEDED(hr))
  660. {
  661. hr = S_OK;
  662. }
  663. return hr;
  664. }
  665. //+----------------------------------------------------------------------------
  666. //
  667. // Function: IcfgInstallInetComponents
  668. //
  669. // Synopsis: Install the components as specified by the dwfOptions values
  670. //
  671. // Arguments hwndParent - handle to parent window
  672. // dwfOptions - set of bit flags indicating which components to
  673. // install
  674. //
  675. // Returns: HRESULT - S_OK if success
  676. // lpfNeedsReboot - TRUE if reboot is required
  677. //
  678. // History: 6/5/97 ChrisK Inherited
  679. //
  680. //-----------------------------------------------------------------------------
  681. HRESULT WINAPI
  682. IcfgInstallInetComponents(HWND hwndParent, DWORD dwfOptions, LPBOOL lpfNeedsRestart)
  683. {
  684. TraceMsg(TF_GENERAL, "ICFGNT: IcfgInstallInetComponents\n");
  685. //
  686. // Assume don't need restart
  687. //
  688. *lpfNeedsRestart = FALSE;
  689. HRESULT hr = S_OK;
  690. INetCfg* pnc = NULL;
  691. BOOL fInitCom = TRUE;
  692. // If the optiona are such that we need an INetCfg interface pointer,
  693. // get one.
  694. //
  695. if ((dwfOptions & ICFG_INSTALLTCP) ||
  696. (dwfOptions & ICFG_INSTALLRAS))
  697. {
  698. BSTR bstrClient;
  699. hr = HrCreateAndInitializeINetCfg (&fInitCom, &pnc, TRUE,
  700. 0, L"", &bstrClient);
  701. }
  702. // Install TCP/IP on behalf of the user.
  703. //
  704. if (SUCCEEDED(hr) && (dwfOptions & ICFG_INSTALLTCP))
  705. {
  706. hr = HrInstallComponent (pnc, &GUID_DEVCLASS_NETTRANS,
  707. NETCFG_TRANS_CID_MS_TCPIP, NULL);
  708. }
  709. // We no longer need the INetCfg interface pointer, so release it.
  710. //
  711. if (pnc)
  712. {
  713. // Apply the changes if everything was successful.
  714. //
  715. if (SUCCEEDED(hr))
  716. {
  717. hr = pnc->Apply ();
  718. if (NETCFG_S_REBOOT == hr)
  719. {
  720. *lpfNeedsRestart = TRUE;
  721. }
  722. }
  723. (void) HrUninitializeAndReleaseINetCfg (fInitCom, pnc, TRUE);
  724. }
  725. if (dwfOptions & ICFG_INSTALLMAIL)
  726. {
  727. // How do we do this?
  728. Assert (0);
  729. }
  730. // Normalize the HRESULT.
  731. if (SUCCEEDED(hr))
  732. {
  733. hr = S_OK;
  734. }
  735. return(hr);
  736. }
  737. //+----------------------------------------------------------------------------
  738. //
  739. // Function: IcfgGetLastInstallErrorText
  740. //
  741. // Synopsis: Format error message for most recent error
  742. //
  743. // Arguments: none
  744. //
  745. // Returns: DWORD - win32 error code
  746. // lpszErrorDesc - string containing error message
  747. // cbErrorDesc - size of lpszErrorDesc
  748. //
  749. // History: 6/5/97 ChrisK Inherited
  750. //
  751. //-----------------------------------------------------------------------------
  752. DWORD WINAPI
  753. IcfgGetLastInstallErrorText(LPTSTR lpszErrorDesc, DWORD cbErrorDesc)
  754. {
  755. TraceMsg(TF_GENERAL, "ICFGNT: IcfgGetLastInstallErrorText\n");
  756. return(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
  757. NULL,
  758. g_dwLastError,
  759. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //The user default language
  760. lpszErrorDesc,
  761. cbErrorDesc,
  762. NULL));
  763. }
  764. //+----------------------------------------------------------------------------
  765. //
  766. // Function: IcfgIsFileSharingTurnedOn
  767. //
  768. // Synopsis: Always returns false for NT 5 because file sharing is controlled
  769. // at the RAS connectoid level, and is always turned off for ICW
  770. // generated connectoids
  771. //
  772. // Arguments: dwfDriverType -
  773. //
  774. // Returns: HRESULT - S_OK is success
  775. // lpfSharingOn - TRUE if sharing is bound
  776. //
  777. // History: 6/5/97 ChrisK Inherited
  778. //
  779. //-----------------------------------------------------------------------------
  780. HRESULT WINAPI IcfgIsFileSharingTurnedOn
  781. (
  782. DWORD dwfDriverType,
  783. LPBOOL lpfSharingOn
  784. )
  785. {
  786. HRESULT hr = ERROR_SUCCESS;
  787. TraceMsg(TF_GENERAL, "ICFGNT: IcfgIsFileSharingTurnedOn\n");
  788. Assert(lpfSharingOn);
  789. if (NULL == lpfSharingOn)
  790. {
  791. hr = ERROR_INVALID_PARAMETER;
  792. goto IcfgIsFileSharingTurnedOnExit;
  793. }
  794. *lpfSharingOn = FALSE;
  795. IcfgIsFileSharingTurnedOnExit:
  796. return hr;
  797. }
  798. //+----------------------------------------------------------------------------
  799. //
  800. // Function: IcfgTurnOffFileSharing
  801. //
  802. // Synopsis; For NT 5, this is handed as a RAS property, so we just return
  803. // success here.
  804. //
  805. //
  806. // Arguments: dwfDriverType -
  807. // hwndParent - parent window
  808. //
  809. // Returns: HRESULT - ERROR_SUCCESS
  810. //
  811. // History: 6/5/97 ChrisK Inherited
  812. // 07/21/98 donaldm
  813. //-----------------------------------------------------------------------------
  814. HRESULT WINAPI IcfgTurnOffFileSharing
  815. (
  816. DWORD dwfDriverType,
  817. HWND hwndParent
  818. )
  819. {
  820. return ERROR_SUCCESS;
  821. }
  822. //+----------------------------------------------------------------------------
  823. //
  824. // Function: IcfgStartServices
  825. //
  826. // Synopsis: Start all services required by system
  827. //
  828. // Arguments: none
  829. //
  830. // Returns: HRESULT - S_OK if success
  831. //
  832. // History: 6/5/97 ChrisK Iherited
  833. //
  834. //-----------------------------------------------------------------------------
  835. HRESULT WINAPI IcfgStartServices()
  836. {
  837. //This stuff is handled auto-magically by the RAS API.
  838. //but since there so much code that calls this function we'll
  839. //be simple and fake success
  840. return(ERROR_SUCCESS);
  841. }
  842. //+----------------------------------------------------------------------------
  843. //
  844. // Function: IcfgIsGlobalDNS
  845. //
  846. // Note: these functions are not needed on an NT system and it therefore not
  847. // implemented
  848. //
  849. //-----------------------------------------------------------------------------
  850. HRESULT WINAPI
  851. IcfgIsGlobalDNS(LPBOOL lpfGlobalDNS)
  852. {
  853. *lpfGlobalDNS = FALSE;
  854. return(ERROR_SUCCESS);
  855. }
  856. HRESULT WINAPI
  857. IcfgRemoveGlobalDNS()
  858. {
  859. return(ERROR_SUCCESS);
  860. }
  861. HRESULT WINAPI
  862. InetGetSupportedPlatform(LPDWORD pdwPlatform)
  863. {
  864. *pdwPlatform = VER_PLATFORM_WIN32_NT;
  865. return(ERROR_SUCCESS);
  866. }
  867. HRESULT WINAPI
  868. InetSetAutodial(BOOL fEnable, LPCTSTR lpszEntryName) {
  869. return(ERROR_INVALID_FUNCTION);
  870. }
  871. HRESULT WINAPI
  872. InetGetAutodial(LPBOOL lpfEnable, LPSTR lpszEntryName, DWORD cbEntryName) {
  873. return(ERROR_INVALID_FUNCTION);
  874. }
  875. HRESULT WINAPI
  876. InetSetAutodialAddress(DWORD dwDialingLocation, LPTSTR szEntry) {
  877. return(ERROR_SUCCESS);
  878. }