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.

4544 lines
109 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997 - 2000
  5. //
  6. // File: H N E T C O N N . C P P
  7. //
  8. // Contents: CHNetConn implementation
  9. //
  10. // Notes:
  11. //
  12. // Author: jonburs 23 May 2000
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. //
  18. // Prototype for iphlpapi routine. For some reason, this isn't defined
  19. // in any header.
  20. //
  21. extern "C"
  22. DWORD
  23. APIENTRY
  24. SetAdapterIpAddress(LPSTR AdapterName,
  25. BOOL EnableDHCP,
  26. ULONG IPAddress,
  27. ULONG SubnetMask,
  28. ULONG DefaultGateway
  29. );
  30. //
  31. // CLSIDs for connection objects. We don't want to pull in all of the
  32. // other guids that are defined in nmclsid.h, so we copy these
  33. // into here
  34. //
  35. #define INITGUID
  36. #include <guiddef.h>
  37. DEFINE_GUID(CLSID_DialupConnection,
  38. 0xBA126AD7,0x2166,0x11D1,0xB1,0xD0,0x00,0x80,0x5F,0xC1,0x27,0x0E);
  39. DEFINE_GUID(CLSID_LanConnection,
  40. 0xBA126ADB,0x2166,0x11D1,0xB1,0xD0,0x00,0x80,0x5F,0xC1,0x27,0x0E);
  41. #undef INITGUID
  42. //
  43. // ATL Methods
  44. //
  45. HRESULT
  46. CHNetConn::FinalConstruct()
  47. {
  48. HRESULT hr = S_OK;
  49. m_bstrWQL = SysAllocString(c_wszWQL);
  50. if (NULL == m_bstrWQL)
  51. {
  52. hr = E_OUTOFMEMORY;
  53. }
  54. return hr;
  55. }
  56. HRESULT
  57. CHNetConn::FinalRelease()
  58. {
  59. if (m_piwsHomenet) m_piwsHomenet->Release();
  60. if (m_bstrConnection) SysFreeString(m_bstrConnection);
  61. if (m_bstrProperties) SysFreeString(m_bstrProperties);
  62. if (m_pNetConn) m_pNetConn->Release();
  63. if (m_bstrWQL) SysFreeString(m_bstrWQL);
  64. if (m_wszName) CoTaskMemFree(m_wszName);
  65. if (m_pGuid) CoTaskMemFree(m_pGuid);
  66. if (m_pNetConnUiUtil) m_pNetConnUiUtil->Release();
  67. if (m_pNetConnHNetUtil) m_pNetConnHNetUtil->Release();
  68. if (m_pNetConnRefresh) m_pNetConnRefresh->Release();
  69. return S_OK;
  70. }
  71. //
  72. // Ojbect initialization
  73. //
  74. HRESULT
  75. CHNetConn::Initialize(
  76. IWbemServices *piwsNamespace,
  77. IWbemClassObject *pwcoProperties
  78. )
  79. {
  80. HRESULT hr = S_OK;
  81. IWbemClassObject *pwcoConnection;
  82. VARIANT vt;
  83. _ASSERT(NULL == m_piwsHomenet);
  84. _ASSERT(NULL == m_bstrProperties);
  85. _ASSERT(NULL == m_bstrConnection);
  86. _ASSERT(NULL != piwsNamespace);
  87. _ASSERT(NULL != pwcoProperties);
  88. //
  89. // Store pointer to our namespace.
  90. //
  91. m_piwsHomenet = piwsNamespace;
  92. m_piwsHomenet->AddRef();
  93. //
  94. // Get the path to the properties
  95. //
  96. hr = GetWmiPathFromObject(pwcoProperties, &m_bstrProperties);
  97. if (WBEM_S_NO_ERROR == hr)
  98. {
  99. //
  100. // Get the path to the HNet_Connection from our properties
  101. //
  102. hr = pwcoProperties->Get(
  103. c_wszConnection,
  104. 0,
  105. &vt,
  106. NULL,
  107. NULL
  108. );
  109. }
  110. if (WBEM_S_NO_ERROR == hr)
  111. {
  112. _ASSERT(VT_BSTR == V_VT(&vt));
  113. m_bstrConnection = V_BSTR(&vt);
  114. //
  115. // BSTR ownership transfered to object
  116. //
  117. VariantInit(&vt);
  118. }
  119. if (WBEM_S_NO_ERROR == hr)
  120. {
  121. //
  122. // Get the underying connection object
  123. //
  124. hr = GetConnectionObject(&pwcoConnection);
  125. }
  126. if (WBEM_S_NO_ERROR == hr)
  127. {
  128. //
  129. // See if this is a lan connection
  130. //
  131. hr = GetBooleanValue(
  132. pwcoConnection,
  133. c_wszIsLanConnection,
  134. &m_fLanConnection
  135. );
  136. pwcoConnection->Release();
  137. }
  138. return hr;
  139. }
  140. HRESULT
  141. CHNetConn::InitializeFromConnection(
  142. IWbemServices *piwsNamespace,
  143. IWbemClassObject *pwcoConnection
  144. )
  145. {
  146. HRESULT hr = S_OK;
  147. BSTR bstr;
  148. IEnumWbemClassObject *pwcoEnum;
  149. IWbemClassObject *pwcoProperties;
  150. _ASSERT(NULL == m_piwsHomenet);
  151. _ASSERT(NULL == m_bstrConnection);
  152. _ASSERT(NULL == m_bstrProperties);
  153. _ASSERT(NULL != piwsNamespace);
  154. _ASSERT(NULL != pwcoConnection);
  155. //
  156. // Store pointer to our namespace.
  157. //
  158. m_piwsHomenet = piwsNamespace;
  159. m_piwsHomenet->AddRef();
  160. //
  161. // Get the path to our connection
  162. //
  163. hr = GetWmiPathFromObject(pwcoConnection, &m_bstrConnection);
  164. if (WBEM_S_NO_ERROR == hr)
  165. {
  166. //
  167. // Get the HNet_ConnectionProperties for our connection and
  168. // store its path
  169. //
  170. hr = GetPropInstanceFromConnInstance(
  171. piwsNamespace,
  172. pwcoConnection,
  173. &pwcoProperties
  174. );
  175. if (WBEM_S_NO_ERROR == hr)
  176. {
  177. hr = GetWmiPathFromObject(pwcoProperties, &m_bstrProperties);
  178. pwcoProperties->Release();
  179. }
  180. }
  181. if (WBEM_S_NO_ERROR == hr)
  182. {
  183. //
  184. // See if this is a lan connection
  185. //
  186. hr = GetBooleanValue(
  187. pwcoConnection,
  188. c_wszIsLanConnection,
  189. &m_fLanConnection
  190. );
  191. }
  192. return hr;
  193. }
  194. HRESULT
  195. CHNetConn::InitializeFromInstances(
  196. IWbemServices *piwsNamespace,
  197. IWbemClassObject *pwcoConnection,
  198. IWbemClassObject *pwcoProperties
  199. )
  200. {
  201. HRESULT hr;
  202. _ASSERT(NULL == m_piwsHomenet);
  203. _ASSERT(NULL == m_bstrConnection);
  204. _ASSERT(NULL == m_bstrProperties);
  205. _ASSERT(NULL != piwsNamespace);
  206. _ASSERT(NULL != pwcoConnection);
  207. _ASSERT(NULL != pwcoProperties);
  208. m_piwsHomenet = piwsNamespace;
  209. m_piwsHomenet->AddRef();
  210. hr = GetWmiPathFromObject(pwcoConnection, &m_bstrConnection);
  211. if (WBEM_S_NO_ERROR == hr)
  212. {
  213. hr = GetWmiPathFromObject(pwcoProperties, &m_bstrProperties);
  214. }
  215. if (WBEM_S_NO_ERROR == hr)
  216. {
  217. hr = GetBooleanValue(
  218. pwcoConnection,
  219. c_wszIsLanConnection,
  220. &m_fLanConnection
  221. );
  222. }
  223. return hr;
  224. }
  225. HRESULT
  226. CHNetConn::InitializeFull(
  227. IWbemServices *piwsNamespace,
  228. BSTR bstrConnection,
  229. BSTR bstrProperties,
  230. BOOLEAN fLanConnection
  231. )
  232. {
  233. HRESULT hr = S_OK;
  234. _ASSERT(NULL == m_piwsHomenet);
  235. _ASSERT(NULL == m_bstrConnection);
  236. _ASSERT(NULL == m_bstrProperties);
  237. _ASSERT(NULL != piwsNamespace);
  238. _ASSERT(NULL != bstrConnection);
  239. _ASSERT(NULL != bstrProperties);
  240. m_piwsHomenet = piwsNamespace;
  241. m_piwsHomenet->AddRef();
  242. m_fLanConnection = fLanConnection;
  243. m_bstrConnection = SysAllocString(bstrConnection);
  244. if (NULL != m_bstrConnection)
  245. {
  246. m_bstrProperties = SysAllocString(bstrProperties);
  247. if (NULL == m_bstrProperties)
  248. {
  249. hr = E_OUTOFMEMORY;
  250. }
  251. }
  252. else
  253. {
  254. hr = E_OUTOFMEMORY;
  255. }
  256. return hr;
  257. }
  258. HRESULT
  259. CHNetConn::SetINetConnection(
  260. INetConnection *pConn
  261. )
  262. {
  263. Lock();
  264. _ASSERT(NULL == m_pNetConn);
  265. _ASSERT(NULL != pConn);
  266. m_pNetConn = pConn;
  267. m_pNetConn->AddRef();
  268. Unlock();
  269. return S_OK;
  270. }
  271. //
  272. // IHNetConnection methods
  273. //
  274. STDMETHODIMP
  275. CHNetConn::GetINetConnection(
  276. INetConnection **ppNetConnection
  277. )
  278. {
  279. HRESULT hr = S_OK;
  280. GUID *pGuid;
  281. if (NULL != ppNetConnection)
  282. {
  283. *ppNetConnection = NULL;
  284. }
  285. else
  286. {
  287. hr = E_POINTER;
  288. }
  289. if (S_OK == hr)
  290. {
  291. Lock();
  292. if (NULL != m_pNetConn)
  293. {
  294. //
  295. // We've already cached away a pointer.
  296. //
  297. *ppNetConnection = m_pNetConn;
  298. (*ppNetConnection)->AddRef();
  299. }
  300. else
  301. {
  302. //
  303. // We don't have a cached pointer. Create the correct
  304. // connection object type and initialize appropriately.
  305. //
  306. hr = GetGuidInternal(&pGuid);
  307. if (S_OK == hr)
  308. {
  309. if (m_fLanConnection)
  310. {
  311. INetLanConnection *pLanConnection;
  312. hr = CoCreateInstance(
  313. CLSID_LanConnection,
  314. NULL,
  315. CLSCTX_SERVER,
  316. IID_PPV_ARG(INetLanConnection, &pLanConnection)
  317. );
  318. if (SUCCEEDED(hr))
  319. {
  320. LANCON_INFO lanInfo;
  321. //
  322. // We must set the proxy blanket on the object we just
  323. // created.
  324. //
  325. SetProxyBlanket(pLanConnection);
  326. //
  327. // We don't need to include the name to initialize
  328. // a LAN connection -- the guid is sufficient.
  329. //
  330. lanInfo.szwConnName = NULL;
  331. lanInfo.fShowIcon = TRUE;
  332. lanInfo.guid = *pGuid;
  333. hr = pLanConnection->SetInfo(
  334. LCIF_COMP,
  335. &lanInfo
  336. );
  337. if (SUCCEEDED(hr))
  338. {
  339. hr = pLanConnection->QueryInterface(
  340. IID_PPV_ARG(
  341. INetConnection,
  342. ppNetConnection
  343. )
  344. );
  345. if (SUCCEEDED(hr))
  346. {
  347. SetProxyBlanket(*ppNetConnection);
  348. }
  349. }
  350. pLanConnection->Release();
  351. }
  352. }
  353. else
  354. {
  355. INetRasConnection *pRasConnection;
  356. hr = CoCreateInstance(
  357. CLSID_DialupConnection,
  358. NULL,
  359. CLSCTX_SERVER,
  360. IID_PPV_ARG(INetRasConnection, &pRasConnection)
  361. );
  362. if (SUCCEEDED(hr))
  363. {
  364. OLECHAR *pszwName;
  365. OLECHAR *pszwPath;
  366. //
  367. // We must set the proxy blanket on the object we just
  368. // created.
  369. //
  370. SetProxyBlanket(pRasConnection);
  371. //
  372. // We need to obtain the name and path of a RAS
  373. // connection in order to initialize it.
  374. //
  375. hr = GetRasConnectionName(&pszwName);
  376. if (S_OK == hr)
  377. {
  378. hr = GetRasPhonebookPath(&pszwPath);
  379. if (S_OK == hr)
  380. {
  381. RASCON_INFO rasInfo;
  382. rasInfo.pszwPbkFile = pszwPath;
  383. rasInfo.pszwEntryName = pszwName;
  384. rasInfo.guidId = *pGuid;
  385. hr = pRasConnection->SetRasConnectionInfo(
  386. &rasInfo
  387. );
  388. if (SUCCEEDED(hr))
  389. {
  390. hr = pRasConnection->QueryInterface(
  391. IID_PPV_ARG(
  392. INetConnection,
  393. ppNetConnection
  394. )
  395. );
  396. if (SUCCEEDED(hr))
  397. {
  398. SetProxyBlanket(*ppNetConnection);
  399. }
  400. }
  401. CoTaskMemFree(pszwPath);
  402. }
  403. CoTaskMemFree(pszwName);
  404. }
  405. pRasConnection->Release();
  406. }
  407. }
  408. if (SUCCEEDED(hr))
  409. {
  410. //
  411. // Cache the connection
  412. //
  413. m_pNetConn = *ppNetConnection;
  414. m_pNetConn->AddRef();
  415. hr = S_OK;
  416. }
  417. }
  418. }
  419. Unlock();
  420. }
  421. return hr;
  422. }
  423. STDMETHODIMP
  424. CHNetConn::GetGuid(
  425. GUID **ppGuid
  426. )
  427. {
  428. HRESULT hr = S_OK;
  429. if (NULL == ppGuid)
  430. {
  431. hr = E_POINTER;
  432. }
  433. if (S_OK == hr)
  434. {
  435. //
  436. // Allocate memory for the guid
  437. //
  438. *ppGuid = reinterpret_cast<GUID*>(
  439. CoTaskMemAlloc(sizeof(GUID))
  440. );
  441. if (NULL == *ppGuid)
  442. {
  443. hr = E_OUTOFMEMORY;
  444. }
  445. }
  446. if (S_OK == hr)
  447. {
  448. GUID *pGuid;
  449. //
  450. // Get our guid
  451. //
  452. hr = GetGuidInternal(&pGuid);
  453. if (SUCCEEDED(hr))
  454. {
  455. CopyMemory(
  456. reinterpret_cast<PVOID>(*ppGuid),
  457. reinterpret_cast<PVOID>(pGuid),
  458. sizeof(GUID)
  459. );
  460. }
  461. else
  462. {
  463. CoTaskMemFree(*ppGuid);
  464. *ppGuid = NULL;
  465. }
  466. }
  467. return hr;
  468. }
  469. STDMETHODIMP
  470. CHNetConn::GetName(
  471. OLECHAR **ppszwName
  472. )
  473. {
  474. HRESULT hr = S_OK;
  475. INetConnection *pConn;
  476. NETCON_PROPERTIES *pProps;
  477. OLECHAR *pszwOldName = NULL;
  478. if (NULL != ppszwName)
  479. {
  480. *ppszwName = NULL;
  481. }
  482. else
  483. {
  484. hr = E_POINTER;
  485. }
  486. if (S_OK == hr)
  487. {
  488. Lock();
  489. hr = GetINetConnection(&pConn);
  490. if (S_OK == hr)
  491. {
  492. hr = pConn->GetProperties(&pProps);
  493. if (SUCCEEDED(hr))
  494. {
  495. pszwOldName = m_wszName;
  496. m_wszName = pProps->pszwName;
  497. //
  498. // We can't call NcFreeNetconProperties, as that
  499. // would free the string pointer we just tucked away.
  500. //
  501. CoTaskMemFree(pProps->pszwDeviceName);
  502. CoTaskMemFree(pProps);
  503. hr = S_OK;
  504. }
  505. pConn->Release();
  506. }
  507. //
  508. // If the new name is not the same as the old name
  509. // store the new name
  510. //
  511. if (S_OK == hr
  512. && (NULL == pszwOldName
  513. || 0 != wcscmp(pszwOldName, m_wszName)))
  514. {
  515. IWbemClassObject *pwcoConnection;
  516. HRESULT hr2;
  517. VARIANT vt;
  518. hr2 = GetConnectionObject(&pwcoConnection);
  519. if (WBEM_S_NO_ERROR == hr2)
  520. {
  521. //
  522. // Write the retrieved name to the store. (While the stored
  523. // name is used only for debugging purposes, it's worth the
  524. // hit to keep it up to date.)
  525. //
  526. V_VT(&vt) = VT_BSTR;
  527. V_BSTR(&vt) = SysAllocString(m_wszName);
  528. if (NULL != V_BSTR(&vt))
  529. {
  530. hr2 = pwcoConnection->Put(
  531. c_wszName,
  532. 0,
  533. &vt,
  534. NULL
  535. );
  536. VariantClear(&vt);
  537. if (WBEM_S_NO_ERROR == hr2)
  538. {
  539. m_piwsHomenet->PutInstance(
  540. pwcoConnection,
  541. WBEM_FLAG_UPDATE_ONLY,
  542. NULL,
  543. NULL
  544. );
  545. }
  546. }
  547. pwcoConnection->Release();
  548. }
  549. }
  550. if (S_OK == hr)
  551. {
  552. ULONG ulSize = (wcslen(m_wszName) + 1) * sizeof(OLECHAR);
  553. *ppszwName = reinterpret_cast<OLECHAR*>(
  554. CoTaskMemAlloc(ulSize)
  555. );
  556. if (NULL != *ppszwName)
  557. {
  558. CopyMemory(
  559. reinterpret_cast<PVOID>(*ppszwName),
  560. reinterpret_cast<PVOID>(m_wszName),
  561. ulSize
  562. );
  563. }
  564. else
  565. {
  566. hr = E_OUTOFMEMORY;
  567. }
  568. }
  569. Unlock();
  570. }
  571. if (NULL != pszwOldName)
  572. {
  573. CoTaskMemFree(pszwOldName);
  574. }
  575. return hr;
  576. }
  577. STDMETHODIMP
  578. CHNetConn::GetRasPhonebookPath(
  579. OLECHAR **ppszwPath
  580. )
  581. {
  582. HRESULT hr = S_OK;
  583. VARIANT vt;
  584. IWbemClassObject *pwcoConnection;
  585. if (NULL != ppszwPath)
  586. {
  587. *ppszwPath = NULL;
  588. }
  589. else
  590. {
  591. hr = E_POINTER;
  592. }
  593. if (TRUE == m_fLanConnection)
  594. {
  595. hr = E_UNEXPECTED;
  596. }
  597. if (S_OK == hr)
  598. {
  599. hr = GetConnectionObject(&pwcoConnection);
  600. }
  601. if (WBEM_S_NO_ERROR == hr)
  602. {
  603. hr = pwcoConnection->Get(
  604. c_wszPhonebookPath,
  605. 0,
  606. &vt,
  607. NULL,
  608. NULL
  609. );
  610. pwcoConnection->Release();
  611. }
  612. if (WBEM_S_NO_ERROR == hr)
  613. {
  614. _ASSERT(VT_BSTR == V_VT(&vt));
  615. *ppszwPath = reinterpret_cast<OLECHAR*>(
  616. CoTaskMemAlloc((SysStringLen(V_BSTR(&vt)) + 1)
  617. * sizeof(OLECHAR))
  618. );
  619. if (NULL != *ppszwPath)
  620. {
  621. wcscpy(*ppszwPath, V_BSTR(&vt));
  622. }
  623. else
  624. {
  625. hr = E_OUTOFMEMORY;
  626. }
  627. VariantClear(&vt);
  628. }
  629. return hr;
  630. }
  631. STDMETHODIMP
  632. CHNetConn::GetProperties(
  633. HNET_CONN_PROPERTIES **ppProperties
  634. )
  635. {
  636. HRESULT hr = S_OK;
  637. IWbemClassObject *pwcoProperties;
  638. if (NULL == ppProperties)
  639. {
  640. hr = E_POINTER;
  641. }
  642. else
  643. {
  644. *ppProperties = reinterpret_cast<HNET_CONN_PROPERTIES*>(
  645. CoTaskMemAlloc(sizeof(HNET_CONN_PROPERTIES))
  646. );
  647. if (NULL == *ppProperties)
  648. {
  649. hr = E_OUTOFMEMORY;
  650. }
  651. }
  652. if (S_OK == hr)
  653. {
  654. hr = GetConnectionPropertiesObject(&pwcoProperties);
  655. if (WBEM_S_NO_ERROR == hr)
  656. {
  657. hr = InternalGetProperties(pwcoProperties, *ppProperties);
  658. pwcoProperties->Release();
  659. }
  660. if (FAILED(hr))
  661. {
  662. CoTaskMemFree(*ppProperties);
  663. *ppProperties = NULL;
  664. }
  665. }
  666. return hr;
  667. }
  668. STDMETHODIMP
  669. CHNetConn::GetControlInterface(
  670. REFIID iid,
  671. void **ppv
  672. )
  673. {
  674. HRESULT hr = S_OK;
  675. HNET_CONN_PROPERTIES Props;
  676. if (NULL != ppv)
  677. {
  678. *ppv = NULL;
  679. }
  680. else
  681. {
  682. hr = E_POINTER;
  683. }
  684. if (S_OK == hr)
  685. {
  686. //
  687. // See if a simple QI will produce the desired interface
  688. //
  689. hr = QueryInterface(iid, ppv);
  690. if (FAILED(hr))
  691. {
  692. //
  693. // Nope. Get our properties and see if it's appropriate to
  694. // provide the requested control interface.
  695. //
  696. IWbemClassObject *pwcoProperties;
  697. hr = GetConnectionPropertiesObject(&pwcoProperties);
  698. if (WBEM_S_NO_ERROR == hr)
  699. {
  700. hr = InternalGetProperties(pwcoProperties, &Props);
  701. pwcoProperties->Release();
  702. }
  703. if (S_OK == hr)
  704. {
  705. if (IsEqualGUID(
  706. __uuidof(IHNetFirewalledConnection),
  707. iid
  708. ))
  709. {
  710. if (TRUE == Props.fFirewalled)
  711. {
  712. CComObject<CHNFWConn> *pfwConn;
  713. hr = CComObject<CHNFWConn>::CreateInstance(&pfwConn);
  714. if (SUCCEEDED(hr))
  715. {
  716. pfwConn->AddRef();
  717. hr = pfwConn->InitializeFull(
  718. m_piwsHomenet,
  719. m_bstrConnection,
  720. m_bstrProperties,
  721. m_fLanConnection
  722. );
  723. if (SUCCEEDED(hr))
  724. {
  725. hr = pfwConn->QueryInterface(iid, ppv);
  726. }
  727. pfwConn->Release();
  728. }
  729. }
  730. else
  731. {
  732. hr = E_NOINTERFACE;
  733. }
  734. }
  735. else if (IsEqualGUID(
  736. __uuidof(IHNetIcsPublicConnection),
  737. iid
  738. ))
  739. {
  740. if (TRUE == Props.fIcsPublic)
  741. {
  742. CComObject<CHNIcsPublicConn> *pIcsPubConn;
  743. hr = CComObject<CHNIcsPublicConn>::CreateInstance(&pIcsPubConn);
  744. if (SUCCEEDED(hr))
  745. {
  746. pIcsPubConn->AddRef();
  747. hr = pIcsPubConn->InitializeFull(
  748. m_piwsHomenet,
  749. m_bstrConnection,
  750. m_bstrProperties,
  751. m_fLanConnection
  752. );
  753. if (SUCCEEDED(hr))
  754. {
  755. hr = pIcsPubConn->QueryInterface(iid, ppv);
  756. }
  757. pIcsPubConn->Release();
  758. }
  759. }
  760. else
  761. {
  762. hr = E_NOINTERFACE;
  763. }
  764. }
  765. else if (IsEqualGUID(
  766. __uuidof(IHNetIcsPrivateConnection),
  767. iid
  768. ))
  769. {
  770. if (TRUE == Props.fIcsPrivate)
  771. {
  772. CComObject<CHNIcsPrivateConn> *pIcsPrvConn;
  773. hr = CComObject<CHNIcsPrivateConn>::CreateInstance(&pIcsPrvConn);
  774. if (SUCCEEDED(hr))
  775. {
  776. pIcsPrvConn->AddRef();
  777. hr = pIcsPrvConn->InitializeFull(
  778. m_piwsHomenet,
  779. m_bstrConnection,
  780. m_bstrProperties,
  781. m_fLanConnection
  782. );
  783. if (SUCCEEDED(hr))
  784. {
  785. hr = pIcsPrvConn->QueryInterface(iid, ppv);
  786. }
  787. pIcsPrvConn->Release();
  788. }
  789. }
  790. else
  791. {
  792. hr = E_NOINTERFACE;
  793. }
  794. }
  795. else if (IsEqualGUID(
  796. __uuidof(IHNetBridge),
  797. iid
  798. ))
  799. {
  800. if (TRUE == Props.fBridge)
  801. {
  802. CComObject<CHNBridge> *pBridge;
  803. hr = CComObject<CHNBridge>::CreateInstance(&pBridge);
  804. if (SUCCEEDED(hr))
  805. {
  806. pBridge->AddRef();
  807. hr = pBridge->InitializeFull(
  808. m_piwsHomenet,
  809. m_bstrConnection,
  810. m_bstrProperties,
  811. m_fLanConnection
  812. );
  813. if (SUCCEEDED(hr))
  814. {
  815. hr = pBridge->QueryInterface(iid, ppv);
  816. }
  817. pBridge->Release();
  818. }
  819. }
  820. else
  821. {
  822. hr = E_NOINTERFACE;
  823. }
  824. }
  825. else if (IsEqualGUID(
  826. __uuidof(IHNetBridgedConnection),
  827. iid
  828. ))
  829. {
  830. if (TRUE == Props.fPartOfBridge)
  831. {
  832. CComObject<CHNBridgedConn> *pBridgeConn;
  833. hr = CComObject<CHNBridgedConn>::CreateInstance(&pBridgeConn);
  834. if (SUCCEEDED(hr))
  835. {
  836. pBridgeConn->AddRef();
  837. hr = pBridgeConn->InitializeFull(
  838. m_piwsHomenet,
  839. m_bstrConnection,
  840. m_bstrProperties,
  841. m_fLanConnection
  842. );
  843. if (SUCCEEDED(hr))
  844. {
  845. hr = pBridgeConn->QueryInterface(iid, ppv);
  846. }
  847. pBridgeConn->Release();
  848. }
  849. }
  850. else
  851. {
  852. hr = E_NOINTERFACE;
  853. }
  854. }
  855. else
  856. {
  857. //
  858. // Unknown control interface
  859. //
  860. hr = E_NOINTERFACE;
  861. }
  862. }
  863. }
  864. }
  865. return hr;
  866. }
  867. STDMETHODIMP
  868. CHNetConn::Firewall(
  869. IHNetFirewalledConnection **ppFirewalledConn
  870. )
  871. {
  872. HRESULT hr = S_OK;
  873. HNET_CONN_PROPERTIES hnProps;
  874. IWbemClassObject *pwcoProperties;
  875. if (NULL == ppFirewalledConn)
  876. {
  877. hr = E_POINTER;
  878. }
  879. else
  880. {
  881. *ppFirewalledConn = NULL;
  882. //
  883. // We fail immediately if firewalling is prohibited by policy,
  884. // or if the NAT routing protocol is installed.
  885. //
  886. if (ProhibitedByPolicy(NCPERM_PersonalFirewallConfig))
  887. {
  888. hr = HN_E_POLICY;
  889. }
  890. if (IsRoutingProtocolInstalled(MS_IP_NAT))
  891. {
  892. hr = HRESULT_FROM_WIN32(ERROR_SHARING_RRAS_CONFLICT);
  893. }
  894. }
  895. if (S_OK == hr)
  896. {
  897. hr = GetConnectionPropertiesObject(&pwcoProperties);
  898. }
  899. if (S_OK == hr)
  900. {
  901. hr = InternalGetProperties(pwcoProperties, &hnProps);
  902. if (S_OK == hr)
  903. {
  904. if (FALSE == hnProps.fCanBeFirewalled || TRUE == hnProps.fFirewalled)
  905. {
  906. hr = E_UNEXPECTED;
  907. }
  908. else
  909. {
  910. //
  911. // Set the firewalled property to true
  912. //
  913. hr = SetBooleanValue(
  914. pwcoProperties,
  915. c_wszIsFirewalled,
  916. TRUE
  917. );
  918. }
  919. }
  920. if (WBEM_S_NO_ERROR == hr)
  921. {
  922. //
  923. // Write the modified instance to the store
  924. //
  925. hr = m_piwsHomenet->PutInstance(
  926. pwcoProperties,
  927. WBEM_FLAG_UPDATE_ONLY,
  928. NULL,
  929. NULL
  930. );
  931. }
  932. if (WBEM_S_NO_ERROR == hr)
  933. {
  934. //
  935. // Inform netman that something changed. Error doesn't matter.
  936. //
  937. UpdateNetman();
  938. }
  939. if (WBEM_S_NO_ERROR == hr)
  940. {
  941. //
  942. // Create the new object
  943. //
  944. CComObject<CHNFWConn> *pfwConn;
  945. hr = CComObject<CHNFWConn>::CreateInstance(&pfwConn);
  946. if (SUCCEEDED(hr))
  947. {
  948. pfwConn->AddRef();
  949. hr = pfwConn->InitializeFull(
  950. m_piwsHomenet,
  951. m_bstrConnection,
  952. m_bstrProperties,
  953. m_fLanConnection
  954. );
  955. if (SUCCEEDED(hr))
  956. {
  957. hr = pfwConn->QueryInterface(
  958. IID_PPV_ARG(IHNetFirewalledConnection, ppFirewalledConn)
  959. );
  960. }
  961. pfwConn->Release();
  962. }
  963. }
  964. pwcoProperties->Release();
  965. }
  966. if (S_OK == hr)
  967. {
  968. //
  969. // Make sure the service is started
  970. //
  971. DWORD dwError = StartOrUpdateService();
  972. if (NO_ERROR != dwError)
  973. {
  974. (*ppFirewalledConn)->Unfirewall();
  975. (*ppFirewalledConn)->Release();
  976. *ppFirewalledConn = NULL;
  977. hr = HRESULT_FROM_WIN32(dwError);
  978. }
  979. RefreshNetConnectionsUI();
  980. }
  981. return hr;
  982. }
  983. STDMETHODIMP
  984. CHNetConn::SharePublic(
  985. IHNetIcsPublicConnection **ppIcsPublicConn
  986. )
  987. {
  988. HRESULT hr = S_OK;
  989. HNET_CONN_PROPERTIES hnProps;
  990. IWbemClassObject *pwcoProperties;
  991. if (NULL == ppIcsPublicConn)
  992. {
  993. hr = E_POINTER;
  994. }
  995. else
  996. {
  997. *ppIcsPublicConn = NULL;
  998. //
  999. // We fail immediately if sharing is prohibited by policy,
  1000. // or if the NAT routing protocol is installed.
  1001. //
  1002. if (ProhibitedByPolicy(NCPERM_ShowSharedAccessUi))
  1003. {
  1004. hr = HN_E_POLICY;
  1005. }
  1006. if (IsRoutingProtocolInstalled(MS_IP_NAT))
  1007. {
  1008. hr = HRESULT_FROM_WIN32(ERROR_SHARING_RRAS_CONFLICT);
  1009. }
  1010. }
  1011. if (S_OK == hr)
  1012. {
  1013. hr = GetConnectionPropertiesObject(&pwcoProperties);
  1014. }
  1015. if (WBEM_S_NO_ERROR == hr)
  1016. {
  1017. hr = InternalGetProperties(pwcoProperties, &hnProps);
  1018. if (S_OK == hr)
  1019. {
  1020. if (FALSE == hnProps.fCanBeIcsPublic || TRUE == hnProps.fIcsPublic)
  1021. {
  1022. hr = E_UNEXPECTED;
  1023. }
  1024. else
  1025. {
  1026. //
  1027. // Set the ICS Public property to true
  1028. //
  1029. hr = SetBooleanValue(
  1030. pwcoProperties,
  1031. c_wszIsIcsPublic,
  1032. TRUE
  1033. );
  1034. }
  1035. }
  1036. if (WBEM_S_NO_ERROR == hr)
  1037. {
  1038. //
  1039. // Write the modified instance to the store
  1040. //
  1041. hr = m_piwsHomenet->PutInstance(
  1042. pwcoProperties,
  1043. WBEM_FLAG_UPDATE_ONLY,
  1044. NULL,
  1045. NULL
  1046. );
  1047. }
  1048. if (WBEM_S_NO_ERROR == hr)
  1049. {
  1050. //
  1051. // Inform netman that something changed. Error doesn't matter.
  1052. //
  1053. UpdateNetman();
  1054. }
  1055. pwcoProperties->Release();
  1056. }
  1057. if (WBEM_S_NO_ERROR == hr)
  1058. {
  1059. //
  1060. // Create the new object
  1061. //
  1062. CComObject<CHNIcsPublicConn> *pIcsConn;
  1063. hr = CComObject<CHNIcsPublicConn>::CreateInstance(&pIcsConn);
  1064. if (SUCCEEDED(hr))
  1065. {
  1066. pIcsConn->AddRef();
  1067. hr = pIcsConn->InitializeFull(
  1068. m_piwsHomenet,
  1069. m_bstrConnection,
  1070. m_bstrProperties,
  1071. m_fLanConnection
  1072. );
  1073. if (SUCCEEDED(hr))
  1074. {
  1075. hr = pIcsConn->QueryInterface(
  1076. IID_PPV_ARG(IHNetIcsPublicConnection, ppIcsPublicConn)
  1077. );
  1078. }
  1079. pIcsConn->Release();
  1080. }
  1081. }
  1082. if (S_OK == hr)
  1083. {
  1084. //
  1085. // Make sure the service is started
  1086. //
  1087. DWORD dwError = StartOrUpdateService();
  1088. if (NO_ERROR != dwError)
  1089. {
  1090. (*ppIcsPublicConn)->Unshare();
  1091. (*ppIcsPublicConn)->Release();
  1092. *ppIcsPublicConn = NULL;
  1093. hr = HRESULT_FROM_WIN32(dwError);
  1094. }
  1095. RefreshNetConnectionsUI();
  1096. }
  1097. if (S_OK == hr && m_fLanConnection)
  1098. {
  1099. DWORD dwMode;
  1100. DWORD dwLength = sizeof(dwMode);
  1101. BOOL fResult;
  1102. //
  1103. // If this is a LAN connection, make sure that WinInet is
  1104. // not set to dial always (#143885)
  1105. //
  1106. fResult =
  1107. InternetQueryOption(
  1108. NULL,
  1109. INTERNET_OPTION_AUTODIAL_MODE,
  1110. &dwMode,
  1111. &dwLength
  1112. );
  1113. _ASSERT(TRUE == fResult);
  1114. if (fResult && AUTODIAL_MODE_ALWAYS == dwMode)
  1115. {
  1116. //
  1117. // Set the mode to contingent dialing.
  1118. //
  1119. dwMode = AUTODIAL_MODE_NO_NETWORK_PRESENT;
  1120. fResult =
  1121. InternetSetOption(
  1122. NULL,
  1123. INTERNET_OPTION_AUTODIAL_MODE,
  1124. &dwMode,
  1125. sizeof(dwMode)
  1126. );
  1127. _ASSERT(TRUE == fResult);
  1128. }
  1129. }
  1130. else if (S_OK == hr)
  1131. {
  1132. RASAUTODIALENTRYW adEntry;
  1133. OLECHAR *pszwName;
  1134. HRESULT hr2;
  1135. //
  1136. // Set this to be the RAS default connection. Errors
  1137. // are not propagated to caller.
  1138. //
  1139. hr2 = GetName(&pszwName);
  1140. if (S_OK == hr2)
  1141. {
  1142. ZeroMemory(&adEntry, sizeof(adEntry));
  1143. adEntry.dwSize = sizeof(adEntry);
  1144. wcsncpy(
  1145. adEntry.szEntry,
  1146. pszwName,
  1147. sizeof(adEntry.szEntry)/sizeof(WCHAR)
  1148. );
  1149. RasSetAutodialAddress(
  1150. NULL,
  1151. 0,
  1152. &adEntry,
  1153. sizeof(adEntry),
  1154. 1
  1155. );
  1156. CoTaskMemFree(pszwName);
  1157. }
  1158. }
  1159. return hr;
  1160. }
  1161. STDMETHODIMP
  1162. CHNetConn::SharePrivate(
  1163. IHNetIcsPrivateConnection **ppIcsPrivateConn
  1164. )
  1165. {
  1166. HRESULT hr = S_OK;
  1167. HNET_CONN_PROPERTIES hnProps;
  1168. IWbemClassObject *pwcoProperties;
  1169. if (NULL == ppIcsPrivateConn)
  1170. {
  1171. hr = E_POINTER;
  1172. }
  1173. else
  1174. {
  1175. *ppIcsPrivateConn = NULL;
  1176. //
  1177. // We fail immediately if sharing is prohibited by policy,
  1178. // or if the NAT routing protocol is installed.
  1179. //
  1180. if (ProhibitedByPolicy(NCPERM_ShowSharedAccessUi))
  1181. {
  1182. hr = HN_E_POLICY;
  1183. }
  1184. if (IsRoutingProtocolInstalled(MS_IP_NAT))
  1185. {
  1186. hr = HRESULT_FROM_WIN32(ERROR_SHARING_RRAS_CONFLICT);
  1187. }
  1188. }
  1189. if (S_OK == hr)
  1190. {
  1191. hr = GetConnectionPropertiesObject(&pwcoProperties);
  1192. }
  1193. if (WBEM_S_NO_ERROR == hr)
  1194. {
  1195. hr = InternalGetProperties(pwcoProperties, &hnProps);
  1196. if (S_OK == hr)
  1197. {
  1198. if (FALSE == hnProps.fCanBeIcsPrivate || TRUE == hnProps.fIcsPrivate)
  1199. {
  1200. hr = E_UNEXPECTED;
  1201. }
  1202. }
  1203. if (WBEM_S_NO_ERROR == hr)
  1204. {
  1205. //
  1206. // Backup current address information
  1207. //
  1208. hr = BackupIpConfiguration();
  1209. }
  1210. if (WBEM_S_NO_ERROR == hr)
  1211. {
  1212. //
  1213. // if we are in ICS Upgrade, we don't need
  1214. // to setup the private address because dhcp client won't be running in GUI Mode Setup
  1215. // and the private tcpip addresses should be upgraded as is.
  1216. //
  1217. HANDLE hIcsUpgradeEvent = OpenEvent( EVENT_MODIFY_STATE, FALSE, c_wszIcsUpgradeEventName );
  1218. if ( NULL != hIcsUpgradeEvent )
  1219. {
  1220. CloseHandle( hIcsUpgradeEvent );
  1221. }
  1222. else
  1223. {
  1224. //
  1225. // Setup addressing for private usage
  1226. //
  1227. hr = SetupConnectionAsPrivateLan();
  1228. }
  1229. }
  1230. if (S_OK == hr)
  1231. {
  1232. //
  1233. // Set the ICS Public property to true
  1234. //
  1235. hr = SetBooleanValue(
  1236. pwcoProperties,
  1237. c_wszIsIcsPrivate,
  1238. TRUE
  1239. );
  1240. }
  1241. if (WBEM_S_NO_ERROR == hr)
  1242. {
  1243. //
  1244. // Write the modified instance to the store
  1245. //
  1246. hr = m_piwsHomenet->PutInstance(
  1247. pwcoProperties,
  1248. WBEM_FLAG_UPDATE_ONLY,
  1249. NULL,
  1250. NULL
  1251. );
  1252. }
  1253. if (WBEM_S_NO_ERROR == hr)
  1254. {
  1255. //
  1256. // Inform netman that something changed. Error doesn't matter.
  1257. //
  1258. UpdateNetman();
  1259. }
  1260. pwcoProperties->Release();
  1261. }
  1262. if (WBEM_S_NO_ERROR == hr)
  1263. {
  1264. //
  1265. // Create the new object
  1266. //
  1267. CComObject<CHNIcsPrivateConn> *pIcsConn;
  1268. hr = CComObject<CHNIcsPrivateConn>::CreateInstance(&pIcsConn);
  1269. if (SUCCEEDED(hr))
  1270. {
  1271. pIcsConn->AddRef();
  1272. hr = pIcsConn->InitializeFull(
  1273. m_piwsHomenet,
  1274. m_bstrConnection,
  1275. m_bstrProperties,
  1276. m_fLanConnection
  1277. );
  1278. if (SUCCEEDED(hr))
  1279. {
  1280. hr = pIcsConn->QueryInterface(
  1281. IID_PPV_ARG(IHNetIcsPrivateConnection, ppIcsPrivateConn)
  1282. );
  1283. }
  1284. pIcsConn->Release();
  1285. }
  1286. }
  1287. else
  1288. {
  1289. //
  1290. // Restore backup address information
  1291. //
  1292. RestoreIpConfiguration();
  1293. }
  1294. if (S_OK == hr)
  1295. {
  1296. //
  1297. // Make sure the service is started
  1298. //
  1299. DWORD dwError = StartOrUpdateService();
  1300. if (NO_ERROR != dwError)
  1301. {
  1302. (*ppIcsPrivateConn)->RemoveFromIcs();
  1303. (*ppIcsPrivateConn)->Release();
  1304. *ppIcsPrivateConn = NULL;
  1305. hr = HRESULT_FROM_WIN32(dwError);
  1306. }
  1307. RefreshNetConnectionsUI();
  1308. }
  1309. return hr;
  1310. }
  1311. STDMETHODIMP
  1312. CHNetConn::EnumPortMappings(
  1313. BOOLEAN fEnabledOnly,
  1314. IEnumHNetPortMappingBindings **ppEnum
  1315. )
  1316. {
  1317. HRESULT hr = S_OK;
  1318. BSTR bstrQuery;
  1319. LPWSTR wszWhere;
  1320. IEnumWbemClassObject *pwcoEnum;
  1321. if (NULL != ppEnum)
  1322. {
  1323. *ppEnum = NULL;
  1324. }
  1325. else
  1326. {
  1327. hr = E_POINTER;
  1328. }
  1329. if (S_OK == hr && FALSE == fEnabledOnly)
  1330. {
  1331. //
  1332. // Make sure that we have port mapping binding instances for
  1333. // all of the port mapping protocols. If we're only enumerating
  1334. // enabled protocols, then there's no need for us to create
  1335. // anything.
  1336. //
  1337. hr = CreatePortMappingBindings();
  1338. }
  1339. if (S_OK == hr)
  1340. {
  1341. hr = BuildEscapedQuotedEqualsString(
  1342. &wszWhere,
  1343. c_wszConnection,
  1344. m_bstrConnection
  1345. );
  1346. if (S_OK == hr && fEnabledOnly)
  1347. {
  1348. LPWSTR wsz;
  1349. //
  1350. // Add "AND Enabled != FALSE"
  1351. //
  1352. hr = BuildAndString(
  1353. &wsz,
  1354. wszWhere,
  1355. L"Enabled != FALSE"
  1356. );
  1357. delete [] wszWhere;
  1358. if (S_OK == hr)
  1359. {
  1360. wszWhere = wsz;
  1361. }
  1362. }
  1363. }
  1364. if (S_OK == hr)
  1365. {
  1366. hr = BuildSelectQueryBstr(
  1367. &bstrQuery,
  1368. c_wszStar,
  1369. c_wszHnetConnectionPortMapping,
  1370. wszWhere
  1371. );
  1372. delete [] wszWhere;
  1373. }
  1374. if (S_OK == hr)
  1375. {
  1376. //
  1377. // Execute the query and build the enum wrapper
  1378. //
  1379. pwcoEnum = NULL;
  1380. hr = m_piwsHomenet->ExecQuery(
  1381. m_bstrWQL,
  1382. bstrQuery,
  1383. WBEM_FLAG_RETURN_IMMEDIATELY,
  1384. NULL,
  1385. &pwcoEnum
  1386. );
  1387. SysFreeString(bstrQuery);
  1388. }
  1389. if (WBEM_S_NO_ERROR == hr)
  1390. {
  1391. CComObject<CEnumHNetPortMappingBindings> *pEnum;
  1392. hr = CComObject<CEnumHNetPortMappingBindings>::CreateInstance(&pEnum);
  1393. if (S_OK == hr)
  1394. {
  1395. pEnum->AddRef();
  1396. hr = pEnum->Initialize(m_piwsHomenet, pwcoEnum);
  1397. if (S_OK == hr)
  1398. {
  1399. hr = pEnum->QueryInterface(
  1400. IID_PPV_ARG(IEnumHNetPortMappingBindings, ppEnum)
  1401. );
  1402. }
  1403. pEnum->Release();
  1404. }
  1405. pwcoEnum->Release();
  1406. }
  1407. return hr;
  1408. }
  1409. STDMETHODIMP
  1410. CHNetConn::GetBindingForPortMappingProtocol(
  1411. IHNetPortMappingProtocol *pProtocol,
  1412. IHNetPortMappingBinding **ppBinding
  1413. )
  1414. {
  1415. HRESULT hr = S_OK;
  1416. BSTR bstrConPath;
  1417. BSTR bstrProtPath;
  1418. IWbemClassObject *pwcoInstance;
  1419. USHORT usPublicPort;
  1420. if (NULL == pProtocol)
  1421. {
  1422. hr = E_INVALIDARG;
  1423. }
  1424. else if (NULL == ppBinding)
  1425. {
  1426. hr = E_POINTER;
  1427. }
  1428. else
  1429. {
  1430. *ppBinding = NULL;
  1431. }
  1432. if (S_OK == hr)
  1433. {
  1434. hr = pProtocol->GetPort(&usPublicPort);
  1435. }
  1436. if (S_OK == hr)
  1437. {
  1438. IHNetPrivate *pHNetPrivate;
  1439. //
  1440. // Use our private interface to get the path to the
  1441. // protocol object
  1442. //
  1443. hr = pProtocol->QueryInterface(
  1444. IID_PPV_ARG(IHNetPrivate, &pHNetPrivate)
  1445. );
  1446. if (S_OK == hr)
  1447. {
  1448. hr = pHNetPrivate->GetObjectPath(&bstrProtPath);
  1449. pHNetPrivate->Release();
  1450. }
  1451. }
  1452. //
  1453. // Retrieve the binding instance for the protocol. If
  1454. // it doesn't yet exist, this routine will create it.
  1455. //
  1456. if (S_OK == hr)
  1457. {
  1458. hr = GetPortMappingBindingInstance(
  1459. m_piwsHomenet,
  1460. m_bstrWQL,
  1461. m_bstrConnection,
  1462. bstrProtPath,
  1463. usPublicPort,
  1464. &pwcoInstance
  1465. );
  1466. SysFreeString(bstrProtPath);
  1467. }
  1468. if (S_OK == hr)
  1469. {
  1470. CComObject<CHNetPortMappingBinding> *pBinding;
  1471. hr = CComObject<CHNetPortMappingBinding>::CreateInstance(&pBinding);
  1472. if (S_OK == hr)
  1473. {
  1474. pBinding->AddRef();
  1475. hr = pBinding->Initialize(m_piwsHomenet, pwcoInstance);
  1476. if (S_OK == hr)
  1477. {
  1478. hr = pBinding->QueryInterface(
  1479. IID_PPV_ARG(IHNetPortMappingBinding, ppBinding)
  1480. );
  1481. }
  1482. pBinding->Release();
  1483. }
  1484. pwcoInstance->Release();
  1485. }
  1486. return hr;
  1487. }
  1488. STDMETHODIMP
  1489. CHNetConn::GetIcmpSettings(
  1490. HNET_FW_ICMP_SETTINGS **ppSettings
  1491. )
  1492. {
  1493. HRESULT hr = S_OK;
  1494. IWbemClassObject *pwcoSettings;
  1495. if (NULL != ppSettings)
  1496. {
  1497. //
  1498. // Allocate output structure
  1499. //
  1500. *ppSettings = reinterpret_cast<HNET_FW_ICMP_SETTINGS*>(
  1501. CoTaskMemAlloc(sizeof(HNET_FW_ICMP_SETTINGS))
  1502. );
  1503. if (NULL == *ppSettings)
  1504. {
  1505. hr = E_OUTOFMEMORY;
  1506. }
  1507. }
  1508. else
  1509. {
  1510. hr = E_POINTER;
  1511. }
  1512. //
  1513. // Retrieve the ICMP setting block for this connection
  1514. //
  1515. if (S_OK == hr)
  1516. {
  1517. hr = GetIcmpSettingsInstance(&pwcoSettings);
  1518. }
  1519. if (S_OK == hr)
  1520. {
  1521. //
  1522. // Copy settings instance to struct
  1523. //
  1524. hr = CopyIcmpSettingsInstanceToStruct(
  1525. pwcoSettings,
  1526. *ppSettings
  1527. );
  1528. pwcoSettings->Release();
  1529. }
  1530. if (FAILED(hr) && NULL != *ppSettings)
  1531. {
  1532. CoTaskMemFree(*ppSettings);
  1533. *ppSettings = NULL;
  1534. }
  1535. return hr;
  1536. }
  1537. STDMETHODIMP
  1538. CHNetConn::SetIcmpSettings(
  1539. HNET_FW_ICMP_SETTINGS *pSettings
  1540. )
  1541. {
  1542. HRESULT hr = S_OK;
  1543. BOOLEAN fNewInstance = FALSE;
  1544. VARIANT vt;
  1545. IEnumWbemClassObject *pwcoEnum;
  1546. IWbemClassObject *pwcoSettings = NULL;
  1547. BSTR bstr;
  1548. if (NULL == pSettings)
  1549. {
  1550. hr = E_INVALIDARG;
  1551. }
  1552. //
  1553. // Retrieve the ICMP setting block for this connection
  1554. //
  1555. if (S_OK == hr)
  1556. {
  1557. hr = GetIcmpSettingsInstance(&pwcoSettings);
  1558. }
  1559. if (WBEM_S_NO_ERROR == hr)
  1560. {
  1561. //
  1562. // Check to see if we need a new settings instace (i.e.,
  1563. // the name of this instance is "Default"
  1564. //
  1565. hr = pwcoSettings->Get(
  1566. c_wszName,
  1567. 0,
  1568. &vt,
  1569. NULL,
  1570. NULL
  1571. );
  1572. if (WBEM_S_NO_ERROR == hr)
  1573. {
  1574. _ASSERT(VT_BSTR == V_VT(&vt));
  1575. if (0 == wcscmp(V_BSTR(&vt), c_wszDefault))
  1576. {
  1577. //
  1578. // Need to create new settings block
  1579. //
  1580. fNewInstance = TRUE;
  1581. pwcoSettings->Release();
  1582. pwcoSettings = NULL;
  1583. }
  1584. VariantClear(&vt);
  1585. }
  1586. else
  1587. {
  1588. pwcoSettings->Release();
  1589. pwcoSettings = NULL;
  1590. }
  1591. }
  1592. if (WBEM_S_NO_ERROR == hr && TRUE == fNewInstance)
  1593. {
  1594. hr = SpawnNewInstance(
  1595. m_piwsHomenet,
  1596. c_wszHnetFwIcmpSettings,
  1597. &pwcoSettings
  1598. );
  1599. }
  1600. if (WBEM_S_NO_ERROR == hr)
  1601. {
  1602. hr = CopyStructToIcmpSettingsInstance(pSettings, pwcoSettings);
  1603. }
  1604. if (WBEM_S_NO_ERROR == hr)
  1605. {
  1606. IWbemCallResult *pResult;
  1607. //
  1608. // Write the instance to the store
  1609. //
  1610. pResult = NULL;
  1611. hr = m_piwsHomenet->PutInstance(
  1612. pwcoSettings,
  1613. WBEM_FLAG_CREATE_OR_UPDATE | WBEM_FLAG_RETURN_IMMEDIATELY,
  1614. NULL,
  1615. &pResult
  1616. );
  1617. if (WBEM_S_NO_ERROR == hr)
  1618. {
  1619. //
  1620. // We need to call GetResultString no matter what so that we
  1621. // can get the proper error code if the put failed. However,
  1622. // we only need to keep the path if this is a new instance,
  1623. // as in that situation we need the path below to create the
  1624. // new association object.
  1625. //
  1626. hr = pResult->GetResultString(WBEM_INFINITE, &bstr);
  1627. pResult->Release();
  1628. if (FALSE == fNewInstance)
  1629. {
  1630. SysFreeString(bstr);
  1631. bstr = NULL;
  1632. }
  1633. }
  1634. }
  1635. if (WBEM_S_NO_ERROR == hr && TRUE == fNewInstance)
  1636. {
  1637. BSTR bstrQuery;
  1638. LPWSTR wsz;
  1639. //
  1640. // Delete the old association object, if any
  1641. //
  1642. hr = BuildEscapedQuotedEqualsString(
  1643. &wsz,
  1644. c_wszConnection,
  1645. m_bstrConnection
  1646. );
  1647. if (S_OK == hr)
  1648. {
  1649. //
  1650. // Query for the object associating the connection to
  1651. // the ICMP settings block
  1652. //
  1653. hr = BuildSelectQueryBstr(
  1654. &bstrQuery,
  1655. c_wszStar,
  1656. c_wszHnetConnectionIcmpSetting,
  1657. wsz
  1658. );
  1659. delete [] wsz;
  1660. if (S_OK == hr)
  1661. {
  1662. pwcoEnum = NULL;
  1663. hr = m_piwsHomenet->ExecQuery(
  1664. m_bstrWQL,
  1665. bstrQuery,
  1666. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  1667. NULL,
  1668. &pwcoEnum
  1669. );
  1670. SysFreeString(bstrQuery);
  1671. }
  1672. }
  1673. if (WBEM_S_NO_ERROR == hr)
  1674. {
  1675. ULONG ulCount;
  1676. IWbemClassObject *pwcoAssoc;
  1677. pwcoAssoc = NULL;
  1678. hr = pwcoEnum->Next(
  1679. WBEM_INFINITE,
  1680. 1,
  1681. &pwcoAssoc,
  1682. &ulCount
  1683. );
  1684. //
  1685. // Enum should be empty at this point
  1686. //
  1687. ValidateFinishedWCOEnum(m_piwsHomenet, pwcoEnum);
  1688. pwcoEnum->Release();
  1689. if (SUCCEEDED(hr) && 1 == ulCount)
  1690. {
  1691. //
  1692. // Delete old association object
  1693. //
  1694. DeleteWmiInstance(m_piwsHomenet, pwcoAssoc);
  1695. pwcoAssoc->Release();
  1696. }
  1697. }
  1698. //
  1699. // Create new association
  1700. //
  1701. hr = CreateIcmpSettingsAssociation(bstr);
  1702. SysFreeString(bstr);
  1703. }
  1704. if (SUCCEEDED(hr))
  1705. {
  1706. //
  1707. // Notify service of configuration change
  1708. //
  1709. UpdateService(IPNATHLP_CONTROL_UPDATE_CONNECTION);
  1710. }
  1711. if (NULL != pwcoSettings)
  1712. {
  1713. pwcoSettings->Release();
  1714. }
  1715. return hr;
  1716. }
  1717. STDMETHODIMP
  1718. CHNetConn::ShowAutoconfigBalloon(
  1719. BOOLEAN *pfShowBalloon
  1720. )
  1721. {
  1722. HRESULT hr = S_OK;
  1723. BOOLEAN fShowBalloon = FALSE;
  1724. BSTR bstrQuery;
  1725. LPWSTR wszWhere;
  1726. IEnumWbemClassObject *pwcoEnum;
  1727. if (NULL != pfShowBalloon)
  1728. {
  1729. *pfShowBalloon = FALSE;
  1730. }
  1731. else
  1732. {
  1733. hr = E_POINTER;
  1734. }
  1735. //
  1736. // Autoconfig balloon is never shown for a RAS connection
  1737. //
  1738. if (!m_fLanConnection)
  1739. {
  1740. hr = E_UNEXPECTED;
  1741. }
  1742. //
  1743. // Attempt to locate the HNet_ConnectionAutoconfig block
  1744. // for this connection
  1745. //
  1746. if (S_OK == hr)
  1747. {
  1748. //
  1749. // Build query string:
  1750. //
  1751. // SELECT * FROM HNet_ConnectionAutoconfig WHERE Connection = [this]
  1752. //
  1753. hr = BuildEscapedQuotedEqualsString(
  1754. &wszWhere,
  1755. c_wszConnection,
  1756. m_bstrConnection
  1757. );
  1758. if (S_OK == hr)
  1759. {
  1760. hr = BuildSelectQueryBstr(
  1761. &bstrQuery,
  1762. c_wszStar,
  1763. c_wszHnetConnectionAutoconfig,
  1764. wszWhere
  1765. );
  1766. delete [] wszWhere;
  1767. }
  1768. }
  1769. if (S_OK == hr)
  1770. {
  1771. //
  1772. // Execute the query
  1773. //
  1774. pwcoEnum = NULL;
  1775. hr = m_piwsHomenet->ExecQuery(
  1776. m_bstrWQL,
  1777. bstrQuery,
  1778. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  1779. NULL,
  1780. &pwcoEnum
  1781. );
  1782. SysFreeString(bstrQuery);
  1783. }
  1784. if (WBEM_S_NO_ERROR == hr)
  1785. {
  1786. ULONG ulCount;
  1787. IWbemClassObject *pwcoInstance;
  1788. pwcoInstance = NULL;
  1789. hr = pwcoEnum->Next(
  1790. WBEM_INFINITE,
  1791. 1,
  1792. &pwcoInstance,
  1793. &ulCount
  1794. );
  1795. //
  1796. // Enum should be empty at this point
  1797. //
  1798. ValidateFinishedWCOEnum(m_piwsHomenet, pwcoEnum);
  1799. pwcoEnum->Release();
  1800. if (WBEM_S_NO_ERROR == hr && 1 == ulCount)
  1801. {
  1802. //
  1803. // Autoconfig block already exists
  1804. //
  1805. fShowBalloon = FALSE;
  1806. pwcoInstance->Release();
  1807. }
  1808. else
  1809. {
  1810. //
  1811. // Block doesn't exist -- create it now.
  1812. //
  1813. fShowBalloon = TRUE;
  1814. hr = SpawnNewInstance(
  1815. m_piwsHomenet,
  1816. c_wszHnetConnectionAutoconfig,
  1817. &pwcoInstance
  1818. );
  1819. if (WBEM_S_NO_ERROR == hr)
  1820. {
  1821. VARIANT vt;
  1822. V_VT(&vt) = VT_BSTR;
  1823. V_BSTR(&vt) = m_bstrConnection;
  1824. hr = pwcoInstance->Put(
  1825. c_wszConnection,
  1826. 0,
  1827. &vt,
  1828. NULL
  1829. );
  1830. //
  1831. // We don't clear the variant as we did not
  1832. // copy m_bstrConnection.
  1833. //
  1834. if (WBEM_S_NO_ERROR == hr)
  1835. {
  1836. hr = m_piwsHomenet->PutInstance(
  1837. pwcoInstance,
  1838. WBEM_FLAG_CREATE_ONLY,
  1839. NULL,
  1840. NULL
  1841. );
  1842. }
  1843. pwcoInstance->Release();
  1844. }
  1845. }
  1846. }
  1847. //
  1848. // If we think that we should show the balloon, make sure
  1849. // that the connection isn't:
  1850. // 1. ICS Public
  1851. // 2. ICS Private
  1852. // 3. Firewalled
  1853. // 4. A bridge
  1854. // 5. Part of a bridge
  1855. //
  1856. // If any of the above are true, we must have seen the connection
  1857. // before, but just not in a way that would have caused us to
  1858. // note it in it's autoconfig settings.
  1859. //
  1860. if (fShowBalloon)
  1861. {
  1862. IWbemClassObject *pwcoProperties;
  1863. HNET_CONN_PROPERTIES hnProps;
  1864. hr = GetConnectionPropertiesObject(&pwcoProperties);
  1865. if (S_OK == hr)
  1866. {
  1867. hr = InternalGetProperties(pwcoProperties, &hnProps);
  1868. pwcoProperties->Release();
  1869. }
  1870. if (S_OK == hr)
  1871. {
  1872. if (hnProps.fFirewalled
  1873. || hnProps.fIcsPublic
  1874. || hnProps.fIcsPrivate
  1875. || hnProps.fBridge
  1876. || hnProps.fPartOfBridge)
  1877. {
  1878. fShowBalloon = FALSE;
  1879. }
  1880. }
  1881. }
  1882. if (S_OK == hr)
  1883. {
  1884. *pfShowBalloon = fShowBalloon;
  1885. }
  1886. return hr;
  1887. }
  1888. STDMETHODIMP
  1889. CHNetConn::DeleteRasConnectionEntry()
  1890. {
  1891. HRESULT hr = S_OK;
  1892. HNET_CONN_PROPERTIES hnProps;
  1893. IHNetFirewalledConnection *pHNetFwConnection;
  1894. IEnumWbemClassObject *pwcoEnum;
  1895. IWbemClassObject *pwcoInstance;
  1896. IWbemClassObject *pwcoProperties;
  1897. ULONG ulPublic;
  1898. ULONG ulPrivate;
  1899. BSTR bstr;
  1900. if (m_fLanConnection)
  1901. {
  1902. hr = E_UNEXPECTED;
  1903. }
  1904. if (SUCCEEDED(hr))
  1905. {
  1906. hr = GetConnectionPropertiesObject(&pwcoProperties);
  1907. }
  1908. if (SUCCEEDED(hr))
  1909. {
  1910. hr = InternalGetProperties(pwcoProperties, &hnProps);
  1911. if (SUCCEEDED(hr))
  1912. {
  1913. if (hnProps.fIcsPublic)
  1914. {
  1915. CComObject<CHNetCfgMgrChild> *pCfgMgr;
  1916. hr = CComObject<CHNetCfgMgrChild>::CreateInstance(&pCfgMgr);
  1917. if (SUCCEEDED(hr))
  1918. {
  1919. pCfgMgr->AddRef();
  1920. hr = pCfgMgr->Initialize(m_piwsHomenet);
  1921. if (SUCCEEDED(hr))
  1922. {
  1923. hr = pCfgMgr->DisableIcs(&ulPublic, &ulPrivate);
  1924. }
  1925. pCfgMgr->Release();
  1926. }
  1927. }
  1928. //
  1929. // If an error occured disabling sharing we'll still
  1930. // try to disable firewalling.
  1931. //
  1932. if (hnProps.fFirewalled)
  1933. {
  1934. hr = GetControlInterface(
  1935. IID_PPV_ARG(
  1936. IHNetFirewalledConnection,
  1937. &pHNetFwConnection
  1938. )
  1939. );
  1940. if (SUCCEEDED(hr))
  1941. {
  1942. hr = pHNetFwConnection->Unfirewall();
  1943. pHNetFwConnection->Release();
  1944. }
  1945. }
  1946. }
  1947. pwcoProperties->Release();
  1948. //
  1949. // Delete the entries relating to this connection. We'll try
  1950. // to do this even if any of the above failed. We ignore any
  1951. // errors that occur during the deletion prcoess (i.e., from
  1952. // Delete[Wmi]Instance).
  1953. //
  1954. hr = GetIcmpSettingsInstance(&pwcoInstance);
  1955. if (SUCCEEDED(hr))
  1956. {
  1957. //
  1958. // We only want to delete this block if it's
  1959. // not the default.
  1960. //
  1961. hr = GetWmiPathFromObject(pwcoInstance, &bstr);
  1962. if (SUCCEEDED(hr))
  1963. {
  1964. if (0 != _wcsicmp(bstr, c_wszDefaultIcmpSettingsPath))
  1965. {
  1966. m_piwsHomenet->DeleteInstance(
  1967. bstr,
  1968. 0,
  1969. NULL,
  1970. NULL
  1971. );
  1972. }
  1973. SysFreeString(bstr);
  1974. }
  1975. pwcoInstance->Release();
  1976. }
  1977. //
  1978. // Now find all object that refer to our conection object.
  1979. //
  1980. hr = BuildReferencesQueryBstr(
  1981. &bstr,
  1982. m_bstrConnection,
  1983. NULL
  1984. );
  1985. if (SUCCEEDED(hr))
  1986. {
  1987. pwcoEnum = NULL;
  1988. hr = m_piwsHomenet->ExecQuery(
  1989. m_bstrWQL,
  1990. bstr,
  1991. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  1992. NULL,
  1993. &pwcoEnum
  1994. );
  1995. SysFreeString(bstr);
  1996. if (SUCCEEDED(hr))
  1997. {
  1998. ULONG ulCount;
  1999. do
  2000. {
  2001. pwcoInstance = NULL;
  2002. hr = pwcoEnum->Next(
  2003. WBEM_INFINITE,
  2004. 1,
  2005. &pwcoInstance,
  2006. &ulCount
  2007. );
  2008. if (S_OK == hr && 1 == ulCount)
  2009. {
  2010. DeleteWmiInstance(
  2011. m_piwsHomenet,
  2012. pwcoInstance
  2013. );
  2014. pwcoInstance->Release();
  2015. }
  2016. }
  2017. while (S_OK == hr && 1 == ulCount);
  2018. pwcoEnum->Release();
  2019. hr = S_OK;
  2020. }
  2021. }
  2022. //
  2023. // Finally, delete the connection object. (The connection
  2024. // properties object will have been deleted during the
  2025. // references set.)
  2026. //
  2027. hr = m_piwsHomenet->DeleteInstance(
  2028. m_bstrConnection,
  2029. 0,
  2030. NULL,
  2031. NULL
  2032. );
  2033. }
  2034. return hr;
  2035. }
  2036. //
  2037. // Protected methods
  2038. //
  2039. HRESULT
  2040. CHNetConn::GetIcmpSettingsInstance(
  2041. IWbemClassObject **ppwcoSettings
  2042. )
  2043. {
  2044. HRESULT hr = S_OK;
  2045. BSTR bstrQuery;
  2046. IEnumWbemClassObject *pwcoEnum;
  2047. ULONG ulCount;
  2048. _ASSERT(NULL != ppwcoSettings);
  2049. hr = BuildAssociatorsQueryBstr(
  2050. &bstrQuery,
  2051. m_bstrConnection,
  2052. c_wszHnetConnectionIcmpSetting
  2053. );
  2054. if (S_OK == hr)
  2055. {
  2056. pwcoEnum = NULL;
  2057. hr = m_piwsHomenet->ExecQuery(
  2058. m_bstrWQL,
  2059. bstrQuery,
  2060. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  2061. NULL,
  2062. &pwcoEnum
  2063. );
  2064. SysFreeString(bstrQuery);
  2065. }
  2066. if (WBEM_S_NO_ERROR == hr)
  2067. {
  2068. //
  2069. // Get the settings instance from the enum
  2070. //
  2071. *ppwcoSettings = NULL;
  2072. hr = pwcoEnum->Next(
  2073. WBEM_INFINITE,
  2074. 1,
  2075. ppwcoSettings,
  2076. &ulCount
  2077. );
  2078. if (SUCCEEDED(hr) && 1 == ulCount)
  2079. {
  2080. //
  2081. // Normalize return value
  2082. //
  2083. hr = S_OK;
  2084. }
  2085. else
  2086. {
  2087. //
  2088. // Settings block not found -- use default settings
  2089. //
  2090. bstrQuery = SysAllocString(c_wszDefaultIcmpSettingsPath);
  2091. if (NULL != bstrQuery)
  2092. {
  2093. hr = GetWmiObjectFromPath(
  2094. m_piwsHomenet,
  2095. bstrQuery,
  2096. ppwcoSettings
  2097. );
  2098. SysFreeString(bstrQuery);
  2099. }
  2100. else
  2101. {
  2102. hr = E_OUTOFMEMORY;
  2103. }
  2104. }
  2105. //
  2106. // Enum should be empty at this point
  2107. //
  2108. ValidateFinishedWCOEnum(m_piwsHomenet, pwcoEnum);
  2109. pwcoEnum->Release();
  2110. }
  2111. return hr;
  2112. }
  2113. HRESULT
  2114. CHNetConn::CopyIcmpSettingsInstanceToStruct(
  2115. IWbemClassObject *pwcoSettings,
  2116. HNET_FW_ICMP_SETTINGS *pSettings
  2117. )
  2118. {
  2119. HRESULT hr = S_OK;
  2120. _ASSERT(NULL != pwcoSettings);
  2121. _ASSERT(NULL != pSettings);
  2122. hr = GetBooleanValue(
  2123. pwcoSettings,
  2124. c_wszAllowOutboundDestinationUnreachable,
  2125. &pSettings->fAllowOutboundDestinationUnreachable
  2126. );
  2127. if (WBEM_S_NO_ERROR == hr)
  2128. {
  2129. hr = GetBooleanValue(
  2130. pwcoSettings,
  2131. c_wszAllowOutboundSourceQuench,
  2132. &pSettings->fAllowOutboundSourceQuench
  2133. );
  2134. }
  2135. if (WBEM_S_NO_ERROR == hr)
  2136. {
  2137. hr = GetBooleanValue(
  2138. pwcoSettings,
  2139. c_wszAllowRedirect,
  2140. &pSettings->fAllowRedirect
  2141. );
  2142. }
  2143. if (WBEM_S_NO_ERROR == hr)
  2144. {
  2145. hr = GetBooleanValue(
  2146. pwcoSettings,
  2147. c_wszAllowInboundEchoRequest,
  2148. &pSettings->fAllowInboundEchoRequest
  2149. );
  2150. }
  2151. if (WBEM_S_NO_ERROR == hr)
  2152. {
  2153. hr = GetBooleanValue(
  2154. pwcoSettings,
  2155. c_wszAllowInboundRouterRequest,
  2156. &pSettings->fAllowInboundRouterRequest
  2157. );
  2158. }
  2159. if (WBEM_S_NO_ERROR == hr)
  2160. {
  2161. hr = GetBooleanValue(
  2162. pwcoSettings,
  2163. c_wszAllowOutboundTimeExceeded,
  2164. &pSettings->fAllowOutboundTimeExceeded
  2165. );
  2166. }
  2167. if (WBEM_S_NO_ERROR == hr)
  2168. {
  2169. hr = GetBooleanValue(
  2170. pwcoSettings,
  2171. c_wszAllowOutboundParameterProblem,
  2172. &pSettings->fAllowOutboundParameterProblem
  2173. );
  2174. }
  2175. if (WBEM_S_NO_ERROR == hr)
  2176. {
  2177. hr = GetBooleanValue(
  2178. pwcoSettings,
  2179. c_wszAllowInboundTimestampRequest,
  2180. &pSettings->fAllowInboundTimestampRequest
  2181. );
  2182. }
  2183. if (WBEM_S_NO_ERROR == hr)
  2184. {
  2185. hr = GetBooleanValue(
  2186. pwcoSettings,
  2187. c_wszAllowInboundMaskRequest,
  2188. &pSettings->fAllowInboundMaskRequest
  2189. );
  2190. }
  2191. return hr;
  2192. }
  2193. HRESULT
  2194. CHNetConn::CopyStructToIcmpSettingsInstance(
  2195. HNET_FW_ICMP_SETTINGS *pSettings,
  2196. IWbemClassObject *pwcoSettings
  2197. )
  2198. {
  2199. HRESULT hr = S_OK;
  2200. _ASSERT(NULL != pSettings);
  2201. _ASSERT(NULL != pwcoSettings);
  2202. hr = SetBooleanValue(
  2203. pwcoSettings,
  2204. c_wszAllowOutboundDestinationUnreachable,
  2205. pSettings->fAllowOutboundDestinationUnreachable
  2206. );
  2207. if (WBEM_S_NO_ERROR == hr)
  2208. {
  2209. hr = SetBooleanValue(
  2210. pwcoSettings,
  2211. c_wszAllowOutboundSourceQuench,
  2212. pSettings->fAllowOutboundSourceQuench
  2213. );
  2214. }
  2215. if (WBEM_S_NO_ERROR == hr)
  2216. {
  2217. hr = SetBooleanValue(
  2218. pwcoSettings,
  2219. c_wszAllowRedirect,
  2220. pSettings->fAllowRedirect
  2221. );
  2222. }
  2223. if (WBEM_S_NO_ERROR == hr)
  2224. {
  2225. hr = SetBooleanValue(
  2226. pwcoSettings,
  2227. c_wszAllowInboundEchoRequest,
  2228. pSettings->fAllowInboundEchoRequest
  2229. );
  2230. }
  2231. if (WBEM_S_NO_ERROR == hr)
  2232. {
  2233. hr = SetBooleanValue(
  2234. pwcoSettings,
  2235. c_wszAllowInboundRouterRequest,
  2236. pSettings->fAllowInboundRouterRequest
  2237. );
  2238. }
  2239. if (WBEM_S_NO_ERROR == hr)
  2240. {
  2241. hr = SetBooleanValue(
  2242. pwcoSettings,
  2243. c_wszAllowOutboundTimeExceeded,
  2244. pSettings->fAllowOutboundTimeExceeded
  2245. );
  2246. }
  2247. if (WBEM_S_NO_ERROR == hr)
  2248. {
  2249. hr = SetBooleanValue(
  2250. pwcoSettings,
  2251. c_wszAllowOutboundParameterProblem,
  2252. pSettings->fAllowOutboundParameterProblem
  2253. );
  2254. }
  2255. if (WBEM_S_NO_ERROR == hr)
  2256. {
  2257. hr = SetBooleanValue(
  2258. pwcoSettings,
  2259. c_wszAllowInboundTimestampRequest,
  2260. pSettings->fAllowInboundTimestampRequest
  2261. );
  2262. }
  2263. if (WBEM_S_NO_ERROR == hr)
  2264. {
  2265. hr = SetBooleanValue(
  2266. pwcoSettings,
  2267. c_wszAllowInboundMaskRequest,
  2268. pSettings->fAllowInboundMaskRequest
  2269. );
  2270. }
  2271. return hr;
  2272. }
  2273. HRESULT
  2274. CHNetConn::CreatePortMappingBindings()
  2275. {
  2276. HRESULT hr = S_OK;
  2277. BSTR bstr;
  2278. IEnumWbemClassObject *pwcoEnumProtocols;
  2279. IWbemClassObject *pwcoInstance;
  2280. VARIANT vt;
  2281. //
  2282. // Get the enumeration of all protocol instances
  2283. //
  2284. bstr = SysAllocString(c_wszHnetPortMappingProtocol);
  2285. if (NULL != bstr)
  2286. {
  2287. pwcoEnumProtocols = NULL;
  2288. hr = m_piwsHomenet->CreateInstanceEnum(
  2289. bstr,
  2290. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
  2291. NULL,
  2292. &pwcoEnumProtocols
  2293. );
  2294. SysFreeString(bstr);
  2295. }
  2296. else
  2297. {
  2298. hr = E_OUTOFMEMORY;
  2299. }
  2300. if (WBEM_S_NO_ERROR == hr)
  2301. {
  2302. ULONG ulCount;
  2303. //
  2304. // Loop through the enumeration, checking to see if the desired binding
  2305. // exists
  2306. //
  2307. do
  2308. {
  2309. pwcoInstance = NULL;
  2310. hr = pwcoEnumProtocols->Next(
  2311. WBEM_INFINITE,
  2312. 1,
  2313. &pwcoInstance,
  2314. &ulCount
  2315. );
  2316. if (SUCCEEDED(hr) && 1 == ulCount)
  2317. {
  2318. hr = pwcoInstance->Get(
  2319. c_wszPort,
  2320. 0,
  2321. &vt,
  2322. NULL,
  2323. NULL
  2324. );
  2325. if (WBEM_S_NO_ERROR == hr)
  2326. {
  2327. ASSERT(VT_I4 == V_VT(&vt));
  2328. hr = GetWmiPathFromObject(pwcoInstance, &bstr);
  2329. }
  2330. if (WBEM_S_NO_ERROR == hr)
  2331. {
  2332. IWbemClassObject *pwcoBinding;
  2333. hr = GetPortMappingBindingInstance(
  2334. m_piwsHomenet,
  2335. m_bstrWQL,
  2336. m_bstrConnection,
  2337. bstr,
  2338. static_cast<USHORT>(V_I4(&vt)),
  2339. &pwcoBinding
  2340. );
  2341. SysFreeString(bstr);
  2342. if (S_OK == hr)
  2343. {
  2344. pwcoBinding->Release();
  2345. }
  2346. else if (WBEM_E_NOT_FOUND == hr)
  2347. {
  2348. //
  2349. // This can occur if the protocol instance is
  2350. // deleted after we retrieved it from the enumeration
  2351. // but before we created the binding instance. It's
  2352. // OK to continue in this situation.
  2353. //
  2354. hr = S_OK;
  2355. }
  2356. }
  2357. pwcoInstance->Release();
  2358. }
  2359. } while (SUCCEEDED(hr) && 1 == ulCount);
  2360. pwcoEnumProtocols->Release();
  2361. }
  2362. return SUCCEEDED(hr) ? S_OK : hr;
  2363. }
  2364. HRESULT
  2365. CHNetConn::InternalGetProperties(
  2366. IWbemClassObject *pwcoProperties,
  2367. HNET_CONN_PROPERTIES *pProperties
  2368. )
  2369. {
  2370. HRESULT hr = S_OK;
  2371. _ASSERT(NULL != pwcoProperties);
  2372. _ASSERT(NULL != pProperties);
  2373. pProperties->fLanConnection = m_fLanConnection;
  2374. if (IsServiceRunning(c_wszSharedAccess))
  2375. {
  2376. hr = GetBooleanValue(
  2377. pwcoProperties,
  2378. c_wszIsFirewalled,
  2379. &pProperties->fFirewalled
  2380. );
  2381. }
  2382. else
  2383. {
  2384. //
  2385. // If the SharedAccess service is not running (or in the process
  2386. // of starting up) we don't want to report this connection as
  2387. // being firewalled. This is to prevent the confusion that could
  2388. // result if the UI indicates the firewall is active, when in
  2389. // reality it's not there providing protection.
  2390. //
  2391. pProperties->fFirewalled = FALSE;
  2392. }
  2393. if (WBEM_S_NO_ERROR == hr)
  2394. {
  2395. hr = GetBooleanValue(
  2396. pwcoProperties,
  2397. c_wszIsIcsPublic,
  2398. &pProperties->fIcsPublic
  2399. );
  2400. }
  2401. if (WBEM_S_NO_ERROR == hr)
  2402. {
  2403. hr = GetBooleanValue(
  2404. pwcoProperties,
  2405. c_wszIsIcsPrivate,
  2406. &pProperties->fIcsPrivate
  2407. );
  2408. }
  2409. if (WBEM_S_NO_ERROR == hr)
  2410. {
  2411. if( m_fLanConnection )
  2412. {
  2413. //
  2414. // Figure out NetCfg-based properties
  2415. //
  2416. INetCfg *pnetcfg;
  2417. hr = CoCreateInstance(
  2418. CLSID_CNetCfg,
  2419. NULL,
  2420. CLSCTX_SERVER,
  2421. IID_PPV_ARG(INetCfg, &pnetcfg)
  2422. );
  2423. if (S_OK == hr)
  2424. {
  2425. hr = pnetcfg->Initialize( NULL );
  2426. if( S_OK == hr )
  2427. {
  2428. GUID *pguid;
  2429. INetCfgComponent *pncfgcomp;
  2430. hr = GetGuidInternal(&pguid);
  2431. if(S_OK == hr)
  2432. {
  2433. // Get the NetCfg component that corresponds to us
  2434. hr = FindAdapterByGUID( pnetcfg, pguid, &pncfgcomp );
  2435. if(S_OK == hr)
  2436. {
  2437. LPWSTR pszwId;
  2438. pncfgcomp->GetId( &pszwId );
  2439. if(S_OK == hr)
  2440. {
  2441. pProperties->fBridge = (BOOLEAN)(_wcsicmp(pszwId, c_wszSBridgeMPID) == 0);
  2442. CoTaskMemFree(pszwId);
  2443. if( pProperties->fBridge )
  2444. {
  2445. // This adapter is the bridge. It can't possibly also be a bridge
  2446. // member.
  2447. pProperties->fPartOfBridge = FALSE;
  2448. }
  2449. else
  2450. {
  2451. //
  2452. // This adapter is not the bridge. Check if it's part of a bridge.
  2453. //
  2454. INetCfgComponent *pnetcfgcompBridgeProtocol;
  2455. // Find the bridge protocol component
  2456. hr = pnetcfg->FindComponent( c_wszSBridgeSID, &pnetcfgcompBridgeProtocol );
  2457. if(S_OK == hr)
  2458. {
  2459. INetCfgComponentBindings *pnetcfgProtocolBindings;
  2460. // Get the ComponentBindings interface for the protocol component
  2461. hr = pnetcfgcompBridgeProtocol->QueryInterface(
  2462. IID_PPV_ARG(INetCfgComponentBindings, &pnetcfgProtocolBindings)
  2463. );
  2464. if(S_OK == hr)
  2465. {
  2466. hr = pnetcfgProtocolBindings->IsBoundTo(pncfgcomp);
  2467. if(S_OK == hr)
  2468. {
  2469. // The bridge protocol is bound to this adapter
  2470. pProperties->fPartOfBridge = TRUE;
  2471. }
  2472. else if(S_FALSE == hr)
  2473. {
  2474. // The bridge protocol is not bound to this adapter
  2475. pProperties->fPartOfBridge = FALSE;
  2476. // Reset to success
  2477. hr = S_OK;
  2478. }
  2479. // else an error occured
  2480. pnetcfgProtocolBindings->Release();
  2481. }
  2482. pnetcfgcompBridgeProtocol->Release();
  2483. }
  2484. else
  2485. {
  2486. // This adapter can't be bridged if there's no bridge protocol
  2487. // in the system
  2488. pProperties->fPartOfBridge = FALSE;
  2489. // Reset to success
  2490. hr = S_OK;
  2491. }
  2492. }
  2493. }
  2494. pncfgcomp->Release();
  2495. }
  2496. }
  2497. pnetcfg->Uninitialize();
  2498. }
  2499. pnetcfg->Release();
  2500. }
  2501. } // if m_fLanConnection
  2502. else
  2503. {
  2504. // We're not a LAN connection. We can never be a bridge or a bridge member.
  2505. pProperties->fBridge = FALSE;
  2506. pProperties->fPartOfBridge = FALSE;
  2507. }
  2508. }
  2509. if(S_OK == hr)
  2510. {
  2511. //
  2512. // Calculated properties
  2513. //
  2514. pProperties->fCanBeFirewalled =
  2515. !pProperties->fPartOfBridge
  2516. && !pProperties->fBridge
  2517. && !pProperties->fIcsPrivate;
  2518. pProperties->fCanBeIcsPublic =
  2519. !pProperties->fBridge
  2520. && !pProperties->fPartOfBridge
  2521. && !pProperties->fIcsPrivate;
  2522. pProperties->fCanBeIcsPrivate =
  2523. m_fLanConnection
  2524. && !pProperties->fIcsPublic
  2525. && !pProperties->fFirewalled
  2526. && !pProperties->fPartOfBridge;
  2527. pProperties->fCanBeBridged =
  2528. m_fLanConnection
  2529. && !pProperties->fIcsPublic
  2530. && !pProperties->fIcsPrivate
  2531. && !pProperties->fFirewalled
  2532. && !pProperties->fBridge;
  2533. }
  2534. return hr;
  2535. }
  2536. HRESULT
  2537. CHNetConn::SetupConnectionAsPrivateLan()
  2538. {
  2539. HRESULT hr;
  2540. GUID *pGuid;
  2541. ANSI_STRING AnsiString;
  2542. UNICODE_STRING UnicodeString;
  2543. ULONG Error;
  2544. DWORD dwAddress;
  2545. DWORD dwMask;
  2546. ULONG i;
  2547. PMIB_IPADDRTABLE Table;
  2548. ZeroMemory(&UnicodeString, sizeof(UnicodeString));
  2549. ZeroMemory(&AnsiString, sizeof(AnsiString));
  2550. hr = GetGuidInternal(&pGuid);
  2551. if (SUCCEEDED(hr))
  2552. {
  2553. hr = RtlStringFromGUID(*pGuid, &UnicodeString);
  2554. if (SUCCEEDED(hr))
  2555. {
  2556. hr = RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, TRUE);
  2557. }
  2558. }
  2559. if (SUCCEEDED(hr))
  2560. {
  2561. //
  2562. // Obtain the address and mask for the private network
  2563. //
  2564. hr = ReadDhcpScopeSettings(&dwAddress, &dwMask);
  2565. }
  2566. if (SUCCEEDED(hr))
  2567. {
  2568. //
  2569. // Determine whether some LAN adapter other than the private LAN
  2570. // is already using an address in the private network scope.
  2571. // In the process, make sure that the private LAN has only one
  2572. // IP address (otherwise, 'SetAdapterIpAddress' fails.)
  2573. //
  2574. Error =
  2575. AllocateAndGetIpAddrTableFromStack(
  2576. &Table,
  2577. FALSE,
  2578. GetProcessHeap(),
  2579. 0
  2580. );
  2581. if (ERROR_SUCCESS == Error)
  2582. {
  2583. ULONG Index = 0;
  2584. ULONG Count;
  2585. hr = MapGuidStringToAdapterIndex(UnicodeString.Buffer, &Index);
  2586. if (SUCCEEDED(hr))
  2587. {
  2588. for (i = 0, Count = 0; i < Table->dwNumEntries; i++)
  2589. {
  2590. if (Index == Table->table[i].dwIndex)
  2591. {
  2592. ++Count;
  2593. }
  2594. else if ((Table->table[i].dwAddr & dwMask)
  2595. == (dwAddress & dwMask))
  2596. {
  2597. //
  2598. // It appears that some other LAN adapter has an
  2599. // address in the proposed scope.
  2600. //
  2601. // This may happen when multiple netcards go into
  2602. // autonet mode or when the RAS server is handing
  2603. // out autonet addresses.
  2604. //
  2605. // Therefore, if we're using the autonet scope,
  2606. // allow this behavior; otherwise prohibit it.
  2607. //
  2608. if ((dwAddress & dwMask) != 0x0000fea9)
  2609. {
  2610. break;
  2611. }
  2612. }
  2613. }
  2614. if (i < Table->dwNumEntries)
  2615. {
  2616. hr = HRESULT_FROM_WIN32(ERROR_SHARING_ADDRESS_EXISTS);
  2617. }
  2618. else if (Count > 1)
  2619. {
  2620. hr = HRESULT_FROM_WIN32(ERROR_SHARING_MULTIPLE_ADDRESSES);
  2621. }
  2622. }
  2623. HeapFree(GetProcessHeap(), 0, Table);
  2624. }
  2625. else
  2626. {
  2627. hr = HRESULT_FROM_WIN32(Error);
  2628. }
  2629. }
  2630. //
  2631. // Set the predefined static IP address for the private LAN.
  2632. //
  2633. if (SUCCEEDED(hr))
  2634. {
  2635. Error =
  2636. SetAdapterIpAddress(
  2637. AnsiString.Buffer,
  2638. FALSE,
  2639. dwAddress,
  2640. dwMask,
  2641. 0
  2642. );
  2643. if (ERROR_SUCCESS != Error)
  2644. {
  2645. if (Error == ERROR_TOO_MANY_NAMES)
  2646. {
  2647. Error = ERROR_SHARING_MULTIPLE_ADDRESSES;
  2648. }
  2649. else if (Error == ERROR_DUP_NAME)
  2650. {
  2651. Error = ERROR_SHARING_HOST_ADDRESS_CONFLICT;
  2652. }
  2653. else
  2654. {
  2655. //
  2656. // Query the state of the connection.
  2657. // If it is disconnected, convert the error code
  2658. // to something more informative.
  2659. //
  2660. UNICODE_STRING DeviceString;
  2661. NIC_STATISTICS NdisStatistics;
  2662. LPWSTR pwsz;
  2663. //
  2664. // Build a buffer large enough for the device string
  2665. //
  2666. pwsz = new WCHAR[wcslen(c_wszDevice) + wcslen(UnicodeString.Buffer) + 1];
  2667. if (NULL != pwsz)
  2668. {
  2669. swprintf(pwsz, L"%s%s", c_wszDevice, UnicodeString.Buffer);
  2670. RtlInitUnicodeString(&DeviceString, pwsz);
  2671. NdisStatistics.Size = sizeof(NdisStatistics);
  2672. NdisQueryStatistics(&DeviceString, &NdisStatistics);
  2673. delete [] pwsz;
  2674. if (NdisStatistics.DeviceState != DEVICE_STATE_CONNECTED)
  2675. {
  2676. Error = ERROR_SHARING_NO_PRIVATE_LAN;
  2677. }
  2678. else if (NdisStatistics.MediaState == MEDIA_STATE_UNKNOWN)
  2679. {
  2680. Error = ERROR_SHARING_HOST_ADDRESS_CONFLICT;
  2681. }
  2682. else if (NdisStatistics.MediaState == MEDIA_STATE_DISCONNECTED)
  2683. {
  2684. //
  2685. // The adapter is connected but is in a media disconnect
  2686. // state. When this happens the correct IP address will
  2687. // be there when the adapter is reconnected, so ignore
  2688. // the error.
  2689. //
  2690. Error = ERROR_SUCCESS;
  2691. }
  2692. }
  2693. }
  2694. hr = HRESULT_FROM_WIN32(Error);
  2695. }
  2696. }
  2697. //
  2698. // As we zeroed out the string structure above, it's safe to call
  2699. // the free routines, even if we never actually allocated anything.
  2700. //
  2701. RtlFreeUnicodeString(&UnicodeString);
  2702. RtlFreeAnsiString(&AnsiString);
  2703. return hr;
  2704. }
  2705. HRESULT
  2706. CHNetConn::BackupIpConfiguration()
  2707. {
  2708. HRESULT hr = S_OK;
  2709. HANDLE Key;
  2710. IWbemClassObject *pwcoInstance = NULL;
  2711. VARIANT vt;
  2712. PKEY_VALUE_PARTIAL_INFORMATION pInformation;
  2713. //
  2714. // Spawn a new HNet_BackupIpConfiguration instance
  2715. //
  2716. hr = SpawnNewInstance(
  2717. m_piwsHomenet,
  2718. c_wszBackupIpConfiguration,
  2719. &pwcoInstance
  2720. );
  2721. if (SUCCEEDED(hr))
  2722. {
  2723. //
  2724. // Write connection property into instance
  2725. //
  2726. V_VT(&vt) = VT_BSTR;
  2727. V_BSTR(&vt) = m_bstrConnection;
  2728. hr = pwcoInstance->Put(
  2729. c_wszConnection,
  2730. 0,
  2731. &vt,
  2732. NULL
  2733. );
  2734. VariantInit(&vt);
  2735. }
  2736. //
  2737. // Open the registry key that stores the IP configuration
  2738. // for this connection
  2739. //
  2740. if (SUCCEEDED(hr))
  2741. {
  2742. hr = OpenIpConfigurationRegKey(KEY_READ, &Key);
  2743. }
  2744. //
  2745. // Read each part of the configuration, and write it to
  2746. // the settings instance
  2747. //
  2748. if (SUCCEEDED(hr))
  2749. {
  2750. hr = QueryRegValueKey(Key, c_wszIPAddress, &pInformation);
  2751. if (SUCCEEDED(hr))
  2752. {
  2753. _ASSERT(REG_MULTI_SZ == pInformation->Type);
  2754. V_VT(&vt) = VT_BSTR;
  2755. V_BSTR(&vt) = SysAllocStringLen(
  2756. reinterpret_cast<OLECHAR*>(pInformation->Data),
  2757. pInformation->DataLength / sizeof(OLECHAR)
  2758. );
  2759. if (NULL != V_BSTR(&vt))
  2760. {
  2761. hr = pwcoInstance->Put(
  2762. c_wszIPAddress,
  2763. 0,
  2764. &vt,
  2765. NULL
  2766. );
  2767. VariantClear(&vt);
  2768. }
  2769. else
  2770. {
  2771. hr = E_OUTOFMEMORY;
  2772. }
  2773. HeapFree(GetProcessHeap(), 0, pInformation);
  2774. }
  2775. if (SUCCEEDED(hr))
  2776. {
  2777. hr = QueryRegValueKey(Key, c_wszSubnetMask, &pInformation);
  2778. }
  2779. if (SUCCEEDED(hr))
  2780. {
  2781. _ASSERT(REG_MULTI_SZ == pInformation->Type);
  2782. V_VT(&vt) = VT_BSTR;
  2783. V_BSTR(&vt) = SysAllocStringLen(
  2784. reinterpret_cast<OLECHAR*>(pInformation->Data),
  2785. pInformation->DataLength / sizeof(OLECHAR)
  2786. );
  2787. if (NULL != V_BSTR(&vt))
  2788. {
  2789. hr = pwcoInstance->Put(
  2790. c_wszSubnetMask,
  2791. 0,
  2792. &vt,
  2793. NULL
  2794. );
  2795. VariantClear(&vt);
  2796. }
  2797. else
  2798. {
  2799. hr = E_OUTOFMEMORY;
  2800. }
  2801. HeapFree(GetProcessHeap(), 0, pInformation);
  2802. }
  2803. if (SUCCEEDED(hr))
  2804. {
  2805. hr = QueryRegValueKey(Key, c_wszDefaultGateway, &pInformation);
  2806. }
  2807. if (SUCCEEDED(hr))
  2808. {
  2809. _ASSERT(REG_MULTI_SZ == pInformation->Type);
  2810. V_VT(&vt) = VT_BSTR;
  2811. V_BSTR(&vt) = SysAllocStringLen(
  2812. reinterpret_cast<OLECHAR*>(pInformation->Data),
  2813. pInformation->DataLength / sizeof(OLECHAR)
  2814. );
  2815. if (NULL != V_BSTR(&vt))
  2816. {
  2817. hr = pwcoInstance->Put(
  2818. c_wszDefaultGateway,
  2819. 0,
  2820. &vt,
  2821. NULL
  2822. );
  2823. VariantClear(&vt);
  2824. }
  2825. else
  2826. {
  2827. hr = E_OUTOFMEMORY;
  2828. }
  2829. HeapFree(GetProcessHeap(), 0, pInformation);
  2830. }
  2831. if (SUCCEEDED(hr))
  2832. {
  2833. hr = QueryRegValueKey(Key, c_wszEnableDHCP, &pInformation);
  2834. }
  2835. if (SUCCEEDED(hr))
  2836. {
  2837. _ASSERT(REG_DWORD == pInformation->Type);
  2838. _ASSERT(sizeof(DWORD) == pInformation->DataLength);
  2839. V_VT(&vt) = VT_I4;
  2840. V_I4(&vt) = *(reinterpret_cast<DWORD*>(pInformation->Data));
  2841. hr = pwcoInstance->Put(
  2842. c_wszEnableDHCP,
  2843. 0,
  2844. &vt,
  2845. NULL
  2846. );
  2847. HeapFree(GetProcessHeap(), 0, pInformation);
  2848. }
  2849. NtClose(Key);
  2850. };
  2851. //
  2852. // Write the settings to the store
  2853. //
  2854. if (SUCCEEDED(hr))
  2855. {
  2856. hr = m_piwsHomenet->PutInstance(
  2857. pwcoInstance,
  2858. WBEM_FLAG_CREATE_OR_UPDATE,
  2859. NULL,
  2860. NULL
  2861. );
  2862. }
  2863. if (NULL != pwcoInstance)
  2864. {
  2865. pwcoInstance->Release();
  2866. }
  2867. return hr;
  2868. }
  2869. HRESULT
  2870. CHNetConn::RestoreIpConfiguration()
  2871. {
  2872. HRESULT hr;
  2873. IEnumWbemClassObject *pwcoEnum;
  2874. IWbemClassObject *pwcoSettings;
  2875. BSTR bstr;
  2876. LPWSTR wszAddress;
  2877. VARIANT vt;
  2878. LPWSTR wsz;
  2879. UNICODE_STRING UnicodeString;
  2880. HANDLE hKey = NULL;
  2881. BOOLEAN fDhcpEnabled;
  2882. ULONG ulLength;
  2883. ULONG ulAddress;
  2884. ULONG ulMask;
  2885. //
  2886. // Open the registry key
  2887. //
  2888. hr = OpenIpConfigurationRegKey(KEY_ALL_ACCESS, &hKey);
  2889. //
  2890. // Get the backup configuration block for this connection
  2891. //
  2892. if (S_OK == hr)
  2893. {
  2894. hr = BuildEscapedQuotedEqualsString(
  2895. &wsz,
  2896. c_wszConnection,
  2897. m_bstrConnection
  2898. );
  2899. }
  2900. if (S_OK == hr)
  2901. {
  2902. hr = BuildSelectQueryBstr(
  2903. &bstr,
  2904. c_wszStar,
  2905. c_wszBackupIpConfiguration,
  2906. wsz
  2907. );
  2908. delete [] wsz;
  2909. }
  2910. if (S_OK == hr)
  2911. {
  2912. pwcoEnum = NULL;
  2913. hr = m_piwsHomenet->ExecQuery(
  2914. m_bstrWQL,
  2915. bstr,
  2916. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  2917. NULL,
  2918. &pwcoEnum
  2919. );
  2920. SysFreeString(bstr);
  2921. }
  2922. if (S_OK == hr)
  2923. {
  2924. ULONG ulCount;
  2925. pwcoSettings = NULL;
  2926. hr = pwcoEnum->Next(WBEM_INFINITE, 1, &pwcoSettings, &ulCount);
  2927. //
  2928. // Even if we're not able to obtain backup settings we continue
  2929. // to operate. By setting pwcoSettings to NULL we indidcate that
  2930. // the default DHCP configuration should be used. (A failure for
  2931. // ExecQuery indicates a much more serious problem, so we don't
  2932. // try to continue if that occurs.)
  2933. //
  2934. if (FAILED(hr) || 1 != ulCount)
  2935. {
  2936. pwcoSettings = NULL;
  2937. }
  2938. hr = S_OK;
  2939. ValidateFinishedWCOEnum(m_piwsHomenet, pwcoEnum);
  2940. pwcoEnum->Release();
  2941. }
  2942. //
  2943. // Write backup values to registry -- start by getting the
  2944. // old IP address
  2945. //
  2946. if (S_OK == hr)
  2947. {
  2948. if (NULL != pwcoSettings)
  2949. {
  2950. hr = pwcoSettings->Get(
  2951. c_wszIPAddress,
  2952. 0,
  2953. &vt,
  2954. NULL,
  2955. NULL
  2956. );
  2957. if (WBEM_S_NO_ERROR == hr)
  2958. {
  2959. ULONG ulDhcpAddress;
  2960. ULONG ulDhcpMask;
  2961. _ASSERT(VT_BSTR == V_VT(&vt));
  2962. //
  2963. // Check to see if the stored backup address is the
  2964. // same as our default DHCP scope -- if so, use
  2965. // the default DHCP configuration.
  2966. //
  2967. hr = ReadDhcpScopeSettings(&ulDhcpAddress, &ulDhcpMask);
  2968. if (S_OK == hr)
  2969. {
  2970. ulAddress =
  2971. RtlUlongByteSwap(
  2972. IpPszToHostAddr(V_BSTR(&vt))
  2973. );
  2974. if (ulAddress == ulDhcpAddress
  2975. || static_cast<DWORD>(-1) == ulAddress)
  2976. {
  2977. //
  2978. // Use the default configuration.
  2979. //
  2980. DeleteWmiInstance(m_piwsHomenet, pwcoSettings);
  2981. pwcoSettings->Release();
  2982. pwcoSettings = NULL;
  2983. VariantClear(&vt);
  2984. V_VT(&vt) = VT_BSTR;
  2985. V_BSTR(&vt) = SysAllocString(c_wszZeroIpAddress);
  2986. if (NULL == V_BSTR(&vt))
  2987. {
  2988. hr = E_OUTOFMEMORY;
  2989. }
  2990. }
  2991. }
  2992. }
  2993. }
  2994. else
  2995. {
  2996. V_VT(&vt) = VT_BSTR;
  2997. V_BSTR(&vt) = SysAllocString(c_wszZeroIpAddress);
  2998. if (NULL == V_BSTR(&vt))
  2999. {
  3000. hr = E_OUTOFMEMORY;
  3001. }
  3002. }
  3003. if (WBEM_S_NO_ERROR == hr)
  3004. {
  3005. //
  3006. // REG_MULTI_SZ is double-null terminated; need to copy
  3007. // the returned string into a larger buffer to add the
  3008. // nulls.
  3009. //
  3010. // The length computation here is correct; SysStringByteLen
  3011. // gives the number of bytes, not WCHARs. The 2 * sizeof(WCHAR)
  3012. // is for the double NULL at the end. (SysStringByteLen also
  3013. // doesn't include the terminating NULL.)
  3014. //
  3015. ulLength = SysStringByteLen(V_BSTR(&vt)) + 2 * sizeof(WCHAR);
  3016. wszAddress =
  3017. reinterpret_cast<LPWSTR>(
  3018. HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulLength)
  3019. );
  3020. if (NULL != wszAddress)
  3021. {
  3022. RtlCopyMemory(wszAddress, V_BSTR(&vt), ulLength - 2 * sizeof(WCHAR));
  3023. RtlInitUnicodeString(&UnicodeString, c_wszIPAddress);
  3024. hr = NtSetValueKey(
  3025. hKey,
  3026. &UnicodeString,
  3027. 0,
  3028. REG_MULTI_SZ,
  3029. reinterpret_cast<PVOID>(wszAddress),
  3030. ulLength
  3031. );
  3032. HeapFree(GetProcessHeap(), 0, wszAddress);
  3033. }
  3034. else
  3035. {
  3036. hr = E_OUTOFMEMORY;
  3037. }
  3038. VariantClear(&vt);
  3039. }
  3040. //
  3041. // DHCP settings
  3042. //
  3043. if (SUCCEEDED(hr))
  3044. {
  3045. if (NULL != pwcoSettings)
  3046. {
  3047. hr = pwcoSettings->Get(
  3048. c_wszEnableDHCP,
  3049. 0,
  3050. &vt,
  3051. NULL,
  3052. NULL
  3053. );
  3054. }
  3055. else
  3056. {
  3057. V_VT(&vt) = VT_I4;
  3058. V_I4(&vt) = 1;
  3059. hr = WBEM_S_NO_ERROR;
  3060. }
  3061. }
  3062. //
  3063. // Subnet mask
  3064. //
  3065. if (WBEM_S_NO_ERROR == hr)
  3066. {
  3067. _ASSERT(VT_I4 == V_VT(&vt));
  3068. RtlInitUnicodeString(&UnicodeString, c_wszEnableDHCP);
  3069. hr = NtSetValueKey(
  3070. hKey,
  3071. &UnicodeString,
  3072. 0,
  3073. REG_DWORD,
  3074. reinterpret_cast<PVOID>(&(V_I4(&vt))),
  3075. sizeof(V_I4(&vt))
  3076. );
  3077. fDhcpEnabled = 1 == V_I4(&vt);
  3078. VariantClear(&vt);
  3079. }
  3080. if (SUCCEEDED(hr))
  3081. {
  3082. if (NULL != pwcoSettings)
  3083. {
  3084. hr = pwcoSettings->Get(
  3085. c_wszSubnetMask,
  3086. 0,
  3087. &vt,
  3088. NULL,
  3089. NULL
  3090. );
  3091. }
  3092. else
  3093. {
  3094. V_VT(&vt) = VT_BSTR;
  3095. V_BSTR(&vt) = SysAllocString(c_wszZeroIpAddress);
  3096. if (NULL != V_BSTR(&vt))
  3097. {
  3098. hr = WBEM_S_NO_ERROR;
  3099. }
  3100. else
  3101. {
  3102. hr = E_OUTOFMEMORY;
  3103. }
  3104. }
  3105. }
  3106. if (WBEM_S_NO_ERROR == hr)
  3107. {
  3108. LPWSTR wszMask;
  3109. _ASSERT(VT_BSTR == V_VT(&vt));
  3110. //
  3111. // REG_MULTI_SZ is double-null terminated; need to copy
  3112. // the returned string into a larger buffer to add the
  3113. // nulls.
  3114. //
  3115. // The length computation here is correct; SysStringByteLen
  3116. // gives the number of bytes, not WCHARs. The 2 * sizeof(WCHAR)
  3117. // is for the double NULL at the end. (SysStringByteLen also
  3118. // doesn't include the terminating NULL.)
  3119. //
  3120. ulLength = SysStringByteLen(V_BSTR(&vt)) + 2 * sizeof(WCHAR);
  3121. wszMask =
  3122. reinterpret_cast<LPWSTR>(
  3123. HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulLength)
  3124. );
  3125. if (NULL != wszMask)
  3126. {
  3127. RtlCopyMemory(wszMask, V_BSTR(&vt), ulLength - 2 * sizeof(WCHAR));
  3128. RtlInitUnicodeString(&UnicodeString, c_wszSubnetMask);
  3129. hr = NtSetValueKey(
  3130. hKey,
  3131. &UnicodeString,
  3132. 0,
  3133. REG_MULTI_SZ,
  3134. reinterpret_cast<PVOID>(wszMask),
  3135. ulLength
  3136. );
  3137. if (!fDhcpEnabled)
  3138. {
  3139. ulMask =
  3140. RtlUlongByteSwap(
  3141. IpPszToHostAddr(wszMask)
  3142. );
  3143. }
  3144. HeapFree(GetProcessHeap(), 0, wszMask);
  3145. }
  3146. else
  3147. {
  3148. hr = E_OUTOFMEMORY;
  3149. }
  3150. VariantClear(&vt);
  3151. }
  3152. //
  3153. // Default gateway
  3154. //
  3155. if (SUCCEEDED(hr))
  3156. {
  3157. if (NULL != pwcoSettings)
  3158. {
  3159. hr = pwcoSettings->Get(
  3160. c_wszDefaultGateway,
  3161. 0,
  3162. &vt,
  3163. NULL,
  3164. NULL
  3165. );
  3166. }
  3167. else
  3168. {
  3169. V_VT(&vt) = VT_BSTR;
  3170. V_BSTR(&vt) = SysAllocString(L"");
  3171. if (NULL != V_BSTR(&vt))
  3172. {
  3173. hr = WBEM_S_NO_ERROR;
  3174. }
  3175. else
  3176. {
  3177. hr = E_OUTOFMEMORY;
  3178. }
  3179. }
  3180. }
  3181. if (WBEM_S_NO_ERROR == hr)
  3182. {
  3183. _ASSERT(VT_BSTR == V_VT(&vt));
  3184. //
  3185. // REG_MULTI_SZ is double-null terminated; need to copy
  3186. // the returned string into a larger buffer to add the
  3187. // nulls.
  3188. //
  3189. // The length computation here is correct; SysStringByteLen
  3190. // gives the number of bytes, not WCHARs. The 2 * sizeof(WCHAR)
  3191. // is for the double NULL at the end. (SysStringByteLen also
  3192. // doesn't include the terminating NULL.)
  3193. //
  3194. ulLength = SysStringByteLen(V_BSTR(&vt)) + 2 * sizeof(WCHAR);
  3195. wsz =
  3196. reinterpret_cast<LPWSTR>(
  3197. HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulLength)
  3198. );
  3199. if (NULL != wsz)
  3200. {
  3201. RtlCopyMemory(wsz, V_BSTR(&vt), ulLength - 2 * sizeof(WCHAR));
  3202. RtlInitUnicodeString(&UnicodeString, c_wszDefaultGateway);
  3203. hr = NtSetValueKey(
  3204. hKey,
  3205. &UnicodeString,
  3206. 0,
  3207. REG_MULTI_SZ,
  3208. reinterpret_cast<PVOID>(wsz),
  3209. ulLength
  3210. );
  3211. HeapFree(GetProcessHeap(), 0, wsz);
  3212. }
  3213. else
  3214. {
  3215. hr = E_OUTOFMEMORY;
  3216. }
  3217. VariantClear(&vt);
  3218. }
  3219. //
  3220. // Delete the backup instance
  3221. //
  3222. if (NULL != pwcoSettings)
  3223. {
  3224. DeleteWmiInstance(m_piwsHomenet, pwcoSettings);
  3225. pwcoSettings->Release();
  3226. }
  3227. }
  3228. if (SUCCEEDED(hr))
  3229. {
  3230. GUID *pGuid;
  3231. LPWSTR wszGuid;
  3232. ULONG ulError;
  3233. //
  3234. // Notify the stack that the IP settings have changed
  3235. //
  3236. hr = GetGuidInternal(&pGuid);
  3237. if (S_OK == hr)
  3238. {
  3239. hr = StringFromCLSID(*pGuid, &wszGuid);
  3240. }
  3241. if (S_OK == hr)
  3242. {
  3243. if (fDhcpEnabled)
  3244. {
  3245. ulError = DhcpNotifyConfigChange(
  3246. NULL,
  3247. wszGuid,
  3248. FALSE,
  3249. 0,
  3250. 0,
  3251. 0,
  3252. DhcpEnable
  3253. );
  3254. if (NO_ERROR != ulError)
  3255. {
  3256. hr = HRESULT_FROM_WIN32(ulError);
  3257. }
  3258. }
  3259. else
  3260. {
  3261. UNICODE_STRING BindList;
  3262. UNICODE_STRING LowerComponent;
  3263. IP_PNP_RECONFIG_REQUEST Request;
  3264. UNICODE_STRING UpperComponent;
  3265. if ((ULONG)-1 != ulMask)
  3266. {
  3267. //
  3268. // First delete the old (static) IP address
  3269. //
  3270. DhcpNotifyConfigChange(
  3271. NULL,
  3272. wszGuid,
  3273. TRUE,
  3274. 0,
  3275. 0,
  3276. 0,
  3277. IgnoreFlag
  3278. );
  3279. //
  3280. // Now set the new address
  3281. //
  3282. ulError =
  3283. DhcpNotifyConfigChange(
  3284. NULL,
  3285. wszGuid,
  3286. TRUE,
  3287. 0,
  3288. ulAddress,
  3289. ulMask,
  3290. DhcpDisable
  3291. );
  3292. if (NO_ERROR != ulError)
  3293. {
  3294. hr = HRESULT_FROM_WIN32(ulError);
  3295. }
  3296. }
  3297. else
  3298. {
  3299. hr = E_FAIL;
  3300. }
  3301. if (SUCCEEDED(hr))
  3302. {
  3303. //
  3304. // Instruct the stack to pickup the
  3305. // new default gateway
  3306. //
  3307. RtlInitUnicodeString(&BindList, L"");
  3308. RtlInitUnicodeString(&LowerComponent, L"");
  3309. RtlInitUnicodeString(&UpperComponent, L"Tcpip");
  3310. ZeroMemory(&Request, sizeof(Request));
  3311. Request.version = IP_PNP_RECONFIG_VERSION;
  3312. Request.gatewayListUpdate = TRUE;
  3313. Request.Flags = IP_PNP_FLAG_GATEWAY_LIST_UPDATE;
  3314. NdisHandlePnPEvent(
  3315. NDIS,
  3316. RECONFIGURE,
  3317. &LowerComponent,
  3318. &UpperComponent,
  3319. &BindList,
  3320. &Request,
  3321. sizeof(Request)
  3322. );
  3323. }
  3324. }
  3325. CoTaskMemFree(wszGuid);
  3326. }
  3327. }
  3328. if (NULL != hKey)
  3329. {
  3330. NtClose(hKey);
  3331. }
  3332. return hr;
  3333. }
  3334. HRESULT
  3335. CHNetConn::OpenIpConfigurationRegKey(
  3336. ACCESS_MASK DesiredAccess,
  3337. HANDLE *phKey
  3338. )
  3339. {
  3340. HRESULT hr;
  3341. LPWSTR KeyName;
  3342. ULONG KeyNameLength;
  3343. GUID *pGuid;
  3344. LPWSTR wszGuid;
  3345. hr = GetGuidInternal(&pGuid);
  3346. if (SUCCEEDED(hr))
  3347. {
  3348. hr = StringFromCLSID(*pGuid, &wszGuid);
  3349. }
  3350. if (SUCCEEDED(hr))
  3351. {
  3352. KeyNameLength =
  3353. wcslen(c_wszTcpipParametersKey) + 1 +
  3354. wcslen(c_wszInterfaces) + 1 +
  3355. wcslen(wszGuid) + 2;
  3356. KeyName = new OLECHAR[KeyNameLength];
  3357. if (NULL != KeyName)
  3358. {
  3359. swprintf(
  3360. KeyName,
  3361. L"%ls\\%ls\\%ls",
  3362. c_wszTcpipParametersKey,
  3363. c_wszInterfaces,
  3364. wszGuid
  3365. );
  3366. }
  3367. else
  3368. {
  3369. hr = E_OUTOFMEMORY;
  3370. }
  3371. CoTaskMemFree(wszGuid);
  3372. }
  3373. if (SUCCEEDED(hr))
  3374. {
  3375. hr = OpenRegKey(phKey, DesiredAccess, KeyName);
  3376. delete [] KeyName;
  3377. }
  3378. return hr;
  3379. }
  3380. HRESULT
  3381. CHNetConn::GetGuidInternal(
  3382. GUID **ppGuid
  3383. )
  3384. {
  3385. HRESULT hr = S_OK;
  3386. VARIANT vt;
  3387. _ASSERT(NULL != ppGuid);
  3388. Lock();
  3389. if (NULL == m_pGuid)
  3390. {
  3391. //
  3392. // Our guid hasn't been retrieved yet -- do it now.
  3393. //
  3394. m_pGuid = reinterpret_cast<GUID*>(
  3395. CoTaskMemAlloc(sizeof(GUID))
  3396. );
  3397. if (NULL == m_pGuid)
  3398. {
  3399. hr = E_OUTOFMEMORY;
  3400. }
  3401. else
  3402. {
  3403. IWbemClassObject *pwcoConnection;
  3404. hr = GetConnectionObject(&pwcoConnection);
  3405. if (WBEM_S_NO_ERROR == hr)
  3406. {
  3407. //
  3408. // Get our guid property
  3409. //
  3410. hr = pwcoConnection->Get(
  3411. c_wszGuid,
  3412. 0,
  3413. &vt,
  3414. NULL,
  3415. NULL
  3416. );
  3417. pwcoConnection->Release();
  3418. }
  3419. }
  3420. if (WBEM_S_NO_ERROR == hr)
  3421. {
  3422. _ASSERT(VT_BSTR == V_VT(&vt));
  3423. //
  3424. // Convert the string to a guid.
  3425. //
  3426. hr = CLSIDFromString(V_BSTR(&vt), m_pGuid);
  3427. VariantClear(&vt);
  3428. }
  3429. if (FAILED(hr) && NULL != m_pGuid)
  3430. {
  3431. CoTaskMemFree(m_pGuid);
  3432. m_pGuid = NULL;
  3433. }
  3434. }
  3435. if (S_OK == hr)
  3436. {
  3437. *ppGuid = m_pGuid;
  3438. }
  3439. Unlock();
  3440. return hr;
  3441. }
  3442. HRESULT
  3443. CHNetConn::GetConnectionObject(
  3444. IWbemClassObject **ppwcoConnection
  3445. )
  3446. {
  3447. _ASSERT(NULL != ppwcoConnection);
  3448. return GetWmiObjectFromPath(
  3449. m_piwsHomenet,
  3450. m_bstrConnection,
  3451. ppwcoConnection
  3452. );
  3453. }
  3454. HRESULT
  3455. CHNetConn::GetConnectionPropertiesObject(
  3456. IWbemClassObject **ppwcoProperties
  3457. )
  3458. {
  3459. _ASSERT(NULL != ppwcoProperties);
  3460. return GetWmiObjectFromPath(
  3461. m_piwsHomenet,
  3462. m_bstrProperties,
  3463. ppwcoProperties
  3464. );
  3465. }
  3466. BOOLEAN
  3467. CHNetConn::ProhibitedByPolicy(
  3468. DWORD dwPerm
  3469. )
  3470. {
  3471. HRESULT hr = S_OK;
  3472. BOOLEAN fProhibited = FALSE;
  3473. if (NULL == m_pNetConnUiUtil)
  3474. {
  3475. Lock();
  3476. if (NULL == m_pNetConnUiUtil)
  3477. {
  3478. hr = CoCreateInstance(
  3479. CLSID_NetConnectionUiUtilities,
  3480. NULL,
  3481. CLSCTX_ALL,
  3482. IID_PPV_ARG(INetConnectionUiUtilities, &m_pNetConnUiUtil)
  3483. );
  3484. }
  3485. Unlock();
  3486. }
  3487. if (SUCCEEDED(hr))
  3488. {
  3489. fProhibited = !m_pNetConnUiUtil->UserHasPermission(dwPerm);
  3490. }
  3491. return fProhibited;
  3492. }
  3493. HRESULT
  3494. CHNetConn::UpdateNetman()
  3495. {
  3496. HRESULT hr = S_OK;
  3497. if (NULL == m_pNetConnHNetUtil)
  3498. {
  3499. Lock();
  3500. if (NULL == m_pNetConnHNetUtil)
  3501. {
  3502. hr = CoCreateInstance(
  3503. CLSID_NetConnectionHNetUtil,
  3504. NULL,
  3505. CLSCTX_ALL,
  3506. IID_PPV_ARG(INetConnectionHNetUtil, &m_pNetConnHNetUtil)
  3507. );
  3508. }
  3509. Unlock();
  3510. }
  3511. if (SUCCEEDED(hr))
  3512. {
  3513. hr = m_pNetConnHNetUtil->NotifyUpdate();
  3514. }
  3515. return hr;
  3516. }
  3517. HRESULT
  3518. CHNetConn::CreateIcmpSettingsAssociation(
  3519. BSTR bstrIcmpSettingsPath
  3520. )
  3521. {
  3522. HRESULT hr;
  3523. VARIANT vt;
  3524. IWbemClassObject *pwcoInstance;
  3525. _ASSERT(NULL != bstrIcmpSettingsPath);
  3526. //
  3527. // Spawn a new instance of the association class
  3528. //
  3529. pwcoInstance = NULL;
  3530. hr = SpawnNewInstance(
  3531. m_piwsHomenet,
  3532. c_wszHnetConnectionIcmpSetting,
  3533. &pwcoInstance
  3534. );
  3535. if (WBEM_S_NO_ERROR == hr)
  3536. {
  3537. //
  3538. // Set connection property
  3539. //
  3540. V_VT(&vt) = VT_BSTR;
  3541. V_BSTR(&vt) = m_bstrConnection;
  3542. hr = pwcoInstance->Put(
  3543. c_wszConnection,
  3544. 0,
  3545. &vt,
  3546. NULL
  3547. );
  3548. }
  3549. if (WBEM_S_NO_ERROR == hr)
  3550. {
  3551. //
  3552. // Point the association to the settings block
  3553. //
  3554. V_VT(&vt) = VT_BSTR;
  3555. V_BSTR(&vt) = bstrIcmpSettingsPath;
  3556. hr = pwcoInstance->Put(
  3557. c_wszIcmpSettings,
  3558. 0,
  3559. &vt,
  3560. NULL
  3561. );
  3562. }
  3563. if (WBEM_S_NO_ERROR == hr)
  3564. {
  3565. //
  3566. // Save the object to the store
  3567. //
  3568. hr = m_piwsHomenet->PutInstance(
  3569. pwcoInstance,
  3570. WBEM_FLAG_CREATE_OR_UPDATE,
  3571. NULL,
  3572. NULL
  3573. );
  3574. }
  3575. return hr;
  3576. }
  3577. HRESULT
  3578. CHNetConn::GetRasConnectionName(
  3579. OLECHAR **ppszwConnectionName
  3580. )
  3581. {
  3582. HRESULT hr;
  3583. GUID *pGuid;
  3584. OLECHAR *pszwPath;
  3585. RASENUMENTRYDETAILS *rgEntryDetails;
  3586. DWORD cBytes;
  3587. DWORD cEntries;
  3588. DWORD dwError;
  3589. _ASSERT(NULL != ppszwConnectionName);
  3590. _ASSERT(FALSE == m_fLanConnection);
  3591. hr = GetGuidInternal(&pGuid);
  3592. if (S_OK == hr)
  3593. {
  3594. hr = GetRasPhonebookPath(&pszwPath);
  3595. }
  3596. if (S_OK == hr)
  3597. {
  3598. //
  3599. // Start with a buffer large enough to hold 5 entries.
  3600. //
  3601. cBytes = 5 * sizeof(RASENUMENTRYDETAILS);
  3602. rgEntryDetails =
  3603. reinterpret_cast<RASENUMENTRYDETAILS *>(
  3604. CoTaskMemAlloc(cBytes)
  3605. );
  3606. if (NULL != rgEntryDetails)
  3607. {
  3608. //
  3609. // Try to obtain the entry details
  3610. //
  3611. rgEntryDetails[0].dwSize = sizeof(RASENUMENTRYDETAILS);
  3612. dwError =
  3613. DwEnumEntryDetails(
  3614. pszwPath,
  3615. rgEntryDetails,
  3616. &cBytes,
  3617. &cEntries
  3618. );
  3619. if (ERROR_BUFFER_TOO_SMALL == dwError)
  3620. {
  3621. //
  3622. // Try again with a larger buffer
  3623. //
  3624. CoTaskMemFree(rgEntryDetails);
  3625. rgEntryDetails =
  3626. reinterpret_cast<RASENUMENTRYDETAILS *>(
  3627. CoTaskMemAlloc(cBytes)
  3628. );
  3629. if (NULL != rgEntryDetails)
  3630. {
  3631. rgEntryDetails[0].dwSize = sizeof(RASENUMENTRYDETAILS);
  3632. dwError =
  3633. DwEnumEntryDetails(
  3634. pszwPath,
  3635. rgEntryDetails,
  3636. &cBytes,
  3637. &cEntries
  3638. );
  3639. if (ERROR_SUCCESS != dwError)
  3640. {
  3641. CoTaskMemFree(rgEntryDetails);
  3642. hr = HRESULT_FROM_WIN32(dwError);
  3643. }
  3644. }
  3645. else
  3646. {
  3647. hr = E_OUTOFMEMORY;
  3648. }
  3649. }
  3650. else if (ERROR_SUCCESS != dwError)
  3651. {
  3652. CoTaskMemFree(rgEntryDetails);
  3653. hr = HRESULT_FROM_WIN32(dwError);
  3654. }
  3655. }
  3656. else
  3657. {
  3658. hr = E_OUTOFMEMORY;
  3659. }
  3660. CoTaskMemFree(pszwPath);
  3661. }
  3662. if (S_OK == hr)
  3663. {
  3664. DWORD i;
  3665. //
  3666. // Locate the correct entry in the returned array
  3667. //
  3668. for (i = 0; i < cEntries; i++)
  3669. {
  3670. if (IsEqualGUID(rgEntryDetails[i].guidId, *pGuid))
  3671. {
  3672. //
  3673. // We've located the correct entry. Allocate the
  3674. // output buffer and copy over the name.
  3675. //
  3676. *ppszwConnectionName =
  3677. reinterpret_cast<OLECHAR *>(
  3678. CoTaskMemAlloc(
  3679. sizeof(OLECHAR)
  3680. * (wcslen(rgEntryDetails[i].szEntryName) + 1)
  3681. )
  3682. );
  3683. if (NULL != *ppszwConnectionName)
  3684. {
  3685. wcscpy(
  3686. *ppszwConnectionName,
  3687. rgEntryDetails[i].szEntryName
  3688. );
  3689. }
  3690. else
  3691. {
  3692. hr = E_OUTOFMEMORY;
  3693. }
  3694. break;
  3695. }
  3696. }
  3697. if (i == cEntries)
  3698. {
  3699. //
  3700. // Connection not found
  3701. //
  3702. hr = E_FAIL;
  3703. }
  3704. CoTaskMemFree(rgEntryDetails);
  3705. }
  3706. return hr;
  3707. }
  3708. HRESULT
  3709. CHNetConn::RefreshNetConnectionsUI(
  3710. VOID
  3711. )
  3712. {
  3713. HRESULT hr = S_OK;
  3714. INetConnection *pNetConnection;
  3715. //
  3716. // Make sure the UI refresh object exists
  3717. //
  3718. if (NULL == m_pNetConnRefresh)
  3719. {
  3720. Lock();
  3721. if (NULL == m_pNetConnRefresh)
  3722. {
  3723. hr = CoCreateInstance(
  3724. CLSID_ConnectionManager,
  3725. NULL,
  3726. CLSCTX_SERVER | CLSCTX_NO_CODE_DOWNLOAD,
  3727. IID_PPV_ARG(INetConnectionRefresh, &m_pNetConnRefresh)
  3728. );
  3729. if (SUCCEEDED(hr))
  3730. {
  3731. SetProxyBlanket(m_pNetConnRefresh);
  3732. }
  3733. }
  3734. Unlock();
  3735. }
  3736. if (SUCCEEDED(hr))
  3737. {
  3738. hr = GetINetConnection(&pNetConnection);
  3739. if (SUCCEEDED(hr))
  3740. {
  3741. hr = m_pNetConnRefresh->ConnectionModified(pNetConnection);
  3742. pNetConnection->Release();
  3743. }
  3744. }
  3745. return hr;
  3746. }