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.

272 lines
8.6 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. hr = HRESULT_FROM_WIN32 (ERROR_FILE_NOT_FOUND);
  110. } else {
  111. // downlevel
  112. CComPtr<IInternetGatewayFinder> spIGF = NULL;
  113. hr = ::CoCreateInstance (CLSID_CInternetGatewayFinder,
  114. NULL,
  115. CLSCTX_ALL,
  116. __uuidof(IInternetGatewayFinder),
  117. (void**)&spIGF);
  118. if (spIGF)
  119. hr = GetServiceFromFinder (spIGF, ppUPS);
  120. }
  121. return hr;
  122. }
  123. template<class C, class I> class UN {
  124. public:
  125. HRESULT Create (I ** ppI)
  126. {
  127. if (ppI)
  128. *ppI = NULL;
  129. if (!ppI)
  130. return E_POINTER;
  131. CComPtr<IUPnPService> spUPS = NULL;
  132. HRESULT hr = GetService (&spUPS);
  133. if (spUPS) {
  134. // create class so that I can initialize it
  135. CComObject<C> * pC = NULL;
  136. hr = CComObject<C>::CreateInstance (&pC);
  137. if (pC) {
  138. pC->AddRef();
  139. // init
  140. hr = pC->Initialize (spUPS);
  141. if (SUCCEEDED(hr))
  142. hr = pC->QueryInterface (__uuidof(I), (void**)ppI);
  143. pC->Release();
  144. }
  145. }
  146. return hr;
  147. }
  148. };
  149. /////////////////////////////////////////////////////////////////////////////
  150. // CUPnPNAT
  151. STDMETHODIMP CUPnPNAT::get_NATEventManager(INATEventManager ** ppNEM)
  152. {
  153. NAT_API_ENTER
  154. UN<CNATEventManager, INATEventManager> un;
  155. return un.Create (ppNEM);
  156. NAT_API_LEAVE
  157. }
  158. STDMETHODIMP CUPnPNAT::get_DynamicPortMappingCollection (IDynamicPortMappingCollection ** ppDPMC)
  159. {
  160. NAT_API_ENTER
  161. // remove the section below when turning dynamic port mappings back on
  162. if (!ppDPMC)
  163. return E_POINTER;
  164. *ppDPMC = NULL;
  165. return E_NOTIMPL;
  166. // remove the section above when turning dynamic port mappings back on
  167. UN<CDynamicPortMappingCollection, IDynamicPortMappingCollection> un;
  168. return un.Create (ppDPMC);
  169. NAT_API_LEAVE
  170. }
  171. STDMETHODIMP CUPnPNAT::get_StaticPortMappingCollection (IStaticPortMappingCollection ** ppSPMC)
  172. {
  173. NAT_API_ENTER
  174. UN<CStaticPortMappingCollection, IStaticPortMappingCollection> un;
  175. return un.Create (ppSPMC);
  176. NAT_API_LEAVE
  177. }
  178. // private method(s)
  179. HRESULT GetOSInfoService (IUPnPService ** ppUPS)
  180. {
  181. if (!ppUPS)
  182. return E_POINTER;
  183. *ppUPS = NULL;
  184. // either enum all netconnections, or
  185. // for downlevel, use Ken's object
  186. CComPtr<INetConnectionManager> spNCM = NULL;
  187. HRESULT hr = ::CoCreateInstance (CLSID_ConnectionManager,
  188. NULL,
  189. CLSCTX_ALL,
  190. __uuidof(INetConnectionManager),
  191. (void**)&spNCM);
  192. if (spNCM) {
  193. CComPtr<IEnumNetConnection> spENC = NULL;
  194. hr = spNCM->EnumConnections (NCME_DEFAULT, &spENC);
  195. if (spENC) {
  196. ULONG ul = 0;
  197. CComPtr<INetConnection> spNC = NULL;
  198. while (S_OK == spENC->Next (1, &spNC, &ul)) {
  199. NETCON_PROPERTIES * pProps = NULL;
  200. spNC->GetProperties (&pProps);
  201. if (pProps) {
  202. NETCON_MEDIATYPE MediaType = pProps->MediaType;
  203. NcFreeNetconProperties (pProps);
  204. if ((MediaType == NCM_SHAREDACCESSHOST_LAN) ||
  205. (MediaType == NCM_SHAREDACCESSHOST_RAS) ){
  206. // found it
  207. break;
  208. }
  209. }
  210. spNC = NULL;
  211. }
  212. if (spNC) {
  213. CComPtr<INetSharedAccessConnection> spNSAC = NULL;
  214. hr = spNC->QueryInterface (__uuidof(INetSharedAccessConnection), (void**)&spNSAC);
  215. if (spNSAC)
  216. hr = spNSAC->GetService (SAHOST_SERVICE_OSINFO, ppUPS);
  217. } else
  218. hr = HRESULT_FROM_WIN32 (ERROR_FILE_NOT_FOUND);
  219. }
  220. } else {
  221. // downlevel
  222. CComPtr<IInternetGatewayFinder> spIGF = NULL;
  223. hr = ::CoCreateInstance (CLSID_CInternetGatewayFinder,
  224. NULL,
  225. CLSCTX_ALL,
  226. __uuidof(IInternetGatewayFinder),
  227. (void**)&spIGF);
  228. if (spIGF) {
  229. CComPtr<IInternetGateway> spIG = NULL;
  230. hr = spIGF->GetInternetGateway (NULL, &spIG); // NULL gets default.
  231. if (spIG)
  232. hr = spIG->GetService (SAHOST_SERVICE_OSINFO, ppUPS);
  233. }
  234. }
  235. return hr;
  236. }
  237. BOOL IsICSHost ()
  238. {
  239. CComPtr<IUPnPService> spOSI = NULL;
  240. GetOSInfoService (&spOSI);
  241. if (spOSI)
  242. return TRUE;
  243. return FALSE;
  244. }