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.

277 lines
8.2 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000.
  5. //
  6. // File: C O N M A N S A. C P P
  7. //
  8. // Contents: Implementation of ICS connection class manager
  9. //
  10. // Notes:
  11. //
  12. // Author: kenwic 8 Aug 2000
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "conmansa.h"
  18. #include "enumsa.h"
  19. #include "cmsabcon.h"
  20. //+---------------------------------------------------------------------------
  21. // INetConnectionManager
  22. //
  23. CSharedAccessConnectionManager::CSharedAccessConnectionManager()
  24. {
  25. m_lSearchCookie = 0;
  26. m_pDeviceFinder = NULL;
  27. m_pDeviceFinderCallback = NULL;
  28. m_SocketEvent = WSA_INVALID_EVENT;
  29. m_hSocketNotificationWait = INVALID_HANDLE_VALUE;
  30. m_DummySocket = INVALID_SOCKET;
  31. }
  32. //+---------------------------------------------------------------------------
  33. //
  34. // Member: CSharedAccessConnectionManager::EnumConnections
  35. //
  36. // Purpose: Returns an enumerator object for ICS connections
  37. //
  38. // Arguments:
  39. // Flags [in]
  40. // ppEnum [out] Returns enumerator object
  41. //
  42. // Returns: S_OK if succeeded, OLE or Win32 error code otherwise
  43. //
  44. // Author: kenwic 17 Jul 2000
  45. //
  46. // Notes:
  47. //
  48. STDMETHODIMP CSharedAccessConnectionManager::EnumConnections(NETCONMGR_ENUM_FLAGS Flags,
  49. IEnumNetConnection** ppEnum)
  50. {
  51. *ppEnum = NULL;
  52. CComObject<CSharedAccessConnectionManagerEnumConnection>* pEnum;
  53. HRESULT hr = CComObject<CSharedAccessConnectionManagerEnumConnection>::CreateInstance(&pEnum);
  54. if(SUCCEEDED(hr))
  55. {
  56. *ppEnum = static_cast<IEnumNetConnection*>(pEnum);
  57. pEnum->AddRef();
  58. }
  59. TraceHr (ttidError, FAL, hr, FALSE, "CSharedAccessConnectionManager::EnumConnections");
  60. return hr;
  61. }
  62. HRESULT CSharedAccessConnectionManager::FinalConstruct(void)
  63. {
  64. HRESULT hr = S_OK;
  65. m_DummySocket = socket(AF_INET, SOCK_DGRAM, 0);
  66. if(INVALID_SOCKET != m_DummySocket)
  67. {
  68. m_SocketEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
  69. if(NULL != m_SocketEvent)
  70. {
  71. if(0 != WSAEventSelect(m_DummySocket, m_SocketEvent, FD_ADDRESS_LIST_CHANGE))
  72. {
  73. hr = E_FAIL;
  74. }
  75. }
  76. else
  77. {
  78. hr = E_FAIL;
  79. }
  80. }
  81. else
  82. {
  83. hr = E_FAIL;
  84. }
  85. if(SUCCEEDED(hr)) // start up the first search on a background thread, this shoud fire immediately
  86. {
  87. // note that there is no addref here because it would keep the object alive forever. In FinalRelease we will make sure we won't get called back
  88. if(0 == RegisterWaitForSingleObject(&m_hSocketNotificationWait, m_SocketEvent, AsyncStartSearching, this, INFINITE, WT_EXECUTEDEFAULT))
  89. {
  90. m_hSocketNotificationWait = INVALID_HANDLE_VALUE;
  91. }
  92. }
  93. TraceHr (ttidError, FAL, hr, FALSE, "CSharedAccessConnectionManager::FinalConstruct");
  94. return hr;
  95. }
  96. HRESULT CSharedAccessConnectionManager::FinalRelease(void)
  97. {
  98. HRESULT hr = S_OK;
  99. if(INVALID_HANDLE_VALUE != m_hSocketNotificationWait)
  100. {
  101. UnregisterWaitEx(m_hSocketNotificationWait, INVALID_HANDLE_VALUE); // we must block here since we are not addrefed
  102. }
  103. if(INVALID_SOCKET != m_DummySocket) // the event wait must be unregistered first
  104. {
  105. closesocket(m_DummySocket);
  106. }
  107. if(WSA_INVALID_EVENT != m_SocketEvent) // the socket must be closed first
  108. {
  109. CloseHandle(m_SocketEvent);
  110. }
  111. // After the other thread is shut down, the device finder and callback won't change any more so we don't need a lock.
  112. if(NULL != m_pDeviceFinder)
  113. {
  114. hr = m_pDeviceFinder->CancelAsyncFind(m_lSearchCookie);
  115. m_pDeviceFinder->Release();
  116. }
  117. if(NULL != m_pDeviceFinderCallback)
  118. {
  119. m_pDeviceFinderCallback->Release();
  120. }
  121. TraceHr (ttidError, FAL, hr, FALSE, "CSharedAccessConnectionManager::FinalRelease");
  122. return hr;
  123. }
  124. HRESULT CSharedAccessConnectionManager::StartSearch(void)
  125. {
  126. HRESULT hr = S_OK;
  127. CComObject<CSharedAccessDeviceFinderCallback>* pDeviceFinderCallback;
  128. hr = CComObject<CSharedAccessDeviceFinderCallback>::CreateInstance(&pDeviceFinderCallback);
  129. if(SUCCEEDED(hr))
  130. {
  131. pDeviceFinderCallback->AddRef();
  132. IUPnPDeviceFinder* pDeviceFinder;
  133. hr = CoCreateInstance(CLSID_UPnPDeviceFinder, NULL, CLSCTX_INPROC_SERVER, IID_IUPnPDeviceFinder, reinterpret_cast<void **>(&pDeviceFinder));
  134. if(SUCCEEDED(hr))
  135. {
  136. BSTR bstrTypeURI;
  137. bstrTypeURI = SysAllocString(L"urn:schemas-upnp-org:device:InternetGatewayDevice:1");
  138. if (NULL != bstrTypeURI)
  139. {
  140. LONG lSearchCookie;
  141. hr = pDeviceFinder->CreateAsyncFind(bstrTypeURI, 0, static_cast<IUPnPDeviceFinderCallback*>(pDeviceFinderCallback), &lSearchCookie);
  142. if(SUCCEEDED(hr))
  143. {
  144. LONG lOldSearchCookie;
  145. IUPnPDeviceFinder* pOldDeviceFinder;
  146. CComObject<CSharedAccessDeviceFinderCallback>* pOldDeviceFinderCallback;
  147. Lock(); // swap in the new finder and callback
  148. lOldSearchCookie = m_lSearchCookie;
  149. m_lSearchCookie = lSearchCookie;
  150. pOldDeviceFinder = m_pDeviceFinder;
  151. m_pDeviceFinder = pDeviceFinder;
  152. pDeviceFinder->AddRef();
  153. pOldDeviceFinderCallback = m_pDeviceFinderCallback;
  154. m_pDeviceFinderCallback = pDeviceFinderCallback;
  155. pDeviceFinderCallback->AddRef();
  156. Unlock();
  157. if(NULL != pOldDeviceFinder)
  158. {
  159. pOldDeviceFinder->CancelAsyncFind(lOldSearchCookie);
  160. pOldDeviceFinder->Release();
  161. }
  162. if(NULL != pOldDeviceFinderCallback)
  163. {
  164. pOldDeviceFinderCallback->DeviceRemoved(NULL, NULL); // clear out the old callback, so netshell gets cleaned up
  165. pOldDeviceFinderCallback->Release();
  166. }
  167. hr = pDeviceFinder->StartAsyncFind(lSearchCookie); // don't start the search until the new callback is in place
  168. }
  169. SysFreeString(bstrTypeURI);
  170. }
  171. pDeviceFinder->Release();
  172. }
  173. pDeviceFinderCallback->Release();
  174. }
  175. DWORD dwBytesReturned;
  176. if(SOCKET_ERROR != WSAIoctl(m_DummySocket, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &dwBytesReturned, NULL, NULL) || WSAEWOULDBLOCK != WSAGetLastError())
  177. {
  178. hr = E_FAIL;
  179. }
  180. WSANETWORKEVENTS NetworkEvents;
  181. ZeroMemory(&NetworkEvents, sizeof(NetworkEvents));
  182. WSAEnumNetworkEvents(m_DummySocket, NULL, &NetworkEvents);
  183. return hr;
  184. }
  185. void CSharedAccessConnectionManager::AsyncStartSearching(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
  186. {
  187. if(FALSE == TimerOrWaitFired)
  188. {
  189. CSharedAccessConnectionManager* pThis = reinterpret_cast<CSharedAccessConnectionManager*>(lpParameter);
  190. HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  191. if(SUCCEEDED(hr))
  192. {
  193. hr = pThis->StartSearch();
  194. CoUninitialize();
  195. }
  196. }
  197. return;
  198. }
  199. HRESULT CSharedAccessConnectionManager::GetSharedAccessBeacon(BSTR DeviceId, ISharedAccessBeacon** ppSharedAccessBeacon)
  200. {
  201. HRESULT hr = S_OK;
  202. *ppSharedAccessBeacon = NULL;
  203. CComObject<CSharedAccessDeviceFinderCallback>* pDeviceFinderCallback;
  204. Lock();
  205. pDeviceFinderCallback = m_pDeviceFinderCallback;
  206. if(NULL != pDeviceFinderCallback)
  207. {
  208. pDeviceFinderCallback->AddRef();
  209. }
  210. Unlock();
  211. if(NULL != pDeviceFinderCallback)
  212. {
  213. hr = pDeviceFinderCallback->GetSharedAccessBeacon(DeviceId, ppSharedAccessBeacon);
  214. pDeviceFinderCallback->Release();
  215. }
  216. else
  217. {
  218. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  219. }
  220. return hr;
  221. }