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.

1114 lines
23 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997 - 2000
  5. //
  6. // File: H N P R T M A P . C P P
  7. //
  8. // Contents: CHNetPortMappingProtocol implementation
  9. //
  10. // Notes:
  11. //
  12. // Author: jonburs 22 June 2000
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. //
  18. // Atl methods
  19. //
  20. HRESULT
  21. CHNetPortMappingProtocol::FinalConstruct()
  22. {
  23. HRESULT hr = S_OK;
  24. m_bstrWQL = SysAllocString(c_wszWQL);
  25. if (NULL == m_bstrWQL)
  26. {
  27. hr = E_OUTOFMEMORY;
  28. }
  29. return hr;
  30. }
  31. HRESULT
  32. CHNetPortMappingProtocol::FinalRelease()
  33. {
  34. if (m_piwsHomenet) m_piwsHomenet->Release();
  35. if (m_bstrProtocol) SysFreeString(m_bstrProtocol);
  36. if (m_bstrWQL) SysFreeString(m_bstrWQL);
  37. return S_OK;
  38. }
  39. //
  40. // Object initialization
  41. //
  42. HRESULT
  43. CHNetPortMappingProtocol::Initialize(
  44. IWbemServices *piwsNamespace,
  45. IWbemClassObject *pwcoInstance
  46. )
  47. {
  48. HRESULT hr = S_OK;
  49. _ASSERT(NULL == m_piwsHomenet);
  50. _ASSERT(NULL == m_bstrProtocol);
  51. _ASSERT(NULL != piwsNamespace);
  52. _ASSERT(NULL != pwcoInstance);
  53. //
  54. // Read and cache our builtin value
  55. //
  56. hr = GetBooleanValue(
  57. pwcoInstance,
  58. c_wszBuiltIn,
  59. &m_fBuiltIn
  60. );
  61. if (WBEM_S_NO_ERROR == hr)
  62. {
  63. hr = GetWmiPathFromObject(pwcoInstance, &m_bstrProtocol);
  64. }
  65. if (WBEM_S_NO_ERROR == hr)
  66. {
  67. m_piwsHomenet = piwsNamespace;
  68. m_piwsHomenet->AddRef();
  69. }
  70. return hr;
  71. }
  72. //
  73. // IHNetPortMappingProtocol methods
  74. //
  75. STDMETHODIMP
  76. CHNetPortMappingProtocol::GetName(
  77. OLECHAR **ppszwName
  78. )
  79. {
  80. HRESULT hr = S_OK;
  81. IWbemClassObject *pwcoProtocol;
  82. VARIANT vt;
  83. if (NULL == ppszwName)
  84. {
  85. hr = E_POINTER;
  86. }
  87. else
  88. {
  89. *ppszwName = NULL;
  90. hr = GetProtocolObject(&pwcoProtocol);
  91. }
  92. if (S_OK == hr)
  93. {
  94. //
  95. // Read the name property from our instance
  96. //
  97. hr = pwcoProtocol->Get(
  98. c_wszName,
  99. NULL,
  100. &vt,
  101. NULL,
  102. NULL
  103. );
  104. pwcoProtocol->Release();
  105. }
  106. if (WBEM_S_NO_ERROR == hr)
  107. {
  108. _ASSERT(VT_BSTR == V_VT(&vt));
  109. if (m_fBuiltIn)
  110. {
  111. UINT uiId;
  112. //
  113. // Attempt to convert the retrieved name to a resource
  114. // ID. (For localization purposes the names for builtin
  115. // protocols are stored as resources instead of directly
  116. // w/in the store.)
  117. //
  118. uiId = static_cast<UINT>(_wtoi(V_BSTR(&vt)));
  119. if (0 != uiId)
  120. {
  121. WCHAR wszBuffer[256];
  122. int iLength;
  123. iLength =
  124. LoadString(
  125. _Module.GetResourceInstance(),
  126. uiId,
  127. wszBuffer,
  128. sizeof(wszBuffer) / sizeof(WCHAR)
  129. );
  130. if (0 != iLength)
  131. {
  132. //
  133. // We were able to map the name to a resource. Allocate
  134. // the output buffer and copy over the resource string.
  135. //
  136. *ppszwName =
  137. reinterpret_cast<OLECHAR*>(
  138. CoTaskMemAlloc((iLength + 1) * sizeof(OLECHAR))
  139. );
  140. if (NULL != *ppszwName)
  141. {
  142. wcscpy(*ppszwName, wszBuffer);
  143. }
  144. else
  145. {
  146. hr = E_OUTOFMEMORY;
  147. }
  148. }
  149. }
  150. }
  151. if (WBEM_S_NO_ERROR == hr && NULL == *ppszwName)
  152. {
  153. //
  154. // This isn't a builtin protocol, or we weren't able to map
  155. // the stored "name" to a resource. Allocate the output
  156. // buffer and copy over the retrieved BSTR.
  157. //
  158. *ppszwName = reinterpret_cast<OLECHAR*>(
  159. CoTaskMemAlloc((SysStringLen(V_BSTR(&vt)) + 1)
  160. * sizeof(OLECHAR))
  161. );
  162. if (NULL != *ppszwName)
  163. {
  164. wcscpy(*ppszwName, V_BSTR(&vt));
  165. }
  166. else
  167. {
  168. hr = E_OUTOFMEMORY;
  169. }
  170. }
  171. VariantClear(&vt);
  172. }
  173. return hr;
  174. }
  175. STDMETHODIMP
  176. CHNetPortMappingProtocol::SetName(
  177. OLECHAR *pszwName
  178. )
  179. {
  180. HRESULT hr = S_OK;
  181. IWbemClassObject *pwcoProtocol;
  182. VARIANT vt;
  183. if (TRUE == m_fBuiltIn)
  184. {
  185. //
  186. // Can't change values for builtin protocols
  187. //
  188. hr = E_ACCESSDENIED;
  189. }
  190. else if (NULL == pszwName)
  191. {
  192. hr = E_INVALIDARG;
  193. }
  194. else
  195. {
  196. hr = GetProtocolObject(&pwcoProtocol);
  197. }
  198. if (S_OK == hr)
  199. {
  200. //
  201. // Wrap the passed-in string in a BSTR and a variant
  202. //
  203. VariantInit(&vt);
  204. V_VT(&vt) = VT_BSTR;
  205. V_BSTR(&vt) = SysAllocString(pszwName);
  206. if (NULL == V_BSTR(&vt))
  207. {
  208. hr = E_OUTOFMEMORY;
  209. }
  210. if (S_OK == hr)
  211. {
  212. //
  213. // Set the property on the instance
  214. //
  215. hr = pwcoProtocol->Put(
  216. c_wszName,
  217. 0,
  218. &vt,
  219. NULL
  220. );
  221. VariantClear(&vt);
  222. }
  223. if (WBEM_S_NO_ERROR == hr)
  224. {
  225. //
  226. // Write the modified instance to the store
  227. //
  228. hr = m_piwsHomenet->PutInstance(
  229. pwcoProtocol,
  230. WBEM_FLAG_UPDATE_ONLY,
  231. NULL,
  232. NULL
  233. );
  234. }
  235. pwcoProtocol->Release();
  236. }
  237. return hr;
  238. }
  239. STDMETHODIMP
  240. CHNetPortMappingProtocol::GetIPProtocol(
  241. UCHAR *pucProtocol
  242. )
  243. {
  244. HRESULT hr = S_OK;
  245. IWbemClassObject *pwcoProtocol;
  246. VARIANT vt;
  247. if (NULL == pucProtocol)
  248. {
  249. hr = E_POINTER;
  250. }
  251. else
  252. {
  253. hr = GetProtocolObject(&pwcoProtocol);
  254. }
  255. if (S_OK == hr)
  256. {
  257. hr = pwcoProtocol->Get(
  258. c_wszIPProtocol,
  259. 0,
  260. &vt,
  261. NULL,
  262. NULL
  263. );
  264. pwcoProtocol->Release();
  265. }
  266. if (WBEM_S_NO_ERROR == hr)
  267. {
  268. _ASSERT(VT_UI1 == V_VT(&vt));
  269. *pucProtocol = V_UI1(&vt);
  270. VariantClear(&vt);
  271. }
  272. return hr;
  273. }
  274. STDMETHODIMP
  275. CHNetPortMappingProtocol::SetIPProtocol(
  276. UCHAR ucProtocol
  277. )
  278. {
  279. BOOLEAN fProtocolChanged = TRUE;
  280. HRESULT hr = S_OK;
  281. IWbemClassObject *pwcoProtocol;
  282. VARIANT vt;
  283. if (TRUE == m_fBuiltIn)
  284. {
  285. //
  286. // Can't change values for builtin protocols
  287. //
  288. hr = E_ACCESSDENIED;
  289. }
  290. else if (0 == ucProtocol)
  291. {
  292. hr = E_INVALIDARG;
  293. }
  294. if (S_OK == hr)
  295. {
  296. UCHAR ucOldProtocol;
  297. hr = GetIPProtocol(&ucOldProtocol);
  298. if (S_OK == hr && ucProtocol == ucOldProtocol)
  299. {
  300. fProtocolChanged = FALSE;
  301. }
  302. }
  303. if (S_OK == hr && fProtocolChanged)
  304. {
  305. USHORT usPort;
  306. //
  307. // Make sure that this won't result in a duplicate
  308. //
  309. hr = GetPort(&usPort);
  310. if (S_OK == hr)
  311. {
  312. if (PortMappingProtocolExists(
  313. m_piwsHomenet,
  314. m_bstrWQL,
  315. usPort,
  316. ucProtocol
  317. ))
  318. {
  319. //
  320. // This change would result in a duplicate
  321. //
  322. hr = HRESULT_FROM_WIN32(ERROR_OBJECT_ALREADY_EXISTS);
  323. }
  324. }
  325. if (S_OK == hr)
  326. {
  327. hr = GetProtocolObject(&pwcoProtocol);
  328. }
  329. if (S_OK == hr)
  330. {
  331. VariantInit(&vt);
  332. V_VT(&vt) = VT_UI1;
  333. V_UI1(&vt) = ucProtocol;
  334. hr = pwcoProtocol->Put(
  335. c_wszIPProtocol,
  336. 0,
  337. &vt,
  338. NULL
  339. );
  340. if (WBEM_S_NO_ERROR == hr)
  341. {
  342. //
  343. // Write the modified instance to the store
  344. //
  345. hr = m_piwsHomenet->PutInstance(
  346. pwcoProtocol,
  347. WBEM_FLAG_UPDATE_ONLY,
  348. NULL,
  349. NULL
  350. );
  351. }
  352. pwcoProtocol->Release();
  353. }
  354. if (S_OK == hr)
  355. {
  356. //
  357. // Update SharedAccess of the change
  358. //
  359. SendUpdateNotification();
  360. }
  361. }
  362. return hr;
  363. }
  364. STDMETHODIMP
  365. CHNetPortMappingProtocol::GetPort(
  366. USHORT *pusPort
  367. )
  368. {
  369. HRESULT hr = S_OK;
  370. IWbemClassObject *pwcoProtocol;
  371. VARIANT vt;
  372. if (NULL == pusPort)
  373. {
  374. hr = E_POINTER;
  375. }
  376. else
  377. {
  378. hr = GetProtocolObject(&pwcoProtocol);
  379. }
  380. if (S_OK == hr)
  381. {
  382. hr = pwcoProtocol->Get(
  383. c_wszPort,
  384. 0,
  385. &vt,
  386. NULL,
  387. NULL
  388. );
  389. pwcoProtocol->Release();
  390. }
  391. if (WBEM_S_NO_ERROR == hr)
  392. {
  393. //
  394. // WMI uses V_I4 for it's uint16 type
  395. //
  396. _ASSERT(VT_I4 == V_VT(&vt));
  397. *pusPort = static_cast<USHORT>(V_I4(&vt));
  398. VariantClear(&vt);
  399. }
  400. return hr;
  401. }
  402. STDMETHODIMP
  403. CHNetPortMappingProtocol::SetPort(
  404. USHORT usPort
  405. )
  406. {
  407. BOOLEAN fPortChanged = TRUE;
  408. HRESULT hr = S_OK;
  409. IWbemClassObject *pwcoProtocol;
  410. VARIANT vt;
  411. if (TRUE == m_fBuiltIn)
  412. {
  413. //
  414. // Can't change values for builtin protocols
  415. //
  416. hr = E_ACCESSDENIED;
  417. }
  418. else if (0 == usPort)
  419. {
  420. hr = E_INVALIDARG;
  421. }
  422. if (S_OK == hr)
  423. {
  424. USHORT usOldPort;
  425. //
  426. // Check if the new value is the same as the old
  427. //
  428. hr = GetPort(&usOldPort);
  429. if (S_OK == hr && usPort == usOldPort)
  430. {
  431. fPortChanged = FALSE;
  432. }
  433. }
  434. if (S_OK == hr && fPortChanged)
  435. {
  436. UCHAR ucIPProtocol;
  437. //
  438. // Make sure that this won't result in a duplicate
  439. //
  440. hr = GetIPProtocol(&ucIPProtocol);
  441. if (S_OK == hr)
  442. {
  443. if (PortMappingProtocolExists(
  444. m_piwsHomenet,
  445. m_bstrWQL,
  446. usPort,
  447. ucIPProtocol
  448. ))
  449. {
  450. //
  451. // This change would result in a duplicate
  452. //
  453. hr = HRESULT_FROM_WIN32(ERROR_OBJECT_ALREADY_EXISTS);
  454. }
  455. }
  456. if (S_OK == hr)
  457. {
  458. hr = GetProtocolObject(&pwcoProtocol);
  459. }
  460. if (S_OK == hr)
  461. {
  462. //
  463. // WMI uses V_I4 for it's uint16 type
  464. //
  465. VariantInit(&vt);
  466. V_VT(&vt) = VT_I4;
  467. V_I4(&vt) = usPort;
  468. hr = pwcoProtocol->Put(
  469. c_wszPort,
  470. 0,
  471. &vt,
  472. NULL
  473. );
  474. if (WBEM_S_NO_ERROR == hr)
  475. {
  476. //
  477. // Write the modified instance to the store
  478. //
  479. hr = m_piwsHomenet->PutInstance(
  480. pwcoProtocol,
  481. WBEM_FLAG_UPDATE_ONLY,
  482. NULL,
  483. NULL
  484. );
  485. }
  486. pwcoProtocol->Release();
  487. }
  488. if (S_OK == hr)
  489. {
  490. //
  491. // Update SharedAccess of the change
  492. //
  493. SendUpdateNotification();
  494. }
  495. }
  496. return hr;
  497. }
  498. STDMETHODIMP
  499. CHNetPortMappingProtocol::GetBuiltIn(
  500. BOOLEAN *pfBuiltIn
  501. )
  502. {
  503. HRESULT hr = S_OK;
  504. if (NULL != pfBuiltIn)
  505. {
  506. *pfBuiltIn = m_fBuiltIn;
  507. }
  508. else
  509. {
  510. hr = E_POINTER;
  511. }
  512. return hr;
  513. }
  514. STDMETHODIMP
  515. CHNetPortMappingProtocol::Delete()
  516. {
  517. HRESULT hr = S_OK;
  518. IEnumWbemClassObject *pwcoEnum;
  519. IWbemClassObject *pwcoInstance;
  520. BSTR bstrQuery = NULL;
  521. ULONG ulCount;
  522. if (TRUE == m_fBuiltIn)
  523. {
  524. //
  525. // Can't delete builtin protocols
  526. //
  527. hr = E_ACCESSDENIED;
  528. }
  529. else
  530. {
  531. LPWSTR pwsz;
  532. //
  533. // Query for all HNet_ConnectionPortMapping instances
  534. // that refer to this protocol -- i.e.,
  535. //
  536. // SELECT * FROM HNet_ConnectionPortMapping2 WHERE PROTOCOL = m_bstrProtocol
  537. //
  538. // We can't use a references query here since once we delete the
  539. // protocol object that query won't return any results...
  540. //
  541. hr = BuildEscapedQuotedEqualsString(
  542. &pwsz,
  543. c_wszProtocol,
  544. m_bstrProtocol
  545. );
  546. if (S_OK == hr)
  547. {
  548. hr = BuildSelectQueryBstr(
  549. &bstrQuery,
  550. c_wszStar,
  551. c_wszHnetConnectionPortMapping,
  552. pwsz
  553. );
  554. delete [] pwsz;
  555. }
  556. }
  557. if (S_OK == hr)
  558. {
  559. //
  560. // Execute the query
  561. //
  562. pwcoEnum = NULL;
  563. m_piwsHomenet->ExecQuery(
  564. m_bstrWQL,
  565. bstrQuery,
  566. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  567. NULL,
  568. &pwcoEnum
  569. );
  570. //
  571. // The query BSTR will be used again below
  572. //
  573. }
  574. if (WBEM_S_NO_ERROR == hr)
  575. {
  576. //
  577. // Loop through the enumeration, making sure that each entry
  578. // is disabled
  579. //
  580. do
  581. {
  582. pwcoInstance = NULL;
  583. hr = pwcoEnum->Next(
  584. WBEM_INFINITE,
  585. 1,
  586. &pwcoInstance,
  587. &ulCount
  588. );
  589. if (SUCCEEDED(hr) && 1 == ulCount)
  590. {
  591. HRESULT hr2;
  592. CComObject<CHNetPortMappingBinding> *pBinding;
  593. //
  594. // Convert this to an actual CHNetPortMappingBinding so
  595. // that we can disable it and generate the change
  596. // notification for SharedAccess.
  597. //
  598. hr2 = CComObject<CHNetPortMappingBinding>::CreateInstance(&pBinding);
  599. if (SUCCEEDED(hr2))
  600. {
  601. pBinding->AddRef();
  602. hr2 = pBinding->Initialize(m_piwsHomenet, pwcoInstance);
  603. if (SUCCEEDED(hr))
  604. {
  605. hr2 = pBinding->SetEnabled(FALSE);
  606. }
  607. pBinding->Release();
  608. }
  609. pwcoInstance->Release();
  610. }
  611. }
  612. while (SUCCEEDED(hr) && 1 == ulCount);
  613. pwcoEnum->Release();
  614. hr = WBEM_S_NO_ERROR;
  615. }
  616. if (WBEM_S_NO_ERROR == hr)
  617. {
  618. //
  619. // Delete the protocol instance
  620. //
  621. hr = m_piwsHomenet->DeleteInstance(
  622. m_bstrProtocol,
  623. 0,
  624. NULL,
  625. NULL
  626. );
  627. }
  628. if (WBEM_S_NO_ERROR == hr)
  629. {
  630. //
  631. // Now that the protocol instance is gone enumerate and
  632. // delete the bindings that refer to this instance. This
  633. // needs to happen after the protocol instance is gone to
  634. // prevent the instance from being recreated after we
  635. // delete it here.
  636. //
  637. pwcoEnum = NULL;
  638. m_piwsHomenet->ExecQuery(
  639. m_bstrWQL,
  640. bstrQuery,
  641. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  642. NULL,
  643. &pwcoEnum
  644. );
  645. }
  646. if (WBEM_S_NO_ERROR == hr)
  647. {
  648. do
  649. {
  650. pwcoInstance = NULL;
  651. hr = pwcoEnum->Next(
  652. WBEM_INFINITE,
  653. 1,
  654. &pwcoInstance,
  655. &ulCount
  656. );
  657. if (SUCCEEDED(hr) && 1 == ulCount)
  658. {
  659. DeleteWmiInstance(m_piwsHomenet, pwcoInstance);
  660. pwcoInstance->Release();
  661. }
  662. }
  663. while (SUCCEEDED(hr) && 1 == ulCount);
  664. pwcoEnum->Release();
  665. hr = WBEM_S_NO_ERROR;
  666. }
  667. if ( WBEM_S_NO_ERROR == hr )
  668. {
  669. SendPortMappingListChangeNotification();
  670. }
  671. //
  672. // bstrQuery is initialized to NULL at start, and SysFreeString
  673. // can deal w/ NULL input, so it's safe to call this even on
  674. // an error path.
  675. //
  676. SysFreeString(bstrQuery);
  677. return hr;
  678. }
  679. STDMETHODIMP
  680. CHNetPortMappingProtocol::GetGuid(
  681. GUID **ppGuid
  682. )
  683. {
  684. HRESULT hr;
  685. IWbemClassObject *pwcoInstance;
  686. VARIANT vt;
  687. if (NULL != ppGuid)
  688. {
  689. *ppGuid = reinterpret_cast<GUID*>(
  690. CoTaskMemAlloc(sizeof(GUID))
  691. );
  692. if (NULL != *ppGuid)
  693. {
  694. hr = GetProtocolObject(&pwcoInstance);
  695. }
  696. else
  697. {
  698. hr = E_OUTOFMEMORY;
  699. }
  700. }
  701. else
  702. {
  703. hr = E_POINTER;
  704. }
  705. if (WBEM_S_NO_ERROR == hr)
  706. {
  707. hr = pwcoInstance->Get(
  708. c_wszId,
  709. 0,
  710. &vt,
  711. NULL,
  712. NULL
  713. );
  714. if (WBEM_S_NO_ERROR == hr)
  715. {
  716. ASSERT(VT_BSTR == V_VT(&vt));
  717. hr = CLSIDFromString(V_BSTR(&vt), *ppGuid);
  718. VariantClear(&vt);
  719. }
  720. pwcoInstance->Release();
  721. }
  722. if (FAILED(hr) && NULL != ppGuid && NULL != *ppGuid)
  723. {
  724. CoTaskMemFree(*ppGuid);
  725. *ppGuid = NULL;
  726. }
  727. return hr;
  728. }
  729. //
  730. // IHNetPrivate methods
  731. //
  732. STDMETHODIMP
  733. CHNetPortMappingProtocol::GetObjectPath(
  734. BSTR *pbstrPath
  735. )
  736. {
  737. HRESULT hr = S_OK;
  738. if (NULL != pbstrPath)
  739. {
  740. _ASSERT(m_bstrProtocol != NULL);
  741. *pbstrPath = SysAllocString(m_bstrProtocol);
  742. if (NULL == *pbstrPath)
  743. {
  744. hr = E_OUTOFMEMORY;
  745. }
  746. }
  747. else
  748. {
  749. hr = E_POINTER;
  750. }
  751. return hr;
  752. }
  753. //
  754. // Private methods
  755. //
  756. HRESULT
  757. CHNetPortMappingProtocol::GetProtocolObject(
  758. IWbemClassObject **ppwcoInstance
  759. )
  760. {
  761. _ASSERT(NULL != ppwcoInstance);
  762. return GetWmiObjectFromPath(
  763. m_piwsHomenet,
  764. m_bstrProtocol,
  765. ppwcoInstance
  766. );
  767. }
  768. HRESULT
  769. CHNetPortMappingProtocol::SendUpdateNotification()
  770. {
  771. HRESULT hr = S_OK;
  772. IEnumHNetPortMappingBindings *pEnum;
  773. GUID *pProtocolGuid = NULL;
  774. ISharedAccessUpdate *pUpdate;
  775. if (IsServiceRunning(c_wszSharedAccess))
  776. {
  777. hr = GetGuid(&pProtocolGuid);
  778. //
  779. // Get the enumeration of enabled port mapping
  780. // bindings for this protocol
  781. //
  782. if (SUCCEEDED(hr))
  783. {
  784. hr = GetEnabledBindingEnumeration(&pEnum);
  785. }
  786. if (SUCCEEDED(hr))
  787. {
  788. hr = CoCreateInstance(
  789. CLSID_SAUpdate,
  790. NULL,
  791. CLSCTX_SERVER,
  792. IID_PPV_ARG(ISharedAccessUpdate, &pUpdate)
  793. );
  794. if (SUCCEEDED(hr))
  795. {
  796. IHNetPortMappingBinding *pBinding;
  797. IHNetConnection *pConnection;
  798. GUID *pConnectionGuid;
  799. ULONG ulCount;
  800. do
  801. {
  802. hr = pEnum->Next(1, &pBinding, &ulCount);
  803. if (SUCCEEDED(hr) && 1 == ulCount)
  804. {
  805. hr = pBinding->GetConnection(&pConnection);
  806. pBinding->Release();
  807. if (SUCCEEDED(hr))
  808. {
  809. hr = pConnection->GetGuid(&pConnectionGuid);
  810. pConnection->Release();
  811. }
  812. if (SUCCEEDED(hr))
  813. {
  814. hr = pUpdate->ConnectionPortMappingChanged(
  815. pConnectionGuid,
  816. pProtocolGuid,
  817. TRUE
  818. );
  819. CoTaskMemFree(pConnectionGuid);
  820. }
  821. }
  822. }
  823. while (SUCCEEDED(hr) && 1 == ulCount);
  824. pUpdate->Release();
  825. }
  826. pEnum->Release();
  827. }
  828. }
  829. if (NULL != pProtocolGuid)
  830. {
  831. CoTaskMemFree(pProtocolGuid);
  832. }
  833. return hr;
  834. }
  835. HRESULT
  836. CHNetPortMappingProtocol::GetEnabledBindingEnumeration(
  837. IEnumHNetPortMappingBindings **ppEnum
  838. )
  839. {
  840. BSTR bstr;
  841. HRESULT hr = S_OK;
  842. OLECHAR *pwsz;
  843. OLECHAR *pwszWhere;
  844. _ASSERT(NULL != ppEnum);
  845. //
  846. // Generate the query string
  847. //
  848. hr = BuildEscapedQuotedEqualsString(
  849. &pwsz,
  850. c_wszProtocol,
  851. m_bstrProtocol
  852. );
  853. if (S_OK == hr)
  854. {
  855. hr = BuildAndString(
  856. &pwszWhere,
  857. pwsz,
  858. L"Enabled != FALSE"
  859. );
  860. delete [] pwsz;
  861. }
  862. if (S_OK == hr)
  863. {
  864. hr = BuildSelectQueryBstr(
  865. &bstr,
  866. c_wszStar,
  867. c_wszHnetConnectionPortMapping,
  868. pwszWhere
  869. );
  870. delete [] pwszWhere;
  871. }
  872. //
  873. // Execute the query and build the enumerator
  874. //
  875. if (S_OK == hr)
  876. {
  877. IEnumWbemClassObject *pwcoEnum = NULL;
  878. hr = m_piwsHomenet->ExecQuery(
  879. m_bstrWQL,
  880. bstr,
  881. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  882. NULL,
  883. &pwcoEnum
  884. );
  885. SysFreeString(bstr);
  886. if (WBEM_S_NO_ERROR == hr)
  887. {
  888. CComObject<CEnumHNetPortMappingBindings> *pEnum;
  889. hr = CComObject<CEnumHNetPortMappingBindings>::CreateInstance(&pEnum);
  890. if (S_OK == hr)
  891. {
  892. pEnum->AddRef();
  893. hr = pEnum->Initialize(m_piwsHomenet, pwcoEnum);
  894. if (S_OK == hr)
  895. {
  896. hr = pEnum->QueryInterface(
  897. IID_PPV_ARG(IEnumHNetPortMappingBindings, ppEnum)
  898. );
  899. }
  900. pEnum->Release();
  901. }
  902. pwcoEnum->Release();
  903. }
  904. }
  905. return hr;
  906. }