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.

332 lines
8.8 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #include "api.h"
  4. #include "upnphost.h"
  5. #include "CInternetGatewayDevice.h"
  6. #include "beaconrc.h"
  7. HRESULT BeaconEnabled(void);
  8. static const WCHAR c_szSharedAccessClientKeyPath[] = L"System\\CurrentControlSet\\Control\\Network\\SharedAccessConnection";
  9. static BSTR g_DeviceId = NULL;
  10. static BOOL g_bStarted = FALSE;
  11. static INATEventsSink* g_pNATEventsSink;
  12. CRITICAL_SECTION g_RegistrationProtection;
  13. CRITICAL_SECTION g_NATEventsProtection;
  14. HRESULT GetXMLPath(BSTR* pPath)
  15. {
  16. HRESULT hr = S_OK;
  17. *pPath = NULL;
  18. WCHAR szXMLDirectory[] = L"ICSXML";
  19. WCHAR szSystemDirectory[MAX_PATH + 1 + (sizeof(szXMLDirectory) / sizeof(WCHAR))];
  20. UINT uiSize = GetSystemDirectory(szSystemDirectory, MAX_PATH);
  21. if(0 != uiSize)
  22. {
  23. if(L'\\' != szSystemDirectory[uiSize])
  24. {
  25. szSystemDirectory[uiSize] = L'\\';
  26. uiSize++;
  27. }
  28. lstrcpy(&szSystemDirectory[uiSize], szXMLDirectory);
  29. *pPath = SysAllocString(szSystemDirectory);
  30. }
  31. else
  32. {
  33. hr = E_FAIL;
  34. }
  35. return hr;
  36. }
  37. HRESULT GetDescriptionDocument(INT nResource, BSTR* pDocument)
  38. {
  39. HRESULT hr = E_FAIL;
  40. *pDocument = NULL;
  41. HRSRC hrsrc = FindResource(_Module.GetResourceInstance(), MAKEINTRESOURCE(nResource), L"XML"); // REVIEW change this from 1
  42. if(hrsrc)
  43. {
  44. HGLOBAL hGlobal = LoadResource(_Module.GetResourceInstance(), hrsrc);
  45. if(hGlobal)
  46. {
  47. void* pvData = LockResource(hGlobal);
  48. if(pvData)
  49. {
  50. long nLength = SizeofResource(_Module.GetResourceInstance(), hrsrc);
  51. WCHAR * sz = new WCHAR[nLength + 1];
  52. if(NULL != sz)
  53. {
  54. if(0 != MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, reinterpret_cast<char*>(pvData), nLength, sz, nLength))
  55. {
  56. sz[nLength] = 0;
  57. *pDocument = SysAllocString(sz);
  58. if(NULL != *pDocument)
  59. {
  60. hr = S_OK;
  61. }
  62. }
  63. delete [] sz;
  64. }
  65. }
  66. FreeResource(hGlobal);
  67. }
  68. }
  69. return hr;
  70. }
  71. HRESULT WINAPI InitializeBeaconSvr()
  72. {
  73. __try
  74. {
  75. InitializeCriticalSection(&g_RegistrationProtection);
  76. InitializeCriticalSection(&g_NATEventsProtection);
  77. } __except(EXCEPTION_EXECUTE_HANDLER)
  78. {
  79. return E_FAIL;
  80. }
  81. return S_OK;
  82. }
  83. HRESULT WINAPI TerminateBeaconSvr()
  84. {
  85. DeleteCriticalSection(&g_RegistrationProtection);
  86. DeleteCriticalSection(&g_NATEventsProtection);
  87. return S_OK;
  88. }
  89. HRESULT WINAPI StartBeaconSvr(void)
  90. {
  91. HRESULT hr = S_OK;
  92. EnterCriticalSection(&g_RegistrationProtection);
  93. g_bStarted = TRUE;
  94. if(NULL == g_DeviceId)
  95. {
  96. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE); // Ensure we are in the MTA
  97. if(SUCCEEDED(hr))
  98. {
  99. hr = BeaconEnabled();
  100. if(SUCCEEDED(hr))
  101. {
  102. IUPnPRegistrar* pRegistrar;
  103. hr = CoCreateInstance(CLSID_UPnPRegistrar, NULL, CLSCTX_SERVER, IID_IUPnPRegistrar, reinterpret_cast<void**>(&pRegistrar));
  104. if(SUCCEEDED(hr))
  105. {
  106. CComObject<CInternetGatewayDevice>* pGatewayDevice;
  107. hr = CComObject<CInternetGatewayDevice>::CreateInstance(&pGatewayDevice);
  108. if(SUCCEEDED(hr))
  109. {
  110. pGatewayDevice->AddRef();
  111. BSTR bstrData;
  112. hr = GetDescriptionDocument(NCM_LAN == pGatewayDevice->m_pWANCommonInterfaceConfigService->m_MediaType ? IDXML_LAN : IDXML_RAS, &bstrData);
  113. if(SUCCEEDED(hr))
  114. {
  115. BSTR bstrInitString = SysAllocString(L"Init");
  116. if(NULL != bstrInitString)
  117. {
  118. BSTR pPath;
  119. hr = GetXMLPath(&pPath);
  120. if(SUCCEEDED(hr))
  121. {
  122. hr = pRegistrar->RegisterRunningDevice(bstrData, static_cast<IUPnPDeviceControl*>(pGatewayDevice), bstrInitString, pPath, 1800, &g_DeviceId);
  123. SysFreeString(pPath);
  124. }
  125. else
  126. {
  127. hr = E_OUTOFMEMORY;
  128. }
  129. SysFreeString(bstrInitString);
  130. }
  131. else
  132. {
  133. hr = E_OUTOFMEMORY;
  134. }
  135. SysFreeString(bstrData);
  136. }
  137. pGatewayDevice->Release();
  138. }
  139. pRegistrar->Release();
  140. }
  141. }
  142. CoUninitialize();
  143. }
  144. }
  145. LeaveCriticalSection(&g_RegistrationProtection);
  146. return hr;
  147. }
  148. HRESULT WINAPI SignalBeaconSvr(void)
  149. {
  150. HRESULT hr = S_OK;
  151. // go ahead and dump the whole object since the services need for the client are different.
  152. if(TRUE == g_bStarted)
  153. {
  154. hr = StopBeaconSvr();
  155. if(SUCCEEDED(hr))
  156. {
  157. hr = StartBeaconSvr();
  158. }
  159. }
  160. return hr;
  161. }
  162. HRESULT WINAPI StopBeaconSvr(void)
  163. {
  164. HRESULT hr = S_OK;
  165. IUPnPRegistrar* pRegistrar;
  166. EnterCriticalSection(&g_RegistrationProtection);
  167. if(NULL != g_DeviceId)
  168. {
  169. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE); // Ensure we are in the MTA
  170. if(SUCCEEDED(hr))
  171. {
  172. hr = CoCreateInstance(CLSID_UPnPRegistrar, NULL, CLSCTX_SERVER, IID_IUPnPRegistrar, reinterpret_cast<void**>(&pRegistrar));
  173. if(SUCCEEDED(hr))
  174. {
  175. hr = pRegistrar->UnregisterDevice(g_DeviceId, TRUE);
  176. pRegistrar->Release();
  177. }
  178. SysFreeString(g_DeviceId);
  179. g_DeviceId = NULL;
  180. CoUninitialize();
  181. }
  182. }
  183. g_bStarted = FALSE;
  184. LeaveCriticalSection(&g_RegistrationProtection);
  185. return hr;
  186. }
  187. HRESULT BeaconEnabled(void)
  188. {
  189. HRESULT hr = S_OK;
  190. HKEY hKey;
  191. if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szSharedAccessClientKeyPath, NULL, KEY_QUERY_VALUE, &hKey))
  192. {
  193. DWORD dwType;
  194. DWORD dwValue;
  195. DWORD dwSize = sizeof(dwValue);
  196. if(ERROR_SUCCESS == RegQueryValueEx(hKey, L"DisableBeacon", NULL, &dwType, reinterpret_cast<LPBYTE>(&dwValue), &dwSize))
  197. {
  198. if(REG_DWORD == dwType && 0 != dwValue)
  199. {
  200. hr = E_FAIL;
  201. }
  202. }
  203. RegCloseKey(hKey);
  204. }
  205. return hr;
  206. }
  207. // This function must be called on an MTA thread
  208. HRESULT AdviseNATEvents(INATEventsSink* pNATEventsSink)
  209. {
  210. HRESULT hr = S_OK;
  211. EnterCriticalSection(&g_NATEventsProtection);
  212. if(NULL == g_pNATEventsSink)
  213. {
  214. g_pNATEventsSink = pNATEventsSink;
  215. g_pNATEventsSink->AddRef();
  216. }
  217. else
  218. {
  219. hr = E_UNEXPECTED;
  220. }
  221. LeaveCriticalSection(&g_NATEventsProtection);
  222. return hr;
  223. }
  224. // This function must be called on an MTA thread
  225. HRESULT UnadviseNATEvents(INATEventsSink* pNatEventsSink)
  226. {
  227. HRESULT hr = S_OK;
  228. EnterCriticalSection(&g_NATEventsProtection);
  229. if(NULL != g_pNATEventsSink)
  230. {
  231. g_pNATEventsSink->Release();
  232. g_pNATEventsSink = NULL;
  233. }
  234. else
  235. {
  236. hr = E_UNEXPECTED;
  237. }
  238. LeaveCriticalSection(&g_NATEventsProtection);
  239. return hr;
  240. }
  241. HRESULT WINAPI FireNATEvent_PublicIPAddressChanged(void)
  242. {
  243. HRESULT hr = S_OK;
  244. EnterCriticalSection(&g_NATEventsProtection);
  245. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE); // Ensure we are in the MTA
  246. if(SUCCEEDED(hr))
  247. {
  248. if(NULL != g_pNATEventsSink)
  249. {
  250. g_pNATEventsSink->PublicIPAddressChanged();
  251. }
  252. CoUninitialize();
  253. }
  254. LeaveCriticalSection(&g_NATEventsProtection);
  255. return hr;
  256. }
  257. HRESULT WINAPI FireNATEvent_PortMappingsChanged(void)
  258. {
  259. HRESULT hr = S_OK;
  260. EnterCriticalSection(&g_NATEventsProtection);
  261. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED| COINIT_DISABLE_OLE1DDE); // Ensure we are in the MTA
  262. if(SUCCEEDED(hr))
  263. {
  264. if(NULL != g_pNATEventsSink)
  265. {
  266. g_pNATEventsSink->PortMappingsChanged();
  267. }
  268. CoUninitialize();
  269. }
  270. LeaveCriticalSection(&g_NATEventsProtection);
  271. return hr;
  272. }