Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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