Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4553 lines
114 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_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_DISABLE_AAA,
  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_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_DISABLE_AAA,
  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 RRAS is configured.
  885. //
  886. if (ProhibitedByPolicy(NCPERM_PersonalFirewallConfig))
  887. {
  888. hr = HN_E_POLICY;
  889. }
  890. if (IsRrasConfigured())
  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 RRAS is configured.
  1001. //
  1002. if (ProhibitedByPolicy(NCPERM_ShowSharedAccessUi))
  1003. {
  1004. hr = HN_E_POLICY;
  1005. }
  1006. if (IsRrasConfigured())
  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 RRAS is configured.
  1179. //
  1180. if (ProhibitedByPolicy(NCPERM_ShowSharedAccessUi))
  1181. {
  1182. hr = HN_E_POLICY;
  1183. }
  1184. if (IsRrasConfigured())
  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. BOOLEAN fCanBeBoundToBridge = FALSE;
  2371. HRESULT hr = S_OK;
  2372. _ASSERT(NULL != pwcoProperties);
  2373. _ASSERT(NULL != pProperties);
  2374. pProperties->fLanConnection = m_fLanConnection;
  2375. if (IsServiceRunning(c_wszSharedAccess))
  2376. {
  2377. hr = GetBooleanValue(
  2378. pwcoProperties,
  2379. c_wszIsFirewalled,
  2380. &pProperties->fFirewalled
  2381. );
  2382. }
  2383. else
  2384. {
  2385. //
  2386. // If the SharedAccess service is not running (or in the process
  2387. // of starting up) we don't want to report this connection as
  2388. // being firewalled. This is to prevent the confusion that could
  2389. // result if the UI indicates the firewall is active, when in
  2390. // reality it's not there providing protection.
  2391. //
  2392. pProperties->fFirewalled = FALSE;
  2393. }
  2394. if (WBEM_S_NO_ERROR == hr)
  2395. {
  2396. hr = GetBooleanValue(
  2397. pwcoProperties,
  2398. c_wszIsIcsPublic,
  2399. &pProperties->fIcsPublic
  2400. );
  2401. }
  2402. if (WBEM_S_NO_ERROR == hr)
  2403. {
  2404. hr = GetBooleanValue(
  2405. pwcoProperties,
  2406. c_wszIsIcsPrivate,
  2407. &pProperties->fIcsPrivate
  2408. );
  2409. }
  2410. if (WBEM_S_NO_ERROR == hr)
  2411. {
  2412. if( m_fLanConnection )
  2413. {
  2414. //
  2415. // Figure out NetCfg-based properties
  2416. //
  2417. INetCfg *pnetcfg;
  2418. hr = CoCreateInstance(
  2419. CLSID_CNetCfg,
  2420. NULL,
  2421. CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_DISABLE_AAA,
  2422. IID_PPV_ARG(INetCfg, &pnetcfg)
  2423. );
  2424. if (S_OK == hr)
  2425. {
  2426. hr = pnetcfg->Initialize( NULL );
  2427. if( S_OK == hr )
  2428. {
  2429. GUID *pguid;
  2430. INetCfgComponent *pncfgcomp;
  2431. hr = GetGuidInternal(&pguid);
  2432. if(S_OK == hr)
  2433. {
  2434. // Get the NetCfg component that corresponds to us
  2435. hr = FindAdapterByGUID( pnetcfg, pguid, &pncfgcomp );
  2436. if(S_OK == hr)
  2437. {
  2438. LPWSTR pszwId;
  2439. pncfgcomp->GetId( &pszwId );
  2440. if(S_OK == hr)
  2441. {
  2442. pProperties->fBridge = (BOOLEAN)(_wcsicmp(pszwId, c_wszSBridgeMPID) == 0);
  2443. CoTaskMemFree(pszwId);
  2444. if( pProperties->fBridge )
  2445. {
  2446. // This adapter is the bridge. It can't possibly also be a bridge
  2447. // member.
  2448. pProperties->fPartOfBridge = FALSE;
  2449. }
  2450. else
  2451. {
  2452. //
  2453. // This adapter is not the bridge. Check if it's part of a bridge.
  2454. //
  2455. INetCfgComponent *pnetcfgcompBridgeProtocol;
  2456. // Find the bridge protocol component
  2457. hr = pnetcfg->FindComponent( c_wszSBridgeSID, &pnetcfgcompBridgeProtocol );
  2458. if(S_OK == hr)
  2459. {
  2460. INetCfgComponentBindings *pnetcfgProtocolBindings;
  2461. // Get the ComponentBindings interface for the protocol component
  2462. hr = pnetcfgcompBridgeProtocol->QueryInterface(
  2463. IID_PPV_ARG(INetCfgComponentBindings, &pnetcfgProtocolBindings)
  2464. );
  2465. if(S_OK == hr)
  2466. {
  2467. hr = pnetcfgProtocolBindings->IsBoundTo(pncfgcomp);
  2468. if(S_OK == hr)
  2469. {
  2470. // The bridge protocol is bound to this adapter
  2471. pProperties->fPartOfBridge = TRUE;
  2472. }
  2473. else if(S_FALSE == hr)
  2474. {
  2475. // The bridge protocol is not bound to this adapter
  2476. pProperties->fPartOfBridge = FALSE;
  2477. //
  2478. // Also need to check if it's even possible to bind
  2479. // the bridge protocol to this adapter.
  2480. //
  2481. hr = pnetcfgProtocolBindings->IsBindableTo(pncfgcomp);
  2482. fCanBeBoundToBridge = (S_OK == hr);
  2483. // Reset to success
  2484. hr = S_OK;
  2485. }
  2486. // else an error occured
  2487. pnetcfgProtocolBindings->Release();
  2488. }
  2489. pnetcfgcompBridgeProtocol->Release();
  2490. }
  2491. else
  2492. {
  2493. // This adapter can't be bridged if there's no bridge protocol
  2494. // in the system
  2495. pProperties->fPartOfBridge = FALSE;
  2496. // Reset to success
  2497. hr = S_OK;
  2498. }
  2499. }
  2500. }
  2501. pncfgcomp->Release();
  2502. }
  2503. }
  2504. pnetcfg->Uninitialize();
  2505. }
  2506. pnetcfg->Release();
  2507. }
  2508. } // if m_fLanConnection
  2509. else
  2510. {
  2511. // We're not a LAN connection. We can never be a bridge or a bridge member.
  2512. pProperties->fBridge = FALSE;
  2513. pProperties->fPartOfBridge = FALSE;
  2514. }
  2515. }
  2516. if(S_OK == hr)
  2517. {
  2518. //
  2519. // Calculated properties
  2520. //
  2521. pProperties->fCanBeFirewalled =
  2522. !pProperties->fPartOfBridge
  2523. && !pProperties->fBridge
  2524. && !pProperties->fIcsPrivate;
  2525. pProperties->fCanBeIcsPublic =
  2526. !pProperties->fBridge
  2527. && !pProperties->fPartOfBridge
  2528. && !pProperties->fIcsPrivate;
  2529. pProperties->fCanBeIcsPrivate =
  2530. m_fLanConnection
  2531. && !pProperties->fIcsPublic
  2532. && !pProperties->fFirewalled
  2533. && !pProperties->fPartOfBridge;
  2534. pProperties->fCanBeBridged =
  2535. m_fLanConnection
  2536. && fCanBeBoundToBridge
  2537. && !pProperties->fIcsPublic
  2538. && !pProperties->fIcsPrivate
  2539. && !pProperties->fFirewalled
  2540. && !pProperties->fBridge;
  2541. }
  2542. return hr;
  2543. }
  2544. HRESULT
  2545. CHNetConn::SetupConnectionAsPrivateLan()
  2546. {
  2547. HRESULT hr;
  2548. GUID *pGuid;
  2549. ANSI_STRING AnsiString;
  2550. UNICODE_STRING UnicodeString;
  2551. ULONG Error;
  2552. DWORD dwAddress;
  2553. DWORD dwMask;
  2554. ULONG i;
  2555. PMIB_IPADDRTABLE Table;
  2556. ZeroMemory(&UnicodeString, sizeof(UnicodeString));
  2557. ZeroMemory(&AnsiString, sizeof(AnsiString));
  2558. hr = GetGuidInternal(&pGuid);
  2559. if (SUCCEEDED(hr))
  2560. {
  2561. hr = RtlStringFromGUID(*pGuid, &UnicodeString);
  2562. if (SUCCEEDED(hr))
  2563. {
  2564. hr = RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, TRUE);
  2565. }
  2566. }
  2567. if (SUCCEEDED(hr))
  2568. {
  2569. //
  2570. // Obtain the address and mask for the private network
  2571. //
  2572. hr = ReadDhcpScopeSettings(&dwAddress, &dwMask);
  2573. }
  2574. if (SUCCEEDED(hr))
  2575. {
  2576. //
  2577. // Determine whether some LAN adapter other than the private LAN
  2578. // is already using an address in the private network scope.
  2579. // In the process, make sure that the private LAN has only one
  2580. // IP address (otherwise, 'SetAdapterIpAddress' fails.)
  2581. //
  2582. Error =
  2583. AllocateAndGetIpAddrTableFromStack(
  2584. &Table,
  2585. FALSE,
  2586. GetProcessHeap(),
  2587. 0
  2588. );
  2589. if (ERROR_SUCCESS == Error)
  2590. {
  2591. ULONG Index = 0;
  2592. ULONG Count;
  2593. hr = MapGuidStringToAdapterIndex(UnicodeString.Buffer, &Index);
  2594. if (SUCCEEDED(hr))
  2595. {
  2596. for (i = 0, Count = 0; i < Table->dwNumEntries; i++)
  2597. {
  2598. if (Index == Table->table[i].dwIndex)
  2599. {
  2600. ++Count;
  2601. }
  2602. else if ((Table->table[i].dwAddr & dwMask)
  2603. == (dwAddress & dwMask))
  2604. {
  2605. //
  2606. // It appears that some other LAN adapter has an
  2607. // address in the proposed scope.
  2608. //
  2609. // This may happen when multiple netcards go into
  2610. // autonet mode or when the RAS server is handing
  2611. // out autonet addresses.
  2612. //
  2613. // Therefore, if we're using the autonet scope,
  2614. // allow this behavior; otherwise prohibit it.
  2615. //
  2616. if ((dwAddress & dwMask) != 0x0000fea9)
  2617. {
  2618. break;
  2619. }
  2620. }
  2621. }
  2622. if (i < Table->dwNumEntries)
  2623. {
  2624. hr = HRESULT_FROM_WIN32(ERROR_SHARING_ADDRESS_EXISTS);
  2625. }
  2626. else if (Count > 1)
  2627. {
  2628. hr = HRESULT_FROM_WIN32(ERROR_SHARING_MULTIPLE_ADDRESSES);
  2629. }
  2630. }
  2631. HeapFree(GetProcessHeap(), 0, Table);
  2632. }
  2633. else
  2634. {
  2635. hr = HRESULT_FROM_WIN32(Error);
  2636. }
  2637. }
  2638. //
  2639. // Set the predefined static IP address for the private LAN.
  2640. //
  2641. if (SUCCEEDED(hr))
  2642. {
  2643. Error =
  2644. SetAdapterIpAddress(
  2645. AnsiString.Buffer,
  2646. FALSE,
  2647. dwAddress,
  2648. dwMask,
  2649. 0
  2650. );
  2651. if (ERROR_SUCCESS != Error)
  2652. {
  2653. if (Error == ERROR_TOO_MANY_NAMES)
  2654. {
  2655. Error = ERROR_SHARING_MULTIPLE_ADDRESSES;
  2656. }
  2657. else if (Error == ERROR_DUP_NAME)
  2658. {
  2659. Error = ERROR_SHARING_HOST_ADDRESS_CONFLICT;
  2660. }
  2661. else
  2662. {
  2663. //
  2664. // Query the state of the connection.
  2665. // If it is disconnected, convert the error code
  2666. // to something more informative.
  2667. //
  2668. UNICODE_STRING DeviceString;
  2669. NIC_STATISTICS NdisStatistics;
  2670. LPWSTR pwsz;
  2671. //
  2672. // Build a buffer large enough for the device string
  2673. //
  2674. pwsz = new WCHAR[wcslen(c_wszDevice) + wcslen(UnicodeString.Buffer) + 1];
  2675. if (NULL != pwsz)
  2676. {
  2677. swprintf(pwsz, L"%s%s", c_wszDevice, UnicodeString.Buffer);
  2678. RtlInitUnicodeString(&DeviceString, pwsz);
  2679. NdisStatistics.Size = sizeof(NdisStatistics);
  2680. NdisQueryStatistics(&DeviceString, &NdisStatistics);
  2681. delete [] pwsz;
  2682. if (NdisStatistics.DeviceState != DEVICE_STATE_CONNECTED)
  2683. {
  2684. Error = ERROR_SHARING_NO_PRIVATE_LAN;
  2685. }
  2686. else if (NdisStatistics.MediaState == MEDIA_STATE_UNKNOWN)
  2687. {
  2688. Error = ERROR_SHARING_HOST_ADDRESS_CONFLICT;
  2689. }
  2690. else if (NdisStatistics.MediaState == MEDIA_STATE_DISCONNECTED)
  2691. {
  2692. //
  2693. // The adapter is connected but is in a media disconnect
  2694. // state. When this happens the correct IP address will
  2695. // be there when the adapter is reconnected, so ignore
  2696. // the error.
  2697. //
  2698. Error = ERROR_SUCCESS;
  2699. }
  2700. }
  2701. }
  2702. hr = HRESULT_FROM_WIN32(Error);
  2703. }
  2704. }
  2705. //
  2706. // As we zeroed out the string structure above, it's safe to call
  2707. // the free routines, even if we never actually allocated anything.
  2708. //
  2709. RtlFreeUnicodeString(&UnicodeString);
  2710. RtlFreeAnsiString(&AnsiString);
  2711. return hr;
  2712. }
  2713. HRESULT
  2714. CHNetConn::BackupIpConfiguration()
  2715. {
  2716. HRESULT hr = S_OK;
  2717. HANDLE Key;
  2718. IWbemClassObject *pwcoInstance = NULL;
  2719. VARIANT vt;
  2720. PKEY_VALUE_PARTIAL_INFORMATION pInformation;
  2721. //
  2722. // Spawn a new HNet_BackupIpConfiguration instance
  2723. //
  2724. hr = SpawnNewInstance(
  2725. m_piwsHomenet,
  2726. c_wszBackupIpConfiguration,
  2727. &pwcoInstance
  2728. );
  2729. if (SUCCEEDED(hr))
  2730. {
  2731. //
  2732. // Write connection property into instance
  2733. //
  2734. V_VT(&vt) = VT_BSTR;
  2735. V_BSTR(&vt) = m_bstrConnection;
  2736. hr = pwcoInstance->Put(
  2737. c_wszConnection,
  2738. 0,
  2739. &vt,
  2740. NULL
  2741. );
  2742. VariantInit(&vt);
  2743. }
  2744. //
  2745. // Open the registry key that stores the IP configuration
  2746. // for this connection
  2747. //
  2748. if (SUCCEEDED(hr))
  2749. {
  2750. hr = OpenIpConfigurationRegKey(KEY_READ, &Key);
  2751. }
  2752. //
  2753. // Read each part of the configuration, and write it to
  2754. // the settings instance
  2755. //
  2756. if (SUCCEEDED(hr))
  2757. {
  2758. hr = QueryRegValueKey(Key, c_wszIPAddress, &pInformation);
  2759. if (SUCCEEDED(hr))
  2760. {
  2761. _ASSERT(REG_MULTI_SZ == pInformation->Type);
  2762. V_VT(&vt) = VT_BSTR;
  2763. V_BSTR(&vt) = SysAllocStringLen(
  2764. reinterpret_cast<OLECHAR*>(pInformation->Data),
  2765. pInformation->DataLength / sizeof(OLECHAR)
  2766. );
  2767. if (NULL != V_BSTR(&vt))
  2768. {
  2769. hr = pwcoInstance->Put(
  2770. c_wszIPAddress,
  2771. 0,
  2772. &vt,
  2773. NULL
  2774. );
  2775. VariantClear(&vt);
  2776. }
  2777. else
  2778. {
  2779. hr = E_OUTOFMEMORY;
  2780. }
  2781. HeapFree(GetProcessHeap(), 0, pInformation);
  2782. }
  2783. if (SUCCEEDED(hr))
  2784. {
  2785. hr = QueryRegValueKey(Key, c_wszSubnetMask, &pInformation);
  2786. }
  2787. if (SUCCEEDED(hr))
  2788. {
  2789. _ASSERT(REG_MULTI_SZ == pInformation->Type);
  2790. V_VT(&vt) = VT_BSTR;
  2791. V_BSTR(&vt) = SysAllocStringLen(
  2792. reinterpret_cast<OLECHAR*>(pInformation->Data),
  2793. pInformation->DataLength / sizeof(OLECHAR)
  2794. );
  2795. if (NULL != V_BSTR(&vt))
  2796. {
  2797. hr = pwcoInstance->Put(
  2798. c_wszSubnetMask,
  2799. 0,
  2800. &vt,
  2801. NULL
  2802. );
  2803. VariantClear(&vt);
  2804. }
  2805. else
  2806. {
  2807. hr = E_OUTOFMEMORY;
  2808. }
  2809. HeapFree(GetProcessHeap(), 0, pInformation);
  2810. }
  2811. if (SUCCEEDED(hr))
  2812. {
  2813. hr = QueryRegValueKey(Key, c_wszDefaultGateway, &pInformation);
  2814. }
  2815. if (SUCCEEDED(hr))
  2816. {
  2817. _ASSERT(REG_MULTI_SZ == pInformation->Type);
  2818. V_VT(&vt) = VT_BSTR;
  2819. V_BSTR(&vt) = SysAllocStringLen(
  2820. reinterpret_cast<OLECHAR*>(pInformation->Data),
  2821. pInformation->DataLength / sizeof(OLECHAR)
  2822. );
  2823. if (NULL != V_BSTR(&vt))
  2824. {
  2825. hr = pwcoInstance->Put(
  2826. c_wszDefaultGateway,
  2827. 0,
  2828. &vt,
  2829. NULL
  2830. );
  2831. VariantClear(&vt);
  2832. }
  2833. else
  2834. {
  2835. hr = E_OUTOFMEMORY;
  2836. }
  2837. HeapFree(GetProcessHeap(), 0, pInformation);
  2838. }
  2839. if (SUCCEEDED(hr))
  2840. {
  2841. hr = QueryRegValueKey(Key, c_wszEnableDHCP, &pInformation);
  2842. }
  2843. if (SUCCEEDED(hr))
  2844. {
  2845. _ASSERT(REG_DWORD == pInformation->Type);
  2846. _ASSERT(sizeof(DWORD) == pInformation->DataLength);
  2847. V_VT(&vt) = VT_I4;
  2848. V_I4(&vt) = *(reinterpret_cast<DWORD*>(pInformation->Data));
  2849. hr = pwcoInstance->Put(
  2850. c_wszEnableDHCP,
  2851. 0,
  2852. &vt,
  2853. NULL
  2854. );
  2855. HeapFree(GetProcessHeap(), 0, pInformation);
  2856. }
  2857. NtClose(Key);
  2858. };
  2859. //
  2860. // Write the settings to the store
  2861. //
  2862. if (SUCCEEDED(hr))
  2863. {
  2864. hr = m_piwsHomenet->PutInstance(
  2865. pwcoInstance,
  2866. WBEM_FLAG_CREATE_OR_UPDATE,
  2867. NULL,
  2868. NULL
  2869. );
  2870. }
  2871. if (NULL != pwcoInstance)
  2872. {
  2873. pwcoInstance->Release();
  2874. }
  2875. return hr;
  2876. }
  2877. HRESULT
  2878. CHNetConn::RestoreIpConfiguration()
  2879. {
  2880. HRESULT hr;
  2881. IEnumWbemClassObject *pwcoEnum;
  2882. IWbemClassObject *pwcoSettings;
  2883. BSTR bstr;
  2884. LPWSTR wszAddress;
  2885. VARIANT vt;
  2886. LPWSTR wsz;
  2887. UNICODE_STRING UnicodeString;
  2888. HANDLE hKey = NULL;
  2889. BOOLEAN fDhcpEnabled;
  2890. ULONG ulLength;
  2891. ULONG ulAddress;
  2892. ULONG ulMask;
  2893. //
  2894. // Open the registry key
  2895. //
  2896. hr = OpenIpConfigurationRegKey(KEY_ALL_ACCESS, &hKey);
  2897. //
  2898. // Get the backup configuration block for this connection
  2899. //
  2900. if (S_OK == hr)
  2901. {
  2902. hr = BuildEscapedQuotedEqualsString(
  2903. &wsz,
  2904. c_wszConnection,
  2905. m_bstrConnection
  2906. );
  2907. }
  2908. if (S_OK == hr)
  2909. {
  2910. hr = BuildSelectQueryBstr(
  2911. &bstr,
  2912. c_wszStar,
  2913. c_wszBackupIpConfiguration,
  2914. wsz
  2915. );
  2916. delete [] wsz;
  2917. }
  2918. if (S_OK == hr)
  2919. {
  2920. pwcoEnum = NULL;
  2921. hr = m_piwsHomenet->ExecQuery(
  2922. m_bstrWQL,
  2923. bstr,
  2924. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  2925. NULL,
  2926. &pwcoEnum
  2927. );
  2928. SysFreeString(bstr);
  2929. }
  2930. if (S_OK == hr)
  2931. {
  2932. ULONG ulCount;
  2933. pwcoSettings = NULL;
  2934. hr = pwcoEnum->Next(WBEM_INFINITE, 1, &pwcoSettings, &ulCount);
  2935. //
  2936. // Even if we're not able to obtain backup settings we continue
  2937. // to operate. By setting pwcoSettings to NULL we indidcate that
  2938. // the default DHCP configuration should be used. (A failure for
  2939. // ExecQuery indicates a much more serious problem, so we don't
  2940. // try to continue if that occurs.)
  2941. //
  2942. if (FAILED(hr) || 1 != ulCount)
  2943. {
  2944. pwcoSettings = NULL;
  2945. }
  2946. hr = S_OK;
  2947. ValidateFinishedWCOEnum(m_piwsHomenet, pwcoEnum);
  2948. pwcoEnum->Release();
  2949. }
  2950. //
  2951. // Write backup values to registry -- start by getting the
  2952. // old IP address
  2953. //
  2954. if (S_OK == hr)
  2955. {
  2956. if (NULL != pwcoSettings)
  2957. {
  2958. hr = pwcoSettings->Get(
  2959. c_wszIPAddress,
  2960. 0,
  2961. &vt,
  2962. NULL,
  2963. NULL
  2964. );
  2965. if (WBEM_S_NO_ERROR == hr)
  2966. {
  2967. ULONG ulDhcpAddress;
  2968. ULONG ulDhcpMask;
  2969. _ASSERT(VT_BSTR == V_VT(&vt));
  2970. //
  2971. // Check to see if the stored backup address is the
  2972. // same as our default DHCP scope -- if so, use
  2973. // the default DHCP configuration.
  2974. //
  2975. hr = ReadDhcpScopeSettings(&ulDhcpAddress, &ulDhcpMask);
  2976. if (S_OK == hr)
  2977. {
  2978. ulAddress =
  2979. RtlUlongByteSwap(
  2980. IpPszToHostAddr(V_BSTR(&vt))
  2981. );
  2982. if (ulAddress == ulDhcpAddress
  2983. || static_cast<DWORD>(-1) == ulAddress)
  2984. {
  2985. //
  2986. // Use the default configuration.
  2987. //
  2988. DeleteWmiInstance(m_piwsHomenet, pwcoSettings);
  2989. pwcoSettings->Release();
  2990. pwcoSettings = NULL;
  2991. VariantClear(&vt);
  2992. V_VT(&vt) = VT_BSTR;
  2993. V_BSTR(&vt) = SysAllocString(c_wszZeroIpAddress);
  2994. if (NULL == V_BSTR(&vt))
  2995. {
  2996. hr = E_OUTOFMEMORY;
  2997. }
  2998. }
  2999. }
  3000. }
  3001. }
  3002. else
  3003. {
  3004. V_VT(&vt) = VT_BSTR;
  3005. V_BSTR(&vt) = SysAllocString(c_wszZeroIpAddress);
  3006. if (NULL == V_BSTR(&vt))
  3007. {
  3008. hr = E_OUTOFMEMORY;
  3009. }
  3010. }
  3011. if (WBEM_S_NO_ERROR == hr)
  3012. {
  3013. //
  3014. // REG_MULTI_SZ is double-null terminated; need to copy
  3015. // the returned string into a larger buffer to add the
  3016. // nulls.
  3017. //
  3018. // The length computation here is correct; SysStringByteLen
  3019. // gives the number of bytes, not WCHARs. The 2 * sizeof(WCHAR)
  3020. // is for the double NULL at the end. (SysStringByteLen also
  3021. // doesn't include the terminating NULL.)
  3022. //
  3023. ulLength = SysStringByteLen(V_BSTR(&vt)) + 2 * sizeof(WCHAR);
  3024. wszAddress =
  3025. reinterpret_cast<LPWSTR>(
  3026. HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulLength)
  3027. );
  3028. if (NULL != wszAddress)
  3029. {
  3030. RtlCopyMemory(wszAddress, V_BSTR(&vt), ulLength - 2 * sizeof(WCHAR));
  3031. RtlInitUnicodeString(&UnicodeString, c_wszIPAddress);
  3032. hr = NtSetValueKey(
  3033. hKey,
  3034. &UnicodeString,
  3035. 0,
  3036. REG_MULTI_SZ,
  3037. reinterpret_cast<PVOID>(wszAddress),
  3038. ulLength
  3039. );
  3040. HeapFree(GetProcessHeap(), 0, wszAddress);
  3041. }
  3042. else
  3043. {
  3044. hr = E_OUTOFMEMORY;
  3045. }
  3046. VariantClear(&vt);
  3047. }
  3048. //
  3049. // DHCP settings
  3050. //
  3051. if (SUCCEEDED(hr))
  3052. {
  3053. if (NULL != pwcoSettings)
  3054. {
  3055. hr = pwcoSettings->Get(
  3056. c_wszEnableDHCP,
  3057. 0,
  3058. &vt,
  3059. NULL,
  3060. NULL
  3061. );
  3062. }
  3063. else
  3064. {
  3065. V_VT(&vt) = VT_I4;
  3066. V_I4(&vt) = 1;
  3067. hr = WBEM_S_NO_ERROR;
  3068. }
  3069. }
  3070. //
  3071. // Subnet mask
  3072. //
  3073. if (WBEM_S_NO_ERROR == hr)
  3074. {
  3075. _ASSERT(VT_I4 == V_VT(&vt));
  3076. RtlInitUnicodeString(&UnicodeString, c_wszEnableDHCP);
  3077. hr = NtSetValueKey(
  3078. hKey,
  3079. &UnicodeString,
  3080. 0,
  3081. REG_DWORD,
  3082. reinterpret_cast<PVOID>(&(V_I4(&vt))),
  3083. sizeof(V_I4(&vt))
  3084. );
  3085. fDhcpEnabled = 1 == V_I4(&vt);
  3086. VariantClear(&vt);
  3087. }
  3088. if (SUCCEEDED(hr))
  3089. {
  3090. if (NULL != pwcoSettings)
  3091. {
  3092. hr = pwcoSettings->Get(
  3093. c_wszSubnetMask,
  3094. 0,
  3095. &vt,
  3096. NULL,
  3097. NULL
  3098. );
  3099. }
  3100. else
  3101. {
  3102. V_VT(&vt) = VT_BSTR;
  3103. V_BSTR(&vt) = SysAllocString(c_wszZeroIpAddress);
  3104. if (NULL != V_BSTR(&vt))
  3105. {
  3106. hr = WBEM_S_NO_ERROR;
  3107. }
  3108. else
  3109. {
  3110. hr = E_OUTOFMEMORY;
  3111. }
  3112. }
  3113. }
  3114. if (WBEM_S_NO_ERROR == hr)
  3115. {
  3116. LPWSTR wszMask;
  3117. _ASSERT(VT_BSTR == V_VT(&vt));
  3118. //
  3119. // REG_MULTI_SZ is double-null terminated; need to copy
  3120. // the returned string into a larger buffer to add the
  3121. // nulls.
  3122. //
  3123. // The length computation here is correct; SysStringByteLen
  3124. // gives the number of bytes, not WCHARs. The 2 * sizeof(WCHAR)
  3125. // is for the double NULL at the end. (SysStringByteLen also
  3126. // doesn't include the terminating NULL.)
  3127. //
  3128. ulLength = SysStringByteLen(V_BSTR(&vt)) + 2 * sizeof(WCHAR);
  3129. wszMask =
  3130. reinterpret_cast<LPWSTR>(
  3131. HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulLength)
  3132. );
  3133. if (NULL != wszMask)
  3134. {
  3135. RtlCopyMemory(wszMask, V_BSTR(&vt), ulLength - 2 * sizeof(WCHAR));
  3136. RtlInitUnicodeString(&UnicodeString, c_wszSubnetMask);
  3137. hr = NtSetValueKey(
  3138. hKey,
  3139. &UnicodeString,
  3140. 0,
  3141. REG_MULTI_SZ,
  3142. reinterpret_cast<PVOID>(wszMask),
  3143. ulLength
  3144. );
  3145. if (!fDhcpEnabled)
  3146. {
  3147. ulMask =
  3148. RtlUlongByteSwap(
  3149. IpPszToHostAddr(wszMask)
  3150. );
  3151. }
  3152. HeapFree(GetProcessHeap(), 0, wszMask);
  3153. }
  3154. else
  3155. {
  3156. hr = E_OUTOFMEMORY;
  3157. }
  3158. VariantClear(&vt);
  3159. }
  3160. //
  3161. // Default gateway
  3162. //
  3163. if (SUCCEEDED(hr))
  3164. {
  3165. if (NULL != pwcoSettings)
  3166. {
  3167. hr = pwcoSettings->Get(
  3168. c_wszDefaultGateway,
  3169. 0,
  3170. &vt,
  3171. NULL,
  3172. NULL
  3173. );
  3174. }
  3175. else
  3176. {
  3177. V_VT(&vt) = VT_BSTR;
  3178. V_BSTR(&vt) = SysAllocString(L"");
  3179. if (NULL != V_BSTR(&vt))
  3180. {
  3181. hr = WBEM_S_NO_ERROR;
  3182. }
  3183. else
  3184. {
  3185. hr = E_OUTOFMEMORY;
  3186. }
  3187. }
  3188. }
  3189. if (WBEM_S_NO_ERROR == hr)
  3190. {
  3191. _ASSERT(VT_BSTR == V_VT(&vt));
  3192. //
  3193. // REG_MULTI_SZ is double-null terminated; need to copy
  3194. // the returned string into a larger buffer to add the
  3195. // nulls.
  3196. //
  3197. // The length computation here is correct; SysStringByteLen
  3198. // gives the number of bytes, not WCHARs. The 2 * sizeof(WCHAR)
  3199. // is for the double NULL at the end. (SysStringByteLen also
  3200. // doesn't include the terminating NULL.)
  3201. //
  3202. ulLength = SysStringByteLen(V_BSTR(&vt)) + 2 * sizeof(WCHAR);
  3203. wsz =
  3204. reinterpret_cast<LPWSTR>(
  3205. HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulLength)
  3206. );
  3207. if (NULL != wsz)
  3208. {
  3209. RtlCopyMemory(wsz, V_BSTR(&vt), ulLength - 2 * sizeof(WCHAR));
  3210. RtlInitUnicodeString(&UnicodeString, c_wszDefaultGateway);
  3211. hr = NtSetValueKey(
  3212. hKey,
  3213. &UnicodeString,
  3214. 0,
  3215. REG_MULTI_SZ,
  3216. reinterpret_cast<PVOID>(wsz),
  3217. ulLength
  3218. );
  3219. HeapFree(GetProcessHeap(), 0, wsz);
  3220. }
  3221. else
  3222. {
  3223. hr = E_OUTOFMEMORY;
  3224. }
  3225. VariantClear(&vt);
  3226. }
  3227. //
  3228. // Delete the backup instance
  3229. //
  3230. if (NULL != pwcoSettings)
  3231. {
  3232. DeleteWmiInstance(m_piwsHomenet, pwcoSettings);
  3233. pwcoSettings->Release();
  3234. }
  3235. }
  3236. if (SUCCEEDED(hr))
  3237. {
  3238. GUID *pGuid;
  3239. LPWSTR wszGuid;
  3240. ULONG ulError;
  3241. //
  3242. // Notify the stack that the IP settings have changed
  3243. //
  3244. hr = GetGuidInternal(&pGuid);
  3245. if (S_OK == hr)
  3246. {
  3247. hr = StringFromCLSID(*pGuid, &wszGuid);
  3248. }
  3249. if (S_OK == hr)
  3250. {
  3251. if (fDhcpEnabled)
  3252. {
  3253. ulError = DhcpNotifyConfigChange(
  3254. NULL,
  3255. wszGuid,
  3256. FALSE,
  3257. 0,
  3258. 0,
  3259. 0,
  3260. DhcpEnable
  3261. );
  3262. if (NO_ERROR != ulError)
  3263. {
  3264. hr = HRESULT_FROM_WIN32(ulError);
  3265. }
  3266. }
  3267. else
  3268. {
  3269. UNICODE_STRING BindList;
  3270. UNICODE_STRING LowerComponent;
  3271. IP_PNP_RECONFIG_REQUEST Request;
  3272. UNICODE_STRING UpperComponent;
  3273. if ((ULONG)-1 != ulMask)
  3274. {
  3275. //
  3276. // First delete the old (static) IP address
  3277. //
  3278. DhcpNotifyConfigChange(
  3279. NULL,
  3280. wszGuid,
  3281. TRUE,
  3282. 0,
  3283. 0,
  3284. 0,
  3285. IgnoreFlag
  3286. );
  3287. //
  3288. // Now set the new address
  3289. //
  3290. ulError =
  3291. DhcpNotifyConfigChange(
  3292. NULL,
  3293. wszGuid,
  3294. TRUE,
  3295. 0,
  3296. ulAddress,
  3297. ulMask,
  3298. DhcpDisable
  3299. );
  3300. if (NO_ERROR != ulError)
  3301. {
  3302. hr = HRESULT_FROM_WIN32(ulError);
  3303. }
  3304. }
  3305. else
  3306. {
  3307. hr = E_FAIL;
  3308. }
  3309. if (SUCCEEDED(hr))
  3310. {
  3311. //
  3312. // Instruct the stack to pickup the
  3313. // new default gateway
  3314. //
  3315. RtlInitUnicodeString(&BindList, L"");
  3316. RtlInitUnicodeString(&LowerComponent, L"");
  3317. RtlInitUnicodeString(&UpperComponent, L"Tcpip");
  3318. ZeroMemory(&Request, sizeof(Request));
  3319. Request.version = IP_PNP_RECONFIG_VERSION;
  3320. Request.gatewayListUpdate = TRUE;
  3321. Request.Flags = IP_PNP_FLAG_GATEWAY_LIST_UPDATE;
  3322. NdisHandlePnPEvent(
  3323. NDIS,
  3324. RECONFIGURE,
  3325. &LowerComponent,
  3326. &UpperComponent,
  3327. &BindList,
  3328. &Request,
  3329. sizeof(Request)
  3330. );
  3331. }
  3332. }
  3333. CoTaskMemFree(wszGuid);
  3334. }
  3335. }
  3336. if (NULL != hKey)
  3337. {
  3338. NtClose(hKey);
  3339. }
  3340. return hr;
  3341. }
  3342. HRESULT
  3343. CHNetConn::OpenIpConfigurationRegKey(
  3344. ACCESS_MASK DesiredAccess,
  3345. HANDLE *phKey
  3346. )
  3347. {
  3348. HRESULT hr;
  3349. LPWSTR KeyName;
  3350. ULONG KeyNameLength;
  3351. GUID *pGuid;
  3352. LPWSTR wszGuid;
  3353. hr = GetGuidInternal(&pGuid);
  3354. if (SUCCEEDED(hr))
  3355. {
  3356. hr = StringFromCLSID(*pGuid, &wszGuid);
  3357. }
  3358. if (SUCCEEDED(hr))
  3359. {
  3360. KeyNameLength =
  3361. wcslen(c_wszTcpipParametersKey) + 1 +
  3362. wcslen(c_wszInterfaces) + 1 +
  3363. wcslen(wszGuid) + 2;
  3364. KeyName = new OLECHAR[KeyNameLength];
  3365. if (NULL != KeyName)
  3366. {
  3367. swprintf(
  3368. KeyName,
  3369. L"%ls\\%ls\\%ls",
  3370. c_wszTcpipParametersKey,
  3371. c_wszInterfaces,
  3372. wszGuid
  3373. );
  3374. }
  3375. else
  3376. {
  3377. hr = E_OUTOFMEMORY;
  3378. }
  3379. CoTaskMemFree(wszGuid);
  3380. }
  3381. if (SUCCEEDED(hr))
  3382. {
  3383. hr = OpenRegKey(phKey, DesiredAccess, KeyName);
  3384. delete [] KeyName;
  3385. }
  3386. return hr;
  3387. }
  3388. HRESULT
  3389. CHNetConn::GetGuidInternal(
  3390. GUID **ppGuid
  3391. )
  3392. {
  3393. HRESULT hr = S_OK;
  3394. VARIANT vt;
  3395. _ASSERT(NULL != ppGuid);
  3396. Lock();
  3397. if (NULL == m_pGuid)
  3398. {
  3399. //
  3400. // Our guid hasn't been retrieved yet -- do it now.
  3401. //
  3402. m_pGuid = reinterpret_cast<GUID*>(
  3403. CoTaskMemAlloc(sizeof(GUID))
  3404. );
  3405. if (NULL == m_pGuid)
  3406. {
  3407. hr = E_OUTOFMEMORY;
  3408. }
  3409. else
  3410. {
  3411. IWbemClassObject *pwcoConnection;
  3412. hr = GetConnectionObject(&pwcoConnection);
  3413. if (WBEM_S_NO_ERROR == hr)
  3414. {
  3415. //
  3416. // Get our guid property
  3417. //
  3418. hr = pwcoConnection->Get(
  3419. c_wszGuid,
  3420. 0,
  3421. &vt,
  3422. NULL,
  3423. NULL
  3424. );
  3425. pwcoConnection->Release();
  3426. }
  3427. }
  3428. if (WBEM_S_NO_ERROR == hr)
  3429. {
  3430. _ASSERT(VT_BSTR == V_VT(&vt));
  3431. //
  3432. // Convert the string to a guid.
  3433. //
  3434. hr = CLSIDFromString(V_BSTR(&vt), m_pGuid);
  3435. VariantClear(&vt);
  3436. }
  3437. if (FAILED(hr) && NULL != m_pGuid)
  3438. {
  3439. CoTaskMemFree(m_pGuid);
  3440. m_pGuid = NULL;
  3441. }
  3442. }
  3443. if (S_OK == hr)
  3444. {
  3445. *ppGuid = m_pGuid;
  3446. }
  3447. Unlock();
  3448. return hr;
  3449. }
  3450. HRESULT
  3451. CHNetConn::GetConnectionObject(
  3452. IWbemClassObject **ppwcoConnection
  3453. )
  3454. {
  3455. _ASSERT(NULL != ppwcoConnection);
  3456. return GetWmiObjectFromPath(
  3457. m_piwsHomenet,
  3458. m_bstrConnection,
  3459. ppwcoConnection
  3460. );
  3461. }
  3462. HRESULT
  3463. CHNetConn::GetConnectionPropertiesObject(
  3464. IWbemClassObject **ppwcoProperties
  3465. )
  3466. {
  3467. _ASSERT(NULL != ppwcoProperties);
  3468. return GetWmiObjectFromPath(
  3469. m_piwsHomenet,
  3470. m_bstrProperties,
  3471. ppwcoProperties
  3472. );
  3473. }
  3474. BOOLEAN
  3475. CHNetConn::ProhibitedByPolicy(
  3476. DWORD dwPerm
  3477. )
  3478. {
  3479. HRESULT hr = S_OK;
  3480. BOOLEAN fProhibited = FALSE;
  3481. if (NULL == m_pNetConnUiUtil)
  3482. {
  3483. Lock();
  3484. if (NULL == m_pNetConnUiUtil)
  3485. {
  3486. hr = CoCreateInstance(
  3487. CLSID_NetConnectionUiUtilities,
  3488. NULL,
  3489. CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_DISABLE_AAA,
  3490. IID_PPV_ARG(INetConnectionUiUtilities, &m_pNetConnUiUtil)
  3491. );
  3492. }
  3493. Unlock();
  3494. }
  3495. if (SUCCEEDED(hr))
  3496. {
  3497. fProhibited = !m_pNetConnUiUtil->UserHasPermission(dwPerm);
  3498. }
  3499. return fProhibited;
  3500. }
  3501. HRESULT
  3502. CHNetConn::UpdateNetman()
  3503. {
  3504. HRESULT hr = S_OK;
  3505. if (NULL == m_pNetConnHNetUtil)
  3506. {
  3507. Lock();
  3508. if (NULL == m_pNetConnHNetUtil)
  3509. {
  3510. hr = CoCreateInstance(
  3511. CLSID_NetConnectionHNetUtil,
  3512. NULL,
  3513. CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_DISABLE_AAA,
  3514. IID_PPV_ARG(INetConnectionHNetUtil, &m_pNetConnHNetUtil)
  3515. );
  3516. }
  3517. Unlock();
  3518. }
  3519. if (SUCCEEDED(hr))
  3520. {
  3521. hr = m_pNetConnHNetUtil->NotifyUpdate();
  3522. }
  3523. return hr;
  3524. }
  3525. HRESULT
  3526. CHNetConn::CreateIcmpSettingsAssociation(
  3527. BSTR bstrIcmpSettingsPath
  3528. )
  3529. {
  3530. HRESULT hr;
  3531. VARIANT vt;
  3532. IWbemClassObject *pwcoInstance;
  3533. _ASSERT(NULL != bstrIcmpSettingsPath);
  3534. //
  3535. // Spawn a new instance of the association class
  3536. //
  3537. pwcoInstance = NULL;
  3538. hr = SpawnNewInstance(
  3539. m_piwsHomenet,
  3540. c_wszHnetConnectionIcmpSetting,
  3541. &pwcoInstance
  3542. );
  3543. if (WBEM_S_NO_ERROR == hr)
  3544. {
  3545. //
  3546. // Set connection property
  3547. //
  3548. V_VT(&vt) = VT_BSTR;
  3549. V_BSTR(&vt) = m_bstrConnection;
  3550. hr = pwcoInstance->Put(
  3551. c_wszConnection,
  3552. 0,
  3553. &vt,
  3554. NULL
  3555. );
  3556. }
  3557. if (WBEM_S_NO_ERROR == hr)
  3558. {
  3559. //
  3560. // Point the association to the settings block
  3561. //
  3562. V_VT(&vt) = VT_BSTR;
  3563. V_BSTR(&vt) = bstrIcmpSettingsPath;
  3564. hr = pwcoInstance->Put(
  3565. c_wszIcmpSettings,
  3566. 0,
  3567. &vt,
  3568. NULL
  3569. );
  3570. }
  3571. if (WBEM_S_NO_ERROR == hr)
  3572. {
  3573. //
  3574. // Save the object to the store
  3575. //
  3576. hr = m_piwsHomenet->PutInstance(
  3577. pwcoInstance,
  3578. WBEM_FLAG_CREATE_OR_UPDATE,
  3579. NULL,
  3580. NULL
  3581. );
  3582. }
  3583. return hr;
  3584. }
  3585. HRESULT
  3586. CHNetConn::GetRasConnectionName(
  3587. OLECHAR **ppszwConnectionName
  3588. )
  3589. {
  3590. HRESULT hr;
  3591. GUID *pGuid;
  3592. OLECHAR *pszwPath;
  3593. RASENUMENTRYDETAILS *rgEntryDetails;
  3594. DWORD cBytes;
  3595. DWORD cEntries;
  3596. DWORD dwError;
  3597. _ASSERT(NULL != ppszwConnectionName);
  3598. _ASSERT(FALSE == m_fLanConnection);
  3599. hr = GetGuidInternal(&pGuid);
  3600. if (S_OK == hr)
  3601. {
  3602. hr = GetRasPhonebookPath(&pszwPath);
  3603. }
  3604. if (S_OK == hr)
  3605. {
  3606. //
  3607. // Start with a buffer large enough to hold 5 entries.
  3608. //
  3609. cBytes = 5 * sizeof(RASENUMENTRYDETAILS);
  3610. rgEntryDetails =
  3611. reinterpret_cast<RASENUMENTRYDETAILS *>(
  3612. CoTaskMemAlloc(cBytes)
  3613. );
  3614. if (NULL != rgEntryDetails)
  3615. {
  3616. //
  3617. // Try to obtain the entry details
  3618. //
  3619. rgEntryDetails[0].dwSize = sizeof(RASENUMENTRYDETAILS);
  3620. dwError =
  3621. DwEnumEntryDetails(
  3622. pszwPath,
  3623. rgEntryDetails,
  3624. &cBytes,
  3625. &cEntries
  3626. );
  3627. if (ERROR_BUFFER_TOO_SMALL == dwError)
  3628. {
  3629. //
  3630. // Try again with a larger buffer
  3631. //
  3632. CoTaskMemFree(rgEntryDetails);
  3633. rgEntryDetails =
  3634. reinterpret_cast<RASENUMENTRYDETAILS *>(
  3635. CoTaskMemAlloc(cBytes)
  3636. );
  3637. if (NULL != rgEntryDetails)
  3638. {
  3639. rgEntryDetails[0].dwSize = sizeof(RASENUMENTRYDETAILS);
  3640. dwError =
  3641. DwEnumEntryDetails(
  3642. pszwPath,
  3643. rgEntryDetails,
  3644. &cBytes,
  3645. &cEntries
  3646. );
  3647. if (ERROR_SUCCESS != dwError)
  3648. {
  3649. CoTaskMemFree(rgEntryDetails);
  3650. hr = HRESULT_FROM_WIN32(dwError);
  3651. }
  3652. }
  3653. else
  3654. {
  3655. hr = E_OUTOFMEMORY;
  3656. }
  3657. }
  3658. else if (ERROR_SUCCESS != dwError)
  3659. {
  3660. CoTaskMemFree(rgEntryDetails);
  3661. hr = HRESULT_FROM_WIN32(dwError);
  3662. }
  3663. }
  3664. else
  3665. {
  3666. hr = E_OUTOFMEMORY;
  3667. }
  3668. CoTaskMemFree(pszwPath);
  3669. }
  3670. if (S_OK == hr)
  3671. {
  3672. DWORD i;
  3673. //
  3674. // Locate the correct entry in the returned array
  3675. //
  3676. for (i = 0; i < cEntries; i++)
  3677. {
  3678. if (IsEqualGUID(rgEntryDetails[i].guidId, *pGuid))
  3679. {
  3680. //
  3681. // We've located the correct entry. Allocate the
  3682. // output buffer and copy over the name.
  3683. //
  3684. *ppszwConnectionName =
  3685. reinterpret_cast<OLECHAR *>(
  3686. CoTaskMemAlloc(
  3687. sizeof(OLECHAR)
  3688. * (wcslen(rgEntryDetails[i].szEntryName) + 1)
  3689. )
  3690. );
  3691. if (NULL != *ppszwConnectionName)
  3692. {
  3693. wcscpy(
  3694. *ppszwConnectionName,
  3695. rgEntryDetails[i].szEntryName
  3696. );
  3697. }
  3698. else
  3699. {
  3700. hr = E_OUTOFMEMORY;
  3701. }
  3702. break;
  3703. }
  3704. }
  3705. if (i == cEntries)
  3706. {
  3707. //
  3708. // Connection not found
  3709. //
  3710. hr = E_FAIL;
  3711. }
  3712. CoTaskMemFree(rgEntryDetails);
  3713. }
  3714. return hr;
  3715. }
  3716. HRESULT
  3717. CHNetConn::RefreshNetConnectionsUI(
  3718. VOID
  3719. )
  3720. {
  3721. HRESULT hr = S_OK;
  3722. INetConnection *pNetConnection;
  3723. //
  3724. // Make sure the UI refresh object exists
  3725. //
  3726. if (NULL == m_pNetConnRefresh)
  3727. {
  3728. Lock();
  3729. if (NULL == m_pNetConnRefresh)
  3730. {
  3731. hr = CoCreateInstance(
  3732. CLSID_ConnectionManager,
  3733. NULL,
  3734. CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_DISABLE_AAA | CLSCTX_NO_CODE_DOWNLOAD,
  3735. IID_PPV_ARG(INetConnectionRefresh, &m_pNetConnRefresh)
  3736. );
  3737. if (SUCCEEDED(hr))
  3738. {
  3739. SetProxyBlanket(m_pNetConnRefresh);
  3740. }
  3741. }
  3742. Unlock();
  3743. }
  3744. if (SUCCEEDED(hr))
  3745. {
  3746. hr = GetINetConnection(&pNetConnection);
  3747. if (SUCCEEDED(hr))
  3748. {
  3749. hr = m_pNetConnRefresh->ConnectionModified(pNetConnection);
  3750. pNetConnection->Release();
  3751. }
  3752. }
  3753. return hr;
  3754. }