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.

391 lines
11 KiB

  1. #include "precomp.h"
  2. #include "iplgxprt.h"
  3. #include "nmmanager.h"
  4. IT120PluggableTransport * CNmManagerObj::ms_pT120Transport = NULL;
  5. #ifdef ENABLE_UPDATE_CONNECTION
  6. IPluggableTransportNotify * CNmManagerObj::ms_pPluggableTransportNotify = NULL;
  7. #endif
  8. BSTR LPSTR2BSTR(LPSTR pszConnID);
  9. BOOL BSTR2LPSTR(BSTR bstrConnID, LPSTR pszConnID);
  10. //////////////////////////////////////////////////
  11. //
  12. // CPluggableTransport
  13. //
  14. void CNmManagerObj::EnsureTransportInterface(void)
  15. {
  16. if (NULL == ms_pT120Transport)
  17. {
  18. T120Error rc = ::T120_CreatePluggableTransport(&ms_pT120Transport);
  19. ASSERT(T120_NO_ERROR == rc);
  20. }
  21. }
  22. BOOL CNmManagerObj::InitPluggableTransportSDK(void)
  23. {
  24. ms_pT120Transport = NULL;
  25. #ifdef ENABLE_UPDATE_CONNECTION
  26. ms_pPluggableTransportNotify = NULL;
  27. #endif
  28. return TRUE;
  29. }
  30. void CNmManagerObj::CleanupPluggableTransportSDK(void)
  31. {
  32. if (NULL != ms_pT120Transport)
  33. {
  34. ms_pT120Transport->ReleaseInterface();
  35. ms_pT120Transport = NULL;
  36. }
  37. #ifdef ENABLE_UPDATE_CONNECTION
  38. ms_pPluggableTransportNotify = NULL;
  39. #endif
  40. }
  41. //////////////////////////////////////////////////
  42. //
  43. // Connection @ CApplet
  44. //
  45. HRESULT CNmManagerObj::CreateConnection
  46. (
  47. BSTR *pbstrConnID, // For placing a call and closing connection
  48. PLUGXPRT_CALL_TYPE eCaller, // caller or callee
  49. DWORD dwProcessID, // Used for DuplicateHandle
  50. HCOMMDEV _hCommLink, // Handle to communications file handle
  51. HEVENT _hevtRead, // Ready To Read event ( data avail )
  52. HEVENT _hevtWrite, // Ready To Write event
  53. HEVENT _hevtClosed, // Connection closed ( unexpectedly???)
  54. PLUGXPRT_FRAMING eFraming, // framing of bits sent on link
  55. PLUGXPRT_PARAMETERS *pParams // OPTIONAL framing specific paramters
  56. )
  57. {
  58. EnsureTransportInterface();
  59. if (NULL != ms_pT120Transport)
  60. {
  61. if (NULL != pbstrConnID)
  62. {
  63. if (dwProcessID && _hCommLink && _hevtRead && _hevtWrite && _hevtClosed)
  64. {
  65. HRESULT hr = E_ACCESSDENIED;
  66. HANDLE hProcess = ::OpenProcess(PROCESS_DUP_HANDLE, TRUE, dwProcessID);
  67. if (NULL != hProcess)
  68. {
  69. HANDLE hCommLink;
  70. if (::DuplicateHandle(hProcess, (HANDLE) _hCommLink,
  71. ::GetCurrentProcess(), &hCommLink,
  72. 0, FALSE, DUPLICATE_SAME_ACCESS))
  73. {
  74. HANDLE hevtRead;
  75. if (::DuplicateHandle(hProcess, (HANDLE) _hevtRead,
  76. ::GetCurrentProcess(), &hevtRead,
  77. 0, FALSE, DUPLICATE_SAME_ACCESS))
  78. {
  79. HANDLE hevtWrite;
  80. if (::DuplicateHandle(hProcess, (HANDLE) _hevtWrite,
  81. ::GetCurrentProcess(), &hevtWrite,
  82. 0, FALSE, DUPLICATE_SAME_ACCESS))
  83. {
  84. HANDLE hevtClose;
  85. if (::DuplicateHandle(hProcess, (HANDLE) _hevtClosed,
  86. ::GetCurrentProcess(), &hevtClose,
  87. 0, FALSE, DUPLICATE_SAME_ACCESS))
  88. {
  89. char szConnID[T120_CONNECTION_ID_LENGTH];
  90. T120Error rc = ms_pT120Transport->CreateConnection(
  91. szConnID, eCaller, hCommLink,
  92. hevtRead, hevtWrite, hevtClose,
  93. eFraming, pParams);
  94. ASSERT(T120_NO_ERROR == rc);
  95. if (T120_NO_ERROR == rc)
  96. {
  97. *pbstrConnID = ::LPSTR2BSTR(szConnID);
  98. if (NULL != *pbstrConnID)
  99. {
  100. ::CloseHandle(hProcess);
  101. return S_OK;
  102. }
  103. hr = E_OUTOFMEMORY;
  104. }
  105. else
  106. {
  107. hr = E_HANDLE;
  108. }
  109. ::CloseHandle(hevtClose);
  110. }
  111. ::CloseHandle(hevtWrite);
  112. }
  113. ::CloseHandle(hevtRead);
  114. }
  115. ::CloseHandle(hCommLink);
  116. }
  117. ::CloseHandle(hProcess);
  118. }
  119. return hr;
  120. }
  121. return E_INVALIDARG;
  122. }
  123. return E_POINTER;
  124. }
  125. return E_OUTOFMEMORY;
  126. }
  127. #ifdef ENABLE_UPDATE_CONNECTION
  128. HRESULT CNmManagerObj::UpdateConnection
  129. (
  130. BSTR bstrConnID,
  131. DWORD dwProcessID, // Used for DuplicateHandle
  132. HCOMMDEV _hCommLink // Handle to communications file handle
  133. )
  134. {
  135. EnsureTransportInterface();
  136. if (NULL != ms_pT120Transport)
  137. {
  138. if (NULL != bstrConnID)
  139. {
  140. if (dwProcessID && _hCommLink)
  141. {
  142. HRESULT hr = E_ACCESSDENIED;
  143. HANDLE hProcess = ::OpenProcess(PROCESS_DUP_HANDLE, TRUE, dwProcessID);
  144. if (NULL != hProcess)
  145. {
  146. HANDLE hCommLink;
  147. if (::DuplicateHandle(hProcess, (HANDLE) _hCommLink,
  148. ::GetCurrentProcess(), &hCommLink,
  149. 0, FALSE, DUPLICATE_SAME_ACCESS))
  150. {
  151. char szConnID[T120_CONNECTION_ID_LENGTH];
  152. if (::BSTR2LPSTR(bstrConnID, szConnID))
  153. {
  154. T120Error rc = ms_pT120Transport->UpdateConnection(szConnID, hCommLink);
  155. ASSERT(T120_NO_ERROR == rc);
  156. if (T120_NO_ERROR == rc)
  157. {
  158. ::CloseHandle(hProcess);
  159. return S_OK;
  160. }
  161. hr = E_HANDLE;
  162. }
  163. ::CloseHandle(hCommLink);
  164. }
  165. ::CloseHandle(hProcess);
  166. }
  167. return hr;
  168. }
  169. return E_INVALIDARG;
  170. }
  171. return E_POINTER;
  172. }
  173. return E_OUTOFMEMORY;
  174. }
  175. #endif
  176. HRESULT CNmManagerObj::CloseConnection(BSTR bstrConnID)
  177. {
  178. EnsureTransportInterface();
  179. if (NULL != ms_pT120Transport)
  180. {
  181. if (NULL != bstrConnID)
  182. {
  183. char szConnID[T120_CONNECTION_ID_LENGTH];
  184. if (::BSTR2LPSTR(bstrConnID, szConnID))
  185. {
  186. T120Error rc = ms_pT120Transport->CloseConnection(szConnID);
  187. ASSERT(T120_NO_ERROR == rc);
  188. return (T120_NO_ERROR == rc) ? S_OK : E_INVALIDARG;
  189. }
  190. return E_INVALIDARG;
  191. }
  192. return E_POINTER;
  193. }
  194. return E_OUTOFMEMORY;
  195. }
  196. //////////////////////////////////////////////////
  197. //
  198. // Winsock @ CApplet
  199. //
  200. HRESULT CNmManagerObj::EnableWinsock(void)
  201. {
  202. EnsureTransportInterface();
  203. if (NULL != ms_pT120Transport)
  204. {
  205. T120Error rc = ms_pT120Transport->EnableWinsock();
  206. ASSERT(T120_NO_ERROR == rc);
  207. return (T120_NO_ERROR == rc) ? S_OK : E_ACCESSDENIED;
  208. }
  209. return E_OUTOFMEMORY;
  210. }
  211. HRESULT CNmManagerObj::DisableWinsock(void)
  212. {
  213. EnsureTransportInterface();
  214. if (NULL != ms_pT120Transport)
  215. {
  216. T120Error rc = ms_pT120Transport->DisableWinsock();
  217. ASSERT(T120_NO_ERROR == rc);
  218. return (T120_NO_ERROR == rc) ? S_OK : E_ACCESSDENIED;
  219. }
  220. return E_OUTOFMEMORY;
  221. }
  222. #ifdef ENABLE_UPDATE_CONNECTION
  223. void CALLBACK OnPluggableTransportNotify(PLUGXPRT_MESSAGE *pMsg)
  224. {
  225. if (NULL != pMsg->pContext)
  226. {
  227. CNmManagerObj *p = (CNmManagerObj *) pMsg->pContext;
  228. IPluggableTransportNotify *pNotify = p->ms_pPluggableTransportNotify;
  229. if (NULL != pNotify)
  230. {
  231. BSTR bstr = ::LPSTR2BSTR(pMsg->pszConnID);
  232. if (NULL != bstr)
  233. {
  234. switch (pMsg->eState)
  235. {
  236. case PLUGXPRT_CONNECTING:
  237. pNotify->OnConnecting(bstr, pMsg->eProtocol);
  238. break;
  239. case PLUGXPRT_CONNECTED:
  240. pNotify->OnConnected(bstr, pMsg->eProtocol, pMsg->eResult);
  241. break;
  242. case PLUGXPRT_DISCONNECTING:
  243. pNotify->OnDisconnecting(bstr, pMsg->eProtocol);
  244. break;
  245. case PLUGXPRT_DISCONNECTED:
  246. pNotify->OnDisconnected(bstr, pMsg->eProtocol, pMsg->eResult);
  247. break;
  248. }
  249. ::SysFreeString(bstr);
  250. }
  251. }
  252. }
  253. }
  254. #endif
  255. #ifdef ENABLE_UPDATE_CONNECTION
  256. HRESULT CNmManagerObj::AdvisePluggableTransport(IPluggableTransportNotify *pNotify, DWORD *pdwCookie)
  257. {
  258. EnsureTransportInterface();
  259. if (NULL != ms_pT120Transport)
  260. {
  261. // only allow one advise
  262. if (NULL == ms_pPluggableTransportNotify)
  263. {
  264. if (NULL != pNotify && NULL != pdwCookie)
  265. {
  266. pNotify->AddRef();
  267. ms_pPluggableTransportNotify = pNotify;
  268. AddRef();
  269. ms_pT120Transport->Advise(OnPluggableTransportNotify, this);
  270. *pdwCookie = (DWORD) this;
  271. return S_OK;
  272. }
  273. return E_POINTER;
  274. }
  275. return E_ACCESSDENIED;
  276. }
  277. return E_OUTOFMEMORY;
  278. }
  279. #endif
  280. #ifdef ENABLE_UPDATE_CONNECTION
  281. HRESULT CNmManagerObj::UnAdvisePluggableTransport(DWORD dwCookie)
  282. {
  283. EnsureTransportInterface();
  284. if (NULL != ms_pT120Transport)
  285. {
  286. if (NULL != ms_pPluggableTransportNotify)
  287. {
  288. if (dwCookie == (DWORD) this)
  289. {
  290. ms_pPluggableTransportNotify->Release();
  291. ms_pPluggableTransportNotify = NULL;
  292. ms_pT120Transport->UnAdvise();
  293. Release();
  294. return S_OK;
  295. }
  296. return E_ACCESSDENIED;
  297. }
  298. return E_POINTER;
  299. }
  300. return E_OUTOFMEMORY;
  301. }
  302. #endif
  303. BSTR LPSTR2BSTR(LPSTR pszConnID)
  304. {
  305. WCHAR wszConnID[T120_CONNECTION_ID_LENGTH];
  306. if (::MultiByteToWideChar(CP_ACP, 0, pszConnID, -1, wszConnID, T120_CONNECTION_ID_LENGTH))
  307. {
  308. return ::SysAllocString(wszConnID);
  309. }
  310. return NULL;
  311. }
  312. BOOL BSTR2LPSTR(BSTR bstrConnID, LPSTR pszConnID)
  313. {
  314. *pszConnID = '\0';
  315. return ::WideCharToMultiByte(CP_ACP, 0, bstrConnID, -1, pszConnID, T120_CONNECTION_ID_LENGTH, NULL, NULL);
  316. }