Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

721 lines
25 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #include "cmsaclbk.h"
  4. #include "cmsabcon.h"
  5. #include "saconob.h"
  6. #include "ncnetcon.h"
  7. static const LPWSTR g_szWANIPConnectionService = L"urn:schemas-upnp-org:service:WANIPConnection:1";
  8. static const LPWSTR g_szWANPPPConnectionService = L"urn:schemas-upnp-org:service:WANPPPConnection:1";
  9. CSharedAccessDeviceFinderCallback::CSharedAccessDeviceFinderCallback()
  10. {
  11. m_pSharedAccessBeacon = NULL;
  12. }
  13. HRESULT CSharedAccessDeviceFinderCallback::FinalRelease()
  14. {
  15. if(NULL != m_pSharedAccessBeacon)
  16. {
  17. m_pSharedAccessBeacon->Release();
  18. }
  19. return S_OK;
  20. }
  21. HRESULT CSharedAccessDeviceFinderCallback::GetSharedAccessBeacon(BSTR DeviceId, ISharedAccessBeacon** ppSharedAccessBeacon)
  22. {
  23. HRESULT hr = S_OK;
  24. *ppSharedAccessBeacon = NULL;
  25. Lock();
  26. if(NULL != m_pSharedAccessBeacon)
  27. {
  28. *ppSharedAccessBeacon = m_pSharedAccessBeacon;
  29. m_pSharedAccessBeacon->AddRef();
  30. }
  31. else
  32. {
  33. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  34. }
  35. Unlock();
  36. return hr;
  37. }
  38. HRESULT CSharedAccessDeviceFinderCallback::DeviceAdded(LONG lFindData, IUPnPDevice* pDevice)
  39. {
  40. return E_UNEXPECTED;
  41. }
  42. #include <wininet.h>
  43. #include <iphlpapi.h>
  44. #include <winsock2.h>
  45. #include <ws2tcpip.h>
  46. void GetGUIDFromString (char * szAdapterName, GUID * pGuid)
  47. {
  48. USES_CONVERSION;
  49. CLSIDFromString (A2OLE(szAdapterName), (CLSID*)pGuid);
  50. }
  51. static BOOL IsIPAddress (LPWSTR szAddress)
  52. {
  53. USES_CONVERSION;
  54. return INADDR_NONE != inet_addr (W2A (szAddress));
  55. }
  56. static BOOL IsIPAddressDefaultGateway (IP_ADDRESS_STRING * pIPAddress, GUID* pguidInterface)
  57. { // return TRUE iff the IP address matches the specified NIC's GW.
  58. BOOL b = FALSE;
  59. // run through adapters
  60. ULONG ulSize = 0;
  61. DWORD dwErr = GetAdaptersInfo ((PIP_ADAPTER_INFO)&ulSize, &ulSize);
  62. if (dwErr == ERROR_BUFFER_OVERFLOW) {
  63. BYTE * pb = new BYTE[ulSize];
  64. if (pb) {
  65. PIP_ADAPTER_INFO pai = (PIP_ADAPTER_INFO)pb;
  66. dwErr = GetAdaptersInfo (pai, &ulSize);
  67. if (dwErr == NO_ERROR) {
  68. do {
  69. GUID guid = {0};
  70. GetGUIDFromString (pai->AdapterName, &guid);
  71. if (IsEqualGUID(*pguidInterface, guid)) {
  72. // found our adapter.
  73. // let's see if the default gateways match our IP address
  74. IP_ADDR_STRING* pDG = &pai->GatewayList;
  75. if (pDG) {
  76. do {
  77. if (!strcmp (pDG->IpAddress.String, pIPAddress->String)) {
  78. b = TRUE;
  79. break;
  80. }
  81. } while (pDG = pDG->Next);
  82. }
  83. break;
  84. }
  85. } while (pai = pai->Next);
  86. }
  87. delete[] pb;
  88. }
  89. }
  90. return b;
  91. }
  92. static HRESULT CheckDeviceDocumentAgainstDefaultGateway (IUPnPDevice* pDevice, GUID* pguidInterface)
  93. {
  94. // bug 561076
  95. // [Ravi Rao] On XP, you can use IUPnPDeviceDocumentAccess to get the
  96. // documentURL from the IGD device object. Crack this URL to get the
  97. // IP address or name. Check if the IP address matches the plumbed
  98. // gateway, or if there is a name, resolve the name and check if the
  99. // one of the resolved addresses matches.
  100. // DebugBreak();
  101. CComPtr<IUPnPDeviceDocumentAccess> spDDA = NULL;
  102. HRESULT hr = pDevice->QueryInterface (__uuidof(IUPnPDeviceDocumentAccess), (void**)&spDDA);
  103. if (spDDA) {
  104. // get the description doc's URL
  105. CComBSTR cbDocumentURL;
  106. hr = spDDA->GetDocumentURL (&cbDocumentURL);
  107. if (SUCCEEDED(hr)) {
  108. // crack the URL
  109. WCHAR szAddress[INTERNET_MAX_HOST_NAME_LENGTH+1] = {0};
  110. URL_COMPONENTS uc = {0};
  111. uc.dwStructSize = sizeof(uc);
  112. uc.lpszHostName = szAddress;
  113. uc.dwHostNameLength = INTERNET_MAX_HOST_NAME_LENGTH;
  114. BOOL b = InternetCrackUrlW(cbDocumentURL,
  115. wcslen (cbDocumentURL),
  116. 0,
  117. &uc);
  118. if (b == FALSE)
  119. hr = E_FAIL;
  120. else {
  121. USES_CONVERSION;
  122. // convert to IP_ADDRESS_STRING
  123. IP_ADDRESS_STRING IPAddress = {0};
  124. if (IsIPAddress (szAddress) == TRUE) {
  125. // we have an IP address
  126. strncpy (IPAddress.String, W2A (szAddress), sizeof(IPAddress.String));
  127. // test it against this NIC's default gateway(s)
  128. if (FALSE == IsIPAddressDefaultGateway (&IPAddress, pguidInterface))
  129. hr = E_FAIL;
  130. } else {
  131. hr = E_FAIL; // default is failure
  132. // we have a DNS name: convert to IP address(es)
  133. struct addrinfo * pai = NULL;
  134. if (0 == getaddrinfo (W2A (szAddress), NULL, NULL, &pai)) {
  135. // could have > 1 ip addresses; unlikely, but try them all.
  136. addrinfo * pai2 = pai;
  137. do {
  138. if (pai2->ai_addr && pai2->ai_addrlen) {
  139. IPAddress.String[0] = 0;
  140. getnameinfo (pai2->ai_addr,
  141. pai2->ai_addrlen,
  142. (char*)&IPAddress.String,
  143. sizeof(IPAddress.String)/sizeof(IPAddress.String[0]),
  144. NULL,
  145. 0,
  146. NI_NUMERICHOST);
  147. if (IPAddress.String[0]) {
  148. // try this one
  149. if (TRUE == IsIPAddressDefaultGateway (&IPAddress, pguidInterface)) {
  150. hr = S_OK;
  151. break;
  152. }
  153. }
  154. }
  155. } while (pai2 = pai2->ai_next);
  156. freeaddrinfo (pai);
  157. }
  158. }
  159. }
  160. }
  161. }
  162. return hr;
  163. }
  164. HRESULT CSharedAccessDeviceFinderCallback::DeviceAddedWithInterface(LONG lFindData, IUPnPDevice* pDevice, GUID* pguidInterface)
  165. {
  166. HRESULT hr = S_OK;
  167. if(IsEqualGUID(*pguidInterface, IID_NULL))
  168. {
  169. #ifndef SHOW_SELF
  170. hr = E_FAIL;
  171. #endif
  172. }
  173. // bug 561076
  174. if (SUCCEEDED(hr))
  175. hr = CheckDeviceDocumentAgainstDefaultGateway (pDevice, pguidInterface);
  176. if(SUCCEEDED(hr))
  177. {
  178. ISharedAccessBeacon* pSharedAccessBeacon;
  179. hr = GetServices(pDevice, pguidInterface, &pSharedAccessBeacon);
  180. if(SUCCEEDED(hr))
  181. {
  182. CComObject<CSharedAccessConnectionEventSink>* pSplitEventSink;
  183. hr = CComObject<CSharedAccessConnectionEventSink>::CreateInstance(&pSplitEventSink);
  184. if(SUCCEEDED(hr))
  185. {
  186. pSplitEventSink->AddRef();
  187. NETCON_MEDIATYPE MediaType;
  188. hr = pSharedAccessBeacon->GetMediaType(&MediaType);
  189. if(SUCCEEDED(hr))
  190. {
  191. IUPnPService* pWANConnection;
  192. hr = pSharedAccessBeacon->GetService(NCM_SHAREDACCESSHOST_LAN == MediaType ? SAHOST_SERVICE_WANIPCONNECTION : SAHOST_SERVICE_WANPPPCONNECTION, &pWANConnection);
  193. if(SUCCEEDED(hr))
  194. {
  195. hr = pWANConnection->AddCallback(pSplitEventSink);
  196. pWANConnection->Release();
  197. }
  198. }
  199. pSplitEventSink->Release();
  200. }
  201. if(SUCCEEDED(hr))
  202. {
  203. ISharedAccessBeacon* pSharedAccessBeaconToRelease;
  204. Lock();
  205. pSharedAccessBeaconToRelease = m_pSharedAccessBeacon;
  206. m_pSharedAccessBeacon = pSharedAccessBeacon;
  207. m_pSharedAccessBeacon->AddRef();
  208. Unlock();
  209. if(NULL != pSharedAccessBeaconToRelease)
  210. {
  211. pSharedAccessBeaconToRelease->Release();
  212. }
  213. CComObject<CSharedAccessConnection>* pSharedAccessConnection; // does this need to be under the lock?
  214. hr = CComObject<CSharedAccessConnection>::CreateInstance(&pSharedAccessConnection);
  215. if(SUCCEEDED(hr))
  216. {
  217. pSharedAccessConnection->AddRef();
  218. INetConnectionRefresh* pNetConnectionRefresh;
  219. hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
  220. if(SUCCEEDED(hr))
  221. {
  222. pNetConnectionRefresh->ConnectionDeleted(&CLSID_SharedAccessConnection);
  223. pNetConnectionRefresh->ConnectionAdded(pSharedAccessConnection);
  224. pNetConnectionRefresh->Release();
  225. }
  226. pSharedAccessConnection->Release();
  227. }
  228. }
  229. pSharedAccessBeacon->Release();
  230. }
  231. }
  232. return hr;
  233. }
  234. HRESULT CSharedAccessDeviceFinderCallback::DeviceRemoved(LONG lFindData, BSTR bstrUDN)
  235. {
  236. HRESULT hr = S_OK;
  237. ISharedAccessBeacon* pSharedAccessBeaconToRelease = NULL;
  238. Lock();
  239. if(NULL != m_pSharedAccessBeacon)
  240. {
  241. BSTR UniqueDeviceName;
  242. hr = m_pSharedAccessBeacon->GetUniqueDeviceName(&UniqueDeviceName); // only remove the deivce if it matches
  243. if(SUCCEEDED(hr))
  244. {
  245. if(NULL == bstrUDN || 0 == lstrcmp(UniqueDeviceName, bstrUDN))
  246. {
  247. pSharedAccessBeaconToRelease = m_pSharedAccessBeacon;
  248. m_pSharedAccessBeacon = NULL;
  249. }
  250. SysFreeString(UniqueDeviceName);
  251. }
  252. }
  253. Unlock();
  254. if(NULL != pSharedAccessBeaconToRelease)
  255. {
  256. pSharedAccessBeaconToRelease->Release();
  257. INetConnectionRefresh* pNetConnectionRefresh;
  258. hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
  259. if(SUCCEEDED(hr))
  260. {
  261. pNetConnectionRefresh->ConnectionDeleted(&CLSID_SharedAccessConnection);
  262. pNetConnectionRefresh->Release();
  263. }
  264. }
  265. return hr;
  266. }
  267. HRESULT CSharedAccessDeviceFinderCallback::SearchComplete(LONG lFindData)
  268. {
  269. HRESULT hr = S_OK;
  270. // don't care
  271. return hr;
  272. }
  273. HRESULT CSharedAccessDeviceFinderCallback::FindChildDevice(IUPnPDevice* pDevice, LPWSTR pszDeviceType, IUPnPDevice** ppChildDevice)
  274. {
  275. HRESULT hr = S_OK;
  276. IUPnPDevices* pDevices;
  277. hr = pDevice->get_Children(&pDevices);
  278. if(SUCCEEDED(hr))
  279. {
  280. hr = FindDevice(pDevices, pszDeviceType, ppChildDevice);
  281. pDevices->Release();
  282. }
  283. TraceHr (ttidError, FAL, hr, FALSE, "CSharedAccessDeviceFinderCallback::FindChildDevice");
  284. return hr;
  285. }
  286. HRESULT CSharedAccessDeviceFinderCallback::FindDevice(IUPnPDevices* pDevices, LPWSTR pszDeviceType, IUPnPDevice** ppChildDevice)
  287. {
  288. HRESULT hr = S_OK;
  289. *ppChildDevice = NULL;
  290. IUnknown* pEnumerator;
  291. hr = pDevices->get__NewEnum(&pEnumerator);
  292. if (SUCCEEDED(hr))
  293. {
  294. IEnumVARIANT* pVariantEnumerator;
  295. hr = pEnumerator->QueryInterface(IID_IEnumVARIANT, reinterpret_cast<void**>(&pVariantEnumerator));
  296. if (SUCCEEDED(hr))
  297. {
  298. VARIANT DeviceVariant;
  299. VariantInit(&DeviceVariant);
  300. pVariantEnumerator->Reset();
  301. // Traverse the collection.
  302. while (NULL == *ppChildDevice && S_OK == pVariantEnumerator->Next(1, &DeviceVariant, NULL))
  303. {
  304. IDispatch * pDeviceDispatch = NULL;
  305. IUPnPDevice * pDevice = NULL;
  306. pDeviceDispatch = V_DISPATCH(&DeviceVariant);
  307. hr = pDeviceDispatch->QueryInterface(IID_IUPnPDevice, reinterpret_cast<void **>(&pDevice));
  308. if (SUCCEEDED(hr))
  309. {
  310. BSTR Type;
  311. hr = pDevice->get_Type(&Type);
  312. if(SUCCEEDED(hr))
  313. {
  314. if(0 == lstrcmp(Type, pszDeviceType))
  315. {
  316. *ppChildDevice = pDevice;
  317. pDevice->AddRef();
  318. }
  319. SysFreeString(Type);
  320. }
  321. pDevice->Release();
  322. }
  323. VariantClear(&DeviceVariant);
  324. };
  325. if(NULL == *ppChildDevice)
  326. {
  327. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  328. }
  329. pVariantEnumerator->Release();
  330. }
  331. pEnumerator->Release();
  332. }
  333. TraceHr (ttidError, FAL, hr, FALSE, "CSharedAccessDeviceFinderCallback::FindDevice");
  334. return hr;
  335. }
  336. HRESULT CSharedAccessDeviceFinderCallback::FindService(IUPnPDevice* pDevice, LPWSTR pszServiceName, IUPnPService** ppICSService)
  337. {
  338. HRESULT hr;
  339. *ppICSService = NULL;
  340. IUPnPServices* pServices;
  341. hr = pDevice->get_Services(&pServices);
  342. if (SUCCEEDED(hr))
  343. {
  344. IUnknown* pEnumerator;
  345. hr = pServices->get__NewEnum(&pEnumerator);
  346. if (SUCCEEDED(hr))
  347. {
  348. IEnumVARIANT* pVariantEnumerator;
  349. hr = pEnumerator->QueryInterface(IID_IEnumVARIANT, reinterpret_cast<void**>(&pVariantEnumerator));
  350. if (SUCCEEDED(hr))
  351. {
  352. VARIANT ServiceVariant;
  353. VariantInit(&ServiceVariant);
  354. while (NULL == *ppICSService && S_OK == pVariantEnumerator->Next(1, &ServiceVariant, NULL))
  355. {
  356. IDispatch * pServiceDispatch = NULL;
  357. IUPnPService * pService = NULL;
  358. pServiceDispatch = V_DISPATCH(&ServiceVariant);
  359. hr = pServiceDispatch->QueryInterface(IID_IUPnPService, reinterpret_cast<void **>(&pService));
  360. if (SUCCEEDED(hr))
  361. {
  362. BOOL bMatch;
  363. hr = IsServiceMatch(pService, pszServiceName, &bMatch);
  364. if(SUCCEEDED(hr) && TRUE == bMatch)
  365. {
  366. *ppICSService = pService;
  367. pService->AddRef();
  368. }
  369. pService->Release();
  370. }
  371. VariantClear(&ServiceVariant);
  372. }
  373. if(NULL == *ppICSService)
  374. {
  375. hr = E_FAIL;
  376. }
  377. pVariantEnumerator->Release();
  378. }
  379. pEnumerator->Release();
  380. }
  381. pServices->Release();
  382. }
  383. TraceHr (ttidError, FAL, hr, FALSE, "CSharedAccessDeviceFinderCallback::FindService");
  384. return hr;
  385. }
  386. HRESULT CSharedAccessDeviceFinderCallback::GetServices(IUPnPDevice* pDevice, GUID* pInterfaceGUID, ISharedAccessBeacon** ppSharedAccessBeacon)
  387. {
  388. HRESULT hr = S_OK;
  389. *ppSharedAccessBeacon = NULL;
  390. CComObject<CSharedAccessBeacon>* pSharedAccessBeacon;
  391. hr = CComObject<CSharedAccessBeacon>::CreateInstance(&pSharedAccessBeacon);
  392. if(SUCCEEDED(hr))
  393. {
  394. pSharedAccessBeacon->AddRef();
  395. BSTR pUniqueDeviceName;
  396. hr = pDevice->get_UniqueDeviceName(&pUniqueDeviceName);
  397. if(SUCCEEDED(hr))
  398. {
  399. hr = pSharedAccessBeacon->SetUniqueDeviceName(pUniqueDeviceName);
  400. SysFreeString(pUniqueDeviceName);
  401. }
  402. if(SUCCEEDED(hr))
  403. {
  404. pSharedAccessBeacon->SetLocalAdapterGUID(pInterfaceGUID);
  405. IUPnPService* pOSInfoService;
  406. hr = FindService(pDevice, L"urn:schemas-microsoft-com:service:OSInfo:1", &pOSInfoService); // this service is not required
  407. if(SUCCEEDED(hr))
  408. {
  409. pSharedAccessBeacon->SetService(SAHOST_SERVICE_OSINFO, pOSInfoService);
  410. pOSInfoService->Release();
  411. }
  412. IUPnPDevice* pWANDevice;
  413. hr = FindChildDevice(pDevice, L"urn:schemas-upnp-org:device:WANDevice:1", &pWANDevice);
  414. if(SUCCEEDED(hr))
  415. {
  416. IUPnPService* pWANCommonInterfaceConfigService;
  417. hr = FindService(pWANDevice, L"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1", &pWANCommonInterfaceConfigService);
  418. if(SUCCEEDED(hr))
  419. {
  420. pSharedAccessBeacon->SetService(SAHOST_SERVICE_WANCOMMONINTERFACECONFIG, pWANCommonInterfaceConfigService);
  421. IUPnPDevice* pWANCommonDevice;
  422. hr = FindChildDevice(pWANDevice, L"urn:schemas-upnp-org:device:WANConnectionDevice:1", &pWANCommonDevice);
  423. if(SUCCEEDED(hr))
  424. {
  425. IUPnPService* pWANConnectionService;
  426. hr = FindService(pWANCommonDevice, NULL, &pWANConnectionService);
  427. if(SUCCEEDED(hr))
  428. {
  429. BSTR ServiceType;
  430. hr = pWANConnectionService->get_ServiceTypeIdentifier(&ServiceType);
  431. if(SUCCEEDED(hr))
  432. {
  433. if(0 == wcscmp(ServiceType, g_szWANPPPConnectionService))
  434. {
  435. pSharedAccessBeacon->SetMediaType(NCM_SHAREDACCESSHOST_RAS);
  436. pSharedAccessBeacon->SetService(SAHOST_SERVICE_WANPPPCONNECTION, pWANConnectionService);
  437. }
  438. else // we can assume this is WANIPConnectionService
  439. {
  440. pSharedAccessBeacon->SetMediaType(NCM_SHAREDACCESSHOST_LAN);
  441. pSharedAccessBeacon->SetService(SAHOST_SERVICE_WANIPCONNECTION, pWANConnectionService);
  442. }
  443. SysFreeString(ServiceType);
  444. }
  445. pWANConnectionService->Release();
  446. }
  447. pWANCommonDevice->Release();
  448. }
  449. pWANCommonInterfaceConfigService->Release();
  450. }
  451. pWANDevice->Release();
  452. }
  453. }
  454. if(SUCCEEDED(hr))
  455. {
  456. *ppSharedAccessBeacon = static_cast<ISharedAccessBeacon*>(pSharedAccessBeacon);
  457. (*ppSharedAccessBeacon)->AddRef();
  458. }
  459. pSharedAccessBeacon->Release();
  460. }
  461. TraceHr (ttidError, FAL, hr, FALSE, "CSharedAccessDeviceFinderCallback::GetServices");
  462. return hr;
  463. }
  464. HRESULT CSharedAccessDeviceFinderCallback::IsServiceMatch(IUPnPService* pService, BSTR SearchCriteria, BOOL* pbMatch)
  465. {
  466. HRESULT hr = S_OK;
  467. *pbMatch = FALSE;
  468. BSTR ServiceType;
  469. hr = pService->get_ServiceTypeIdentifier(&ServiceType);
  470. if(SUCCEEDED(hr))
  471. {
  472. if(NULL != SearchCriteria) // if the caller provides a name then we search for it
  473. {
  474. if(0 == wcscmp(ServiceType, SearchCriteria))
  475. {
  476. *pbMatch = TRUE;
  477. }
  478. }
  479. else // otherwise we enter the special search case
  480. {
  481. if(0 == wcscmp(ServiceType, g_szWANIPConnectionService) || 0 == wcscmp(ServiceType, g_szWANPPPConnectionService))
  482. {
  483. VARIANT OutArgsGetConnectionTypeInfo;
  484. hr = InvokeVoidAction(pService, L"GetConnectionTypeInfo", &OutArgsGetConnectionTypeInfo);
  485. if(SUCCEEDED(hr))
  486. {
  487. VARIANT ConnectionType;
  488. LONG lIndex = 0;
  489. hr = SafeArrayGetElement(V_ARRAY(&OutArgsGetConnectionTypeInfo), &lIndex, &ConnectionType);
  490. if(SUCCEEDED(hr))
  491. {
  492. if(V_VT(&ConnectionType) == VT_BSTR)
  493. {
  494. if(0 == wcscmp(V_BSTR(&ConnectionType), L"IP_Routed"))
  495. {
  496. VARIANT OutArgsGetNATRSIPStatus;
  497. hr = InvokeVoidAction(pService, L"GetNATRSIPStatus", &OutArgsGetNATRSIPStatus);
  498. if(SUCCEEDED(hr))
  499. {
  500. VARIANT NATEnabled;
  501. lIndex = 1;
  502. hr = SafeArrayGetElement(V_ARRAY(&OutArgsGetNATRSIPStatus), &lIndex, &NATEnabled);
  503. if(SUCCEEDED(hr))
  504. {
  505. if(V_VT(&NATEnabled) == VT_BOOL)
  506. {
  507. if(VARIANT_TRUE == V_BOOL(&NATEnabled))
  508. {
  509. *pbMatch = TRUE;
  510. }
  511. }
  512. VariantClear(&NATEnabled);
  513. }
  514. VariantClear(&OutArgsGetNATRSIPStatus);
  515. }
  516. }
  517. }
  518. VariantClear(&ConnectionType);
  519. }
  520. VariantClear(&OutArgsGetConnectionTypeInfo);
  521. }
  522. }
  523. }
  524. SysFreeString(ServiceType);
  525. }
  526. return hr;
  527. }
  528. HRESULT CSharedAccessDeviceFinderCallback::GetStringStateVariable(IUPnPService* pService, LPWSTR pszVariableName, BSTR* pString)
  529. {
  530. HRESULT hr = S_OK;
  531. VARIANT Variant;
  532. VariantInit(&Variant);
  533. BSTR VariableName;
  534. VariableName = SysAllocString(pszVariableName);
  535. if(NULL != VariableName)
  536. {
  537. hr = pService->QueryStateVariable(VariableName, &Variant);
  538. if(SUCCEEDED(hr))
  539. {
  540. if(V_VT(&Variant) == VT_BSTR)
  541. {
  542. *pString = V_BSTR(&Variant);
  543. }
  544. else
  545. {
  546. hr = E_UNEXPECTED;
  547. }
  548. }
  549. if(FAILED(hr))
  550. {
  551. VariantClear(&Variant);
  552. }
  553. SysFreeString(VariableName);
  554. }
  555. else
  556. {
  557. hr = E_OUTOFMEMORY;
  558. }
  559. TraceHr (ttidError, FAL, hr, FALSE, "CSharedAccessConnection::GetStringStateVariable");
  560. return hr;
  561. }
  562. HRESULT CSharedAccessConnectionEventSink::StateVariableChanged(IUPnPService *pus, LPCWSTR pcwszStateVarName, VARIANT vaValue)
  563. {
  564. HRESULT hr = S_OK;
  565. if(0 == lstrcmp(pcwszStateVarName, L"ConnectionStatus"))
  566. {
  567. CComObject<CSharedAccessConnection>* pSharedAccessConnection;
  568. hr = CComObject<CSharedAccessConnection>::CreateInstance(&pSharedAccessConnection);
  569. if(SUCCEEDED(hr))
  570. {
  571. pSharedAccessConnection->AddRef();
  572. NETCON_PROPERTIES* pProperties;
  573. hr = pSharedAccessConnection->GetProperties(&pProperties);
  574. if(SUCCEEDED(hr))
  575. {
  576. INetConnectionRefresh* pNetConnectionRefresh;
  577. hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
  578. if(SUCCEEDED(hr))
  579. {
  580. pNetConnectionRefresh->ConnectionStatusChanged(&CLSID_SharedAccessConnection, pProperties->Status);
  581. pNetConnectionRefresh->Release();
  582. }
  583. FreeNetconProperties(pProperties);
  584. }
  585. pSharedAccessConnection->Release();
  586. }
  587. }
  588. else if(0 == lstrcmp(pcwszStateVarName, L"X_Name"))
  589. {
  590. CComObject<CSharedAccessConnection>* pSharedAccessConnection;
  591. hr = CComObject<CSharedAccessConnection>::CreateInstance(&pSharedAccessConnection);
  592. if(SUCCEEDED(hr))
  593. {
  594. pSharedAccessConnection->AddRef();
  595. INetConnectionRefresh* pNetConnectionRefresh;
  596. hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
  597. if(SUCCEEDED(hr))
  598. {
  599. pNetConnectionRefresh->ConnectionRenamed(pSharedAccessConnection);
  600. pNetConnectionRefresh->Release();
  601. }
  602. pSharedAccessConnection->Release();
  603. }
  604. }
  605. return hr;
  606. }
  607. HRESULT CSharedAccessConnectionEventSink::ServiceInstanceDied(IUPnPService *pus)
  608. {
  609. return S_OK;
  610. }