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.

281 lines
8.7 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. TraceTag(ttidConman, "CSharedAccessConnectionManager::FinalConstruct");
  66. m_DummySocket = socket(AF_INET, SOCK_DGRAM, 0);
  67. if(INVALID_SOCKET != m_DummySocket)
  68. {
  69. m_SocketEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
  70. if(NULL != m_SocketEvent)
  71. {
  72. if(0 != WSAEventSelect(m_DummySocket, m_SocketEvent, FD_ADDRESS_LIST_CHANGE))
  73. {
  74. hr = E_FAIL;
  75. }
  76. }
  77. else
  78. {
  79. hr = E_FAIL;
  80. }
  81. }
  82. else
  83. {
  84. hr = E_FAIL;
  85. }
  86. if(SUCCEEDED(hr)) // start up the first search on a background thread, this shoud fire immediately
  87. {
  88. // 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
  89. if(0 == RegisterWaitForSingleObject(&m_hSocketNotificationWait, m_SocketEvent, AsyncStartSearching, this, INFINITE, WT_EXECUTEDEFAULT))
  90. {
  91. m_hSocketNotificationWait = INVALID_HANDLE_VALUE;
  92. }
  93. }
  94. TraceHr (ttidError, FAL, hr, FALSE, "CSharedAccessConnectionManager::FinalConstruct");
  95. return hr;
  96. }
  97. HRESULT CSharedAccessConnectionManager::FinalRelease(void)
  98. {
  99. HRESULT hr = S_OK;
  100. TraceTag(ttidConman, "CSharedAccessConnectionManager::FinalRelease");
  101. if(INVALID_HANDLE_VALUE != m_hSocketNotificationWait)
  102. {
  103. UnregisterWaitEx(m_hSocketNotificationWait, INVALID_HANDLE_VALUE); // we must block here since we are not addrefed
  104. }
  105. if(INVALID_SOCKET != m_DummySocket) // the event wait must be unregistered first
  106. {
  107. closesocket(m_DummySocket);
  108. }
  109. if(WSA_INVALID_EVENT != m_SocketEvent) // the socket must be closed first
  110. {
  111. CloseHandle(m_SocketEvent);
  112. }
  113. // After the other thread is shut down, the device finder and callback won't change any more so we don't need a lock.
  114. if(NULL != m_pDeviceFinder)
  115. {
  116. hr = m_pDeviceFinder->CancelAsyncFind(m_lSearchCookie);
  117. m_pDeviceFinder->Release();
  118. }
  119. if(NULL != m_pDeviceFinderCallback)
  120. {
  121. m_pDeviceFinderCallback->Release();
  122. }
  123. TraceHr (ttidError, FAL, hr, FALSE, "CSharedAccessConnectionManager::FinalRelease");
  124. return hr;
  125. }
  126. HRESULT CSharedAccessConnectionManager::StartSearch(void)
  127. {
  128. HRESULT hr = S_OK;
  129. CComObject<CSharedAccessDeviceFinderCallback>* pDeviceFinderCallback;
  130. hr = CComObject<CSharedAccessDeviceFinderCallback>::CreateInstance(&pDeviceFinderCallback);
  131. if(SUCCEEDED(hr))
  132. {
  133. pDeviceFinderCallback->AddRef();
  134. IUPnPDeviceFinder* pDeviceFinder;
  135. hr = CoCreateInstance(CLSID_UPnPDeviceFinder, NULL, CLSCTX_INPROC_SERVER, IID_IUPnPDeviceFinder, reinterpret_cast<void **>(&pDeviceFinder));
  136. if(SUCCEEDED(hr))
  137. {
  138. BSTR bstrTypeURI;
  139. bstrTypeURI = SysAllocString(L"urn:schemas-upnp-org:device:InternetGatewayDevice:1");
  140. if (NULL != bstrTypeURI)
  141. {
  142. LONG lSearchCookie;
  143. hr = pDeviceFinder->CreateAsyncFind(bstrTypeURI, 0, static_cast<IUPnPDeviceFinderCallback*>(pDeviceFinderCallback), &lSearchCookie);
  144. if(SUCCEEDED(hr))
  145. {
  146. LONG lOldSearchCookie;
  147. IUPnPDeviceFinder* pOldDeviceFinder;
  148. CComObject<CSharedAccessDeviceFinderCallback>* pOldDeviceFinderCallback;
  149. Lock(); // swap in the new finder and callback
  150. lOldSearchCookie = m_lSearchCookie;
  151. m_lSearchCookie = lSearchCookie;
  152. pOldDeviceFinder = m_pDeviceFinder;
  153. m_pDeviceFinder = pDeviceFinder;
  154. pDeviceFinder->AddRef();
  155. pOldDeviceFinderCallback = m_pDeviceFinderCallback;
  156. m_pDeviceFinderCallback = pDeviceFinderCallback;
  157. pDeviceFinderCallback->AddRef();
  158. Unlock();
  159. if(NULL != pOldDeviceFinder)
  160. {
  161. pOldDeviceFinder->CancelAsyncFind(lOldSearchCookie);
  162. pOldDeviceFinder->Release();
  163. }
  164. if(NULL != pOldDeviceFinderCallback)
  165. {
  166. pOldDeviceFinderCallback->DeviceRemoved(NULL, NULL); // clear out the old callback, so netshell gets cleaned up
  167. pOldDeviceFinderCallback->Release();
  168. }
  169. hr = pDeviceFinder->StartAsyncFind(lSearchCookie); // don't start the search until the new callback is in place
  170. }
  171. SysFreeString(bstrTypeURI);
  172. }
  173. pDeviceFinder->Release();
  174. }
  175. pDeviceFinderCallback->Release();
  176. }
  177. DWORD dwBytesReturned;
  178. if(SOCKET_ERROR != WSAIoctl(m_DummySocket, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &dwBytesReturned, NULL, NULL) || WSAEWOULDBLOCK != WSAGetLastError())
  179. {
  180. hr = E_FAIL;
  181. }
  182. WSANETWORKEVENTS NetworkEvents;
  183. ZeroMemory(&NetworkEvents, sizeof(NetworkEvents));
  184. WSAEnumNetworkEvents(m_DummySocket, NULL, &NetworkEvents);
  185. return hr;
  186. }
  187. void CSharedAccessConnectionManager::AsyncStartSearching(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
  188. {
  189. if(FALSE == TimerOrWaitFired)
  190. {
  191. CSharedAccessConnectionManager* pThis = reinterpret_cast<CSharedAccessConnectionManager*>(lpParameter);
  192. HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  193. if(SUCCEEDED(hr))
  194. {
  195. hr = pThis->StartSearch();
  196. CoUninitialize();
  197. }
  198. }
  199. return;
  200. }
  201. HRESULT CSharedAccessConnectionManager::GetSharedAccessBeacon(BSTR DeviceId, ISharedAccessBeacon** ppSharedAccessBeacon)
  202. {
  203. HRESULT hr = S_OK;
  204. *ppSharedAccessBeacon = NULL;
  205. CComObject<CSharedAccessDeviceFinderCallback>* pDeviceFinderCallback;
  206. Lock();
  207. pDeviceFinderCallback = m_pDeviceFinderCallback;
  208. if(NULL != pDeviceFinderCallback)
  209. {
  210. pDeviceFinderCallback->AddRef();
  211. }
  212. Unlock();
  213. if(NULL != pDeviceFinderCallback)
  214. {
  215. hr = pDeviceFinderCallback->GetSharedAccessBeacon(DeviceId, ppSharedAccessBeacon);
  216. pDeviceFinderCallback->Release();
  217. }
  218. else
  219. {
  220. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  221. }
  222. return hr;
  223. }