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.

3573 lines
81 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997 - 2000
  5. //
  6. // File: H N C F G M G R . C P P
  7. //
  8. // Contents: CHNetCfgMgr implementation
  9. //
  10. // Notes:
  11. //
  12. // Author: jonburs 23 May 2000
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #define STRSAFE_NO_DEPRECATE
  18. #include <strsafe.h>
  19. //
  20. // Atl methods
  21. //
  22. HRESULT
  23. CHNetCfgMgr::FinalConstruct()
  24. {
  25. HRESULT hr = S_OK;
  26. IWbemLocator *pLocator = NULL;
  27. BSTR bstrNamespace = NULL;
  28. //
  29. // Allocate the commonly used BSTRs
  30. //
  31. m_bstrWQL = SysAllocString(c_wszWQL);
  32. if (NULL == m_bstrWQL)
  33. {
  34. hr = E_OUTOFMEMORY;
  35. }
  36. if (S_OK == hr)
  37. {
  38. //
  39. // Allocate the BSTR for our namespace
  40. //
  41. bstrNamespace = SysAllocString(c_wszNamespace);
  42. if (NULL == bstrNamespace)
  43. {
  44. hr = E_OUTOFMEMORY;
  45. }
  46. }
  47. if (S_OK == hr)
  48. {
  49. //
  50. // Create the IWbemLocator object. This interface allows us to
  51. // connect to the desired namespace.
  52. //
  53. hr = CoCreateInstance(
  54. CLSID_WbemLocator,
  55. NULL,
  56. CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_DISABLE_AAA,
  57. IID_PPV_ARG(IWbemLocator, &pLocator)
  58. );
  59. }
  60. if (S_OK == hr)
  61. {
  62. //
  63. // Connect to our namespace
  64. //
  65. hr = pLocator->ConnectServer(
  66. bstrNamespace,
  67. NULL, // user
  68. NULL, // password
  69. NULL, // locale
  70. 0, // security flags
  71. NULL, // authority
  72. NULL, // context
  73. &m_piwsHomenet
  74. );
  75. }
  76. //
  77. // Cleanup locals.
  78. //
  79. if (pLocator) pLocator->Release();
  80. if (bstrNamespace) SysFreeString(bstrNamespace);
  81. if (S_OK != hr)
  82. {
  83. //
  84. // Cleanup object members
  85. //
  86. SysFreeString(m_bstrWQL);
  87. m_bstrWQL = NULL;
  88. if (NULL != m_piwsHomenet)
  89. {
  90. m_piwsHomenet->Release();
  91. m_piwsHomenet = NULL;
  92. }
  93. }
  94. return hr;
  95. }
  96. HRESULT
  97. CHNetCfgMgr::FinalRelease()
  98. {
  99. if (m_piwsHomenet) m_piwsHomenet->Release();
  100. if (m_pNetConnUiUtil) m_pNetConnUiUtil->Release();
  101. if (m_pNetConnHNetUtil) m_pNetConnHNetUtil->Release();
  102. if (m_bstrWQL) SysFreeString(m_bstrWQL);
  103. return S_OK;
  104. }
  105. //
  106. // IHNetCfgMgr methods
  107. //
  108. STDMETHODIMP
  109. CHNetCfgMgr::GetIHNetConnectionForINetConnection(
  110. INetConnection *pNetConnection,
  111. IHNetConnection **ppHNetConnection
  112. )
  113. {
  114. HRESULT hr = S_OK;
  115. NETCON_PROPERTIES* pProps;
  116. IWbemClassObject *pwcoConnection = NULL;
  117. IWbemClassObject *pwcoProperties = NULL;
  118. BOOLEAN fLanConnection;
  119. if (NULL == ppHNetConnection)
  120. {
  121. hr = E_POINTER;
  122. }
  123. if (S_OK == hr)
  124. {
  125. *ppHNetConnection = NULL;
  126. if (NULL == pNetConnection)
  127. {
  128. hr = E_INVALIDARG;
  129. }
  130. }
  131. if (S_OK == hr)
  132. {
  133. //
  134. // Get the properties for the connection
  135. //
  136. hr = pNetConnection->GetProperties(&pProps);
  137. }
  138. if (SUCCEEDED(hr))
  139. {
  140. //
  141. // Attempt to find the connection and properties
  142. // instances in the store
  143. //
  144. hr = GetConnAndPropInstancesByGuid(
  145. m_piwsHomenet,
  146. &pProps->guidId,
  147. &pwcoConnection,
  148. &pwcoProperties
  149. );
  150. if (FAILED(hr))
  151. {
  152. //
  153. // We have no record of this connection. Determine
  154. // if it is a lan connection. (Will need to update
  155. // this for bridge)
  156. //
  157. fLanConnection = (NCM_LAN == pProps->MediaType ||
  158. NCM_BRIDGE == pProps->MediaType);
  159. //
  160. // Create the store instances
  161. //
  162. hr = CreateConnectionAndPropertyInstances(
  163. &pProps->guidId,
  164. fLanConnection,
  165. pProps->pszwName,
  166. &pwcoConnection,
  167. &pwcoProperties
  168. );
  169. //
  170. // If this is a ras connection, determine the
  171. // phonebook path
  172. //
  173. if (S_OK == hr && FALSE == fLanConnection)
  174. {
  175. LPWSTR wsz;
  176. VARIANT vt;
  177. hr = GetPhonebookPathFromRasNetcon(pNetConnection, &wsz);
  178. if (SUCCEEDED(hr))
  179. {
  180. V_VT(&vt) = VT_BSTR;
  181. V_BSTR(&vt) = SysAllocString(wsz);
  182. CoTaskMemFree(wsz);
  183. if (NULL != V_BSTR(&vt))
  184. {
  185. hr = pwcoConnection->Put(
  186. c_wszPhonebookPath,
  187. 0,
  188. &vt,
  189. NULL
  190. );
  191. VariantClear(&vt);
  192. }
  193. else
  194. {
  195. hr = E_OUTOFMEMORY;
  196. }
  197. }
  198. if (SUCCEEDED(hr))
  199. {
  200. //
  201. // Save modified connection instance
  202. //
  203. hr = m_piwsHomenet->PutInstance(
  204. pwcoConnection,
  205. WBEM_FLAG_CREATE_OR_UPDATE,
  206. NULL,
  207. NULL
  208. );
  209. }
  210. else
  211. {
  212. //
  213. // Delete the newly created instances
  214. //
  215. DeleteWmiInstance(m_piwsHomenet, pwcoConnection);
  216. DeleteWmiInstance(m_piwsHomenet, pwcoProperties);
  217. pwcoConnection->Release();
  218. pwcoProperties->Release();
  219. }
  220. }
  221. }
  222. NcFreeNetconProperties(pProps);
  223. }
  224. if (S_OK == hr)
  225. {
  226. CComObject<CHNetConn> *pHNConn;
  227. //
  228. // Create the wrapper object
  229. //
  230. hr = CComObject<CHNetConn>::CreateInstance(&pHNConn);
  231. if (SUCCEEDED(hr))
  232. {
  233. pHNConn->AddRef();
  234. hr = pHNConn->SetINetConnection(pNetConnection);
  235. if (S_OK == hr)
  236. {
  237. hr = pHNConn->InitializeFromInstances(
  238. m_piwsHomenet,
  239. pwcoConnection,
  240. pwcoProperties
  241. );
  242. }
  243. if (S_OK == hr)
  244. {
  245. hr = pHNConn->QueryInterface(
  246. IID_PPV_ARG(IHNetConnection, ppHNetConnection)
  247. );
  248. }
  249. pHNConn->Release();
  250. }
  251. pwcoConnection->Release();
  252. pwcoProperties->Release();
  253. }
  254. return hr;
  255. }
  256. STDMETHODIMP
  257. CHNetCfgMgr::GetIHNetConnectionForGuid(
  258. GUID *pGuid,
  259. BOOLEAN fLanConnection,
  260. BOOLEAN fCreateEntries,
  261. IHNetConnection **ppHNetConnection
  262. )
  263. {
  264. HRESULT hr = S_OK;
  265. IWbemClassObject *pwcoConnection = NULL;
  266. IWbemClassObject *pwcoProperties = NULL;
  267. if (NULL == ppHNetConnection)
  268. {
  269. hr = E_POINTER;
  270. }
  271. if (S_OK == hr)
  272. {
  273. *ppHNetConnection = NULL;
  274. if (NULL == pGuid)
  275. {
  276. hr = E_INVALIDARG;
  277. }
  278. }
  279. if (S_OK == hr)
  280. {
  281. //
  282. // Attempt to find the connection and properties
  283. // instances in the store
  284. //
  285. hr = GetConnAndPropInstancesByGuid(
  286. m_piwsHomenet,
  287. pGuid,
  288. &pwcoConnection,
  289. &pwcoProperties
  290. );
  291. if (FAILED(hr) && fCreateEntries)
  292. {
  293. INetConnection *pNetConn;
  294. //
  295. // We don't have a record of this guid. Get the INetConnection
  296. // that it corresponds to.
  297. //
  298. hr = FindINetConnectionByGuid(pGuid, &pNetConn);
  299. if (SUCCEEDED(hr))
  300. {
  301. hr = GetIHNetConnectionForINetConnection(
  302. pNetConn,
  303. ppHNetConnection
  304. );
  305. pNetConn->Release();
  306. return hr;
  307. }
  308. }
  309. }
  310. if (S_OK == hr)
  311. {
  312. CComObject<CHNetConn> *pHNConn;
  313. //
  314. // Create the wrapper object
  315. //
  316. hr = CComObject<CHNetConn>::CreateInstance(&pHNConn);
  317. if (SUCCEEDED(hr))
  318. {
  319. pHNConn->AddRef();
  320. hr = pHNConn->InitializeFromInstances(
  321. m_piwsHomenet,
  322. pwcoConnection,
  323. pwcoProperties
  324. );
  325. if (S_OK == hr)
  326. {
  327. hr = pHNConn->QueryInterface(
  328. IID_PPV_ARG(IHNetConnection, ppHNetConnection)
  329. );
  330. }
  331. pHNConn->Release();
  332. }
  333. pwcoConnection->Release();
  334. pwcoProperties->Release();
  335. }
  336. return hr;
  337. }
  338. //
  339. // IHNetBridgeSettings methods
  340. //
  341. STDMETHODIMP
  342. CHNetCfgMgr::EnumBridges(
  343. IEnumHNetBridges **ppEnum
  344. )
  345. {
  346. HRESULT hr;
  347. CComObject<CEnumHNetBridges> *pEnum;
  348. IHNetBridge *phnbridge;
  349. if( NULL != ppEnum )
  350. {
  351. *ppEnum = NULL;
  352. hr = GetBridgeConnection( m_piwsHomenet, &phnbridge );
  353. if( S_OK == hr )
  354. {
  355. hr = CComObject<CEnumHNetBridges>::CreateInstance(&pEnum);
  356. if( SUCCEEDED(hr) )
  357. {
  358. pEnum->AddRef();
  359. hr = pEnum->Initialize(&phnbridge, 1L);
  360. if( SUCCEEDED(hr) )
  361. {
  362. hr = pEnum-> QueryInterface(
  363. IID_PPV_ARG(IEnumHNetBridges, ppEnum)
  364. );
  365. }
  366. pEnum->Release();
  367. }
  368. phnbridge->Release();
  369. }
  370. else
  371. {
  372. // Make an empty enumerator
  373. hr = CComObject<CEnumHNetBridges>::CreateInstance(&pEnum);
  374. if( SUCCEEDED(hr) )
  375. {
  376. pEnum->AddRef();
  377. hr = pEnum->Initialize(NULL, 0L);
  378. if( SUCCEEDED(hr) )
  379. {
  380. hr = pEnum-> QueryInterface(
  381. IID_PPV_ARG(IEnumHNetBridges, ppEnum)
  382. );
  383. }
  384. pEnum->Release();
  385. }
  386. }
  387. }
  388. else
  389. {
  390. hr = E_POINTER;
  391. }
  392. return hr;
  393. }
  394. STDMETHODIMP
  395. CHNetCfgMgr::CreateBridge(
  396. IHNetBridge **ppHNetBridge,
  397. INetCfg *pnetcfgExisting
  398. )
  399. {
  400. HRESULT hr = S_OK;
  401. GUID guid;
  402. IWbemClassObject *pwcoConnection = NULL;
  403. IWbemClassObject *pwcoProperties = NULL;
  404. if (NULL != ppHNetBridge)
  405. {
  406. *ppHNetBridge = NULL;
  407. }
  408. else
  409. {
  410. hr = E_POINTER;
  411. }
  412. if (ProhibitedByPolicy(NCPERM_AllowNetBridge_NLA))
  413. {
  414. hr = HN_E_POLICY;
  415. }
  416. if (S_OK == hr)
  417. {
  418. //
  419. // Install the bridge driver, and create the bridge miniport.
  420. //
  421. hr = InstallBridge( &guid, pnetcfgExisting );
  422. }
  423. if (S_OK == hr)
  424. {
  425. //
  426. // See if we already have property instances for this connection.
  427. // (They may have been created when the bridge connection object
  428. // was instantiated.)
  429. //
  430. hr = GetConnAndPropInstancesByGuid(
  431. m_piwsHomenet,
  432. &guid,
  433. &pwcoConnection,
  434. &pwcoProperties
  435. );
  436. if (S_OK != hr)
  437. {
  438. //
  439. // Create the store instances
  440. //
  441. hr = CreateConnectionAndPropertyInstances(
  442. &guid,
  443. TRUE,
  444. c_wszBridge,
  445. &pwcoConnection,
  446. &pwcoProperties
  447. );
  448. }
  449. }
  450. if (S_OK == hr)
  451. {
  452. //
  453. // Inform netman that something changed. Error doesn't matter.
  454. //
  455. UpdateNetman();
  456. }
  457. if (S_OK == hr)
  458. {
  459. CComObject<CHNBridge> *pBridge;
  460. //
  461. // Create wrapper object to return
  462. //
  463. hr = CComObject<CHNBridge>::CreateInstance(&pBridge);
  464. if (SUCCEEDED(hr))
  465. {
  466. pBridge->AddRef();
  467. hr = pBridge->InitializeFromInstances(
  468. m_piwsHomenet,
  469. pwcoConnection,
  470. pwcoProperties
  471. );
  472. if (S_OK == hr)
  473. {
  474. hr = pBridge->QueryInterface(
  475. IID_PPV_ARG(IHNetBridge, ppHNetBridge)
  476. );
  477. }
  478. pBridge->Release();
  479. }
  480. }
  481. if (NULL != pwcoConnection) pwcoConnection->Release();
  482. if (NULL != pwcoProperties) pwcoProperties->Release();
  483. return hr;
  484. }
  485. STDMETHODIMP
  486. CHNetCfgMgr::DestroyAllBridges(
  487. ULONG *pcBridges,
  488. INetCfg *pnetcfgExisting
  489. )
  490. {
  491. HRESULT hr = S_OK;
  492. IEnumHNetBridges *pehnbEnum;
  493. IHNetBridge *phnBridge;
  494. if (!pcBridges)
  495. {
  496. hr = E_POINTER;
  497. }
  498. if (ProhibitedByPolicy(NCPERM_AllowNetBridge_NLA))
  499. {
  500. hr = HN_E_POLICY;
  501. }
  502. if (S_OK == hr)
  503. {
  504. *pcBridges = 0;
  505. //
  506. // Get the enumeration of the bridges.
  507. //
  508. hr = EnumBridges(&pehnbEnum);
  509. }
  510. if (S_OK == hr)
  511. {
  512. //
  513. // Walk through the enumeration, destroying
  514. // each bridge
  515. //
  516. do
  517. {
  518. hr = pehnbEnum->Next(1, &phnBridge, NULL);
  519. if (S_OK == hr)
  520. {
  521. phnBridge->Destroy( pnetcfgExisting );
  522. phnBridge->Release();
  523. *pcBridges += 1;
  524. }
  525. }
  526. while (S_OK == hr);
  527. hr = S_OK;
  528. pehnbEnum->Release();
  529. }
  530. return hr;
  531. }
  532. //
  533. // IHNetFirewallSettings methods
  534. //
  535. STDMETHODIMP
  536. CHNetCfgMgr::EnumFirewalledConnections(
  537. IEnumHNetFirewalledConnections **ppEnum
  538. )
  539. {
  540. HRESULT hr = S_OK;
  541. IEnumWbemClassObject *pwcoEnum;
  542. BSTR bstrQuery;
  543. if (!ppEnum)
  544. {
  545. hr = E_POINTER;
  546. }
  547. if (S_OK == hr)
  548. {
  549. *ppEnum = NULL;
  550. //
  551. // Query the WMI store for HNet_ConnectionProperties instances
  552. // where IsFirewall is true.
  553. //
  554. hr = BuildSelectQueryBstr(
  555. &bstrQuery,
  556. c_wszStar,
  557. c_wszHnetProperties,
  558. L"IsFirewalled != FALSE"
  559. );
  560. }
  561. if (S_OK == hr)
  562. {
  563. pwcoEnum = NULL;
  564. hr = m_piwsHomenet->ExecQuery(
  565. m_bstrWQL,
  566. bstrQuery,
  567. WBEM_FLAG_RETURN_IMMEDIATELY,
  568. NULL,
  569. &pwcoEnum
  570. );
  571. SysFreeString(bstrQuery);
  572. }
  573. if (WBEM_S_NO_ERROR == hr)
  574. {
  575. //
  576. // Create and initialize the wrapper for the enum
  577. //
  578. CComObject<CEnumHNetFirewalledConnections> *pEnum;
  579. hr = CComObject<CEnumHNetFirewalledConnections>::CreateInstance(&pEnum);
  580. if (SUCCEEDED(hr))
  581. {
  582. pEnum->AddRef();
  583. hr = pEnum->Initialize(m_piwsHomenet, pwcoEnum);
  584. if (SUCCEEDED(hr))
  585. {
  586. hr = pEnum->QueryInterface(
  587. IID_PPV_ARG(IEnumHNetFirewalledConnections, ppEnum)
  588. );
  589. }
  590. pEnum->Release();
  591. }
  592. pwcoEnum->Release();
  593. }
  594. return hr;
  595. }
  596. STDMETHODIMP
  597. CHNetCfgMgr::GetFirewallLoggingSettings(
  598. HNET_FW_LOGGING_SETTINGS **ppSettings
  599. )
  600. {
  601. HRESULT hr = S_OK;
  602. IWbemClassObject *pwcoSettings = NULL;
  603. if (!ppSettings)
  604. {
  605. hr = E_POINTER;
  606. }
  607. //
  608. // Allocate the necessary memory for the settings structure.
  609. //
  610. if (S_OK == hr)
  611. {
  612. *ppSettings = reinterpret_cast<HNET_FW_LOGGING_SETTINGS *>(
  613. CoTaskMemAlloc(sizeof(HNET_FW_LOGGING_SETTINGS))
  614. );
  615. if (NULL == *ppSettings)
  616. {
  617. hr = E_OUTOFMEMORY;
  618. }
  619. }
  620. if (S_OK == hr)
  621. {
  622. hr = RetrieveSingleInstance(
  623. m_piwsHomenet,
  624. c_wszHnetFWLoggingSettings,
  625. FALSE,
  626. &pwcoSettings
  627. );
  628. }
  629. if (S_OK == hr)
  630. {
  631. //
  632. // Copy the instance info into the settings block
  633. //
  634. hr = CopyLoggingInstanceToStruct(pwcoSettings, *ppSettings);
  635. pwcoSettings->Release();
  636. }
  637. if (FAILED(hr))
  638. {
  639. //
  640. // Clean up output structure
  641. //
  642. if (ppSettings && *ppSettings)
  643. {
  644. CoTaskMemFree(*ppSettings);
  645. *ppSettings = NULL;
  646. }
  647. }
  648. return hr;
  649. }
  650. STDMETHODIMP
  651. CHNetCfgMgr::SetFirewallLoggingSettings(
  652. HNET_FW_LOGGING_SETTINGS *pSettings
  653. )
  654. {
  655. HRESULT hr = S_OK;
  656. IWbemClassObject *pwcoSettings;
  657. if (NULL == pSettings)
  658. {
  659. hr = E_INVALIDARG;
  660. }
  661. if (ProhibitedByPolicy(NCPERM_PersonalFirewallConfig))
  662. {
  663. hr = HN_E_POLICY;
  664. }
  665. if (S_OK == hr)
  666. {
  667. //
  668. // Attempt to retrieve the HNet_FirewallLoggingSettings instance from
  669. // the store
  670. //
  671. hr = RetrieveSingleInstance(
  672. m_piwsHomenet,
  673. c_wszHnetFWLoggingSettings,
  674. TRUE,
  675. &pwcoSettings
  676. );
  677. }
  678. if (S_OK == hr)
  679. {
  680. //
  681. // Copy settings struct into object instance
  682. //
  683. hr = CopyStructToLoggingInstance(pSettings, pwcoSettings);
  684. if (S_OK == hr)
  685. {
  686. //
  687. // Write settings instance back to the store
  688. //
  689. hr = m_piwsHomenet->PutInstance(
  690. pwcoSettings,
  691. WBEM_FLAG_CREATE_OR_UPDATE,
  692. NULL,
  693. NULL
  694. );
  695. }
  696. pwcoSettings->Release();
  697. }
  698. if (SUCCEEDED(hr))
  699. {
  700. //
  701. // Notify service of configuration change
  702. //
  703. UpdateService(IPNATHLP_CONTROL_UPDATE_FWLOGGER);
  704. }
  705. return hr;
  706. }
  707. STDMETHODIMP
  708. CHNetCfgMgr::DisableAllFirewalling(
  709. ULONG *pcFirewalledConnections
  710. )
  711. {
  712. HRESULT hr = S_OK;
  713. IEnumHNetFirewalledConnections *pehfcEnum;
  714. IHNetFirewalledConnection *phfcConnection;
  715. if (!pcFirewalledConnections)
  716. {
  717. hr = E_POINTER;
  718. }
  719. if (ProhibitedByPolicy(NCPERM_PersonalFirewallConfig))
  720. {
  721. hr = HN_E_POLICY;
  722. }
  723. if (S_OK == hr)
  724. {
  725. *pcFirewalledConnections = 0;
  726. //
  727. // Get the enumeration of firewalled connections
  728. //
  729. hr = EnumFirewalledConnections(&pehfcEnum);
  730. }
  731. if (S_OK == hr)
  732. {
  733. //
  734. // Walk through the enumeration, turning off
  735. // firewalling for each connection
  736. //
  737. do
  738. {
  739. hr = pehfcEnum->Next(1, &phfcConnection, NULL);
  740. if (S_OK == hr)
  741. {
  742. phfcConnection->Unfirewall();
  743. phfcConnection->Release();
  744. *pcFirewalledConnections += 1;
  745. }
  746. }
  747. while (S_OK == hr);
  748. hr = S_OK;
  749. pehfcEnum->Release();
  750. }
  751. return hr;
  752. }
  753. //
  754. // IHNetIcsSettings methods
  755. //
  756. STDMETHODIMP
  757. CHNetCfgMgr::EnumIcsPublicConnections(
  758. IEnumHNetIcsPublicConnections **ppEnum
  759. )
  760. {
  761. HRESULT hr = S_OK;
  762. IEnumWbemClassObject *pwcoEnum;
  763. BSTR bstrQuery;
  764. if (!ppEnum)
  765. {
  766. hr = E_POINTER;
  767. }
  768. if (S_OK == hr)
  769. {
  770. *ppEnum = NULL;
  771. //
  772. // Query the WMI store for HNet_ConnectionProperties instances
  773. // where IsIcsPublic is true.
  774. //
  775. hr = BuildSelectQueryBstr(
  776. &bstrQuery,
  777. c_wszStar,
  778. c_wszHnetProperties,
  779. L"IsIcsPublic != FALSE"
  780. );
  781. }
  782. if (S_OK == hr)
  783. {
  784. pwcoEnum = NULL;
  785. hr = m_piwsHomenet->ExecQuery(
  786. m_bstrWQL,
  787. bstrQuery,
  788. WBEM_FLAG_RETURN_IMMEDIATELY,
  789. NULL,
  790. &pwcoEnum
  791. );
  792. SysFreeString(bstrQuery);
  793. }
  794. if (WBEM_S_NO_ERROR == hr)
  795. {
  796. //
  797. // Create and initialize the wrapper for the enum
  798. //
  799. CComObject<CEnumHNetIcsPublicConnections> *pEnum;
  800. hr = CComObject<CEnumHNetIcsPublicConnections>::CreateInstance(&pEnum);
  801. if (SUCCEEDED(hr))
  802. {
  803. pEnum->AddRef();
  804. hr = pEnum->Initialize(m_piwsHomenet, pwcoEnum);
  805. if (SUCCEEDED(hr))
  806. {
  807. hr = pEnum->QueryInterface(
  808. IID_PPV_ARG(IEnumHNetIcsPublicConnections, ppEnum)
  809. );
  810. }
  811. pEnum->Release();
  812. }
  813. pwcoEnum->Release();
  814. }
  815. return hr;
  816. }
  817. STDMETHODIMP
  818. CHNetCfgMgr::EnumIcsPrivateConnections(
  819. IEnumHNetIcsPrivateConnections **ppEnum
  820. )
  821. {
  822. HRESULT hr = S_OK;
  823. IEnumWbemClassObject *pwcoEnum;
  824. BSTR bstrQuery;
  825. if (!ppEnum)
  826. {
  827. hr = E_POINTER;
  828. }
  829. if (S_OK == hr)
  830. {
  831. *ppEnum = NULL;
  832. //
  833. // Query the WMI store for HNet_ConnectionProperties instances
  834. // where IsIcsPrivate is true.
  835. //
  836. hr = BuildSelectQueryBstr(
  837. &bstrQuery,
  838. c_wszStar,
  839. c_wszHnetProperties,
  840. L"IsIcsPrivate != FALSE"
  841. );
  842. }
  843. if (S_OK == hr)
  844. {
  845. pwcoEnum = NULL;
  846. hr = m_piwsHomenet->ExecQuery(
  847. m_bstrWQL,
  848. bstrQuery,
  849. WBEM_FLAG_RETURN_IMMEDIATELY,
  850. NULL,
  851. &pwcoEnum
  852. );
  853. SysFreeString(bstrQuery);
  854. }
  855. if (WBEM_S_NO_ERROR == hr)
  856. {
  857. //
  858. // Create and initialize the wrapper for the enum
  859. //
  860. CComObject<CEnumHNetIcsPrivateConnections> *pEnum;
  861. hr = CComObject<CEnumHNetIcsPrivateConnections>::CreateInstance(&pEnum);
  862. if (SUCCEEDED(hr))
  863. {
  864. pEnum->AddRef();
  865. hr = pEnum->Initialize(m_piwsHomenet, pwcoEnum);
  866. if (SUCCEEDED(hr))
  867. {
  868. hr = pEnum->QueryInterface(
  869. IID_PPV_ARG(IEnumHNetIcsPrivateConnections, ppEnum)
  870. );
  871. }
  872. pEnum->Release();
  873. }
  874. pwcoEnum->Release();
  875. }
  876. return hr;
  877. }
  878. STDMETHODIMP
  879. CHNetCfgMgr::DisableIcs(
  880. ULONG *pcIcsPublicConnections,
  881. ULONG *pcIcsPrivateConnections
  882. )
  883. {
  884. HRESULT hr = S_OK;
  885. IEnumHNetIcsPrivateConnections *pehiPrivate;
  886. IEnumHNetIcsPublicConnections *pehiPublic;
  887. IHNetIcsPrivateConnection *phicPrivate;
  888. IHNetIcsPublicConnection *phicPublic;
  889. if (!pcIcsPublicConnections
  890. || !pcIcsPrivateConnections)
  891. {
  892. hr = E_POINTER;
  893. }
  894. if (ProhibitedByPolicy(NCPERM_ShowSharedAccessUi))
  895. {
  896. hr = HN_E_POLICY;
  897. }
  898. if (S_OK == hr)
  899. {
  900. *pcIcsPublicConnections = 0;
  901. *pcIcsPrivateConnections = 0;
  902. //
  903. // Get enumeration of private connections
  904. //
  905. hr = EnumIcsPrivateConnections(&pehiPrivate);
  906. }
  907. if (S_OK == hr)
  908. {
  909. //
  910. // Loop through enumeration, unsharing the connection
  911. //
  912. do
  913. {
  914. hr = pehiPrivate->Next(1, &phicPrivate, NULL);
  915. if (S_OK == hr)
  916. {
  917. phicPrivate->RemoveFromIcs();
  918. phicPrivate->Release();
  919. *pcIcsPrivateConnections += 1;
  920. }
  921. } while (S_OK == hr);
  922. hr = S_OK;
  923. pehiPrivate->Release();
  924. }
  925. if (S_OK == hr)
  926. {
  927. //
  928. // Get enumeration of public connections
  929. //
  930. hr = EnumIcsPublicConnections(&pehiPublic);
  931. }
  932. if (S_OK == hr)
  933. {
  934. //
  935. // Loop through enumeration, unsharing the connection
  936. //
  937. do
  938. {
  939. hr = pehiPublic->Next(1, &phicPublic, NULL);
  940. if (S_OK == hr)
  941. {
  942. phicPublic->Unshare();
  943. phicPublic->Release();
  944. *pcIcsPublicConnections += 1;
  945. }
  946. } while (S_OK == hr);
  947. hr = S_OK;
  948. pehiPublic->Release();
  949. }
  950. if (S_OK == hr)
  951. {
  952. //
  953. // Currently, maximum of 1 public and private connection
  954. //
  955. _ASSERT(*pcIcsPrivateConnections <= 1);
  956. _ASSERT(*pcIcsPublicConnections <= 1);
  957. }
  958. return hr;
  959. }
  960. STDMETHODIMP
  961. CHNetCfgMgr::GetPossiblePrivateConnections(
  962. IHNetConnection *pConn,
  963. ULONG *pcPrivateConnections,
  964. IHNetConnection **pprgPrivateConnections[],
  965. LONG *pxCurrentPrivate
  966. )
  967. /*++
  968. Routine Description:
  969. Given an IHNetConnection, determines the what connections may
  970. serve as a private connection. Only connections that meet the
  971. following criteria may serve as a private connection:
  972. * it's a LAN connection
  973. * it's not part of a bridge
  974. * it's not firewalled
  975. * it's not the connection passed in
  976. * it's bound to TCP/IP
  977. Note that these are not the same rules that are used to set the
  978. fCanBeIcsPrivate member in HNET_CONN_PROPERTIES. In particular,
  979. these rules don't take into account whether or not a connection
  980. is currently marked as IcsPublic.
  981. Arguments:
  982. pConn - the connection that would be the public connection
  983. pcPrivateConnections - receives the count of connections returned
  984. pprgPrivateConnections - receives that possible private connections.
  985. The caller is responsible for:
  986. 1) Releasing all of the interface pointers w/in the array
  987. 2) Calling CoTaskMemFree on the pointer to the array
  988. pxCurrentPrivate - receives the index into pprgPrivateConnections of
  989. the connection that is currently marked IcsPrivate. If no connection
  990. is so marked, receives -1.
  991. Return Value:
  992. Standard HRESULT
  993. --*/
  994. {
  995. HRESULT hr = S_OK;
  996. INetConnectionManager *pNetConnMgr;
  997. IEnumNetConnection *pEnum;
  998. INetConnection *rgNetConn[16];
  999. GUID *pGuid = NULL;
  1000. HNET_CONN_PROPERTIES *pProps;
  1001. IHNetConnection **rgConnections = NULL;
  1002. ULONG cConn = 0;
  1003. ULONG i;
  1004. PIP_INTERFACE_INFO pIpIfTable = NULL;
  1005. if (NULL != pprgPrivateConnections)
  1006. {
  1007. *pprgPrivateConnections = NULL;
  1008. if (NULL == pConn)
  1009. {
  1010. hr = E_INVALIDARG;
  1011. }
  1012. else if (NULL == pcPrivateConnections
  1013. || NULL == pxCurrentPrivate)
  1014. {
  1015. hr = E_POINTER;
  1016. }
  1017. else
  1018. {
  1019. *pcPrivateConnections = 0;
  1020. *pxCurrentPrivate = -1;
  1021. }
  1022. }
  1023. else
  1024. {
  1025. hr = E_POINTER;
  1026. }
  1027. //
  1028. // Obtain the IP interface table. We use this table to see if an
  1029. // adapter is bound to TCP/IP.
  1030. //
  1031. if (S_OK == hr)
  1032. {
  1033. DWORD dwError;
  1034. ULONG ulSize = 0;
  1035. dwError = GetInterfaceInfo(NULL, &ulSize);
  1036. if (ERROR_INSUFFICIENT_BUFFER == dwError)
  1037. {
  1038. pIpIfTable =
  1039. reinterpret_cast<PIP_INTERFACE_INFO>(
  1040. HeapAlloc(GetProcessHeap(), 0, ulSize)
  1041. );
  1042. if (NULL != pIpIfTable)
  1043. {
  1044. dwError = GetInterfaceInfo(pIpIfTable, &ulSize);
  1045. if (ERROR_SUCCESS != dwError)
  1046. {
  1047. hr = HRESULT_FROM_WIN32(dwError);
  1048. HeapFree(GetProcessHeap(), 0, pIpIfTable);
  1049. pIpIfTable = NULL;
  1050. }
  1051. }
  1052. else
  1053. {
  1054. hr = E_OUTOFMEMORY;
  1055. }
  1056. }
  1057. else
  1058. {
  1059. hr = HRESULT_FROM_WIN32(dwError);
  1060. }
  1061. }
  1062. //
  1063. // If the connection we we're given is a LAN connection, get its
  1064. // guid so that we can exclude it from the possible private
  1065. // connections.
  1066. //
  1067. if (S_OK == hr)
  1068. {
  1069. hr = pConn->GetProperties(&pProps);
  1070. if (SUCCEEDED(hr))
  1071. {
  1072. if (pProps->fLanConnection)
  1073. {
  1074. hr = pConn->GetGuid(&pGuid);
  1075. }
  1076. CoTaskMemFree(pProps);
  1077. }
  1078. }
  1079. //
  1080. // Create the net connections manager, and enumerate through the
  1081. // connections. We don't enumerate through just what our store has,
  1082. // as it might have stale entries (i.e., information for adapters
  1083. // that have been removed from the system).
  1084. //
  1085. if (SUCCEEDED(hr))
  1086. {
  1087. hr = CoCreateInstance(
  1088. CLSID_ConnectionManager,
  1089. NULL,
  1090. CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_DISABLE_AAA,
  1091. IID_PPV_ARG(INetConnectionManager, &pNetConnMgr)
  1092. );
  1093. }
  1094. if (SUCCEEDED(hr))
  1095. {
  1096. SetProxyBlanket(pNetConnMgr);
  1097. hr = pNetConnMgr->EnumConnections(NCME_DEFAULT, &pEnum);
  1098. pNetConnMgr->Release();
  1099. }
  1100. if (SUCCEEDED(hr))
  1101. {
  1102. ULONG ulCount;
  1103. SetProxyBlanket(pEnum);
  1104. do
  1105. {
  1106. //
  1107. // Grab a bunch of connections out of the enumeration
  1108. //
  1109. hr = pEnum->Next(ARRAYSIZE(rgNetConn), rgNetConn, &ulCount);
  1110. if (SUCCEEDED(hr) && ulCount > 0)
  1111. {
  1112. //
  1113. // Allocate memory for the output array
  1114. //
  1115. LPVOID pTemp = reinterpret_cast<LPVOID>(rgConnections);
  1116. rgConnections = reinterpret_cast<IHNetConnection**>(
  1117. CoTaskMemRealloc(
  1118. pTemp,
  1119. (cConn + ulCount) * sizeof(IHNetConnection*))
  1120. );
  1121. if (NULL != rgConnections)
  1122. {
  1123. for (i = 0; i < ulCount; i++)
  1124. {
  1125. SetProxyBlanket(rgNetConn[i]);
  1126. hr = GetIHNetConnectionForINetConnection(
  1127. rgNetConn[i],
  1128. &rgConnections[cConn]
  1129. );
  1130. if (SUCCEEDED(hr))
  1131. {
  1132. hr = rgConnections[cConn]->GetProperties(&pProps);
  1133. if (SUCCEEDED(hr))
  1134. {
  1135. if (!pProps->fLanConnection
  1136. || pProps->fPartOfBridge
  1137. || pProps->fFirewalled)
  1138. {
  1139. //
  1140. // Connection can't be private
  1141. //
  1142. rgConnections[cConn]->Release();
  1143. rgConnections[cConn] = NULL;
  1144. }
  1145. else
  1146. {
  1147. GUID *pg;
  1148. //
  1149. // This connection can be private if:
  1150. // 1) it's not the same as the public connection
  1151. // (if the public is LAN), and,
  1152. // 2) it's bound to TCP/IP
  1153. //
  1154. hr = rgConnections[cConn]->GetGuid(&pg);
  1155. if (SUCCEEDED(hr))
  1156. {
  1157. if ((NULL == pGuid
  1158. || !IsEqualGUID(*pGuid, *pg))
  1159. && ConnectionIsBoundToTcp(pIpIfTable, pg))
  1160. {
  1161. //
  1162. // Connection can be private
  1163. //
  1164. if (pProps->fIcsPrivate)
  1165. {
  1166. _ASSERT(-1 == *pxCurrentPrivate);
  1167. *pxCurrentPrivate = cConn;
  1168. }
  1169. cConn += 1;
  1170. }
  1171. else
  1172. {
  1173. rgConnections[cConn]->Release();
  1174. rgConnections[cConn] = NULL;
  1175. }
  1176. CoTaskMemFree(pg);
  1177. }
  1178. else
  1179. {
  1180. rgConnections[cConn]->Release();
  1181. rgConnections[cConn] = NULL;
  1182. }
  1183. }
  1184. CoTaskMemFree(pProps);
  1185. }
  1186. }
  1187. else
  1188. {
  1189. //
  1190. // The connection couldn't be converted to an
  1191. // IHNetConnection -- this is expected for
  1192. // certain connection types (e.g., inbound)
  1193. //
  1194. hr = S_OK;
  1195. rgConnections[cConn] = NULL;
  1196. }
  1197. }
  1198. }
  1199. else
  1200. {
  1201. hr = E_OUTOFMEMORY;
  1202. if (NULL != pTemp)
  1203. {
  1204. rgConnections = reinterpret_cast<IHNetConnection**>(pTemp);
  1205. for (i = 0; i < cConn; i++)
  1206. {
  1207. rgConnections[i]->Release();
  1208. }
  1209. CoTaskMemFree(pTemp);
  1210. }
  1211. }
  1212. //
  1213. // Free the retrieved INetConnections
  1214. //
  1215. for (i = 0; i < ulCount; i++)
  1216. {
  1217. rgNetConn[i]->Release();
  1218. }
  1219. }
  1220. } while (SUCCEEDED(hr) && ulCount > 0);
  1221. pEnum->Release();
  1222. }
  1223. if (SUCCEEDED(hr))
  1224. {
  1225. hr = S_OK;
  1226. if (cConn > 0)
  1227. {
  1228. *pcPrivateConnections = cConn;
  1229. *pprgPrivateConnections = rgConnections;
  1230. }
  1231. else if (NULL != rgConnections)
  1232. {
  1233. CoTaskMemFree(reinterpret_cast<LPVOID>(rgConnections));
  1234. }
  1235. }
  1236. else
  1237. {
  1238. //
  1239. // Cleanup output array
  1240. //
  1241. if (NULL != rgConnections)
  1242. {
  1243. for (i = 0; i < cConn; i++)
  1244. {
  1245. if (NULL != rgConnections[i])
  1246. {
  1247. rgConnections[i]->Release();
  1248. }
  1249. }
  1250. CoTaskMemFree(reinterpret_cast<LPVOID>(rgConnections));
  1251. }
  1252. if (NULL != pxCurrentPrivate)
  1253. {
  1254. *pxCurrentPrivate = -1;
  1255. }
  1256. //
  1257. // Even though a failure occurred, return success (with 0 possible
  1258. // private connnections). Doing this allows our UI to continue to
  1259. // show other homenet features, instead of throwing up an error
  1260. // dialog and blocking everything.
  1261. //
  1262. hr = S_OK;
  1263. }
  1264. if (NULL != pGuid)
  1265. {
  1266. CoTaskMemFree(pGuid);
  1267. }
  1268. if (NULL != pIpIfTable)
  1269. {
  1270. HeapFree(GetProcessHeap(), 0, pIpIfTable);
  1271. }
  1272. return hr;
  1273. }
  1274. STDMETHODIMP
  1275. CHNetCfgMgr::GetAutodialSettings(
  1276. BOOLEAN *pfAutodialEnabled
  1277. )
  1278. {
  1279. HRESULT hr = S_OK;
  1280. BOOL fEnabled;
  1281. DWORD dwError;
  1282. if (!pfAutodialEnabled)
  1283. {
  1284. hr = E_POINTER;
  1285. }
  1286. if (S_OK == hr)
  1287. {
  1288. //
  1289. // Autodial information is stored in the registry and managed through
  1290. // routines exported from rasapi32.dll. We're not changing any of the
  1291. // autodial code, as to do so would require modifications to numerous
  1292. // files and binaries, and thus would result in a very large test hit.
  1293. //
  1294. dwError = RasQuerySharedAutoDial(&fEnabled);
  1295. if (ERROR_SUCCESS == dwError)
  1296. {
  1297. *pfAutodialEnabled = !!fEnabled;
  1298. }
  1299. else
  1300. {
  1301. //
  1302. // Autodial defaults to true on failure.
  1303. //
  1304. *pfAutodialEnabled = TRUE;
  1305. hr = HRESULT_FROM_WIN32(dwError);
  1306. }
  1307. }
  1308. return hr;
  1309. }
  1310. STDMETHODIMP
  1311. CHNetCfgMgr::SetAutodialSettings(
  1312. BOOLEAN fEnableAutodial
  1313. )
  1314. {
  1315. DWORD dwError;
  1316. //
  1317. // Autodial information is stored in the registry and managed through
  1318. // routines exported from rasapi32.dll. We're not changing any of the
  1319. // autodial code, as to do so would require modifications to numerous
  1320. // files and binaries, and thus would result in a very large test hit.
  1321. //
  1322. dwError = RasSetSharedAutoDial(!!fEnableAutodial);
  1323. return HRESULT_FROM_WIN32(dwError);
  1324. }
  1325. STDMETHODIMP
  1326. CHNetCfgMgr::GetDhcpEnabled(
  1327. BOOLEAN *pfDhcpEnabled
  1328. )
  1329. {
  1330. //
  1331. // Not supported in whistler, per 173399.
  1332. //
  1333. return E_NOTIMPL;
  1334. /**
  1335. HRESULT hr = S_OK;
  1336. IWbemClassObject *pwcoInstance;
  1337. if (NULL == pfDhcpEnabled)
  1338. {
  1339. hr = E_POINTER;
  1340. }
  1341. if (S_OK == hr)
  1342. {
  1343. //
  1344. // Default to true on failure
  1345. //
  1346. *pfDhcpEnabled = TRUE;
  1347. //
  1348. // Get the HNet_IcsSettings instance from the store
  1349. //
  1350. hr = RetrieveSingleInstance(
  1351. m_piwsHomenet,
  1352. c_wszHnetIcsSettings,
  1353. FALSE,
  1354. &pwcoInstance
  1355. );
  1356. }
  1357. if (S_OK == hr)
  1358. {
  1359. //
  1360. // Retrieve the DHCP enabled property
  1361. //
  1362. hr = GetBooleanValue(
  1363. pwcoInstance,
  1364. c_wszDhcpEnabled,
  1365. pfDhcpEnabled
  1366. );
  1367. pwcoInstance->Release();
  1368. }
  1369. return hr;
  1370. **/
  1371. }
  1372. STDMETHODIMP
  1373. CHNetCfgMgr::SetDhcpEnabled(
  1374. BOOLEAN fEnableDhcp
  1375. )
  1376. {
  1377. //
  1378. // Not supported in whistler, per 173399.
  1379. //
  1380. return E_NOTIMPL;
  1381. /**
  1382. HRESULT hr = S_OK;
  1383. IWbemClassObject *pwcoInstance = NULL;
  1384. //
  1385. // Get the HNet_IcsSettings instance from the store
  1386. //
  1387. hr = RetrieveSingleInstance(
  1388. m_piwsHomenet,
  1389. c_wszHnetIcsSettings,
  1390. TRUE,
  1391. &pwcoInstance
  1392. );
  1393. if (S_OK == hr)
  1394. {
  1395. //
  1396. // Write the property
  1397. //
  1398. hr = SetBooleanValue(
  1399. pwcoInstance,
  1400. c_wszDhcpEnabled,
  1401. fEnableDhcp
  1402. );
  1403. if (WBEM_S_NO_ERROR == hr)
  1404. {
  1405. //
  1406. // Write the modified instance to the store
  1407. //
  1408. hr = m_piwsHomenet->PutInstance(
  1409. pwcoInstance,
  1410. WBEM_FLAG_CREATE_OR_UPDATE,
  1411. NULL,
  1412. NULL
  1413. );
  1414. }
  1415. pwcoInstance->Release();
  1416. }
  1417. return hr;
  1418. **/
  1419. }
  1420. STDMETHODIMP
  1421. CHNetCfgMgr::GetDhcpScopeSettings(
  1422. DWORD *pdwScopeAddress,
  1423. DWORD *pdwScopeMask
  1424. )
  1425. {
  1426. HRESULT hr = S_OK;
  1427. if (NULL == pdwScopeAddress || NULL == pdwScopeMask)
  1428. {
  1429. hr = E_POINTER;
  1430. }
  1431. else
  1432. {
  1433. hr = ReadDhcpScopeSettings(pdwScopeAddress, pdwScopeMask);
  1434. }
  1435. return hr;
  1436. }
  1437. STDMETHODIMP
  1438. CHNetCfgMgr::SetDhcpScopeSettings(
  1439. DWORD dwScopeAddress,
  1440. DWORD dwScopeMask
  1441. )
  1442. {
  1443. //
  1444. // This functionality isn't exposed in any way at the moment.
  1445. //
  1446. // People needing to override the default settings can do so
  1447. // through the registry...
  1448. //
  1449. return E_NOTIMPL;
  1450. }
  1451. STDMETHODIMP
  1452. CHNetCfgMgr::GetDnsEnabled(
  1453. BOOLEAN *pfDnsEnabled
  1454. )
  1455. {
  1456. //
  1457. // Not supported in whistler, per 173399.
  1458. //
  1459. return E_NOTIMPL;
  1460. /**
  1461. HRESULT hr = S_OK;
  1462. IWbemClassObject *pwcoInstance = NULL;
  1463. if (NULL == pfDnsEnabled)
  1464. {
  1465. hr = E_POINTER;
  1466. }
  1467. if (S_OK == hr)
  1468. {
  1469. //
  1470. // Default to true on failure
  1471. //
  1472. *pfDnsEnabled = TRUE;
  1473. //
  1474. // Get the HNet_IcsSettings instance from the store
  1475. //
  1476. hr = RetrieveSingleInstance(
  1477. m_piwsHomenet,
  1478. c_wszHnetIcsSettings,
  1479. FALSE,
  1480. &pwcoInstance
  1481. );
  1482. }
  1483. if (S_OK == hr)
  1484. {
  1485. //
  1486. // Retrieve the DHCP enabled property
  1487. //
  1488. hr = GetBooleanValue(
  1489. pwcoInstance,
  1490. c_wszDnsEnabled,
  1491. pfDnsEnabled
  1492. );
  1493. pwcoInstance->Release();
  1494. }
  1495. return hr;
  1496. **/
  1497. }
  1498. STDMETHODIMP
  1499. CHNetCfgMgr::SetDnsEnabled(
  1500. BOOLEAN fEnableDns
  1501. )
  1502. {
  1503. //
  1504. // Not supported in whistler, per 173399.
  1505. //
  1506. return E_NOTIMPL;
  1507. /**
  1508. HRESULT hr = S_OK;
  1509. IWbemClassObject *pwcoInstance = NULL;
  1510. //
  1511. // Get the HNet_IcsSettings instance from the store
  1512. //
  1513. hr = RetrieveSingleInstance(
  1514. m_piwsHomenet,
  1515. c_wszHnetIcsSettings,
  1516. TRUE,
  1517. &pwcoInstance
  1518. );
  1519. if (S_OK == hr)
  1520. {
  1521. //
  1522. // Write the property
  1523. //
  1524. hr = SetBooleanValue(
  1525. pwcoInstance,
  1526. c_wszDnsEnabled,
  1527. fEnableDns
  1528. );
  1529. if (WBEM_S_NO_ERROR == hr)
  1530. {
  1531. //
  1532. // Write the modified instance to the store
  1533. //
  1534. hr = m_piwsHomenet->PutInstance(
  1535. pwcoInstance,
  1536. WBEM_FLAG_CREATE_OR_UPDATE,
  1537. NULL,
  1538. NULL
  1539. );
  1540. }
  1541. pwcoInstance->Release();
  1542. }
  1543. return hr;
  1544. **/
  1545. }
  1546. STDMETHODIMP
  1547. CHNetCfgMgr::EnumDhcpReservedAddresses(
  1548. IEnumHNetPortMappingBindings **ppEnum
  1549. )
  1550. {
  1551. HRESULT hr = S_OK;
  1552. BSTR bstrQuery;
  1553. IEnumWbemClassObject *pwcoEnum;
  1554. if (NULL != ppEnum)
  1555. {
  1556. *ppEnum = NULL;
  1557. }
  1558. else
  1559. {
  1560. hr = E_POINTER;
  1561. }
  1562. //
  1563. // Query for all enabled bindings where the name is active.
  1564. //
  1565. if (S_OK == hr)
  1566. {
  1567. hr = BuildSelectQueryBstr(
  1568. &bstrQuery,
  1569. c_wszStar,
  1570. c_wszHnetConnectionPortMapping,
  1571. L"Enabled != FALSE AND NameActive != FALSE"
  1572. );
  1573. }
  1574. if (S_OK == hr)
  1575. {
  1576. pwcoEnum = NULL;
  1577. hr = m_piwsHomenet->ExecQuery(
  1578. m_bstrWQL,
  1579. bstrQuery,
  1580. WBEM_FLAG_RETURN_IMMEDIATELY,
  1581. NULL,
  1582. &pwcoEnum
  1583. );
  1584. SysFreeString(bstrQuery);
  1585. }
  1586. if (WBEM_S_NO_ERROR == hr)
  1587. {
  1588. //
  1589. // Build wrapper object
  1590. //
  1591. CComObject<CEnumHNetPortMappingBindings> *pEnum;
  1592. hr = CComObject<CEnumHNetPortMappingBindings>::CreateInstance(&pEnum);
  1593. if (S_OK == hr)
  1594. {
  1595. pEnum->AddRef();
  1596. hr = pEnum->Initialize(m_piwsHomenet, pwcoEnum);
  1597. if (S_OK == hr)
  1598. {
  1599. hr = pEnum->QueryInterface(
  1600. IID_PPV_ARG(IEnumHNetPortMappingBindings, ppEnum)
  1601. );
  1602. }
  1603. pEnum->Release();
  1604. }
  1605. pwcoEnum->Release();
  1606. }
  1607. return hr;
  1608. }
  1609. STDMETHODIMP
  1610. CHNetCfgMgr::RefreshTargetComputerAddress(
  1611. OLECHAR *pszwName,
  1612. ULONG ulAddress
  1613. )
  1614. {
  1615. HRESULT hr = S_OK;
  1616. BSTR bstrQuery;
  1617. LPWSTR wszNameClause;
  1618. LPWSTR wszWhereClause;
  1619. IEnumWbemClassObject *pwcoEnum = NULL;
  1620. IWbemClassObject *pwcoInstance;
  1621. VARIANT vt;
  1622. if (NULL == pszwName
  1623. || 0 == ulAddress)
  1624. {
  1625. hr = E_INVALIDARG;
  1626. }
  1627. //
  1628. // Query for all bindings which match the target computer name.
  1629. //
  1630. // SELECT * FROM HNet_ConnectionPortMapping2 where
  1631. // TargetName = (computer name) AND NameActive != FALSE
  1632. //
  1633. if (S_OK == hr)
  1634. {
  1635. hr = BuildQuotedEqualsString(
  1636. &wszNameClause,
  1637. c_wszTargetName,
  1638. pszwName
  1639. );
  1640. }
  1641. if (S_OK == hr)
  1642. {
  1643. hr = BuildAndString(
  1644. &wszWhereClause,
  1645. wszNameClause,
  1646. L"NameActive != FALSE"
  1647. );
  1648. delete [] wszNameClause;
  1649. }
  1650. if (S_OK == hr)
  1651. {
  1652. hr = BuildSelectQueryBstr(
  1653. &bstrQuery,
  1654. c_wszStar,
  1655. c_wszHnetConnectionPortMapping,
  1656. wszWhereClause
  1657. );
  1658. delete [] wszWhereClause;
  1659. }
  1660. if (S_OK == hr)
  1661. {
  1662. hr = m_piwsHomenet->ExecQuery(
  1663. m_bstrWQL,
  1664. bstrQuery,
  1665. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
  1666. NULL,
  1667. &pwcoEnum
  1668. );
  1669. SysFreeString(bstrQuery);
  1670. }
  1671. while (WBEM_S_NO_ERROR == hr)
  1672. {
  1673. ULONG ulCount;
  1674. pwcoInstance = NULL;
  1675. hr = pwcoEnum->Next(WBEM_INFINITE, 1, &pwcoInstance, &ulCount);
  1676. if (SUCCEEDED(hr) && ulCount == 1)
  1677. {
  1678. V_VT(&vt) = VT_I4;
  1679. V_I4(&vt) = ulAddress;
  1680. hr = pwcoInstance->Put(
  1681. c_wszTargetIPAddress,
  1682. 0,
  1683. &vt,
  1684. NULL
  1685. );
  1686. if (WBEM_S_NO_ERROR == hr)
  1687. {
  1688. //
  1689. // Write the modified instance to the store
  1690. //
  1691. hr = m_piwsHomenet->PutInstance(
  1692. pwcoInstance,
  1693. WBEM_FLAG_UPDATE_ONLY,
  1694. NULL,
  1695. NULL
  1696. );
  1697. }
  1698. pwcoInstance->Release();
  1699. }
  1700. }
  1701. if (S_FALSE == hr)
  1702. {
  1703. hr = S_OK;
  1704. }
  1705. if (pwcoEnum)
  1706. {
  1707. pwcoEnum->Release();
  1708. }
  1709. return hr;
  1710. }
  1711. //
  1712. // IHNetProtocolSettings methods
  1713. //
  1714. STDMETHODIMP
  1715. CHNetCfgMgr::EnumApplicationProtocols(
  1716. BOOLEAN fEnabledOnly,
  1717. IEnumHNetApplicationProtocols **ppEnum
  1718. )
  1719. {
  1720. HRESULT hr = S_OK;
  1721. IEnumWbemClassObject *pwcoEnum;
  1722. BSTR bstrQuery;
  1723. if (!ppEnum)
  1724. {
  1725. hr = E_POINTER;
  1726. }
  1727. if (S_OK == hr)
  1728. {
  1729. *ppEnum = NULL;
  1730. //
  1731. // Query the WMI store for HNet_ApplicationProtocol instances;
  1732. // if fEnabledOnly is true, then only retrieve instances for
  1733. // which the Enabled property is true
  1734. //
  1735. hr = BuildSelectQueryBstr(
  1736. &bstrQuery,
  1737. c_wszStar,
  1738. c_wszHnetApplicationProtocol,
  1739. fEnabledOnly ? L"Enabled != FALSE" : NULL
  1740. );
  1741. }
  1742. if (S_OK == hr)
  1743. {
  1744. pwcoEnum = NULL;
  1745. hr = m_piwsHomenet->ExecQuery(
  1746. m_bstrWQL,
  1747. bstrQuery,
  1748. WBEM_FLAG_RETURN_IMMEDIATELY,
  1749. NULL,
  1750. &pwcoEnum
  1751. );
  1752. SysFreeString(bstrQuery);
  1753. }
  1754. if (WBEM_S_NO_ERROR == hr)
  1755. {
  1756. //
  1757. // Create and initialize the wrapper for the enum
  1758. //
  1759. CComObject<CEnumHNetApplicationProtocols> *pEnum;
  1760. hr = CComObject<CEnumHNetApplicationProtocols>::CreateInstance(&pEnum);
  1761. if (SUCCEEDED(hr))
  1762. {
  1763. pEnum->AddRef();
  1764. hr = pEnum->Initialize(m_piwsHomenet, pwcoEnum);
  1765. if (SUCCEEDED(hr))
  1766. {
  1767. hr = pEnum->QueryInterface(
  1768. IID_PPV_ARG(IEnumHNetApplicationProtocols, ppEnum)
  1769. );
  1770. }
  1771. pEnum->Release();
  1772. }
  1773. pwcoEnum->Release();
  1774. }
  1775. return hr;
  1776. }
  1777. STDMETHODIMP
  1778. CHNetCfgMgr::CreateApplicationProtocol(
  1779. OLECHAR *pszwName,
  1780. UCHAR ucOutgoingIPProtocol,
  1781. USHORT usOutgoingPort,
  1782. USHORT uscResponses,
  1783. HNET_RESPONSE_RANGE rgResponses[],
  1784. IHNetApplicationProtocol **ppProtocol
  1785. )
  1786. {
  1787. HRESULT hr = S_OK;
  1788. BSTR bstr;
  1789. VARIANT vt;
  1790. SAFEARRAY *psa;
  1791. IWbemClassObject *pwcoInstance;
  1792. if (NULL == ppProtocol)
  1793. {
  1794. hr = E_POINTER;
  1795. }
  1796. else
  1797. {
  1798. *ppProtocol = NULL;
  1799. if (NULL == pszwName
  1800. || 0 == ucOutgoingIPProtocol
  1801. || 0 == usOutgoingPort
  1802. || 0 == uscResponses
  1803. || NULL == rgResponses)
  1804. {
  1805. hr = E_INVALIDARG;
  1806. }
  1807. }
  1808. if (S_OK == hr)
  1809. {
  1810. //
  1811. // Check to see if there already exists a protocol with the same
  1812. // outgoing protocol and port
  1813. //
  1814. if (ApplicationProtocolExists(
  1815. m_piwsHomenet,
  1816. m_bstrWQL,
  1817. usOutgoingPort,
  1818. ucOutgoingIPProtocol
  1819. ))
  1820. {
  1821. hr = HRESULT_FROM_WIN32(ERROR_OBJECT_ALREADY_EXISTS);
  1822. }
  1823. }
  1824. if (S_OK == hr)
  1825. {
  1826. //
  1827. // Convert the array of response range structure to a
  1828. // SAFEARRAY of IUnknowns representing instances.
  1829. //
  1830. hr = ConvertResponseRangeArrayToInstanceSafearray(
  1831. m_piwsHomenet,
  1832. uscResponses,
  1833. rgResponses,
  1834. &psa
  1835. );
  1836. }
  1837. if (S_OK == hr)
  1838. {
  1839. //
  1840. // Spawn a new HNet_ApplicationProtocol
  1841. //
  1842. hr = SpawnNewInstance(
  1843. m_piwsHomenet,
  1844. c_wszHnetApplicationProtocol,
  1845. &pwcoInstance
  1846. );
  1847. if (WBEM_S_NO_ERROR == hr)
  1848. {
  1849. //
  1850. // Write the array property
  1851. //
  1852. V_VT(&vt) = VT_ARRAY | VT_UNKNOWN;
  1853. V_ARRAY(&vt) = psa;
  1854. hr = pwcoInstance->Put(
  1855. c_wszResponseArray,
  1856. 0,
  1857. &vt,
  1858. NULL
  1859. );
  1860. if (WBEM_S_NO_ERROR == hr)
  1861. {
  1862. // bug 555896: should limit the length of untrusted input string
  1863. // to some reasonable size. Am using INTERNET_MAX_HOST_NAME_LENGTH
  1864. // (somewhat arbitrarily), which is 256.
  1865. WCHAR szwName[INTERNET_MAX_HOST_NAME_LENGTH];
  1866. StringCchCopyW (szwName, INTERNET_MAX_HOST_NAME_LENGTH, pszwName);
  1867. //
  1868. // Write the name
  1869. //
  1870. V_VT(&vt) = VT_BSTR;
  1871. V_BSTR(&vt) = SysAllocString(szwName);
  1872. if (NULL != V_BSTR(&vt))
  1873. {
  1874. hr = pwcoInstance->Put(
  1875. c_wszName,
  1876. 0,
  1877. &vt,
  1878. NULL
  1879. );
  1880. VariantClear(&vt);
  1881. }
  1882. }
  1883. if (WBEM_S_NO_ERROR == hr)
  1884. {
  1885. //
  1886. // Write the response count. WMI uses VT_I4
  1887. // for its uint16 type
  1888. //
  1889. V_VT(&vt) = VT_I4;
  1890. V_I4(&vt) = uscResponses;
  1891. hr = pwcoInstance->Put(
  1892. c_wszResponseCount,
  1893. 0,
  1894. &vt,
  1895. NULL
  1896. );
  1897. }
  1898. if (WBEM_S_NO_ERROR == hr)
  1899. {
  1900. //
  1901. // Write the outgoing port
  1902. //
  1903. V_VT(&vt) = VT_I4;
  1904. V_I4(&vt) = usOutgoingPort;
  1905. hr = pwcoInstance->Put(
  1906. c_wszOutgoingPort,
  1907. 0,
  1908. &vt,
  1909. NULL
  1910. );
  1911. }
  1912. if (WBEM_S_NO_ERROR == hr)
  1913. {
  1914. //
  1915. // Write the outgoing IP protocol
  1916. //
  1917. V_VT(&vt) = VT_UI1;
  1918. V_UI1(&vt) = ucOutgoingIPProtocol;
  1919. hr = pwcoInstance->Put(
  1920. c_wszOutgoingIPProtocol,
  1921. 0,
  1922. &vt,
  1923. NULL
  1924. );
  1925. }
  1926. if (WBEM_S_NO_ERROR == hr)
  1927. {
  1928. //
  1929. // Set the builtin value to false
  1930. //
  1931. hr = SetBooleanValue(
  1932. pwcoInstance,
  1933. c_wszBuiltIn,
  1934. FALSE
  1935. );
  1936. }
  1937. if (WBEM_S_NO_ERROR == hr)
  1938. {
  1939. //
  1940. // New protocols are disabled by default
  1941. //
  1942. hr = SetBooleanValue(
  1943. pwcoInstance,
  1944. c_wszEnabled,
  1945. FALSE
  1946. );
  1947. }
  1948. if (WBEM_S_NO_ERROR == hr)
  1949. {
  1950. IWbemCallResult *pResult;
  1951. //
  1952. // Write the instance to the store
  1953. //
  1954. pResult = NULL;
  1955. hr = m_piwsHomenet->PutInstance(
  1956. pwcoInstance,
  1957. WBEM_FLAG_CREATE_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  1958. NULL,
  1959. &pResult
  1960. );
  1961. if (WBEM_S_NO_ERROR == hr)
  1962. {
  1963. pwcoInstance->Release();
  1964. pwcoInstance = NULL;
  1965. hr = pResult->GetResultString(WBEM_INFINITE, &bstr);
  1966. if (WBEM_S_NO_ERROR == hr)
  1967. {
  1968. hr = GetWmiObjectFromPath(
  1969. m_piwsHomenet,
  1970. bstr,
  1971. &pwcoInstance
  1972. );
  1973. SysFreeString(bstr);
  1974. }
  1975. pResult->Release();
  1976. }
  1977. }
  1978. if (WBEM_S_NO_ERROR == hr)
  1979. {
  1980. //
  1981. // Create the object to return
  1982. //
  1983. CComObject<CHNetAppProtocol> *pProt;
  1984. hr = CComObject<CHNetAppProtocol>::CreateInstance(&pProt);
  1985. if (S_OK == hr)
  1986. {
  1987. pProt->AddRef();
  1988. hr = pProt->Initialize(m_piwsHomenet, pwcoInstance);
  1989. if (S_OK == hr)
  1990. {
  1991. hr = pProt->QueryInterface(
  1992. IID_PPV_ARG(IHNetApplicationProtocol, ppProtocol)
  1993. );
  1994. }
  1995. pProt->Release();
  1996. }
  1997. }
  1998. if (NULL != pwcoInstance)
  1999. {
  2000. pwcoInstance->Release();
  2001. }
  2002. }
  2003. SafeArrayDestroy(psa);
  2004. }
  2005. return hr;
  2006. }
  2007. STDMETHODIMP
  2008. CHNetCfgMgr::EnumPortMappingProtocols(
  2009. IEnumHNetPortMappingProtocols **ppEnum
  2010. )
  2011. {
  2012. HRESULT hr = S_OK;
  2013. IEnumWbemClassObject *pwcoEnum;
  2014. BSTR bstrClass;
  2015. if (!ppEnum)
  2016. {
  2017. hr = E_POINTER;
  2018. }
  2019. else
  2020. {
  2021. *ppEnum = NULL;
  2022. }
  2023. if (S_OK == hr)
  2024. {
  2025. bstrClass = SysAllocString(c_wszHnetPortMappingProtocol);
  2026. if (NULL == bstrClass)
  2027. {
  2028. hr = E_OUTOFMEMORY;
  2029. }
  2030. }
  2031. if (S_OK == hr)
  2032. {
  2033. //
  2034. // Query the WMI store for HNet_PortMappingProtocol instances.
  2035. //
  2036. pwcoEnum = NULL;
  2037. hr = m_piwsHomenet->CreateInstanceEnum(
  2038. bstrClass,
  2039. WBEM_FLAG_RETURN_IMMEDIATELY,
  2040. NULL,
  2041. &pwcoEnum
  2042. );
  2043. SysFreeString(bstrClass);
  2044. }
  2045. if (WBEM_S_NO_ERROR == hr)
  2046. {
  2047. //
  2048. // Create and initialize the wrapper for the enum
  2049. //
  2050. CComObject<CEnumHNetPortMappingProtocols> *pEnum;
  2051. hr = CComObject<CEnumHNetPortMappingProtocols>::CreateInstance(&pEnum);
  2052. if (SUCCEEDED(hr))
  2053. {
  2054. pEnum->AddRef();
  2055. hr = pEnum->Initialize(m_piwsHomenet, pwcoEnum);
  2056. if (SUCCEEDED(hr))
  2057. {
  2058. hr = pEnum->QueryInterface(
  2059. IID_PPV_ARG(IEnumHNetPortMappingProtocols, ppEnum)
  2060. );
  2061. }
  2062. pEnum->Release();
  2063. }
  2064. pwcoEnum->Release();
  2065. }
  2066. return hr;
  2067. }
  2068. STDMETHODIMP
  2069. CHNetCfgMgr::CreatePortMappingProtocol(
  2070. OLECHAR *pszwName,
  2071. UCHAR ucIPProtocol,
  2072. USHORT usPort,
  2073. IHNetPortMappingProtocol **ppProtocol
  2074. )
  2075. {
  2076. HRESULT hr = S_OK;
  2077. BSTR bstr;
  2078. VARIANT vt;
  2079. IWbemClassObject *pwcoInstance;
  2080. if (NULL == ppProtocol)
  2081. {
  2082. hr = E_POINTER;
  2083. }
  2084. else
  2085. {
  2086. *ppProtocol = NULL;
  2087. if (NULL == pszwName
  2088. || 0 == ucIPProtocol
  2089. || 0 == usPort)
  2090. {
  2091. hr = E_INVALIDARG;
  2092. }
  2093. }
  2094. if (S_OK == hr)
  2095. {
  2096. //
  2097. // Check to see if there already exists a protocol with
  2098. // the same port/protocol combination
  2099. //
  2100. if (PortMappingProtocolExists(
  2101. m_piwsHomenet,
  2102. m_bstrWQL,
  2103. usPort,
  2104. ucIPProtocol
  2105. ))
  2106. {
  2107. hr = HRESULT_FROM_WIN32(ERROR_OBJECT_ALREADY_EXISTS);
  2108. }
  2109. }
  2110. if (S_OK == hr)
  2111. {
  2112. hr = SpawnNewInstance(
  2113. m_piwsHomenet,
  2114. c_wszHnetPortMappingProtocol,
  2115. &pwcoInstance
  2116. );
  2117. }
  2118. if (WBEM_S_NO_ERROR == hr)
  2119. {
  2120. // bug 555896: should limit the length of untrusted input string
  2121. // to some reasonable size. Am using INTERNET_MAX_HOST_NAME_LENGTH
  2122. // (somewhat arbitrarily), which is 256.
  2123. WCHAR szwName[INTERNET_MAX_HOST_NAME_LENGTH];
  2124. StringCchCopyW (szwName, INTERNET_MAX_HOST_NAME_LENGTH, pszwName);
  2125. V_VT(&vt) = VT_BSTR;
  2126. V_BSTR(&vt) = SysAllocString(szwName);
  2127. if (NULL != V_BSTR(&vt))
  2128. {
  2129. //
  2130. // Write the name
  2131. //
  2132. hr = pwcoInstance->Put(
  2133. c_wszName,
  2134. 0,
  2135. &vt,
  2136. NULL
  2137. );
  2138. VariantClear(&vt);
  2139. }
  2140. else
  2141. {
  2142. hr = E_OUTOFMEMORY;
  2143. }
  2144. if (WBEM_S_NO_ERROR == hr)
  2145. {
  2146. //
  2147. // Write the port
  2148. //
  2149. V_VT(&vt) = VT_I4;
  2150. V_I4(&vt) = usPort;
  2151. hr = pwcoInstance->Put(
  2152. c_wszPort,
  2153. 0,
  2154. &vt,
  2155. NULL
  2156. );
  2157. }
  2158. if (WBEM_S_NO_ERROR == hr)
  2159. {
  2160. //
  2161. // Write the IP protocol
  2162. //
  2163. V_VT(&vt) = VT_UI1;
  2164. V_UI1(&vt) = ucIPProtocol;
  2165. hr = pwcoInstance->Put(
  2166. c_wszIPProtocol,
  2167. 0,
  2168. &vt,
  2169. NULL
  2170. );
  2171. }
  2172. if (WBEM_S_NO_ERROR == hr)
  2173. {
  2174. //
  2175. // Set BuiltIn to false
  2176. //
  2177. hr = SetBooleanValue(
  2178. pwcoInstance,
  2179. c_wszBuiltIn,
  2180. FALSE
  2181. );
  2182. }
  2183. if (WBEM_S_NO_ERROR == hr)
  2184. {
  2185. IWbemCallResult *pResult;
  2186. //
  2187. // Write the instance to the store
  2188. //
  2189. pResult = NULL;
  2190. hr = m_piwsHomenet->PutInstance(
  2191. pwcoInstance,
  2192. WBEM_FLAG_CREATE_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  2193. NULL,
  2194. &pResult
  2195. );
  2196. if (WBEM_S_NO_ERROR == hr)
  2197. {
  2198. pwcoInstance->Release();
  2199. pwcoInstance = NULL;
  2200. hr = pResult->GetResultString(WBEM_INFINITE, &bstr);
  2201. if (WBEM_S_NO_ERROR == hr)
  2202. {
  2203. hr = GetWmiObjectFromPath(
  2204. m_piwsHomenet,
  2205. bstr,
  2206. &pwcoInstance
  2207. );
  2208. SysFreeString(bstr);
  2209. }
  2210. pResult->Release();
  2211. }
  2212. }
  2213. if (WBEM_S_NO_ERROR == hr)
  2214. {
  2215. //
  2216. // Create the object to return
  2217. //
  2218. CComObject<CHNetPortMappingProtocol> *pProt;
  2219. hr = CComObject<CHNetPortMappingProtocol>::CreateInstance(&pProt);
  2220. if (S_OK == hr)
  2221. {
  2222. pProt->AddRef();
  2223. hr = pProt->Initialize(m_piwsHomenet, pwcoInstance);
  2224. if (S_OK == hr)
  2225. {
  2226. hr = pProt->QueryInterface(
  2227. IID_PPV_ARG(IHNetPortMappingProtocol, ppProtocol)
  2228. );
  2229. }
  2230. pProt->Release();
  2231. }
  2232. }
  2233. if (NULL != pwcoInstance)
  2234. {
  2235. pwcoInstance->Release();
  2236. }
  2237. }
  2238. if (WBEM_S_NO_ERROR == hr)
  2239. {
  2240. SendPortMappingListChangeNotification();
  2241. }
  2242. return hr;
  2243. }
  2244. STDMETHODIMP
  2245. CHNetCfgMgr::FindPortMappingProtocol(
  2246. GUID *pGuid,
  2247. IHNetPortMappingProtocol **ppProtocol
  2248. )
  2249. {
  2250. BSTR bstr;
  2251. HRESULT hr = S_OK;
  2252. OLECHAR *pwszGuid;
  2253. OLECHAR wszPath[MAX_PATH];
  2254. IWbemClassObject *pwcoInstance;
  2255. if (NULL != ppProtocol)
  2256. {
  2257. *ppProtocol = NULL;
  2258. if (NULL == pGuid)
  2259. {
  2260. hr = E_INVALIDARG;
  2261. }
  2262. }
  2263. else
  2264. {
  2265. hr = E_POINTER;
  2266. }
  2267. if (S_OK == hr)
  2268. {
  2269. //
  2270. // Convert the GUID to string form
  2271. //
  2272. hr = StringFromCLSID(*pGuid, &pwszGuid);
  2273. }
  2274. if (S_OK == hr)
  2275. {
  2276. //
  2277. // Construct the path to the desired protocol
  2278. //
  2279. int count =
  2280. _snwprintf(
  2281. wszPath,
  2282. MAX_PATH,
  2283. L"%s.%s=\"%s\"",
  2284. c_wszHnetPortMappingProtocol,
  2285. c_wszId,
  2286. pwszGuid
  2287. );
  2288. _ASSERT(count > 0);
  2289. CoTaskMemFree(pwszGuid);
  2290. bstr = SysAllocString(wszPath);
  2291. if (NULL != bstr)
  2292. {
  2293. hr = GetWmiObjectFromPath(m_piwsHomenet, bstr, &pwcoInstance);
  2294. SysFreeString(bstr);
  2295. }
  2296. else
  2297. {
  2298. hr = E_OUTOFMEMORY;
  2299. }
  2300. }
  2301. if (S_OK == hr)
  2302. {
  2303. CComObject<CHNetPortMappingProtocol> *pProtocol;
  2304. hr = CComObject<CHNetPortMappingProtocol>::CreateInstance(&pProtocol);
  2305. if (SUCCEEDED(hr))
  2306. {
  2307. pProtocol->AddRef();
  2308. hr = pProtocol->Initialize(m_piwsHomenet, pwcoInstance);
  2309. if (SUCCEEDED(hr))
  2310. {
  2311. hr = pProtocol->QueryInterface(
  2312. IID_PPV_ARG(IHNetPortMappingProtocol, ppProtocol)
  2313. );
  2314. }
  2315. pProtocol->Release();
  2316. }
  2317. pwcoInstance->Release();
  2318. }
  2319. return hr;
  2320. }
  2321. //
  2322. // Private methods
  2323. //
  2324. HRESULT
  2325. CHNetCfgMgr::CopyLoggingInstanceToStruct(
  2326. IWbemClassObject *pwcoInstance,
  2327. HNET_FW_LOGGING_SETTINGS *pfwSettings
  2328. )
  2329. {
  2330. HRESULT hr;
  2331. VARIANT vt;
  2332. BSTR bstrPath;
  2333. _ASSERT(pwcoInstance);
  2334. _ASSERT(pfwSettings);
  2335. //
  2336. // Zero-out settings structure
  2337. //
  2338. ZeroMemory(pfwSettings, sizeof(*pfwSettings));
  2339. //
  2340. // Get the Path property.
  2341. //
  2342. hr = pwcoInstance->Get(
  2343. c_wszPath,
  2344. 0,
  2345. &vt,
  2346. NULL,
  2347. NULL
  2348. );
  2349. if (WBEM_S_NO_ERROR == hr)
  2350. {
  2351. _ASSERT(VT_BSTR == V_VT(&vt));
  2352. //
  2353. // Allocate space to hold the string
  2354. //
  2355. pfwSettings->pszwPath =
  2356. (LPWSTR) CoTaskMemAlloc((SysStringLen(V_BSTR(&vt)) + 1)
  2357. * sizeof(OLECHAR));
  2358. if (NULL != pfwSettings->pszwPath)
  2359. {
  2360. //
  2361. // Copy string over
  2362. //
  2363. wcscpy(pfwSettings->pszwPath, V_BSTR(&vt));
  2364. }
  2365. else
  2366. {
  2367. hr = E_OUTOFMEMORY;
  2368. }
  2369. //
  2370. // Free the returned BSTR
  2371. //
  2372. VariantClear(&vt);
  2373. }
  2374. if (WBEM_S_NO_ERROR == hr)
  2375. {
  2376. //
  2377. // Get max file size
  2378. //
  2379. hr = pwcoInstance->Get(
  2380. c_wszMaxFileSize,
  2381. 0,
  2382. &vt,
  2383. NULL,
  2384. NULL
  2385. );
  2386. if (WBEM_S_NO_ERROR == hr)
  2387. {
  2388. _ASSERT(VT_I4 == V_VT(&vt));
  2389. pfwSettings->ulMaxFileSize = V_I4(&vt);
  2390. VariantClear(&vt);
  2391. }
  2392. }
  2393. if (WBEM_S_NO_ERROR == hr)
  2394. {
  2395. //
  2396. // Get log dropped packets value
  2397. //
  2398. hr = GetBooleanValue(
  2399. pwcoInstance,
  2400. c_wszLogDroppedPackets,
  2401. &pfwSettings->fLogDroppedPackets
  2402. );
  2403. }
  2404. if (WBEM_S_NO_ERROR == hr)
  2405. {
  2406. //
  2407. // Get log connections value
  2408. //
  2409. hr = GetBooleanValue(
  2410. pwcoInstance,
  2411. c_wszLogConnections,
  2412. &pfwSettings->fLogConnections
  2413. );
  2414. }
  2415. if (FAILED(hr) && NULL != pfwSettings->pszwPath)
  2416. {
  2417. CoTaskMemFree(pfwSettings->pszwPath);
  2418. }
  2419. return hr;
  2420. }
  2421. HRESULT
  2422. CHNetCfgMgr::CopyStructToLoggingInstance(
  2423. HNET_FW_LOGGING_SETTINGS *pfwSettings,
  2424. IWbemClassObject *pwcoInstance
  2425. )
  2426. {
  2427. HRESULT hr = S_OK;
  2428. VARIANT vt;
  2429. _ASSERT(pwcoInstance);
  2430. _ASSERT(pfwSettings);
  2431. //
  2432. // Wrap the path in a BSTR in a varaint
  2433. //
  2434. VariantInit(&vt);
  2435. V_VT(&vt) = VT_BSTR;
  2436. V_BSTR(&vt) = SysAllocString(pfwSettings->pszwPath);
  2437. if (NULL == V_BSTR(&vt))
  2438. {
  2439. hr = E_OUTOFMEMORY;
  2440. }
  2441. if (S_OK == hr)
  2442. {
  2443. //
  2444. // Set the Path property.
  2445. //
  2446. hr = pwcoInstance->Put(
  2447. c_wszPath,
  2448. 0,
  2449. &vt,
  2450. NULL
  2451. );
  2452. //
  2453. // Clearing the variant will free the BSTR we allocated
  2454. // above.
  2455. //
  2456. VariantClear(&vt);
  2457. }
  2458. if (WBEM_S_NO_ERROR == hr)
  2459. {
  2460. //
  2461. // Set max file size
  2462. //
  2463. V_VT(&vt) = VT_I4;
  2464. V_I4(&vt) = pfwSettings->ulMaxFileSize;
  2465. hr = pwcoInstance->Put(
  2466. c_wszMaxFileSize,
  2467. 0,
  2468. &vt,
  2469. NULL
  2470. );
  2471. }
  2472. if (WBEM_S_NO_ERROR == hr)
  2473. {
  2474. //
  2475. // Set log dropped packets value
  2476. //
  2477. hr = SetBooleanValue(
  2478. pwcoInstance,
  2479. c_wszLogDroppedPackets,
  2480. pfwSettings->fLogDroppedPackets
  2481. );
  2482. }
  2483. if (WBEM_S_NO_ERROR == hr)
  2484. {
  2485. //
  2486. // Set log connections value
  2487. //
  2488. hr = SetBooleanValue(
  2489. pwcoInstance,
  2490. c_wszLogConnections,
  2491. pfwSettings->fLogConnections
  2492. );
  2493. }
  2494. return hr;
  2495. }
  2496. HRESULT
  2497. CHNetCfgMgr::InstallBridge(
  2498. GUID *pguid,
  2499. INetCfg *pnetcfgExisting
  2500. )
  2501. {
  2502. HRESULT hr = S_OK;
  2503. INetCfg *pnetcfg = NULL;
  2504. INetCfgLock *pncfglock = NULL;
  2505. INetCfgComponent *pncfgcomp = NULL;
  2506. if( NULL == pnetcfgExisting )
  2507. {
  2508. hr = InitializeNetCfgForWrite( &pnetcfg, &pncfglock );
  2509. // Bail out if we can't acquire NetCfg.
  2510. if( FAILED(hr) )
  2511. {
  2512. return hr;
  2513. }
  2514. }
  2515. else
  2516. {
  2517. // Use the NetCfg context we were given
  2518. pnetcfg = pnetcfgExisting;
  2519. }
  2520. // We must have a NetCfg context at this point
  2521. _ASSERT( pnetcfg != NULL );
  2522. // ===================================================================
  2523. // (cut here)
  2524. //
  2525. // Check if the bridge component already exists
  2526. //
  2527. // **
  2528. // Remove this check when it becomes legal to have
  2529. // multiple bridges
  2530. // **
  2531. //
  2532. hr = pnetcfg->FindComponent(
  2533. c_wszSBridgeMPID,
  2534. &pncfgcomp
  2535. );
  2536. // S_OK indicates that the bridge component is present, which is BAD.
  2537. // We take any other success code to indicate that the search succeeded,
  2538. // but that the bridge component was not present (which is what we want).
  2539. // We take failure codes to mean the search blew up.
  2540. if ( S_OK == hr )
  2541. {
  2542. // Bridge was present
  2543. pncfgcomp->Release();
  2544. hr = E_UNEXPECTED;
  2545. }
  2546. // (cut here)
  2547. // ===================================================================
  2548. if ( SUCCEEDED(hr) )
  2549. {
  2550. const GUID guidClass = GUID_DEVCLASS_NET;
  2551. INetCfgClassSetup *pncfgsetup = NULL;
  2552. //
  2553. // Recover the NetCfgClassSetup interface
  2554. //
  2555. hr = pnetcfg->QueryNetCfgClass(
  2556. &guidClass,
  2557. IID_PPV_ARG(INetCfgClassSetup, &pncfgsetup)
  2558. );
  2559. if ( SUCCEEDED(hr) )
  2560. {
  2561. //
  2562. // Install the bridge miniport component
  2563. //
  2564. hr = pncfgsetup->Install(
  2565. c_wszSBridgeMPID,
  2566. NULL,
  2567. NSF_PRIMARYINSTALL,
  2568. 0,
  2569. NULL,
  2570. NULL,
  2571. &pncfgcomp
  2572. );
  2573. if ( SUCCEEDED(hr) )
  2574. {
  2575. hr = pncfgcomp->GetInstanceGuid(pguid);
  2576. pncfgcomp->Release();
  2577. }
  2578. pncfgsetup->Release();
  2579. }
  2580. }
  2581. // If we created our own NetCfg context, shut it down now
  2582. if( NULL == pnetcfgExisting )
  2583. {
  2584. // Apply everything if we succeeded, back out otherwise
  2585. if ( SUCCEEDED(hr) )
  2586. {
  2587. hr = pnetcfg->Apply();
  2588. // Signal that the bridge should be drawn
  2589. SignalNewConnection( pguid );
  2590. }
  2591. else
  2592. {
  2593. // Don't want to lose the original error code
  2594. pnetcfg->Cancel();
  2595. }
  2596. UninitializeNetCfgForWrite( pnetcfg, pncfglock );
  2597. }
  2598. return hr;
  2599. }
  2600. HRESULT
  2601. CHNetCfgMgr::CreateConnectionAndPropertyInstances(
  2602. GUID *pGuid,
  2603. BOOLEAN fLanConnection,
  2604. LPCWSTR pszwName,
  2605. IWbemClassObject **ppwcoConnection,
  2606. IWbemClassObject **ppwcoProperties
  2607. )
  2608. {
  2609. HRESULT hr;
  2610. BSTR bstr = NULL;
  2611. IWbemClassObject *pwcoConnection = NULL;
  2612. IWbemClassObject *pwcoProperties;
  2613. IWbemCallResult *pResult;
  2614. VARIANT vt;
  2615. _ASSERT(NULL != pGuid);
  2616. _ASSERT(NULL != pszwName);
  2617. _ASSERT(NULL != ppwcoConnection);
  2618. _ASSERT(NULL != ppwcoProperties);
  2619. //
  2620. // Create the HNet_Connection instance
  2621. //
  2622. hr = SpawnNewInstance(
  2623. m_piwsHomenet,
  2624. c_wszHnetConnection,
  2625. &pwcoConnection
  2626. );
  2627. //
  2628. // Fill out the HNet_Connection instance
  2629. //
  2630. if (WBEM_S_NO_ERROR == hr)
  2631. {
  2632. LPOLESTR wszGuid;
  2633. //
  2634. // Set GUID property
  2635. //
  2636. hr = StringFromCLSID(*pGuid, &wszGuid);
  2637. if (S_OK == hr)
  2638. {
  2639. V_VT(&vt) = VT_BSTR;
  2640. V_BSTR(&vt) = SysAllocString(wszGuid);
  2641. if (NULL != V_BSTR(&vt))
  2642. {
  2643. hr = pwcoConnection->Put(
  2644. c_wszGuid,
  2645. 0,
  2646. &vt,
  2647. NULL
  2648. );
  2649. VariantClear(&vt);
  2650. }
  2651. else
  2652. {
  2653. hr = E_OUTOFMEMORY;
  2654. }
  2655. CoTaskMemFree(wszGuid);
  2656. }
  2657. //
  2658. // Set Name property
  2659. //
  2660. if (WBEM_S_NO_ERROR == hr)
  2661. {
  2662. V_VT(&vt) = VT_BSTR;
  2663. V_BSTR(&vt) = SysAllocString(pszwName);
  2664. if (NULL != V_BSTR(&vt))
  2665. {
  2666. hr = pwcoConnection->Put(
  2667. c_wszName,
  2668. 0,
  2669. &vt,
  2670. NULL
  2671. );
  2672. VariantClear(&vt);
  2673. }
  2674. else
  2675. {
  2676. hr = E_OUTOFMEMORY;
  2677. }
  2678. }
  2679. if (WBEM_S_NO_ERROR == hr)
  2680. {
  2681. //
  2682. // Set the IsLan property
  2683. //
  2684. hr = SetBooleanValue(
  2685. pwcoConnection,
  2686. c_wszIsLanConnection,
  2687. fLanConnection
  2688. );
  2689. }
  2690. if (WBEM_S_NO_ERROR == hr)
  2691. {
  2692. //
  2693. // Commit the object and retrieve its path
  2694. //
  2695. pResult = NULL;
  2696. hr = m_piwsHomenet->PutInstance(
  2697. pwcoConnection,
  2698. WBEM_FLAG_CREATE_OR_UPDATE | WBEM_FLAG_RETURN_IMMEDIATELY,
  2699. NULL,
  2700. &pResult
  2701. );
  2702. if (WBEM_S_NO_ERROR == hr)
  2703. {
  2704. pwcoConnection->Release();
  2705. pwcoConnection = NULL;
  2706. hr = pResult->GetResultString(WBEM_INFINITE, &bstr);
  2707. pResult->Release();
  2708. if (WBEM_S_NO_ERROR == hr)
  2709. {
  2710. hr = GetWmiObjectFromPath(
  2711. m_piwsHomenet,
  2712. bstr,
  2713. &pwcoConnection
  2714. );
  2715. if (FAILED(hr))
  2716. {
  2717. SysFreeString(bstr);
  2718. bstr = NULL;
  2719. }
  2720. //
  2721. // The bstr will be freed below on success
  2722. //
  2723. }
  2724. }
  2725. }
  2726. if (FAILED(hr) && NULL != pwcoConnection)
  2727. {
  2728. //
  2729. // Something went wrong -- get rid
  2730. // of the instance we created
  2731. //
  2732. pwcoConnection->Release();
  2733. pwcoConnection = NULL;
  2734. }
  2735. }
  2736. if (S_OK == hr)
  2737. {
  2738. //
  2739. // Create the HNet_ConnectionProperties instance
  2740. //
  2741. hr = SpawnNewInstance(
  2742. m_piwsHomenet,
  2743. c_wszHnetProperties,
  2744. &pwcoProperties
  2745. );
  2746. //
  2747. // Fill out the HNet_ConnectionProperties instance
  2748. //
  2749. if (WBEM_S_NO_ERROR == hr)
  2750. {
  2751. //
  2752. // Set the path to our connection
  2753. //
  2754. V_VT(&vt) = VT_BSTR;
  2755. V_BSTR(&vt) = bstr;
  2756. hr = pwcoProperties->Put(
  2757. c_wszConnection,
  2758. 0,
  2759. &vt,
  2760. NULL
  2761. );
  2762. VariantClear(&vt);
  2763. bstr = NULL;
  2764. if (WBEM_S_NO_ERROR == hr)
  2765. {
  2766. hr = SetBooleanValue(
  2767. pwcoProperties,
  2768. c_wszIsFirewalled,
  2769. FALSE
  2770. );
  2771. }
  2772. if (WBEM_S_NO_ERROR == hr)
  2773. {
  2774. hr = SetBooleanValue(
  2775. pwcoProperties,
  2776. c_wszIsIcsPublic,
  2777. FALSE
  2778. );
  2779. }
  2780. if (WBEM_S_NO_ERROR == hr)
  2781. {
  2782. hr = SetBooleanValue(
  2783. pwcoProperties,
  2784. c_wszIsIcsPrivate,
  2785. FALSE
  2786. );
  2787. }
  2788. if (WBEM_S_NO_ERROR == hr)
  2789. {
  2790. //
  2791. // Commit properties instance to the store
  2792. //
  2793. pResult = NULL;
  2794. hr = m_piwsHomenet->PutInstance(
  2795. pwcoProperties,
  2796. WBEM_FLAG_CREATE_OR_UPDATE | WBEM_FLAG_RETURN_IMMEDIATELY,
  2797. NULL,
  2798. &pResult
  2799. );
  2800. if (WBEM_S_NO_ERROR == hr)
  2801. {
  2802. pwcoProperties->Release();
  2803. pwcoProperties = NULL;
  2804. hr = pResult->GetResultString(WBEM_INFINITE, &bstr);
  2805. pResult->Release();
  2806. if (WBEM_S_NO_ERROR == hr)
  2807. {
  2808. hr = GetWmiObjectFromPath(
  2809. m_piwsHomenet,
  2810. bstr,
  2811. &pwcoProperties
  2812. );
  2813. SysFreeString(bstr);
  2814. bstr = NULL;
  2815. }
  2816. }
  2817. }
  2818. if (FAILED(hr))
  2819. {
  2820. //
  2821. // Something went wrong -- get rid of the instances
  2822. // we created. We also need to delete the connection
  2823. // instance from the store.
  2824. //
  2825. DeleteWmiInstance(m_piwsHomenet, pwcoConnection);
  2826. pwcoConnection->Release();
  2827. pwcoConnection = NULL;
  2828. if (NULL != pwcoProperties)
  2829. {
  2830. pwcoProperties->Release();
  2831. pwcoProperties = NULL;
  2832. }
  2833. }
  2834. }
  2835. }
  2836. if (bstr) {
  2837. SysFreeString (bstr);
  2838. bstr = NULL;
  2839. }
  2840. if (WBEM_S_NO_ERROR == hr)
  2841. {
  2842. //
  2843. // Transferring reference, so skip release on pwco[x] and
  2844. // addref on ppwco[x]
  2845. //
  2846. *ppwcoConnection = pwcoConnection;
  2847. *ppwcoProperties = pwcoProperties;
  2848. }
  2849. return hr;
  2850. }
  2851. BOOLEAN
  2852. CHNetCfgMgr::ProhibitedByPolicy(
  2853. DWORD dwPerm
  2854. )
  2855. {
  2856. HRESULT hr = S_OK;
  2857. BOOLEAN fProhibited = FALSE;
  2858. if (NULL == m_pNetConnUiUtil)
  2859. {
  2860. Lock();
  2861. if (NULL == m_pNetConnUiUtil)
  2862. {
  2863. hr = CoCreateInstance(
  2864. CLSID_NetConnectionUiUtilities,
  2865. NULL,
  2866. CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_DISABLE_AAA,
  2867. IID_PPV_ARG(INetConnectionUiUtilities, &m_pNetConnUiUtil)
  2868. );
  2869. }
  2870. Unlock();
  2871. }
  2872. if (SUCCEEDED(hr))
  2873. {
  2874. fProhibited = !m_pNetConnUiUtil->UserHasPermission(dwPerm);
  2875. }
  2876. return fProhibited;
  2877. }
  2878. HRESULT
  2879. CHNetCfgMgr::UpdateNetman()
  2880. {
  2881. HRESULT hr = S_OK;
  2882. if (NULL == m_pNetConnHNetUtil)
  2883. {
  2884. Lock();
  2885. if (NULL == m_pNetConnHNetUtil)
  2886. {
  2887. hr = CoCreateInstance(
  2888. CLSID_NetConnectionHNetUtil,
  2889. NULL,
  2890. CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_DISABLE_AAA,
  2891. IID_PPV_ARG(INetConnectionHNetUtil, &m_pNetConnHNetUtil)
  2892. );
  2893. }
  2894. Unlock();
  2895. }
  2896. if (SUCCEEDED(hr))
  2897. {
  2898. hr = m_pNetConnHNetUtil->NotifyUpdate();
  2899. }
  2900. return hr;
  2901. }