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.

270 lines
8.3 KiB

  1. // UPnPNAT.cpp : Implementation of CUPnPNAT
  2. #include "stdafx.h"
  3. #pragma hdrstop
  4. #include "UPnPNAT.h"
  5. #include "NATEM.h"
  6. #include "dprtmapc.h"
  7. #include "sprtmapc.h"
  8. DEFINE_GUID(CLSID_CInternetGatewayFinder,
  9. 0x4d3f9715, 0x73da, 0x4506, 0x89, 0x33, 0x1e, 0xe, 0x17, 0x18, 0xba, 0x3b);
  10. void __cdecl nat_trans_func (unsigned int uSECode, EXCEPTION_POINTERS* pExp)
  11. {
  12. throw NAT_SEH_Exception (uSECode);
  13. }
  14. void EnableNATExceptionHandling()
  15. {
  16. _set_se_translator (nat_trans_func);
  17. }
  18. void DisableNATExceptionHandling()
  19. {
  20. _set_se_translator (NULL);
  21. }
  22. HRESULT GetServiceFromINetConnection (IUnknown * pUnk, IUPnPService ** ppUPS)
  23. {
  24. CComPtr<INetConnection> spNC = NULL;
  25. HRESULT hr = pUnk->QueryInterface (__uuidof(INetConnection), (void**)&spNC);
  26. if (!spNC)
  27. return E_INVALIDARG;
  28. SAHOST_SERVICES sas;
  29. // make sure we have either
  30. // NCM_SHAREDACCESSHOST_LAN or NCM_SHAREDACCESSHOST_RAS
  31. switch (GetMediaType (spNC)) {
  32. case NCM_SHAREDACCESSHOST_LAN:
  33. sas = SAHOST_SERVICE_WANIPCONNECTION;
  34. break;
  35. case NCM_SHAREDACCESSHOST_RAS:
  36. sas = SAHOST_SERVICE_WANPPPCONNECTION;
  37. break;
  38. default:
  39. return E_INVALIDARG;
  40. }
  41. CComPtr<INetSharedAccessConnection> spNSAC = NULL;
  42. hr = pUnk->QueryInterface (__uuidof(INetSharedAccessConnection), (void**)&spNSAC);
  43. if (spNSAC)
  44. hr = spNSAC->GetService (sas, ppUPS);
  45. return hr;
  46. }
  47. HRESULT GetServiceFromFinder (IInternetGatewayFinder * pIGF, IUPnPService ** ppUPS)
  48. {
  49. CComPtr<IInternetGateway> spIG = NULL;
  50. HRESULT hr = pIGF->GetInternetGateway (NULL, &spIG); // NULL gets default.
  51. if (spIG) {
  52. NETCON_MEDIATYPE MediaType = NCM_NONE;
  53. hr = spIG->GetMediaType (&MediaType);
  54. if (SUCCEEDED(hr)) {
  55. switch (MediaType) {
  56. case NCM_SHAREDACCESSHOST_LAN:
  57. hr = spIG->GetService (SAHOST_SERVICE_WANIPCONNECTION, ppUPS);
  58. break;
  59. case NCM_SHAREDACCESSHOST_RAS:
  60. hr = spIG->GetService (SAHOST_SERVICE_WANPPPCONNECTION, ppUPS);
  61. break;
  62. default:
  63. return E_UNEXPECTED;
  64. }
  65. }
  66. }
  67. return hr;
  68. }
  69. HRESULT GetService (IUPnPService ** ppUPS)
  70. {
  71. if (!ppUPS)
  72. return E_POINTER;
  73. *ppUPS = NULL;
  74. // either enum all netconnections, or
  75. // for downlevel, use Ken's object
  76. CComPtr<INetConnectionManager> spNCM = NULL;
  77. HRESULT hr = ::CoCreateInstance (CLSID_ConnectionManager,
  78. NULL,
  79. CLSCTX_ALL,
  80. __uuidof(INetConnectionManager),
  81. (void**)&spNCM);
  82. if (spNCM) {
  83. CComPtr<IUnknown> spUnk = NULL;
  84. CComPtr<IEnumNetConnection> spENC = NULL;
  85. hr = spNCM->EnumConnections (NCME_DEFAULT, &spENC);
  86. if (spENC) {
  87. ULONG ul = 0;
  88. CComPtr<INetConnection> spNC = NULL;
  89. while (S_OK == spENC->Next (1, &spNC, &ul)) {
  90. NETCON_PROPERTIES * pProps = NULL;
  91. spNC->GetProperties (&pProps);
  92. if (pProps) {
  93. NETCON_MEDIATYPE MediaType = pProps->MediaType;
  94. NcFreeNetconProperties (pProps);
  95. if ((MediaType == NCM_SHAREDACCESSHOST_LAN) ||
  96. (MediaType == NCM_SHAREDACCESSHOST_RAS) ){
  97. // found it
  98. spNC->QueryInterface (__uuidof(IUnknown),
  99. (void**)&spUnk);
  100. break;
  101. }
  102. }
  103. spNC = NULL;
  104. }
  105. }
  106. if (spUnk)
  107. hr = GetServiceFromINetConnection (spUnk, ppUPS);
  108. } else {
  109. // downlevel
  110. CComPtr<IInternetGatewayFinder> spIGF = NULL;
  111. hr = ::CoCreateInstance (CLSID_CInternetGatewayFinder,
  112. NULL,
  113. CLSCTX_ALL,
  114. __uuidof(IInternetGatewayFinder),
  115. (void**)&spIGF);
  116. if (spIGF)
  117. hr = GetServiceFromFinder (spIGF, ppUPS);
  118. }
  119. return hr;
  120. }
  121. template<class C, class I> class UN {
  122. public:
  123. HRESULT Create (I ** ppI)
  124. {
  125. if (ppI)
  126. *ppI = NULL;
  127. if (!ppI)
  128. return E_POINTER;
  129. CComPtr<IUPnPService> spUPS = NULL;
  130. HRESULT hr = GetService (&spUPS);
  131. if (spUPS) {
  132. // create class so that I can initialize it
  133. CComObject<C> * pC = NULL;
  134. hr = CComObject<C>::CreateInstance (&pC);
  135. if (pC) {
  136. pC->AddRef();
  137. // init
  138. hr = pC->Initialize (spUPS);
  139. if (SUCCEEDED(hr))
  140. hr = pC->QueryInterface (__uuidof(I), (void**)ppI);
  141. pC->Release();
  142. }
  143. }
  144. return hr;
  145. }
  146. };
  147. /////////////////////////////////////////////////////////////////////////////
  148. // CUPnPNAT
  149. STDMETHODIMP CUPnPNAT::get_NATEventManager(INATEventManager ** ppNEM)
  150. {
  151. NAT_API_ENTER
  152. UN<CNATEventManager, INATEventManager> un;
  153. return un.Create (ppNEM);
  154. NAT_API_LEAVE
  155. }
  156. STDMETHODIMP CUPnPNAT::get_DynamicPortMappingCollection (IDynamicPortMappingCollection ** ppDPMC)
  157. {
  158. NAT_API_ENTER
  159. // remove the section below when turning dynamic port mappings back on
  160. if (!ppDPMC)
  161. return E_POINTER;
  162. *ppDPMC = NULL;
  163. return E_NOTIMPL;
  164. // remove the section above when turning dynamic port mappings back on
  165. UN<CDynamicPortMappingCollection, IDynamicPortMappingCollection> un;
  166. return un.Create (ppDPMC);
  167. NAT_API_LEAVE
  168. }
  169. STDMETHODIMP CUPnPNAT::get_StaticPortMappingCollection (IStaticPortMappingCollection ** ppSPMC)
  170. {
  171. NAT_API_ENTER
  172. UN<CStaticPortMappingCollection, IStaticPortMappingCollection> un;
  173. return un.Create (ppSPMC);
  174. NAT_API_LEAVE
  175. }
  176. // private method(s)
  177. HRESULT GetOSInfoService (IUPnPService ** ppUPS)
  178. {
  179. if (!ppUPS)
  180. return E_POINTER;
  181. *ppUPS = NULL;
  182. // either enum all netconnections, or
  183. // for downlevel, use Ken's object
  184. CComPtr<INetConnectionManager> spNCM = NULL;
  185. HRESULT hr = ::CoCreateInstance (CLSID_ConnectionManager,
  186. NULL,
  187. CLSCTX_ALL,
  188. __uuidof(INetConnectionManager),
  189. (void**)&spNCM);
  190. if (spNCM) {
  191. CComPtr<IEnumNetConnection> spENC = NULL;
  192. hr = spNCM->EnumConnections (NCME_DEFAULT, &spENC);
  193. if (spENC) {
  194. ULONG ul = 0;
  195. CComPtr<INetConnection> spNC = NULL;
  196. while (S_OK == spENC->Next (1, &spNC, &ul)) {
  197. NETCON_PROPERTIES * pProps = NULL;
  198. spNC->GetProperties (&pProps);
  199. if (pProps) {
  200. NETCON_MEDIATYPE MediaType = pProps->MediaType;
  201. NcFreeNetconProperties (pProps);
  202. if ((MediaType == NCM_SHAREDACCESSHOST_LAN) ||
  203. (MediaType == NCM_SHAREDACCESSHOST_RAS) ){
  204. // found it
  205. break;
  206. }
  207. }
  208. spNC = NULL;
  209. }
  210. if (spNC) {
  211. CComPtr<INetSharedAccessConnection> spNSAC = NULL;
  212. hr = spNC->QueryInterface (__uuidof(INetSharedAccessConnection), (void**)&spNSAC);
  213. if (spNSAC)
  214. hr = spNSAC->GetService (SAHOST_SERVICE_OSINFO, ppUPS);
  215. } else
  216. hr = HRESULT_FROM_WIN32 (ERROR_FILE_NOT_FOUND);
  217. }
  218. } else {
  219. // downlevel
  220. CComPtr<IInternetGatewayFinder> spIGF = NULL;
  221. hr = ::CoCreateInstance (CLSID_CInternetGatewayFinder,
  222. NULL,
  223. CLSCTX_ALL,
  224. __uuidof(IInternetGatewayFinder),
  225. (void**)&spIGF);
  226. if (spIGF) {
  227. CComPtr<IInternetGateway> spIG = NULL;
  228. hr = spIGF->GetInternetGateway (NULL, &spIG); // NULL gets default.
  229. if (spIG)
  230. hr = spIG->GetService (SAHOST_SERVICE_OSINFO, ppUPS);
  231. }
  232. }
  233. return hr;
  234. }
  235. BOOL IsICSHost ()
  236. {
  237. CComPtr<IUPnPService> spOSI = NULL;
  238. GetOSInfoService (&spOSI);
  239. if (spOSI)
  240. return TRUE;
  241. return FALSE;
  242. }