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.

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