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.

1169 lines
24 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997 - 2000
  5. //
  6. // File: H N P R T M A P . H
  7. //
  8. // Contents: CHNetPortMappingBinding 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. CHNetPortMappingBinding::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. CHNetPortMappingBinding::FinalRelease()
  33. {
  34. if (m_bstrWQL) SysFreeString(m_bstrWQL);
  35. if (m_piwsHomenet) m_piwsHomenet->Release();
  36. if (m_bstrBinding) SysFreeString(m_bstrBinding);
  37. return S_OK;
  38. }
  39. //
  40. // Object initialization
  41. //
  42. HRESULT
  43. CHNetPortMappingBinding::Initialize(
  44. IWbemServices *piwsNamespace,
  45. IWbemClassObject *pwcoInstance
  46. )
  47. {
  48. HRESULT hr = S_OK;
  49. _ASSERT(NULL == m_piwsHomenet);
  50. _ASSERT(NULL == m_bstrBinding);
  51. _ASSERT(NULL != piwsNamespace);
  52. _ASSERT(NULL != pwcoInstance);
  53. m_piwsHomenet = piwsNamespace;
  54. m_piwsHomenet->AddRef();
  55. hr = GetWmiPathFromObject(pwcoInstance, &m_bstrBinding);
  56. return hr;
  57. }
  58. //
  59. // IHNetPortMappingBinding methods
  60. //
  61. STDMETHODIMP
  62. CHNetPortMappingBinding::GetConnection(
  63. IHNetConnection **ppConnection
  64. )
  65. {
  66. HRESULT hr = S_OK;
  67. VARIANT vt;
  68. IWbemClassObject *pwcoInstance;
  69. IWbemClassObject *pwcoBinding;
  70. if (NULL == ppConnection)
  71. {
  72. hr = E_POINTER;
  73. }
  74. else
  75. {
  76. *ppConnection = NULL;
  77. hr = GetBindingObject(&pwcoBinding);
  78. }
  79. if (S_OK == hr)
  80. {
  81. //
  82. // Read our protocol reference
  83. //
  84. hr = pwcoBinding->Get(
  85. c_wszConnection,
  86. 0,
  87. &vt,
  88. NULL,
  89. NULL
  90. );
  91. pwcoBinding->Release();
  92. }
  93. if (WBEM_S_NO_ERROR == hr)
  94. {
  95. _ASSERT(VT_BSTR == V_VT(&vt));
  96. //
  97. // Get the IWbemClassObject
  98. //
  99. hr = GetWmiObjectFromPath(
  100. m_piwsHomenet,
  101. V_BSTR(&vt),
  102. &pwcoInstance
  103. );
  104. VariantClear(&vt);
  105. }
  106. if (S_OK == hr)
  107. {
  108. //
  109. // Create the object for the instance
  110. //
  111. CComObject<CHNetConn> *pConnection;
  112. hr = CComObject<CHNetConn>::CreateInstance(&pConnection);
  113. if (SUCCEEDED(hr))
  114. {
  115. pConnection->AddRef();
  116. hr = pConnection->InitializeFromConnection(m_piwsHomenet, pwcoInstance);
  117. if (SUCCEEDED(hr))
  118. {
  119. hr = pConnection->QueryInterface(
  120. IID_PPV_ARG(IHNetConnection, ppConnection)
  121. );
  122. }
  123. pConnection->Release();
  124. }
  125. pwcoInstance->Release();
  126. }
  127. return hr;
  128. }
  129. STDMETHODIMP
  130. CHNetPortMappingBinding::GetProtocol(
  131. IHNetPortMappingProtocol **ppProtocol
  132. )
  133. {
  134. HRESULT hr = S_OK;
  135. VARIANT vt;
  136. IWbemClassObject *pwcoInstance;
  137. IWbemClassObject *pwcoBinding;
  138. if (NULL == ppProtocol)
  139. {
  140. hr = E_POINTER;
  141. }
  142. else
  143. {
  144. *ppProtocol = NULL;
  145. hr = GetBindingObject(&pwcoBinding);
  146. }
  147. if (S_OK == hr)
  148. {
  149. //
  150. // Read our protocol reference
  151. //
  152. hr = pwcoBinding->Get(
  153. c_wszProtocol,
  154. 0,
  155. &vt,
  156. NULL,
  157. NULL
  158. );
  159. if (WBEM_S_NO_ERROR == hr)
  160. {
  161. _ASSERT(VT_BSTR == V_VT(&vt));
  162. //
  163. // Get the IWbemClassObject for the protocol.
  164. //
  165. hr = GetWmiObjectFromPath(
  166. m_piwsHomenet,
  167. V_BSTR(&vt),
  168. &pwcoInstance
  169. );
  170. VariantClear(&vt);
  171. if (S_OK == hr)
  172. {
  173. //
  174. // Create the object for the instance
  175. //
  176. CComObject<CHNetPortMappingProtocol> *pProt;
  177. hr = CComObject<CHNetPortMappingProtocol>::CreateInstance(&pProt);
  178. if (SUCCEEDED(hr))
  179. {
  180. pProt->AddRef();
  181. hr = pProt->Initialize(m_piwsHomenet, pwcoInstance);
  182. if (SUCCEEDED(hr))
  183. {
  184. hr = pProt->QueryInterface(
  185. IID_PPV_ARG(IHNetPortMappingProtocol, ppProtocol)
  186. );
  187. }
  188. pProt->Release();
  189. }
  190. pwcoInstance->Release();
  191. }
  192. else if (WBEM_E_NOT_FOUND == hr)
  193. {
  194. //
  195. // The protocol object we refer to doesn't exist --
  196. // the store is in an invalid state. Delete our
  197. // binding instance and return the error to the
  198. // caller.
  199. //
  200. DeleteWmiInstance(m_piwsHomenet, pwcoBinding);
  201. }
  202. }
  203. pwcoBinding->Release();
  204. }
  205. return hr;
  206. }
  207. STDMETHODIMP
  208. CHNetPortMappingBinding::GetEnabled(
  209. BOOLEAN *pfEnabled
  210. )
  211. {
  212. HRESULT hr = S_OK;
  213. IWbemClassObject *pwcoBinding;
  214. if (NULL == pfEnabled)
  215. {
  216. hr = E_POINTER;
  217. }
  218. else
  219. {
  220. hr = GetBindingObject(&pwcoBinding);
  221. }
  222. if (S_OK == hr)
  223. {
  224. hr = GetBooleanValue(
  225. pwcoBinding,
  226. c_wszEnabled,
  227. pfEnabled
  228. );
  229. pwcoBinding->Release();
  230. }
  231. return hr;
  232. }
  233. STDMETHODIMP
  234. CHNetPortMappingBinding::SetEnabled(
  235. BOOLEAN fEnable
  236. )
  237. {
  238. BOOLEAN fOldEnabled;
  239. HRESULT hr;
  240. IWbemClassObject *pwcoBinding;
  241. hr = GetEnabled(&fOldEnabled);
  242. if (S_OK == hr && fOldEnabled != fEnable)
  243. {
  244. hr = GetBindingObject(&pwcoBinding);
  245. if (WBEM_S_NO_ERROR == hr)
  246. {
  247. hr = SetBooleanValue(
  248. pwcoBinding,
  249. c_wszEnabled,
  250. fEnable
  251. );
  252. if (WBEM_S_NO_ERROR == hr)
  253. {
  254. //
  255. // Write the modified instance to the store
  256. //
  257. hr = m_piwsHomenet->PutInstance(
  258. pwcoBinding,
  259. WBEM_FLAG_UPDATE_ONLY,
  260. NULL,
  261. NULL
  262. );
  263. }
  264. pwcoBinding->Release();
  265. }
  266. if (WBEM_S_NO_ERROR == hr)
  267. {
  268. //
  269. // Notify service of update.
  270. //
  271. SendUpdateNotification();
  272. }
  273. }
  274. return hr;
  275. }
  276. STDMETHODIMP
  277. CHNetPortMappingBinding::GetCurrentMethod(
  278. BOOLEAN *pfUseName
  279. )
  280. {
  281. HRESULT hr = S_OK;
  282. IWbemClassObject *pwcoBinding;
  283. if (NULL == pfUseName)
  284. {
  285. hr = E_POINTER;
  286. }
  287. else
  288. {
  289. hr = GetBindingObject(&pwcoBinding);
  290. }
  291. if (S_OK == hr)
  292. {
  293. hr = GetBooleanValue(
  294. pwcoBinding,
  295. c_wszNameActive,
  296. pfUseName
  297. );
  298. pwcoBinding->Release();
  299. }
  300. return hr;
  301. }
  302. STDMETHODIMP
  303. CHNetPortMappingBinding::GetTargetComputerName(
  304. OLECHAR **ppszwName
  305. )
  306. {
  307. HRESULT hr = S_OK;
  308. IWbemClassObject *pwcoBinding;
  309. BOOLEAN fNameActive;
  310. VARIANT vt;
  311. if (NULL == ppszwName)
  312. {
  313. hr = E_POINTER;
  314. }
  315. else
  316. {
  317. *ppszwName = NULL;
  318. hr = GetBindingObject(&pwcoBinding);
  319. }
  320. if (S_OK == hr)
  321. {
  322. //
  323. // Check to see if the name is valid
  324. //
  325. hr = GetCurrentMethod(&fNameActive);
  326. if (S_OK == hr && FALSE == fNameActive)
  327. {
  328. hr = E_UNEXPECTED;
  329. }
  330. if (S_OK == hr)
  331. {
  332. *ppszwName = NULL;
  333. //
  334. // Read the name property from our instance
  335. //
  336. hr = pwcoBinding->Get(
  337. c_wszTargetName,
  338. NULL,
  339. &vt,
  340. NULL,
  341. NULL
  342. );
  343. }
  344. pwcoBinding->Release();
  345. }
  346. if (WBEM_S_NO_ERROR == hr)
  347. {
  348. _ASSERT(VT_BSTR == V_VT(&vt));
  349. //
  350. // Allocate memory for the return string
  351. //
  352. *ppszwName = reinterpret_cast<OLECHAR*>(
  353. CoTaskMemAlloc((SysStringLen(V_BSTR(&vt)) + 1)
  354. * sizeof(OLECHAR))
  355. );
  356. if (NULL != *ppszwName)
  357. {
  358. wcscpy(*ppszwName, V_BSTR(&vt));
  359. }
  360. else
  361. {
  362. hr = E_OUTOFMEMORY;
  363. }
  364. VariantClear(&vt);
  365. }
  366. return hr;
  367. }
  368. STDMETHODIMP
  369. CHNetPortMappingBinding::SetTargetComputerName(
  370. OLECHAR *pszwName
  371. )
  372. {
  373. BOOLEAN fNameChanged = TRUE;
  374. BOOLEAN fNameWasActive;
  375. HRESULT hr = S_OK;
  376. IWbemClassObject *pwcoBinding;
  377. VARIANT vt;
  378. if (NULL == pszwName)
  379. {
  380. hr = E_INVALIDARG;
  381. }
  382. else
  383. {
  384. //
  385. // Check to see if we actually need to do any work. This
  386. // will be the case if:
  387. // 1) Our name wasn't active to start with, or
  388. // 2) The new name is different than the old.
  389. //
  390. hr = GetCurrentMethod(&fNameWasActive);
  391. if (S_OK == hr)
  392. {
  393. if (fNameWasActive)
  394. {
  395. OLECHAR *pszwOldName;
  396. hr = GetTargetComputerName(&pszwOldName);
  397. if (S_OK == hr)
  398. {
  399. fNameChanged = 0 != _wcsicmp(pszwOldName, pszwName);
  400. CoTaskMemFree(pszwOldName);
  401. }
  402. }
  403. }
  404. }
  405. if (S_OK == hr && fNameChanged)
  406. {
  407. hr = GetBindingObject(&pwcoBinding);
  408. if (S_OK == hr)
  409. {
  410. //
  411. // Wrap the passed-in string in a BSTR and a variant
  412. //
  413. VariantInit(&vt);
  414. V_VT(&vt) = VT_BSTR;
  415. V_BSTR(&vt) = SysAllocString(pszwName);
  416. if (NULL == V_BSTR(&vt))
  417. {
  418. hr = E_OUTOFMEMORY;
  419. }
  420. if (S_OK == hr)
  421. {
  422. //
  423. // Set the property on the instance
  424. //
  425. hr = pwcoBinding->Put(
  426. c_wszTargetName,
  427. 0,
  428. &vt,
  429. NULL
  430. );
  431. VariantClear(&vt);
  432. }
  433. if (WBEM_S_NO_ERROR == hr)
  434. {
  435. //
  436. // Set that our name is now active
  437. //
  438. hr = SetBooleanValue(
  439. pwcoBinding,
  440. c_wszNameActive,
  441. TRUE
  442. );
  443. }
  444. if (WBEM_S_NO_ERROR == hr)
  445. {
  446. ULONG ulAddress;
  447. //
  448. // Generate an address to use as our target. We must always
  449. // regenerate the address when our name changes, as there
  450. // might be another entry with our new name that already has
  451. // a reserved address
  452. //
  453. hr = GenerateTargetAddress(pszwName, &ulAddress);
  454. if (SUCCEEDED(hr))
  455. {
  456. V_VT(&vt) = VT_I4;
  457. V_I4(&vt) = ulAddress;
  458. hr = pwcoBinding->Put(
  459. c_wszTargetIPAddress,
  460. 0,
  461. &vt,
  462. NULL
  463. );
  464. }
  465. }
  466. if (WBEM_S_NO_ERROR == hr)
  467. {
  468. //
  469. // Write the modified instance to the store
  470. //
  471. hr = m_piwsHomenet->PutInstance(
  472. pwcoBinding,
  473. WBEM_FLAG_UPDATE_ONLY,
  474. NULL,
  475. NULL
  476. );
  477. }
  478. pwcoBinding->Release();
  479. }
  480. if (WBEM_S_NO_ERROR == hr)
  481. {
  482. //
  483. // Notify service of update.
  484. //
  485. SendUpdateNotification();
  486. }
  487. }
  488. return hr;
  489. }
  490. STDMETHODIMP
  491. CHNetPortMappingBinding::GetTargetComputerAddress(
  492. ULONG *pulAddress
  493. )
  494. {
  495. HRESULT hr = S_OK;
  496. IWbemClassObject *pwcoBinding;
  497. VARIANT vt;
  498. if (NULL == pulAddress)
  499. {
  500. hr = E_POINTER;
  501. }
  502. else
  503. {
  504. hr = GetBindingObject(&pwcoBinding);
  505. }
  506. //
  507. // We don't check to see what the current method is, as if the
  508. // name is valid, we would have generated an address to use
  509. // as the target
  510. //
  511. if (S_OK == hr)
  512. {
  513. hr = pwcoBinding->Get(
  514. c_wszTargetIPAddress,
  515. 0,
  516. &vt,
  517. NULL,
  518. NULL
  519. );
  520. pwcoBinding->Release();
  521. }
  522. if (WBEM_S_NO_ERROR == hr)
  523. {
  524. _ASSERT(VT_I4 == V_VT(&vt));
  525. *pulAddress = static_cast<ULONG>(V_I4(&vt));
  526. VariantClear(&vt);
  527. }
  528. return hr;
  529. }
  530. STDMETHODIMP
  531. CHNetPortMappingBinding::SetTargetComputerAddress(
  532. ULONG ulAddress
  533. )
  534. {
  535. BOOLEAN fNameWasActive;
  536. HRESULT hr = S_OK;
  537. IWbemClassObject *pwcoBinding;
  538. ULONG ulOldAddress;
  539. VARIANT vt;
  540. if (0 == ulAddress)
  541. {
  542. hr = E_INVALIDARG;
  543. }
  544. else
  545. {
  546. hr = GetTargetComputerAddress(&ulOldAddress);
  547. if (S_OK == hr)
  548. {
  549. hr = GetCurrentMethod(&fNameWasActive);
  550. }
  551. }
  552. //
  553. // If the new address is the same as the old address, and
  554. // we were previously using the address as the target (as
  555. // opposed to the name) we can skip the rest of the work.
  556. //
  557. if (S_OK == hr
  558. && (ulAddress != ulOldAddress || fNameWasActive))
  559. {
  560. hr = GetBindingObject(&pwcoBinding);
  561. if (S_OK == hr)
  562. {
  563. VariantInit(&vt);
  564. V_VT(&vt) = VT_I4;
  565. V_I4(&vt) = ulAddress;
  566. hr = pwcoBinding->Put(
  567. c_wszTargetIPAddress,
  568. 0,
  569. &vt,
  570. NULL
  571. );
  572. if (WBEM_S_NO_ERROR == hr)
  573. {
  574. //
  575. // Set that our name is no longer active
  576. //
  577. hr = SetBooleanValue(
  578. pwcoBinding,
  579. c_wszNameActive,
  580. FALSE
  581. );
  582. }
  583. if (WBEM_S_NO_ERROR == hr)
  584. {
  585. //
  586. // Write the modified instance to the store
  587. //
  588. hr = m_piwsHomenet->PutInstance(
  589. pwcoBinding,
  590. WBEM_FLAG_UPDATE_ONLY,
  591. NULL,
  592. NULL
  593. );
  594. }
  595. pwcoBinding->Release();
  596. }
  597. if (WBEM_S_NO_ERROR == hr)
  598. {
  599. //
  600. // Notify service of update.
  601. //
  602. SendUpdateNotification();
  603. }
  604. }
  605. return hr;
  606. }
  607. STDMETHODIMP
  608. CHNetPortMappingBinding::GetTargetPort(
  609. USHORT *pusPort
  610. )
  611. {
  612. HRESULT hr;
  613. IWbemClassObject *pwcoBinding;
  614. VARIANT vt;
  615. if (NULL == pusPort)
  616. {
  617. hr = E_POINTER;
  618. }
  619. else
  620. {
  621. hr = GetBindingObject(&pwcoBinding);
  622. }
  623. if (S_OK == hr)
  624. {
  625. hr = pwcoBinding->Get(
  626. c_wszTargetPort,
  627. 0,
  628. &vt,
  629. NULL,
  630. NULL
  631. );
  632. pwcoBinding->Release();
  633. }
  634. if (WBEM_S_NO_ERROR == hr)
  635. {
  636. _ASSERT(VT_I4 == V_VT(&vt));
  637. *pusPort = static_cast<USHORT>(V_I4(&vt));
  638. VariantClear(&vt);
  639. }
  640. return hr;
  641. }
  642. STDMETHODIMP
  643. CHNetPortMappingBinding::SetTargetPort(
  644. USHORT usPort
  645. )
  646. {
  647. HRESULT hr = S_OK;
  648. IWbemClassObject *pwcoBinding;
  649. USHORT usOldPort;
  650. VARIANT vt;
  651. if (0 == usPort)
  652. {
  653. hr = E_INVALIDARG;
  654. }
  655. else
  656. {
  657. hr = GetTargetPort(&usOldPort);
  658. }
  659. if (S_OK == hr && usPort != usOldPort)
  660. {
  661. hr = GetBindingObject(&pwcoBinding);
  662. if (S_OK == hr)
  663. {
  664. VariantInit(&vt);
  665. V_VT(&vt) = VT_I4;
  666. V_I4(&vt) = usPort;
  667. hr = pwcoBinding->Put(
  668. c_wszTargetPort,
  669. 0,
  670. &vt,
  671. NULL
  672. );
  673. if (WBEM_S_NO_ERROR == hr)
  674. {
  675. //
  676. // Write the modified instance to the store
  677. //
  678. hr = m_piwsHomenet->PutInstance(
  679. pwcoBinding,
  680. WBEM_FLAG_UPDATE_ONLY,
  681. NULL,
  682. NULL
  683. );
  684. }
  685. pwcoBinding->Release();
  686. }
  687. if (WBEM_S_NO_ERROR == hr)
  688. {
  689. //
  690. // Notify service of update.
  691. //
  692. SendUpdateNotification();
  693. }
  694. }
  695. return hr;
  696. }
  697. //
  698. // Private methods
  699. //
  700. HRESULT
  701. CHNetPortMappingBinding::GenerateTargetAddress(
  702. LPCWSTR pszwTargetName,
  703. ULONG *pulAddress
  704. )
  705. {
  706. HRESULT hr;
  707. ULONG ulAddress = 0;
  708. BSTR bstrQuery;
  709. LPWSTR wszNameClause;
  710. LPWSTR wszWhereClause;
  711. IEnumWbemClassObject *pwcoEnum;
  712. IWbemClassObject *pwcoInstance;
  713. ULONG ulCount;
  714. VARIANT vt;
  715. _ASSERT(NULL != pszwTargetName);
  716. _ASSERT(NULL != pulAddress);
  717. *pulAddress = 0;
  718. //
  719. // Check to see if there any other bindings w/ the same
  720. // name that have a valid address
  721. //
  722. // SELECT * FROM HNet_ConnectionPortMapping where
  723. // TargetName = (our name) AND
  724. // NameActive != FALSE AND
  725. // TargetIPAddress != 0
  726. //
  727. hr = BuildQuotedEqualsString(
  728. &wszNameClause,
  729. c_wszTargetName,
  730. pszwTargetName
  731. );
  732. if (S_OK == hr)
  733. {
  734. hr = BuildAndString(
  735. &wszWhereClause,
  736. wszNameClause,
  737. L"NameActive != FALSE AND TargetIPAddress != 0"
  738. );
  739. delete [] wszNameClause;
  740. }
  741. if (S_OK == hr)
  742. {
  743. hr = BuildSelectQueryBstr(
  744. &bstrQuery,
  745. c_wszStar,
  746. c_wszHnetConnectionPortMapping,
  747. wszWhereClause
  748. );
  749. delete [] wszWhereClause;
  750. }
  751. if (S_OK == hr)
  752. {
  753. pwcoEnum = NULL;
  754. hr = m_piwsHomenet->ExecQuery(
  755. m_bstrWQL,
  756. bstrQuery,
  757. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
  758. NULL,
  759. &pwcoEnum
  760. );
  761. SysFreeString(bstrQuery);
  762. }
  763. if (WBEM_S_NO_ERROR == hr)
  764. {
  765. pwcoInstance = NULL;
  766. hr = pwcoEnum->Next(WBEM_INFINITE, 1, &pwcoInstance, &ulCount);
  767. if (SUCCEEDED(hr) && 1 == ulCount)
  768. {
  769. //
  770. // We got one. Return the address from this instance
  771. //
  772. hr = pwcoInstance->Get(
  773. c_wszTargetIPAddress,
  774. 0,
  775. &vt,
  776. NULL,
  777. NULL
  778. );
  779. if (WBEM_S_NO_ERROR == hr)
  780. {
  781. _ASSERT(VT_I4 == V_VT(&vt));
  782. ulAddress = static_cast<ULONG>(V_I4(&vt));
  783. }
  784. pwcoInstance->Release();
  785. }
  786. else
  787. {
  788. hr = S_OK;
  789. }
  790. pwcoEnum->Release();
  791. }
  792. if (SUCCEEDED(hr) && 0 == ulAddress)
  793. {
  794. DWORD dwScopeAddress;
  795. DWORD dwScopeMask;
  796. ULONG ulScopeLength;
  797. ULONG ulIndex;
  798. WCHAR wszBuffer[128];
  799. //
  800. // No other binding using the same name was found. Generate
  801. // a new target address now
  802. //
  803. ReadDhcpScopeSettings(&dwScopeAddress, &dwScopeMask);
  804. ulScopeLength = NTOHL(~dwScopeMask);
  805. for (ulIndex = 1; ulIndex < ulScopeLength - 1; ulIndex++)
  806. {
  807. ulAddress = (dwScopeAddress & dwScopeMask) | NTOHL(ulIndex);
  808. if (ulAddress == dwScopeAddress) { continue; }
  809. //
  810. // Check to see if this address is already in use
  811. //
  812. _snwprintf(
  813. wszBuffer,
  814. ARRAYSIZE(wszBuffer),
  815. L"SELECT * FROM HNet_ConnectionPortMapping2 WHERE TargetIPAddress = %u",
  816. ulAddress
  817. );
  818. bstrQuery = SysAllocString(wszBuffer);
  819. if (NULL != bstrQuery)
  820. {
  821. pwcoEnum = NULL;
  822. hr = m_piwsHomenet->ExecQuery(
  823. m_bstrWQL,
  824. bstrQuery,
  825. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
  826. NULL,
  827. &pwcoEnum
  828. );
  829. SysFreeString(bstrQuery);
  830. if (WBEM_S_NO_ERROR == hr)
  831. {
  832. pwcoInstance = NULL;
  833. hr = pwcoEnum->Next(WBEM_INFINITE, 1, &pwcoInstance, &ulCount);
  834. if (SUCCEEDED(hr))
  835. {
  836. if (0 == ulCount)
  837. {
  838. //
  839. // This address isn't in use.
  840. //
  841. pwcoEnum->Release();
  842. hr = S_OK;
  843. break;
  844. }
  845. else
  846. {
  847. //
  848. // Address already in use
  849. //
  850. pwcoInstance->Release();
  851. }
  852. pwcoEnum->Release();
  853. }
  854. }
  855. }
  856. else
  857. {
  858. hr = E_OUTOFMEMORY;
  859. }
  860. if (FAILED(hr))
  861. {
  862. break;
  863. }
  864. }
  865. }
  866. if (SUCCEEDED(hr) && 0 != ulAddress)
  867. {
  868. *pulAddress = ulAddress;
  869. }
  870. else
  871. {
  872. hr = E_FAIL;
  873. }
  874. return hr;
  875. }
  876. HRESULT
  877. CHNetPortMappingBinding::GetBindingObject(
  878. IWbemClassObject **ppwcoInstance
  879. )
  880. {
  881. _ASSERT(NULL != ppwcoInstance);
  882. return GetWmiObjectFromPath(
  883. m_piwsHomenet,
  884. m_bstrBinding,
  885. ppwcoInstance
  886. );
  887. }
  888. HRESULT
  889. CHNetPortMappingBinding::SendUpdateNotification()
  890. {
  891. HRESULT hr = S_OK;
  892. IHNetConnection *pConnection;
  893. GUID *pConnectionGuid = NULL;
  894. IHNetPortMappingProtocol *pProtocol;
  895. GUID *pProtocolGuid = NULL;
  896. ISharedAccessUpdate *pUpdate;
  897. if (IsServiceRunning(c_wszSharedAccess))
  898. {
  899. hr = GetConnection(&pConnection);
  900. if (SUCCEEDED(hr))
  901. {
  902. hr = pConnection->GetGuid(&pConnectionGuid);
  903. pConnection->Release();
  904. }
  905. if (SUCCEEDED(hr))
  906. {
  907. hr = GetProtocol(&pProtocol);
  908. }
  909. if (SUCCEEDED(hr))
  910. {
  911. hr = pProtocol->GetGuid(&pProtocolGuid);
  912. pProtocol->Release();
  913. }
  914. if (SUCCEEDED(hr))
  915. {
  916. hr = CoCreateInstance(
  917. CLSID_SAUpdate,
  918. NULL,
  919. CLSCTX_SERVER,
  920. IID_PPV_ARG(ISharedAccessUpdate, &pUpdate)
  921. );
  922. if (SUCCEEDED(hr))
  923. {
  924. hr = pUpdate->ConnectionPortMappingChanged(
  925. pConnectionGuid,
  926. pProtocolGuid,
  927. FALSE
  928. );
  929. pUpdate->Release();
  930. }
  931. }
  932. }
  933. if (NULL != pConnectionGuid)
  934. {
  935. CoTaskMemFree(pConnectionGuid);
  936. }
  937. if (NULL != pProtocolGuid)
  938. {
  939. CoTaskMemFree(pProtocolGuid);
  940. }
  941. return hr;
  942. }