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.

407 lines
9.8 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. CTSRDPServerChannelMgr.h
  5. Abstract:
  6. This module contains the TSRDP server-side subclass of
  7. CRemoteDesktopChannelMgr. Classes in this hierarchy are used to multiplex
  8. a single data channel into multiple client channels.
  9. CRemoteDesktopChannelMgr handles most of the details of multiplexing
  10. the data. Subclasses are responsible for implementing the details of
  11. interfacing with the transport for the underlying single data channel.
  12. The CTSRDPServerChannelMgr class creates a named pipe that
  13. can be connected to by the TSRDP Assistant SessionVC Add-In. The TSRDP
  14. Assistant Session VC Add-In acts as a proxy for virtual channel data
  15. from the client-side Remote Desktop Host ActiveX Control. A background
  16. thread in this class handles the movement of data between an instance
  17. of this class and the proxy.
  18. Author:
  19. Tad Brockway 02/00
  20. Revision History:
  21. --*/
  22. #ifndef __CTSRDPSERVERDATACHANNELMGR_H__
  23. #define __CTSRDPSERVERDATACHANNELMGR_H__
  24. #include <DataChannelMgr.h>
  25. #include <atlbase.h>
  26. #include <aclapi.h>
  27. #include <RemoteDesktopChannels.h>
  28. #include <rdshost.h>
  29. #include <resource.h>
  30. #include <ServerDataChannelMgrP.h>
  31. ///////////////////////////////////////////////////////
  32. //
  33. // CTSRDPServerDataChannel
  34. //
  35. // TSRDP Server-Specific Subclass of CRemoteDesktopDataChannel.
  36. //
  37. class ATL_NO_VTABLE CTSRDPServerDataChannel :
  38. public CRemoteDesktopDataChannel,
  39. public CComObjectRootEx<CComSingleThreadModel>,
  40. public CComCoClass<CTSRDPServerDataChannel, &CLSID_TSRDPServerDataChannel>,
  41. public IConnectionPointContainerImpl<CTSRDPServerDataChannel>,
  42. public IDispatchImpl<ISAFRemoteDesktopDataChannel, &IID_ISAFRemoteDesktopDataChannel, &LIBID_RDSSERVERHOSTLib>,
  43. public IProvideClassInfo2Impl<&CLSID_TSRDPServerDataChannelMgr, NULL, &LIBID_RDSSERVERHOSTLib>,
  44. public CProxy_ISAFRemoteDesktopDataChannelEvents< CTSRDPServerDataChannel >
  45. {
  46. protected:
  47. //
  48. // Scriptable Event Callback Object
  49. //
  50. CComPtr<IDispatch> m_OnChannelDataReady;
  51. //
  52. // Back pointer to the channel manager.
  53. //
  54. CRemoteDesktopChannelMgr *m_ChannelMgr;
  55. public:
  56. //
  57. // Constructor/Destructor
  58. //
  59. CTSRDPServerDataChannel();
  60. virtual ~CTSRDPServerDataChannel();
  61. //
  62. // Initialize an instance of this class.
  63. //
  64. virtual void Initialize(
  65. CRemoteDesktopChannelMgr *mgr,
  66. BSTR channelName
  67. )
  68. {
  69. m_ChannelMgr = mgr;
  70. m_ChannelName = channelName;
  71. }
  72. DECLARE_REGISTRY_RESOURCEID(IDR_TSRDPSERVERDATACHANNEL)
  73. DECLARE_PROTECT_FINAL_CONSTRUCT()
  74. BEGIN_COM_MAP(CTSRDPServerDataChannel)
  75. COM_INTERFACE_ENTRY(ISAFRemoteDesktopDataChannel)
  76. COM_INTERFACE_ENTRY2(IDispatch, ISAFRemoteDesktopDataChannel)
  77. COM_INTERFACE_ENTRY(IProvideClassInfo)
  78. COM_INTERFACE_ENTRY(IProvideClassInfo2)
  79. COM_INTERFACE_ENTRY(IConnectionPointContainer)
  80. END_COM_MAP()
  81. BEGIN_CONNECTION_POINT_MAP(CTSRDPServerDataChannel)
  82. CONNECTION_POINT_ENTRY(DIID__ISAFRemoteDesktopDataChannelEvents)
  83. END_CONNECTION_POINT_MAP()
  84. //
  85. // ISAFRemoteDesktopDataChannel Methods
  86. //
  87. // The parent class handles the details of these methods.
  88. //
  89. STDMETHOD(ReceiveChannelData)(/*[out, retval]*/BSTR *data);
  90. STDMETHOD(SendChannelData)(BSTR data);
  91. STDMETHOD(put_OnChannelDataReady)(/*[in]*/ IDispatch * newVal);
  92. STDMETHOD(get_ChannelName)(/*[out, retval]*/ BSTR *pVal);
  93. //
  94. // Called to return our ISAFRemoteDesktopDataChannel interface.
  95. //
  96. virtual HRESULT GetISAFRemoteDesktopDataChannel(
  97. ISAFRemoteDesktopDataChannel **channel
  98. ) {
  99. HRESULT hr;
  100. hr = this->QueryInterface(
  101. IID_ISAFRemoteDesktopDataChannel, (PVOID*)channel
  102. );
  103. return hr;
  104. }
  105. //
  106. // Called by the data channel manager when data is ready on our channel.
  107. //
  108. virtual VOID DataReady();
  109. //
  110. // Return this class name.
  111. //
  112. virtual const LPTSTR ClassName() { return TEXT("CTSRDPServerDataChannel"); }
  113. };
  114. ///////////////////////////////////////////////////////
  115. //
  116. // CTSRDPServerChannelMgr
  117. //
  118. class CTSRDPRemoteDesktopSession;
  119. class CTSRDPServerChannelMgr : public CRemoteDesktopChannelMgr,
  120. public CComObjectRootEx<CComSingleThreadModel>,
  121. public CComCoClass<CTSRDPServerChannelMgr, &CLSID_TSRDPServerDataChannelMgr>,
  122. public IDispatchImpl<ISAFRemoteDesktopChannelMgr, &IID_ISAFRemoteDesktopChannelMgr, &LIBID_RDSSERVERHOSTLib>,
  123. public IDispatchImpl<IRDSThreadBridge, &IID_IRDSThreadBridge, &LIBID_RDSSERVERHOSTLib>
  124. {
  125. private:
  126. //
  127. // Named pipe connection to TSRDP Assistant Session VC Add-In
  128. //
  129. HANDLE m_VCAddInPipe;
  130. BOOL m_Connected;
  131. //
  132. // Management of Bridge between Background Thread and STA
  133. // for this component.
  134. //
  135. LPSTREAM m_IOThreadBridgeStream;
  136. DWORD m_IOThreadBridgeThreadID;
  137. IRDSThreadBridge *m_IOThreadBridge;
  138. //
  139. // Back Pointer to the TSRDP Session Object
  140. //
  141. CTSRDPRemoteDesktopSession *m_RDPSessionObject;
  142. //
  143. // Incoming buffer and size.
  144. //
  145. BSTR m_IncomingBuffer;
  146. DWORD m_IncomingBufferSize;
  147. //
  148. // Handle to background thread and related events.
  149. //
  150. HANDLE m_IOThreadHndl;
  151. DWORD m_IOThreadID;
  152. HANDLE m_ReadIOCompleteEvent;
  153. HANDLE m_WriteIOCompleteEvent;
  154. HANDLE m_PipeCreateEvent;
  155. //
  156. // Machine Assistant Account Name
  157. //
  158. CComBSTR m_AssistAccount;
  159. //
  160. // Help session ID for the help session associated with this
  161. // instance of the channel manager.
  162. //
  163. CComBSTR m_HelpSessionID;
  164. //
  165. // Shutdown flag.
  166. //
  167. BOOL m_ThreadShutdownFlag;
  168. //
  169. // ThreadLock
  170. //
  171. CRITICAL_SECTION m_cs;
  172. #if DBG
  173. LONG m_LockCount;
  174. #endif
  175. //
  176. // ThreadLock/ThreadUnlock an instance of this class.
  177. //
  178. VOID ThreadLock();
  179. VOID ThreadUnlock();
  180. //
  181. // Background Thread Managing Named Pipe Connection to the
  182. // TSRDP Assistant SessionVC Add-In.
  183. //
  184. DWORD IOThread();
  185. static DWORD _IOThread(CTSRDPServerChannelMgr *instance);
  186. //
  187. // Process messages on the named pipe until it disconnects or
  188. // until the shutdown flag is set.
  189. //
  190. VOID ProcessPipeMessagesUntilDisconnect();
  191. //
  192. // Get the SID for a particular user.
  193. //
  194. PSID GetUserSid(HANDLE userToken);
  195. //
  196. // Release security attribs allocated via a call to
  197. // GetPipeSecurityAttribs
  198. //
  199. VOID FreePipeSecurityAttribs(PSECURITY_ATTRIBUTES attribs);
  200. //
  201. // Returns the security attribs for the named pipe.
  202. //
  203. PSECURITY_ATTRIBUTES GetPipeSecurityAttribs(LPTSTR assistantUserName);
  204. //
  205. // Close the named pipe.
  206. //
  207. VOID ClosePipe();
  208. //
  209. // Called on Init/Shutdown of IO Background Thread.
  210. //
  211. DWORD IOThreadInit();
  212. DWORD IOThreadShutdown(HANDLE shutDownEvent);
  213. //
  214. // Help the parent class out by opening the right channel object
  215. // for the platform.
  216. //
  217. virtual CRemoteDesktopDataChannel *OpenPlatformSpecificDataChannel(
  218. BSTR channelName,
  219. ISAFRemoteDesktopDataChannel **channel
  220. )
  221. {
  222. CComObject<CTSRDPServerDataChannel> *obj;
  223. obj = new CComObject<CTSRDPServerDataChannel>();
  224. if (obj != NULL) {
  225. obj->Initialize(this, channelName);
  226. obj->QueryInterface(
  227. __uuidof(ISAFRemoteDesktopDataChannel),
  228. (PVOID *)channel
  229. );
  230. }
  231. return obj;
  232. }
  233. protected:
  234. //
  235. // Send Function Invoked by Parent Class
  236. //
  237. virtual HRESULT SendData(PREMOTEDESKTOP_CHANNELBUFHEADER msg);
  238. //
  239. // Read the next message from the pipe. This function will
  240. // return, immediately, if the shutdown event is signaled.
  241. //
  242. DWORD ReadNextPipeMessage(DWORD bytesToRead, DWORD *bytesRead, PBYTE buf);
  243. public:
  244. //
  245. // Constructor/Destructor
  246. //
  247. CTSRDPServerChannelMgr();
  248. ~CTSRDPServerChannelMgr();
  249. //
  250. // Start/stop listening for channel data.
  251. //
  252. virtual HRESULT StartListening(BSTR assistAccount);
  253. virtual HRESULT StopListening();
  254. DECLARE_REGISTRY_RESOURCEID(IDR_TSRDPSERVERCHANNELMGR)
  255. DECLARE_PROTECT_FINAL_CONSTRUCT()
  256. BEGIN_COM_MAP(CTSRDPServerChannelMgr)
  257. COM_INTERFACE_ENTRY(ISAFRemoteDesktopChannelMgr)
  258. COM_INTERFACE_ENTRY(IDispatch)
  259. COM_INTERFACE_ENTRY(IRDSThreadBridge)
  260. END_COM_MAP()
  261. //
  262. // ISAFRemoteDesktopChannelMgr Methods
  263. //
  264. STDMETHOD(OpenDataChannel)(BSTR name, ISAFRemoteDesktopDataChannel **channel)
  265. {
  266. //
  267. // Let the parent handle it.
  268. //
  269. return OpenDataChannel_(name, channel);
  270. }
  271. //
  272. // Force a disconnect of the currently connected client.
  273. //
  274. VOID Disconnect() {
  275. StopListening();
  276. }
  277. //
  278. // IRDSThreadBridge Functions
  279. //
  280. // These functions are used to bridge functions that get called,
  281. // asynchronously, from a thread other than the STA thread associated
  282. // with an instance of this class.
  283. //
  284. STDMETHOD(ClientConnectedNotify)();
  285. STDMETHOD(ClientDisconnectedNotify)();
  286. STDMETHOD(DataReadyNotify)(BSTR data);
  287. //
  288. // Initialize an instance of this class.
  289. //
  290. virtual HRESULT Initialize(
  291. CTSRDPRemoteDesktopSession *sessionObject,
  292. BSTR helpSessionID
  293. );
  294. //
  295. // Return this class name.
  296. //
  297. virtual const LPTSTR ClassName()
  298. { return TEXT("CTSRDPServerChannelMgr"); }
  299. };
  300. ///////////////////////////////////////////////////////
  301. //
  302. // Inline Members
  303. //
  304. //
  305. // TODO: If nothing is using these functions,
  306. //
  307. inline VOID CTSRDPServerChannelMgr::ThreadLock()
  308. {
  309. DC_BEGIN_FN("CTSRDPServerChannelMgr::ThreadLock");
  310. #if DBG
  311. m_LockCount++;
  312. //TRC_NRM((TB, TEXT("ThreadLock count is now %ld."), m_LockCount));
  313. #endif
  314. EnterCriticalSection(&m_cs);
  315. DC_END_FN();
  316. }
  317. inline VOID CTSRDPServerChannelMgr::ThreadUnlock()
  318. {
  319. DC_BEGIN_FN("CTSRDPServerChannelMgr::ThreadUnlock");
  320. #if DBG
  321. m_LockCount--;
  322. //TRC_NRM((TB, TEXT("ThreadLock count is now %ld."), m_LockCount));
  323. ASSERT(m_LockCount >= 0);
  324. #endif
  325. LeaveCriticalSection(&m_cs);
  326. DC_END_FN();
  327. }
  328. #endif //__CTSRDPSERVERDATACHANNELMGR_H__