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.

946 lines
25 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #include "nccom.h"
  4. #include "ncnetcon.h"
  5. #include "ncreg.h"
  6. #include "saconob.h"
  7. static const CLSID CLSID_SharedAccessConnectionUi =
  8. {0x7007ACD5,0x3202,0x11D1,{0xAA,0xD2,0x00,0x80,0x5F,0xC1,0x27,0x0E}};
  9. static const WCHAR c_szConnName[] = L"Name";
  10. static const WCHAR c_szShowIcon[] = L"ShowIcon";
  11. static const WCHAR c_szSharedAccessClientKeyPath[] = L"System\\CurrentControlSet\\Control\\Network\\SharedAccessConnection";
  12. #define UPNP_ACTION_HRESULT(lError) (UPNP_E_ACTION_SPECIFIC_BASE + (lError - FAULT_ACTION_SPECIFIC_BASE))
  13. CSharedAccessConnection::CSharedAccessConnection()
  14. {
  15. m_pSharedAccessBeacon = NULL;
  16. m_pWANConnectionService = NULL;
  17. }
  18. HRESULT CSharedAccessConnection::FinalConstruct()
  19. {
  20. HRESULT hr = S_OK;
  21. ISharedAccessBeaconFinder* pBeaconFinder;
  22. hr = HrCreateInstance(CLSID_SharedAccessConnectionManager, CLSCTX_SERVER, &pBeaconFinder);
  23. if(SUCCEEDED(hr))
  24. {
  25. hr = pBeaconFinder->GetSharedAccessBeacon(NULL, &m_pSharedAccessBeacon);
  26. if(SUCCEEDED(hr))
  27. {
  28. NETCON_MEDIATYPE MediaType;
  29. hr = m_pSharedAccessBeacon->GetMediaType(&MediaType);
  30. if(SUCCEEDED(hr))
  31. {
  32. hr = m_pSharedAccessBeacon->GetService(NCM_SHAREDACCESSHOST_LAN == MediaType ? SAHOST_SERVICE_WANIPCONNECTION : SAHOST_SERVICE_WANPPPCONNECTION, &m_pWANConnectionService);
  33. }
  34. }
  35. pBeaconFinder->Release();
  36. }
  37. return hr;
  38. }
  39. HRESULT CSharedAccessConnection::FinalRelease()
  40. {
  41. HRESULT hr = S_OK;
  42. if(NULL != m_pSharedAccessBeacon)
  43. {
  44. m_pSharedAccessBeacon->Release();
  45. }
  46. if(NULL != m_pWANConnectionService)
  47. {
  48. m_pWANConnectionService->Release();
  49. }
  50. return hr;
  51. }
  52. //+---------------------------------------------------------------------------
  53. //
  54. // Member: CSharedAccessConnection::GetConnectionName
  55. //
  56. // Purpose: Initializes the connection object for the first time.
  57. //
  58. // Arguments:
  59. // (none)
  60. //
  61. // Returns: S_OK if success, Win32 or OLE error code otherwise
  62. //
  63. // Author: kenwic 8 Aug 2000
  64. //
  65. // Notes: This function is only called when the object is created for
  66. // the very first time and has no identity.
  67. //
  68. HRESULT CSharedAccessConnection::GetConnectionName(LPWSTR* pName)
  69. {
  70. HRESULT hr = S_OK;
  71. HKEY hKey;
  72. // first get the user assigned name
  73. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szSharedAccessClientKeyPath, KEY_READ, &hKey);
  74. if(SUCCEEDED(hr))
  75. {
  76. tstring strName;
  77. hr = HrRegQueryString(hKey, c_szConnName, &strName);
  78. if (SUCCEEDED(hr))
  79. {
  80. hr = HrCoTaskMemAllocAndDupSz (strName.c_str(), pName, NETCON_MAX_NAME_LEN);
  81. }
  82. RegCloseKey(hKey);
  83. }
  84. // if that doesn't exist, construct the name
  85. if(FAILED(hr))
  86. {
  87. IUPnPService* pOSInfoService;
  88. hr = m_pSharedAccessBeacon->GetService(SAHOST_SERVICE_OSINFO, &pOSInfoService);
  89. if(SUCCEEDED(hr))
  90. {
  91. BSTR MachineName;
  92. hr = GetStringStateVariable(pOSInfoService, L"OSMachineName", &MachineName);
  93. if(SUCCEEDED(hr))
  94. {
  95. BSTR SharedAdapterName;
  96. hr = GetStringStateVariable(m_pWANConnectionService, L"X_Name", &SharedAdapterName);
  97. if(SUCCEEDED(hr))
  98. {
  99. LPWSTR szNameString;
  100. LPCWSTR szTemplateString = SzLoadIds(IDS_SHAREDACCESS_CONN_NAME);
  101. Assert(NULL != szTemplateString);
  102. LPOLESTR pszParams[] = {SharedAdapterName, MachineName};
  103. if(0 != FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, szTemplateString, 0, 0, reinterpret_cast<LPWSTR>(&szNameString), 0, reinterpret_cast<va_list *>(pszParams)))
  104. {
  105. HrCoTaskMemAllocAndDupSz (szNameString, pName, NETCON_MAX_NAME_LEN);
  106. LocalFree(szNameString);
  107. }
  108. else
  109. {
  110. hr = HRESULT_FROM_WIN32(GetLastError());
  111. }
  112. SysFreeString(SharedAdapterName);
  113. }
  114. SysFreeString(MachineName);
  115. }
  116. pOSInfoService->Release();
  117. }
  118. }
  119. // if that fails, use the default
  120. if(FAILED(hr))
  121. {
  122. hr = HrCoTaskMemAllocAndDupSz (SzLoadIds(IDS_SHAREDACCESS_DEFAULT_CONN_NAME), pName, NETCON_MAX_NAME_LEN);
  123. }
  124. TraceError("CSharedAccessConnection::HrInitialize", hr);
  125. return hr;
  126. }
  127. //+---------------------------------------------------------------------------
  128. //
  129. // Member: CSharedAccessConnection::GetStatus
  130. //
  131. // Purpose: Returns the status of this ICS connection
  132. //
  133. // Arguments:
  134. // pStatus [out] Returns status value
  135. //
  136. // Returns: S_OK if success, OLE or Win32 error code otherwise
  137. //
  138. // Author: kenwic 8 Aug 2000
  139. //
  140. // Notes:
  141. //
  142. HRESULT CSharedAccessConnection::GetStatus(NETCON_STATUS *pStatus)
  143. {
  144. HRESULT hr = S_OK;
  145. if (!pStatus)
  146. {
  147. hr = E_POINTER;
  148. }
  149. else
  150. {
  151. BSTR ConnectionStatus;
  152. hr = GetStringStateVariable(m_pWANConnectionService, L"ConnectionStatus", &ConnectionStatus);
  153. if(SUCCEEDED(hr))
  154. {
  155. if(0 == lstrcmp(ConnectionStatus, L"Connected"))
  156. {
  157. *pStatus = NCS_CONNECTED;
  158. }
  159. else if(0 == lstrcmp(ConnectionStatus, L"Disconnected"))
  160. {
  161. *pStatus = NCS_DISCONNECTED;
  162. }
  163. else if(0 == lstrcmp(ConnectionStatus, L"Unconfigured"))
  164. {
  165. *pStatus = NCS_HARDWARE_DISABLED; // REVIEW: better state?
  166. }
  167. else if(0 == lstrcmp(ConnectionStatus, L"Connecting"))
  168. {
  169. *pStatus = NCS_CONNECTING;
  170. }
  171. else if(0 == lstrcmp(ConnectionStatus, L"Authenticating"))
  172. {
  173. *pStatus = NCS_CONNECTING;
  174. }
  175. else if(0 == lstrcmp(ConnectionStatus, L"PendingDisconnect"))
  176. {
  177. *pStatus = NCS_DISCONNECTING;
  178. }
  179. else if(0 == lstrcmp(ConnectionStatus, L"Disconnecting"))
  180. {
  181. *pStatus = NCS_DISCONNECTING;
  182. }
  183. else
  184. {
  185. *pStatus = NCS_HARDWARE_DISABLED;
  186. }
  187. SysFreeString(ConnectionStatus);
  188. }
  189. }
  190. TraceError("CSharedAccessConnection::GetStatus", hr);
  191. return hr;
  192. }
  193. //+---------------------------------------------------------------------------
  194. //
  195. // Member: CSharedAccessConnection::GetCharacteristics
  196. //
  197. // Purpose: Returns the characteristics of this connection type
  198. //
  199. // Arguments:
  200. // pdwFlags [out] Returns characteristics flags
  201. //
  202. // Returns: S_OK if successful, OLE or Win32 error code otherwise
  203. //
  204. // Author: kenwic 8 Aug 2000
  205. //
  206. // Notes:
  207. //
  208. HRESULT CSharedAccessConnection::GetCharacteristics(DWORD* pdwFlags)
  209. {
  210. Assert (pdwFlags);
  211. // TODO when get have a place to save the name, allow rename
  212. HRESULT hr = S_OK;
  213. *pdwFlags = NCCF_ALL_USERS | NCCF_ALLOW_RENAME; // REVIEW always ok, group policy?
  214. HKEY hKey;
  215. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szSharedAccessClientKeyPath, KEY_QUERY_VALUE, &hKey);
  216. if(SUCCEEDED(hr))
  217. {
  218. DWORD dwShowIcon = 0;
  219. DWORD dwSize = sizeof(dwShowIcon);
  220. DWORD dwType;
  221. hr = HrRegQueryValueEx(hKey, c_szShowIcon, &dwType, reinterpret_cast<LPBYTE>(&dwShowIcon), &dwSize);
  222. if(SUCCEEDED(hr) && REG_DWORD == dwType)
  223. {
  224. if(0 != dwShowIcon)
  225. {
  226. *pdwFlags |= NCCF_SHOW_ICON;
  227. }
  228. }
  229. RegCloseKey(hKey);
  230. }
  231. hr = S_OK; // it's ok if the key doesn't exist
  232. TraceError("CSharedAccessConnection::GetCharacteristics", hr);
  233. return hr;
  234. }
  235. //+---------------------------------------------------------------------------
  236. //
  237. // Member: CSharedAccessConnection::Connect
  238. //
  239. // Purpose: Connects the remote ICS host
  240. //
  241. // Arguments:
  242. // (none)
  243. //
  244. // Returns: S_OK if success, OLE or Win32 error code otherwise
  245. //
  246. // Author: kenwic 8 Aug 2000
  247. //
  248. HRESULT CSharedAccessConnection::Connect()
  249. {
  250. HRESULT hr = S_OK;
  251. VARIANT OutArgs;
  252. hr = InvokeVoidAction(m_pWANConnectionService, L"RequestConnection", &OutArgs);
  253. if(UPNP_ACTION_HRESULT(800) == hr)
  254. {
  255. hr = E_ACCESSDENIED;
  256. VariantClear(&OutArgs);
  257. }
  258. TraceError("CSharedAccessConnection::Connect", hr);
  259. return hr;
  260. }
  261. //+---------------------------------------------------------------------------
  262. //
  263. // Member: CSharedAccessConnection::Disconnect
  264. //
  265. // Purpose: Disconnects the remote ICS host
  266. //
  267. // Arguments:
  268. // (none)
  269. //
  270. // Returns: S_OK if success, OLE or Win32 error code otherwise
  271. //
  272. // Author: kenwic 8 Aug 2000
  273. //
  274. HRESULT CSharedAccessConnection::Disconnect()
  275. {
  276. HRESULT hr = S_OK;
  277. VARIANT OutArgs;
  278. hr = InvokeVoidAction(m_pWANConnectionService, L"ForceTermination", &OutArgs);
  279. if(UPNP_ACTION_HRESULT(800) == hr)
  280. {
  281. hr = E_ACCESSDENIED;
  282. VariantClear(&OutArgs);
  283. }
  284. TraceError("CSharedAccessConnection::Disconnect", hr);
  285. return hr;
  286. }
  287. //+---------------------------------------------------------------------------
  288. //
  289. // Member: CSharedAccessConnection::Delete
  290. //
  291. // Purpose: Delete the remote ICS connection. This not allowed.
  292. //
  293. // Arguments:
  294. // (none)
  295. //
  296. // Returns: E_FAIL;
  297. //
  298. // Author: kenwic 8 Aug 2000
  299. //
  300. // Notes: This function is not expected to ever be called.
  301. //
  302. HRESULT CSharedAccessConnection::Delete()
  303. {
  304. return E_FAIL; // can't delete the beacon
  305. }
  306. //+---------------------------------------------------------------------------
  307. //
  308. // Member: CSharedAccessConnection::Duplicate
  309. //
  310. // Purpose: Duplicates the remote ICS connection. This not allowed.
  311. //
  312. // Arguments:
  313. // (none)
  314. //
  315. // Returns: E_UNEXPECTED;
  316. //
  317. // Author: kenwic 8 Aug 2000
  318. //
  319. // Notes: This function is not expected to ever be called.
  320. //
  321. STDMETHODIMP CSharedAccessConnection::Duplicate (
  322. PCWSTR pszDuplicateName,
  323. INetConnection** ppCon)
  324. {
  325. return E_NOTIMPL;
  326. }
  327. //+---------------------------------------------------------------------------
  328. //
  329. // Member: CSharedAccessConnection::GetProperties
  330. //
  331. // Purpose: Get all of the properties associated with the connection.
  332. // Returning all of them at once saves us RPCs vs. returning
  333. // each one individually.
  334. //
  335. // Arguments:
  336. // ppProps [out] Returned block of properties.
  337. //
  338. // Returns: S_OK or an error.
  339. //
  340. // Author: kenwic 8 Aug 2000
  341. //
  342. // Notes:
  343. //
  344. STDMETHODIMP CSharedAccessConnection::GetProperties (
  345. NETCON_PROPERTIES** ppProps)
  346. {
  347. HRESULT hr = S_OK;
  348. // Validate parameters.
  349. //
  350. if (!ppProps)
  351. {
  352. hr = E_POINTER;
  353. }
  354. else
  355. {
  356. // Initialize the output parameter.
  357. //
  358. *ppProps = NULL;
  359. NETCON_PROPERTIES* pProps;
  360. hr = HrCoTaskMemAlloc (sizeof (NETCON_PROPERTIES), reinterpret_cast<void**>(&pProps));
  361. if (SUCCEEDED(hr))
  362. {
  363. HRESULT hrT;
  364. ZeroMemory (pProps, sizeof (NETCON_PROPERTIES));
  365. // guidId
  366. //
  367. pProps->guidId = CLSID_SharedAccessConnection; // there is only ever one beacon icon, so we'll just use our class id.
  368. // we can't use all zeroes because the add connection wizard does that
  369. // pszwName
  370. //
  371. hrT = GetConnectionName(&pProps->pszwName);
  372. if (FAILED(hrT))
  373. {
  374. hr = hrT;
  375. }
  376. // pszwDeviceName
  377. //
  378. hrT = HrCoTaskMemAllocAndDupSz (pProps->pszwName, &pProps->pszwDeviceName, NETCON_MAX_NAME_LEN); // TODO the spec says the same as pszwName here, is that right
  379. if (FAILED(hrT))
  380. {
  381. hr = hrT;
  382. }
  383. // Status
  384. //
  385. hrT = GetStatus (&pProps->Status);
  386. if (FAILED(hrT))
  387. {
  388. hr = hrT;
  389. }
  390. if(NULL != m_pSharedAccessBeacon)
  391. {
  392. hr = m_pSharedAccessBeacon->GetMediaType(&pProps->MediaType);
  393. }
  394. else
  395. {
  396. hr = E_UNEXPECTED;
  397. }
  398. hrT = GetCharacteristics (&pProps->dwCharacter);
  399. if (FAILED(hrT))
  400. {
  401. hr = hrT;
  402. }
  403. // clsidThisObject
  404. //
  405. pProps->clsidThisObject = CLSID_SharedAccessConnection;
  406. // clsidUiObject
  407. //
  408. pProps->clsidUiObject = CLSID_SharedAccessConnectionUi;
  409. // Assign the output parameter or cleanup if we had any failures.
  410. //
  411. if (SUCCEEDED(hr))
  412. {
  413. *ppProps = pProps;
  414. }
  415. else
  416. {
  417. Assert (NULL == *ppProps);
  418. FreeNetconProperties (pProps);
  419. }
  420. }
  421. }
  422. TraceError ("CLanConnection::GetProperties", hr);
  423. return hr;
  424. }
  425. //+---------------------------------------------------------------------------
  426. //
  427. // Member: CSharedAccessConnection::GetUiObjectClassId
  428. //
  429. // Purpose: Returns the CLSID of the object that handles UI for this
  430. // connection type
  431. //
  432. // Arguments:
  433. // pclsid [out] Returns CLSID of UI object
  434. //
  435. // Returns: S_OK if success, OLE error code otherwise
  436. //
  437. // Author: kenwic 8 Aug 2000
  438. //
  439. // Notes:
  440. //
  441. STDMETHODIMP CSharedAccessConnection::GetUiObjectClassId(CLSID *pclsid)
  442. {
  443. HRESULT hr = S_OK;
  444. // Validate parameters.
  445. //
  446. if (!pclsid)
  447. {
  448. hr = E_POINTER;
  449. }
  450. else
  451. {
  452. *pclsid = CLSID_SharedAccessConnectionUi;
  453. }
  454. TraceError("CLanConnection::GetUiObjectClassId", hr);
  455. return hr;
  456. }
  457. //+---------------------------------------------------------------------------
  458. //
  459. // Member: CSharedAccessConnection::Rename
  460. //
  461. // Purpose: Changes the name of the connection
  462. //
  463. // Arguments:
  464. // pszName [in] New connection name (must be valid)
  465. //
  466. // Returns: S_OK if success, OLE error code otherwise
  467. //
  468. // Author: kenwic 8 Aug 2000
  469. //
  470. // Notes:
  471. //
  472. STDMETHODIMP CSharedAccessConnection::Rename(PCWSTR pszName)
  473. {
  474. HRESULT hr = S_OK;
  475. if (!pszName)
  476. {
  477. hr = E_POINTER;
  478. }
  479. else if (!FIsValidConnectionName(pszName))
  480. {
  481. // Bad connection name
  482. hr = E_INVALIDARG;
  483. }
  484. else
  485. {
  486. HKEY hKey;
  487. hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, c_szSharedAccessClientKeyPath, NULL, KEY_SET_VALUE, NULL, &hKey, NULL);
  488. if(SUCCEEDED(hr))
  489. {
  490. hr = HrRegSetSz(hKey, c_szConnName, pszName);
  491. if (S_OK == hr)
  492. {
  493. INetConnectionRefresh* pNetConnectionRefresh;
  494. hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
  495. if(SUCCEEDED(hr))
  496. {
  497. pNetConnectionRefresh->ConnectionRenamed(this);
  498. pNetConnectionRefresh->Release();
  499. }
  500. }
  501. }
  502. }
  503. TraceError("CLanConnection::Rename", hr);
  504. return hr;
  505. }
  506. //+---------------------------------------------------------------------------
  507. // IPersistNetConnection
  508. //
  509. //+---------------------------------------------------------------------------
  510. //
  511. // Member: CSharedAccessConnection::GetClassID
  512. //
  513. // Purpose: Returns the CLSID of connection objects
  514. //
  515. // Arguments:
  516. // pclsid [out] Returns CLSID to caller
  517. //
  518. // Returns: S_OK if success, OLE error otherwise
  519. //
  520. // Author: kenwic 8 Aug 2000
  521. //
  522. // Notes:
  523. //
  524. STDMETHODIMP CSharedAccessConnection::GetClassID(CLSID* pclsid)
  525. {
  526. HRESULT hr = S_OK;
  527. // Validate parameters.
  528. //
  529. if (!pclsid)
  530. {
  531. hr = E_POINTER;
  532. }
  533. else
  534. {
  535. *pclsid = CLSID_SharedAccessConnection; // we just use our guid since there is only ever one saconob
  536. }
  537. TraceError("CSharedAccessConnection::GetClassID", hr);
  538. return hr;
  539. }
  540. //+---------------------------------------------------------------------------
  541. //
  542. // Member: CSharedAccessConnection::GetSizeMax
  543. //
  544. // Purpose: Returns the maximum size of the persistence data
  545. //
  546. // Arguments:
  547. // pcbSize [out] Returns size
  548. //
  549. // Returns: S_OK if success, OLE error otherwise
  550. //
  551. // Author: kenwic 8 Aug 2000
  552. //
  553. // Notes:
  554. //
  555. STDMETHODIMP CSharedAccessConnection::GetSizeMax(ULONG *pcbSize)
  556. {
  557. HRESULT hr = S_OK;
  558. // Validate parameters.
  559. //
  560. if (!pcbSize)
  561. {
  562. hr = E_POINTER;
  563. }
  564. else
  565. {
  566. *pcbSize = sizeof(GUID);
  567. }
  568. TraceError("CLanConnection::GetSizeMax", hr);
  569. return hr;
  570. }
  571. //+---------------------------------------------------------------------------
  572. //
  573. // Member: CSharedAccessConnection::Load
  574. //
  575. // Purpose: Allows the connection object to initialize (restore) itself
  576. // from previously persisted data
  577. //
  578. // Arguments:
  579. // pbBuf [in] Private data to use for restoring
  580. // cbSize [in] Size of data
  581. //
  582. // Returns: S_OK if success, OLE error otherwise
  583. //
  584. // Author: kenwic 8 Aug 2000
  585. //
  586. // Notes:
  587. //
  588. STDMETHODIMP CSharedAccessConnection::Load(const BYTE *pbBuf, ULONG cbSize)
  589. {
  590. HRESULT hr = E_INVALIDARG;
  591. // Validate parameters.
  592. //
  593. if (!pbBuf)
  594. {
  595. hr = E_POINTER;
  596. }
  597. else if (cbSize != sizeof(GUID))
  598. {
  599. hr = E_INVALIDARG;
  600. }
  601. else
  602. {
  603. hr = S_OK; // we don't need this guid, but we have to implemenet IPersistNetConnection
  604. }
  605. TraceError("CLanConnection::Load", hr);
  606. return hr;
  607. }
  608. //+---------------------------------------------------------------------------
  609. //
  610. // Member: CSharedAccessConnection::Save
  611. //
  612. // Purpose: Provides the caller with data to use in restoring this object
  613. // at a later time.
  614. //
  615. // Arguments:
  616. // pbBuf [out] Returns data to use for restoring
  617. // cbSize [in] Size of data buffer
  618. //
  619. // Returns: S_OK if success, OLE error otherwise
  620. //
  621. // Author: kenwic 8 Aug 2000
  622. //
  623. // Notes:
  624. //
  625. STDMETHODIMP CSharedAccessConnection::Save(BYTE *pbBuf, ULONG cbSize)
  626. {
  627. HRESULT hr;
  628. // Validate parameters.
  629. //
  630. if (!pbBuf)
  631. {
  632. hr = E_POINTER;
  633. }
  634. else
  635. {
  636. CopyMemory(pbBuf, &CLSID_SharedAccessConnection, cbSize); // REVIEW can we eliminate this?
  637. }
  638. TraceError("CLanConnection::Save", hr);
  639. return hr;
  640. }
  641. //+---------------------------------------------------------------------------
  642. //
  643. // Member: CSharedAccessConnection::GetInfo
  644. //
  645. // Purpose: Returns information about this connection
  646. //
  647. // Arguments:
  648. // dwMask [in] Flags that control which fields to return. Use
  649. // SACIF_ALL to get all fields.
  650. // pLanConInfo [out] Structure that holds returned information
  651. //
  652. // Returns: S_OK if success, OLE error code otherwise
  653. //
  654. // Author: kenwic 6 Sep 2000
  655. //
  656. // Notes: Caller should delete the szwConnName value.
  657. //
  658. STDMETHODIMP CSharedAccessConnection::GetInfo(DWORD dwMask, SHAREDACCESSCON_INFO* pConInfo)
  659. {
  660. HRESULT hr = S_OK;
  661. if (!pConInfo)
  662. {
  663. hr = E_POINTER;
  664. }
  665. else
  666. {
  667. ZeroMemory(pConInfo, sizeof(SHAREDACCESSCON_INFO));
  668. if (dwMask & SACIF_ICON)
  669. {
  670. if (SUCCEEDED(hr))
  671. {
  672. DWORD dwValue;
  673. // OK if value not there. Default to FALSE always.
  674. //
  675. HKEY hKey;
  676. hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szSharedAccessClientKeyPath, KEY_QUERY_VALUE, &hKey);
  677. if(SUCCEEDED(hr))
  678. {
  679. if (S_OK == HrRegQueryDword(hKey, c_szShowIcon, &dwValue))
  680. {
  681. pConInfo->fShowIcon = !!(dwValue);
  682. }
  683. RegCloseKey(hKey);
  684. }
  685. }
  686. }
  687. }
  688. // Mask S_FALSE if it slipped thru.
  689. if (S_FALSE == hr)
  690. {
  691. hr = S_OK;
  692. }
  693. TraceError("CSharedAccessConnection::GetInfo", hr);
  694. return hr;
  695. }
  696. //+---------------------------------------------------------------------------
  697. //
  698. // Member: CSharedAccessConnection::SetInfo
  699. //
  700. // Purpose: Sets information about this connection.
  701. //
  702. // Arguments:
  703. // dwMask [in] Flags that control which fields to set
  704. // pConInfo [in] Structure containing information to set
  705. //
  706. // Returns: S_OK if success, OLE or Win32 error code otherwise
  707. //
  708. // Author: kenwic 6 Sep 2000
  709. //
  710. STDMETHODIMP CSharedAccessConnection::SetInfo(DWORD dwMask,
  711. const SHAREDACCESSCON_INFO* pConInfo)
  712. {
  713. HRESULT hr = S_OK;
  714. if (!pConInfo)
  715. {
  716. hr = E_POINTER;
  717. }
  718. else
  719. {
  720. if (dwMask & SACIF_ICON)
  721. {
  722. if (SUCCEEDED(hr))
  723. {
  724. // Set ShowIcon value
  725. HKEY hKey;
  726. hr = HrRegCreateKeyEx(HKEY_LOCAL_MACHINE, c_szSharedAccessClientKeyPath, NULL, KEY_SET_VALUE, NULL, &hKey, NULL);
  727. if(SUCCEEDED(hr))
  728. {
  729. hr = HrRegSetDword(hKey, c_szShowIcon, pConInfo->fShowIcon);
  730. RegCloseKey(hKey);
  731. }
  732. }
  733. }
  734. if (SUCCEEDED(hr))
  735. {
  736. INetConnectionRefresh* pNetConnectionRefresh;
  737. hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
  738. if(SUCCEEDED(hr))
  739. {
  740. pNetConnectionRefresh->ConnectionModified(this);
  741. pNetConnectionRefresh->Release();
  742. }
  743. }
  744. }
  745. TraceError("CSharedAccessConnection::SetInfo", hr);
  746. return hr;
  747. }
  748. HRESULT CSharedAccessConnection::GetLocalAdapterGUID(GUID* pGuid)
  749. {
  750. return m_pSharedAccessBeacon->GetLocalAdapterGUID(pGuid);
  751. }
  752. HRESULT CSharedAccessConnection::GetService(SAHOST_SERVICES ulService, IUPnPService** ppService)
  753. {
  754. return m_pSharedAccessBeacon->GetService(ulService, ppService);
  755. }
  756. HRESULT CSharedAccessConnection::GetStringStateVariable(IUPnPService* pService, LPWSTR pszVariableName, BSTR* pString)
  757. {
  758. HRESULT hr = S_OK;
  759. VARIANT Variant;
  760. VariantInit(&Variant);
  761. BSTR VariableName;
  762. VariableName = SysAllocString(pszVariableName);
  763. if(NULL != VariableName)
  764. {
  765. hr = pService->QueryStateVariable(VariableName, &Variant);
  766. if(SUCCEEDED(hr))
  767. {
  768. if(V_VT(&Variant) == VT_BSTR)
  769. {
  770. *pString = V_BSTR(&Variant);
  771. }
  772. else
  773. {
  774. hr = E_UNEXPECTED;
  775. }
  776. }
  777. if(FAILED(hr))
  778. {
  779. VariantClear(&Variant);
  780. }
  781. SysFreeString(VariableName);
  782. }
  783. else
  784. {
  785. hr = E_OUTOFMEMORY;
  786. }
  787. TraceHr (ttidError, FAL, hr, FALSE, "CSharedAccessConnection::GetStringStateVariable");
  788. return hr;
  789. }
  790. HRESULT InvokeVoidAction(IUPnPService * pService, LPTSTR pszCommand, VARIANT* pOutParams)
  791. {
  792. HRESULT hr;
  793. BSTR bstrActionName;
  794. bstrActionName = SysAllocString(pszCommand);
  795. if (NULL != bstrActionName)
  796. {
  797. SAFEARRAYBOUND rgsaBound[1];
  798. SAFEARRAY * psa = NULL;
  799. rgsaBound[0].lLbound = 0;
  800. rgsaBound[0].cElements = 0;
  801. psa = SafeArrayCreate(VT_VARIANT, 1, rgsaBound);
  802. if (psa)
  803. {
  804. LONG lStatus;
  805. VARIANT varInArgs;
  806. VARIANT varReturnVal;
  807. VariantInit(&varInArgs);
  808. VariantInit(pOutParams);
  809. VariantInit(&varReturnVal);
  810. varInArgs.vt = VT_VARIANT | VT_ARRAY;
  811. V_ARRAY(&varInArgs) = psa;
  812. hr = pService->InvokeAction(bstrActionName,
  813. varInArgs,
  814. pOutParams,
  815. &varReturnVal);
  816. if(SUCCEEDED(hr))
  817. {
  818. VariantClear(&varReturnVal);
  819. }
  820. SafeArrayDestroy(psa);
  821. }
  822. else
  823. {
  824. hr = E_OUTOFMEMORY;
  825. }
  826. SysFreeString(bstrActionName);
  827. }
  828. else
  829. {
  830. hr = E_OUTOFMEMORY;
  831. }
  832. return hr;
  833. }