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.

582 lines
20 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. HRESULT CSharedAccessDeviceFinderCallback::DeviceAddedWithInterface(LONG lFindData, IUPnPDevice* pDevice, GUID* pguidInterface)
  43. {
  44. HRESULT hr = S_OK;
  45. if(IsEqualGUID(*pguidInterface, IID_NULL))
  46. {
  47. #ifndef SHOW_SELF
  48. hr = E_FAIL;
  49. #endif
  50. }
  51. if(SUCCEEDED(hr))
  52. {
  53. ISharedAccessBeacon* pSharedAccessBeacon;
  54. hr = GetServices(pDevice, pguidInterface, &pSharedAccessBeacon);
  55. if(SUCCEEDED(hr))
  56. {
  57. CComObject<CSharedAccessConnectionEventSink>* pSplitEventSink;
  58. hr = CComObject<CSharedAccessConnectionEventSink>::CreateInstance(&pSplitEventSink);
  59. if(SUCCEEDED(hr))
  60. {
  61. pSplitEventSink->AddRef();
  62. NETCON_MEDIATYPE MediaType;
  63. hr = pSharedAccessBeacon->GetMediaType(&MediaType);
  64. if(SUCCEEDED(hr))
  65. {
  66. IUPnPService* pWANConnection;
  67. hr = pSharedAccessBeacon->GetService(NCM_SHAREDACCESSHOST_LAN == MediaType ? SAHOST_SERVICE_WANIPCONNECTION : SAHOST_SERVICE_WANPPPCONNECTION, &pWANConnection);
  68. if(SUCCEEDED(hr))
  69. {
  70. hr = pWANConnection->AddCallback(pSplitEventSink);
  71. pWANConnection->Release();
  72. }
  73. }
  74. pSplitEventSink->Release();
  75. }
  76. if(SUCCEEDED(hr))
  77. {
  78. ISharedAccessBeacon* pSharedAccessBeaconToRelease;
  79. Lock();
  80. pSharedAccessBeaconToRelease = m_pSharedAccessBeacon;
  81. m_pSharedAccessBeacon = pSharedAccessBeacon;
  82. m_pSharedAccessBeacon->AddRef();
  83. Unlock();
  84. if(NULL != pSharedAccessBeaconToRelease)
  85. {
  86. pSharedAccessBeaconToRelease->Release();
  87. }
  88. CComObject<CSharedAccessConnection>* pSharedAccessConnection; // does this need to be under the lock?
  89. hr = CComObject<CSharedAccessConnection>::CreateInstance(&pSharedAccessConnection);
  90. if(SUCCEEDED(hr))
  91. {
  92. pSharedAccessConnection->AddRef();
  93. INetConnectionRefresh* pNetConnectionRefresh;
  94. hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
  95. if(SUCCEEDED(hr))
  96. {
  97. pNetConnectionRefresh->ConnectionDeleted(&CLSID_SharedAccessConnection);
  98. pNetConnectionRefresh->ConnectionAdded(pSharedAccessConnection);
  99. pNetConnectionRefresh->Release();
  100. }
  101. pSharedAccessConnection->Release();
  102. }
  103. }
  104. pSharedAccessBeacon->Release();
  105. }
  106. }
  107. return hr;
  108. }
  109. HRESULT CSharedAccessDeviceFinderCallback::DeviceRemoved(LONG lFindData, BSTR bstrUDN)
  110. {
  111. HRESULT hr = S_OK;
  112. ISharedAccessBeacon* pSharedAccessBeaconToRelease = NULL;
  113. Lock();
  114. if(NULL != m_pSharedAccessBeacon)
  115. {
  116. BSTR UniqueDeviceName;
  117. hr = m_pSharedAccessBeacon->GetUniqueDeviceName(&UniqueDeviceName); // only remove the deivce if it matches
  118. if(SUCCEEDED(hr))
  119. {
  120. if(NULL == bstrUDN || 0 == lstrcmp(UniqueDeviceName, bstrUDN))
  121. {
  122. pSharedAccessBeaconToRelease = m_pSharedAccessBeacon;
  123. m_pSharedAccessBeacon = NULL;
  124. }
  125. SysFreeString(UniqueDeviceName);
  126. }
  127. }
  128. Unlock();
  129. if(NULL != pSharedAccessBeaconToRelease)
  130. {
  131. pSharedAccessBeaconToRelease->Release();
  132. INetConnectionRefresh* pNetConnectionRefresh;
  133. hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
  134. if(SUCCEEDED(hr))
  135. {
  136. pNetConnectionRefresh->ConnectionDeleted(&CLSID_SharedAccessConnection);
  137. pNetConnectionRefresh->Release();
  138. }
  139. }
  140. return hr;
  141. }
  142. HRESULT CSharedAccessDeviceFinderCallback::SearchComplete(LONG lFindData)
  143. {
  144. HRESULT hr = S_OK;
  145. // don't care
  146. return hr;
  147. }
  148. HRESULT CSharedAccessDeviceFinderCallback::FindChildDevice(IUPnPDevice* pDevice, LPWSTR pszDeviceType, IUPnPDevice** ppChildDevice)
  149. {
  150. HRESULT hr = S_OK;
  151. IUPnPDevices* pDevices;
  152. hr = pDevice->get_Children(&pDevices);
  153. if(SUCCEEDED(hr))
  154. {
  155. hr = FindDevice(pDevices, pszDeviceType, ppChildDevice);
  156. pDevices->Release();
  157. }
  158. TraceHr (ttidError, FAL, hr, FALSE, "CSharedAccessDeviceFinderCallback::FindChildDevice");
  159. return hr;
  160. }
  161. HRESULT CSharedAccessDeviceFinderCallback::FindDevice(IUPnPDevices* pDevices, LPWSTR pszDeviceType, IUPnPDevice** ppChildDevice)
  162. {
  163. HRESULT hr = S_OK;
  164. *ppChildDevice = NULL;
  165. IUnknown* pEnumerator;
  166. hr = pDevices->get__NewEnum(&pEnumerator);
  167. if (SUCCEEDED(hr))
  168. {
  169. IEnumVARIANT* pVariantEnumerator;
  170. hr = pEnumerator->QueryInterface(IID_IEnumVARIANT, reinterpret_cast<void**>(&pVariantEnumerator));
  171. if (SUCCEEDED(hr))
  172. {
  173. VARIANT DeviceVariant;
  174. VariantInit(&DeviceVariant);
  175. pVariantEnumerator->Reset();
  176. // Traverse the collection.
  177. while (NULL == *ppChildDevice && S_OK == pVariantEnumerator->Next(1, &DeviceVariant, NULL))
  178. {
  179. IDispatch * pDeviceDispatch = NULL;
  180. IUPnPDevice * pDevice = NULL;
  181. pDeviceDispatch = V_DISPATCH(&DeviceVariant);
  182. hr = pDeviceDispatch->QueryInterface(IID_IUPnPDevice, reinterpret_cast<void **>(&pDevice));
  183. if (SUCCEEDED(hr))
  184. {
  185. BSTR Type;
  186. hr = pDevice->get_Type(&Type);
  187. if(SUCCEEDED(hr))
  188. {
  189. if(0 == lstrcmp(Type, pszDeviceType))
  190. {
  191. *ppChildDevice = pDevice;
  192. pDevice->AddRef();
  193. }
  194. SysFreeString(Type);
  195. }
  196. pDevice->Release();
  197. }
  198. VariantClear(&DeviceVariant);
  199. };
  200. if(NULL == *ppChildDevice)
  201. {
  202. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  203. }
  204. pVariantEnumerator->Release();
  205. }
  206. pEnumerator->Release();
  207. }
  208. TraceHr (ttidError, FAL, hr, FALSE, "CSharedAccessDeviceFinderCallback::FindDevice");
  209. return hr;
  210. }
  211. HRESULT CSharedAccessDeviceFinderCallback::FindService(IUPnPDevice* pDevice, LPWSTR pszServiceName, IUPnPService** ppICSService)
  212. {
  213. HRESULT hr;
  214. *ppICSService = NULL;
  215. IUPnPServices* pServices;
  216. hr = pDevice->get_Services(&pServices);
  217. if (SUCCEEDED(hr))
  218. {
  219. IUnknown* pEnumerator;
  220. hr = pServices->get__NewEnum(&pEnumerator);
  221. if (SUCCEEDED(hr))
  222. {
  223. IEnumVARIANT* pVariantEnumerator;
  224. hr = pEnumerator->QueryInterface(IID_IEnumVARIANT, reinterpret_cast<void**>(&pVariantEnumerator));
  225. if (SUCCEEDED(hr))
  226. {
  227. VARIANT ServiceVariant;
  228. VariantInit(&ServiceVariant);
  229. while (NULL == *ppICSService && S_OK == pVariantEnumerator->Next(1, &ServiceVariant, NULL))
  230. {
  231. IDispatch * pServiceDispatch = NULL;
  232. IUPnPService * pService = NULL;
  233. pServiceDispatch = V_DISPATCH(&ServiceVariant);
  234. hr = pServiceDispatch->QueryInterface(IID_IUPnPService, reinterpret_cast<void **>(&pService));
  235. if (SUCCEEDED(hr))
  236. {
  237. BOOL bMatch;
  238. hr = IsServiceMatch(pService, pszServiceName, &bMatch);
  239. if(SUCCEEDED(hr) && TRUE == bMatch)
  240. {
  241. *ppICSService = pService;
  242. pService->AddRef();
  243. }
  244. pService->Release();
  245. }
  246. VariantClear(&ServiceVariant);
  247. }
  248. if(NULL == *ppICSService)
  249. {
  250. hr = E_FAIL;
  251. }
  252. pVariantEnumerator->Release();
  253. }
  254. pEnumerator->Release();
  255. }
  256. pServices->Release();
  257. }
  258. TraceHr (ttidError, FAL, hr, FALSE, "CSharedAccessDeviceFinderCallback::FindService");
  259. return hr;
  260. }
  261. HRESULT CSharedAccessDeviceFinderCallback::GetServices(IUPnPDevice* pDevice, GUID* pInterfaceGUID, ISharedAccessBeacon** ppSharedAccessBeacon)
  262. {
  263. HRESULT hr = S_OK;
  264. *ppSharedAccessBeacon = NULL;
  265. CComObject<CSharedAccessBeacon>* pSharedAccessBeacon;
  266. hr = CComObject<CSharedAccessBeacon>::CreateInstance(&pSharedAccessBeacon);
  267. if(SUCCEEDED(hr))
  268. {
  269. pSharedAccessBeacon->AddRef();
  270. BSTR pUniqueDeviceName;
  271. hr = pDevice->get_UniqueDeviceName(&pUniqueDeviceName);
  272. if(SUCCEEDED(hr))
  273. {
  274. hr = pSharedAccessBeacon->SetUniqueDeviceName(pUniqueDeviceName);
  275. SysFreeString(pUniqueDeviceName);
  276. }
  277. if(SUCCEEDED(hr))
  278. {
  279. pSharedAccessBeacon->SetLocalAdapterGUID(pInterfaceGUID);
  280. IUPnPService* pOSInfoService;
  281. hr = FindService(pDevice, L"urn:schemas-microsoft-com:service:OSInfo:1", &pOSInfoService); // this service is not required
  282. if(SUCCEEDED(hr))
  283. {
  284. pSharedAccessBeacon->SetService(SAHOST_SERVICE_OSINFO, pOSInfoService);
  285. pOSInfoService->Release();
  286. }
  287. IUPnPDevice* pWANDevice;
  288. hr = FindChildDevice(pDevice, L"urn:schemas-upnp-org:device:WANDevice:1", &pWANDevice);
  289. if(SUCCEEDED(hr))
  290. {
  291. IUPnPService* pWANCommonInterfaceConfigService;
  292. hr = FindService(pWANDevice, L"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1", &pWANCommonInterfaceConfigService);
  293. if(SUCCEEDED(hr))
  294. {
  295. pSharedAccessBeacon->SetService(SAHOST_SERVICE_WANCOMMONINTERFACECONFIG, pWANCommonInterfaceConfigService);
  296. IUPnPDevice* pWANCommonDevice;
  297. hr = FindChildDevice(pWANDevice, L"urn:schemas-upnp-org:device:WANConnectionDevice:1", &pWANCommonDevice);
  298. if(SUCCEEDED(hr))
  299. {
  300. IUPnPService* pWANConnectionService;
  301. hr = FindService(pWANCommonDevice, NULL, &pWANConnectionService);
  302. if(SUCCEEDED(hr))
  303. {
  304. BSTR ServiceType;
  305. hr = pWANConnectionService->get_ServiceTypeIdentifier(&ServiceType);
  306. if(SUCCEEDED(hr))
  307. {
  308. if(0 == wcscmp(ServiceType, g_szWANPPPConnectionService))
  309. {
  310. pSharedAccessBeacon->SetMediaType(NCM_SHAREDACCESSHOST_RAS);
  311. pSharedAccessBeacon->SetService(SAHOST_SERVICE_WANPPPCONNECTION, pWANConnectionService);
  312. }
  313. else // we can assume this is WANIPConnectionService
  314. {
  315. pSharedAccessBeacon->SetMediaType(NCM_SHAREDACCESSHOST_LAN);
  316. pSharedAccessBeacon->SetService(SAHOST_SERVICE_WANIPCONNECTION, pWANConnectionService);
  317. }
  318. SysFreeString(ServiceType);
  319. }
  320. pWANConnectionService->Release();
  321. }
  322. pWANCommonDevice->Release();
  323. }
  324. pWANCommonInterfaceConfigService->Release();
  325. }
  326. pWANDevice->Release();
  327. }
  328. }
  329. if(SUCCEEDED(hr))
  330. {
  331. *ppSharedAccessBeacon = static_cast<ISharedAccessBeacon*>(pSharedAccessBeacon);
  332. (*ppSharedAccessBeacon)->AddRef();
  333. }
  334. pSharedAccessBeacon->Release();
  335. }
  336. TraceHr (ttidError, FAL, hr, FALSE, "CSharedAccessDeviceFinderCallback::GetServices");
  337. return hr;
  338. }
  339. HRESULT CSharedAccessDeviceFinderCallback::IsServiceMatch(IUPnPService* pService, BSTR SearchCriteria, BOOL* pbMatch)
  340. {
  341. HRESULT hr = S_OK;
  342. *pbMatch = FALSE;
  343. BSTR ServiceType;
  344. hr = pService->get_ServiceTypeIdentifier(&ServiceType);
  345. if(SUCCEEDED(hr))
  346. {
  347. if(NULL != SearchCriteria) // if the caller provides a name then we search for it
  348. {
  349. if(0 == wcscmp(ServiceType, SearchCriteria))
  350. {
  351. *pbMatch = TRUE;
  352. }
  353. }
  354. else // otherwise we enter the special search case
  355. {
  356. if(0 == wcscmp(ServiceType, g_szWANIPConnectionService) || 0 == wcscmp(ServiceType, g_szWANPPPConnectionService))
  357. {
  358. VARIANT OutArgsGetConnectionTypeInfo;
  359. hr = InvokeVoidAction(pService, L"GetConnectionTypeInfo", &OutArgsGetConnectionTypeInfo);
  360. if(SUCCEEDED(hr))
  361. {
  362. VARIANT ConnectionType;
  363. LONG lIndex = 0;
  364. hr = SafeArrayGetElement(V_ARRAY(&OutArgsGetConnectionTypeInfo), &lIndex, &ConnectionType);
  365. if(SUCCEEDED(hr))
  366. {
  367. if(V_VT(&ConnectionType) == VT_BSTR)
  368. {
  369. if(0 == wcscmp(V_BSTR(&ConnectionType), L"IP_Routed"))
  370. {
  371. VARIANT OutArgsGetNATRSIPStatus;
  372. hr = InvokeVoidAction(pService, L"GetNATRSIPStatus", &OutArgsGetNATRSIPStatus);
  373. if(SUCCEEDED(hr))
  374. {
  375. VARIANT NATEnabled;
  376. lIndex = 1;
  377. hr = SafeArrayGetElement(V_ARRAY(&OutArgsGetNATRSIPStatus), &lIndex, &NATEnabled);
  378. if(SUCCEEDED(hr))
  379. {
  380. if(V_VT(&NATEnabled) == VT_BOOL)
  381. {
  382. if(VARIANT_TRUE == V_BOOL(&NATEnabled))
  383. {
  384. *pbMatch = TRUE;
  385. }
  386. }
  387. VariantClear(&NATEnabled);
  388. }
  389. VariantClear(&OutArgsGetNATRSIPStatus);
  390. }
  391. }
  392. }
  393. VariantClear(&ConnectionType);
  394. }
  395. VariantClear(&OutArgsGetConnectionTypeInfo);
  396. }
  397. }
  398. }
  399. SysFreeString(ServiceType);
  400. }
  401. return hr;
  402. }
  403. HRESULT CSharedAccessDeviceFinderCallback::GetStringStateVariable(IUPnPService* pService, LPWSTR pszVariableName, BSTR* pString)
  404. {
  405. HRESULT hr = S_OK;
  406. VARIANT Variant;
  407. VariantInit(&Variant);
  408. BSTR VariableName;
  409. VariableName = SysAllocString(pszVariableName);
  410. if(NULL != VariableName)
  411. {
  412. hr = pService->QueryStateVariable(VariableName, &Variant);
  413. if(SUCCEEDED(hr))
  414. {
  415. if(V_VT(&Variant) == VT_BSTR)
  416. {
  417. *pString = V_BSTR(&Variant);
  418. }
  419. else
  420. {
  421. hr = E_UNEXPECTED;
  422. }
  423. }
  424. if(FAILED(hr))
  425. {
  426. VariantClear(&Variant);
  427. }
  428. SysFreeString(VariableName);
  429. }
  430. else
  431. {
  432. hr = E_OUTOFMEMORY;
  433. }
  434. TraceHr (ttidError, FAL, hr, FALSE, "CSharedAccessConnection::GetStringStateVariable");
  435. return hr;
  436. }
  437. HRESULT CSharedAccessConnectionEventSink::StateVariableChanged(IUPnPService *pus, LPCWSTR pcwszStateVarName, VARIANT vaValue)
  438. {
  439. HRESULT hr = S_OK;
  440. if(0 == lstrcmp(pcwszStateVarName, L"ConnectionStatus"))
  441. {
  442. CComObject<CSharedAccessConnection>* pSharedAccessConnection;
  443. hr = CComObject<CSharedAccessConnection>::CreateInstance(&pSharedAccessConnection);
  444. if(SUCCEEDED(hr))
  445. {
  446. pSharedAccessConnection->AddRef();
  447. NETCON_PROPERTIES* pProperties;
  448. hr = pSharedAccessConnection->GetProperties(&pProperties);
  449. if(SUCCEEDED(hr))
  450. {
  451. INetConnectionRefresh* pNetConnectionRefresh;
  452. hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
  453. if(SUCCEEDED(hr))
  454. {
  455. pNetConnectionRefresh->ConnectionStatusChanged(&CLSID_SharedAccessConnection, pProperties->Status);
  456. pNetConnectionRefresh->Release();
  457. }
  458. FreeNetconProperties(pProperties);
  459. }
  460. pSharedAccessConnection->Release();
  461. }
  462. }
  463. else if(0 == lstrcmp(pcwszStateVarName, L"X_Name"))
  464. {
  465. CComObject<CSharedAccessConnection>* pSharedAccessConnection;
  466. hr = CComObject<CSharedAccessConnection>::CreateInstance(&pSharedAccessConnection);
  467. if(SUCCEEDED(hr))
  468. {
  469. pSharedAccessConnection->AddRef();
  470. INetConnectionRefresh* pNetConnectionRefresh;
  471. hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
  472. if(SUCCEEDED(hr))
  473. {
  474. pNetConnectionRefresh->ConnectionRenamed(pSharedAccessConnection);
  475. pNetConnectionRefresh->Release();
  476. }
  477. pSharedAccessConnection->Release();
  478. }
  479. }
  480. return hr;
  481. }
  482. HRESULT CSharedAccessConnectionEventSink::ServiceInstanceDied(IUPnPService *pus)
  483. {
  484. return S_OK;
  485. }