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.

858 lines
24 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. TSRDPRemoteDesktopClient
  5. Abstract:
  6. This is the TS/RDP implementation of the Remote Desktop Client class.
  7. The Remote Desktop Client class hierarchy provides a pluggable C++
  8. interface for remote desktop access, by abstracting the implementation
  9. specific details of remote desktop access for the client-side
  10. The TSRDPRemoteDesktopClass implements remote-desktopping
  11. with the help of an instance of the MSTSC ActiveX client control.
  12. Author:
  13. Tad Brockway 02/00
  14. Revision History:
  15. --*/
  16. #ifndef __TSRDPREMOTEDESKTOPCLIENT_H_
  17. #define __TSRDPREMOTEDESKTOPCLIENT_H_
  18. #include "resource.h"
  19. #include <atlctl.h>
  20. #include "RDCHostCP.h"
  21. #include <mstsax.h>
  22. #include <rdchost.h>
  23. #include <RemoteDesktopTopLevelObject.h>
  24. #include <RemoteDesktopUtils.h>
  25. #include "parseaddr.h"
  26. #pragma warning (disable: 4786)
  27. #include <list>
  28. #include "icshelpapi.h"
  29. #define IDC_MSTSCEVENT_SOURCE_OBJ 1
  30. #define IDC_CHANNELEVENT_SOURCE_OBJ 2
  31. #define WM_STARTLISTEN (0xBFFE)
  32. #define WM_TSCONNECT (0xBFFF)
  33. #define WM_LISTENTIMEOUT_TIMER 1
  34. #define WM_CONNECTCHECK_TIMER 2
  35. #define MAX_FETCHIPADDRESSRETRY 5
  36. //
  37. // MSTSC ActiveX GUID
  38. //
  39. #define MSTSCAX_TEXTGUID _T("{7cacbd7b-0d99-468f-ac33-22e495c0afe5}")
  40. #define RDC_CHECKCONN_TIMEOUT (30 * 1000) //millisec. default value to ping is 30 seconds
  41. #define RDC_CONNCHECK_ENTRY L"ConnectionCheck"
  42. //
  43. // Info for all the event functions is entered here
  44. // there is a way to have ATL do this automatically using typelib's
  45. // but it is slower.
  46. //
  47. static _ATL_FUNC_INFO TSRDPClientEventFuncNoParamsInfo =
  48. {
  49. CC_STDCALL, // Calling convention.
  50. VT_EMPTY, // Return type.
  51. 0, // Number of arguments.
  52. {VT_EMPTY} // Argument types.
  53. };
  54. static _ATL_FUNC_INFO TSRDPClientEventFuncLongParamInfo =
  55. {
  56. CC_STDCALL, // Calling convention.
  57. VT_EMPTY, // Return type.
  58. 1, // Number of arguments.
  59. {VT_I4} // Argument types.
  60. };
  61. static _ATL_FUNC_INFO TSRDPClientEventFuncTwoStringParamInfo =
  62. {
  63. CC_STDCALL, // Calling convention.
  64. VT_EMPTY, // Return type.
  65. 2, // Number of arguments.
  66. {VT_BSTR, // Argument types
  67. VT_BSTR}
  68. };
  69. static _ATL_FUNC_INFO TSRDPClientEventFuncReceivePublicKeyParamInfo =
  70. {
  71. CC_STDCALL, // Calling convention.
  72. VT_EMPTY, // Return type.
  73. 2, // Number of arguments.
  74. {VT_BSTR, // Argument types
  75. VT_BYREF | VT_BOOL }
  76. };
  77. static _ATL_FUNC_INFO TSRDPClientEventFuncOneStringParamInfo =
  78. {
  79. CC_STDCALL, // Calling convention.
  80. VT_EMPTY, // Return type.
  81. 1, // Number of arguments.
  82. {VT_BSTR} // Argument types
  83. };
  84. ///////////////////////////////////////////////////////
  85. //
  86. // CMSTSCClientEventSink
  87. //
  88. class CTSRDPRemoteDesktopClient;
  89. class CMSTSCClientEventSink :
  90. public IDispEventSimpleImpl<IDC_MSTSCEVENT_SOURCE_OBJ, CMSTSCClientEventSink,
  91. &DIID_IMsTscAxEvents>,
  92. public CRemoteDesktopTopLevelObject
  93. {
  94. public:
  95. CTSRDPRemoteDesktopClient *m_Obj;
  96. public:
  97. BEGIN_SINK_MAP(CMSTSCClientEventSink)
  98. SINK_ENTRY_INFO(IDC_MSTSCEVENT_SOURCE_OBJ, DIID_IMsTscAxEvents,
  99. DISPID_CONNECTED, OnRDPConnected,
  100. &TSRDPClientEventFuncNoParamsInfo)
  101. SINK_ENTRY_INFO(IDC_MSTSCEVENT_SOURCE_OBJ, DIID_IMsTscAxEvents,
  102. DISPID_DISCONNECTED, OnDisconnected,
  103. &TSRDPClientEventFuncLongParamInfo)
  104. SINK_ENTRY_INFO(IDC_MSTSCEVENT_SOURCE_OBJ, DIID_IMsTscAxEvents,
  105. DISPID_LOGINCOMPLETE, OnLoginComplete,
  106. &TSRDPClientEventFuncNoParamsInfo)
  107. SINK_ENTRY_INFO(IDC_MSTSCEVENT_SOURCE_OBJ, DIID_IMsTscAxEvents,
  108. DISPID_RECEVIEDTSPUBLICKEY, OnReceivedTSPublicKey,
  109. &TSRDPClientEventFuncReceivePublicKeyParamInfo)
  110. SINK_ENTRY_INFO(IDC_MSTSCEVENT_SOURCE_OBJ, DIID_IMsTscAxEvents,
  111. DISPID_CHANNELRECEIVEDDATA, OnReceiveData,
  112. &TSRDPClientEventFuncTwoStringParamInfo)
  113. END_SINK_MAP()
  114. CMSTSCClientEventSink()
  115. {
  116. m_Obj = NULL;
  117. }
  118. ~CMSTSCClientEventSink();
  119. //
  120. // Event Sinks
  121. //
  122. void __stdcall OnReceivedTSPublicKey(BSTR publicKey, VARIANT_BOOL* pfContinue);
  123. HRESULT __stdcall OnRDPConnected();
  124. HRESULT __stdcall OnLoginComplete();
  125. HRESULT __stdcall OnDisconnected(long disconReason);
  126. void __stdcall OnReceiveData(BSTR chanName, BSTR data);
  127. //
  128. // Return the name of this class.
  129. //
  130. virtual const LPTSTR ClassName() {
  131. return TEXT("CMSTSCClientEventSink");
  132. }
  133. };
  134. ///////////////////////////////////////////////////////
  135. //
  136. // CCtlChannelEventSink
  137. //
  138. // Control Channel Event Sink
  139. //
  140. class CCtlChannelEventSink :
  141. public IDispEventSimpleImpl<IDC_CHANNELEVENT_SOURCE_OBJ, CCtlChannelEventSink,
  142. &DIID__ISAFRemoteDesktopDataChannelEvents>,
  143. public CRemoteDesktopTopLevelObject
  144. {
  145. public:
  146. CTSRDPRemoteDesktopClient *m_Obj;
  147. public:
  148. BEGIN_SINK_MAP(CCtlChannelEventSink)
  149. SINK_ENTRY_INFO(IDC_CHANNELEVENT_SOURCE_OBJ, DIID__ISAFRemoteDesktopDataChannelEvents,
  150. DISPID_RDSCHANNELEVENTS_CHANNELDATAREADY, DataReady,
  151. &TSRDPClientEventFuncOneStringParamInfo)
  152. END_SINK_MAP()
  153. CCtlChannelEventSink()
  154. {
  155. m_Obj = NULL;
  156. }
  157. ~CCtlChannelEventSink();
  158. //
  159. // Event Sinks
  160. //
  161. void __stdcall DataReady(BSTR channelName);
  162. //
  163. // Return the name of this class.
  164. //
  165. virtual const LPTSTR ClassName() {
  166. return TEXT("CCtlChannelEventSink");
  167. }
  168. };
  169. ///////////////////////////////////////////////////////
  170. //
  171. // CTSRDPRemoteDesktopClient
  172. //
  173. class CMSTSCClientEventSink;
  174. class ATL_NO_VTABLE CTSRDPRemoteDesktopClient :
  175. public CComObjectRootEx<CComSingleThreadModel>,
  176. public CComControl<CTSRDPRemoteDesktopClient>,
  177. public IPersistStreamInitImpl<CTSRDPRemoteDesktopClient>,
  178. public IOleControlImpl<CTSRDPRemoteDesktopClient>,
  179. public IOleObjectImpl<CTSRDPRemoteDesktopClient>,
  180. public IOleInPlaceActiveObjectImpl<CTSRDPRemoteDesktopClient>,
  181. public IViewObjectExImpl<CTSRDPRemoteDesktopClient>,
  182. public IOleInPlaceObjectWindowlessImpl<CTSRDPRemoteDesktopClient>,
  183. public IPersistStorageImpl<CTSRDPRemoteDesktopClient>,
  184. public ISpecifyPropertyPagesImpl<CTSRDPRemoteDesktopClient>,
  185. public IQuickActivateImpl<CTSRDPRemoteDesktopClient>,
  186. public IDataObjectImpl<CTSRDPRemoteDesktopClient>,
  187. public IProvideClassInfo2Impl<&CLSID_TSRDPRemoteDesktopClient, &DIID__ISAFRemoteDesktopClientEvents, &LIBID_RDCCLIENTHOSTLib>,
  188. public CComCoClass<CTSRDPRemoteDesktopClient, &CLSID_TSRDPRemoteDesktopClient>,
  189. public IDispatchImpl<ISAFRemoteDesktopClient, &IID_ISAFRemoteDesktopClient, &LIBID_RDCCLIENTHOSTLib>,
  190. public IDispatchImpl<ISAFRemoteDesktopTestExtension, &IID_ISAFRemoteDesktopTestExtension, &LIBID_RDCCLIENTHOSTLib>,
  191. public IDataChannelIO,
  192. public CProxy_ISAFRemoteDesktopClientEvents< CTSRDPRemoteDesktopClient>,
  193. public CProxy_IDataChannelIOEvents< CTSRDPRemoteDesktopClient>,
  194. public IConnectionPointContainerImpl<CTSRDPRemoteDesktopClient>,
  195. public CRemoteDesktopTopLevelObject
  196. {
  197. friend CCtlChannelEventSink;
  198. private:
  199. IMsRdpClient2 *m_TSClient;
  200. HWND m_TSClientWnd;
  201. CAxWindow m_TSClientAxView;
  202. BOOL m_ConnectionInProgress;
  203. BOOL m_RemoteControlRequestInProgress;
  204. BOOL m_ConnectedToServer;
  205. BOOL m_Initialized;
  206. LONG m_LastExtendedErrorInfo;
  207. //
  208. // Event sink receives events fired by the TS client control..
  209. //
  210. CMSTSCClientEventSink m_TSClientEventSink;
  211. //
  212. // Control Channel Event Sink
  213. //
  214. CCtlChannelEventSink m_CtlChannelEventSink;
  215. //
  216. // Multiplexes Channel Data
  217. //
  218. CComPtr<ISAFRemoteDesktopChannelMgr> m_ChannelMgr;
  219. CComPtr<ISAFRemoteDesktopDataChannel> m_CtlChannel;
  220. //
  221. // The parsed connection parameters.
  222. //
  223. DWORD m_ConnectParmVersion;
  224. CComBSTR m_AssistantAccount;
  225. CComBSTR m_AssistantAccountPwd;
  226. CComBSTR m_HelpSessionName;
  227. CComBSTR m_HelpSessionID;
  228. CComBSTR m_HelpSessionPwd;
  229. CComBSTR m_TSSecurityBlob;
  230. ServerAddressList m_ServerAddressList;
  231. CComBSTR m_ConnectedServer;
  232. LONG m_ConnectedPort;
  233. //
  234. // The complete connection string.
  235. //
  236. CComBSTR m_ConnectParms;
  237. //
  238. // Expert side to be transmitted over to user
  239. //
  240. CComBSTR m_ExpertBlob;
  241. //
  242. // Search for a child window of the specified parent window.
  243. //
  244. typedef struct _WinSearch
  245. {
  246. HWND foundWindow;
  247. LPTSTR srchCaption;
  248. LPTSTR srchClass;
  249. } WINSEARCH, *PWINSEARCH;
  250. HWND SearchForWindow(HWND hwndParent, LPTSTR srchCaption, LPTSTR srchClass);
  251. static BOOL CALLBACK _WindowSrchProc(HWND hwnd, PWINSEARCH srch);
  252. //timer related members
  253. DWORD m_PrevTimer;
  254. UINT m_TimerId;
  255. DWORD m_RdcConnCheckTimeInterval;
  256. BOOL m_ListenConnectInProgress; // duration of StartListen() until mstscax connected.
  257. SOCKET m_ListenSocket; // listen() socket
  258. SOCKET m_TSConnectSocket; // accept() scoket
  259. DWORD m_ICSPort; // port that ICS library punch on ICS server
  260. BOOL m_InitListeningLibrary; // Instance of object initialize WinSock/ICS library.
  261. UINT_PTR m_ListenTimeoutTimerID; // Timer ID for listen timeout.
  262. void
  263. ListenConnectCleanup()
  264. {
  265. m_ListenConnectInProgress = FALSE;
  266. if( INVALID_SOCKET != m_ListenSocket ) {
  267. closesocket( m_ListenSocket );
  268. }
  269. if( (UINT_PTR)0 != m_ListenTimeoutTimerID ) {
  270. KillTimer( m_ListenTimeoutTimerID );
  271. }
  272. if( INVALID_SOCKET != m_TSConnectSocket ) {
  273. closesocket( m_TSConnectSocket );
  274. }
  275. if( 0 != m_ICSPort ) {
  276. ClosePort( m_ICSPort );
  277. }
  278. m_ListenSocket = INVALID_SOCKET;
  279. m_TSConnectSocket = INVALID_SOCKET;
  280. m_ICSPort = 0;
  281. }
  282. //
  283. // Variable to manage WinSock and ICS library startup/shutdown, WinSock/ICS library
  284. // is RDP specific so not declare in parent class.
  285. //
  286. static LONG gm_ListeningLibraryRefCount; // Number of time we reference WinSock and ICS library
  287. //
  288. // accessing only global variable, no need for per-instance.
  289. //
  290. static HRESULT
  291. InitListeningLibrary();
  292. static HRESULT
  293. TerminateListeningLibrary();
  294. //
  295. // Listen socket already in progress
  296. //
  297. inline BOOL
  298. ListenConnectInProgress() {
  299. return m_ListenConnectInProgress;
  300. }
  301. protected:
  302. //
  303. // Final Initialization.
  304. //
  305. virtual HRESULT Initialize(LPCREATESTRUCT pCreateStruct);
  306. //
  307. // Generate a remote control request message for the
  308. // server.
  309. //
  310. HRESULT GenerateRCRequest(BSTR *rcRequest);
  311. //
  312. // Generate a 'client authenticate' request.
  313. //
  314. HRESULT GenerateClientAuthenticateRequest(BSTR *authenticateReq);
  315. //
  316. // Generate a version information packet.
  317. //
  318. HRESULT GenerateVersionInfoPacket(BSTR *versionInfoPacket);
  319. //
  320. // Send the terminate shadowing key sequence to the server.
  321. //
  322. HRESULT SendTerminateRCKeysToServer();
  323. //
  324. // Handle Remote Control 'Control' Channel messages.
  325. //
  326. VOID HandleControlChannelMsg();
  327. //
  328. // Translate an MSTSC disconnect code into a Salem disconnect
  329. // code.
  330. //
  331. LONG TranslateMSTSCDisconnectCode(DisconnectReasonCode disconReason,
  332. ExtendedDisconnectReasonCode extendedReasonCode);
  333. //
  334. // Disconnects the client from the server.
  335. //
  336. STDMETHOD(DisconnectFromServerInternal)(
  337. LONG disconnectCode
  338. );
  339. HRESULT
  340. SetupConnectionInfo(BOOL bListen, BSTR expertBlob);
  341. //
  342. // Connect to server with port
  343. //
  344. HRESULT
  345. ConnectServerPort(
  346. BSTR ServerName,
  347. LONG portNumber
  348. );
  349. //
  350. // Internal stop listening function for dealing with calls from external
  351. // and internal contexts.
  352. //
  353. HRESULT StopListenInternal(LONG returnCode = 0);
  354. //
  355. // Connect to server with established socket
  356. //
  357. HRESULT
  358. ConnectServerWithOpenedSocket();
  359. //generate a simple message for checking if the connection is alive
  360. HRESULT GenerateNullData(BSTR *bstrMsg);
  361. //
  362. // Retrieve connect parm
  363. //
  364. HRESULT
  365. RetrieveUserConnectParm( BSTR* pConnectParm );
  366. void
  367. FireListenConnect( DWORD ErrCode )
  368. {
  369. return;
  370. }
  371. HRESULT
  372. GetCurrentUser(
  373. LPTSTR* pszUserName
  374. );
  375. public:
  376. //
  377. // Constructor/Destructor
  378. //
  379. CTSRDPRemoteDesktopClient() {
  380. //
  381. // We are window'd, even if our parent supports Windowless
  382. // controls.
  383. //
  384. m_bWindowOnly = TRUE;
  385. m_ConnectedToServer = FALSE;
  386. m_Initialized = FALSE;
  387. m_TSClient = NULL;
  388. m_TSClientWnd = NULL;
  389. m_ConnectionInProgress = FALSE;
  390. m_RemoteControlRequestInProgress = FALSE;
  391. m_LastExtendedErrorInfo = 0;
  392. m_TimerId = 0; //used for pinging
  393. m_RdcConnCheckTimeInterval = RDC_CHECKCONN_TIMEOUT;
  394. //
  395. // No reference to listening library.
  396. //
  397. m_InitListeningLibrary = FALSE;
  398. m_ListenConnectInProgress = FALSE;
  399. m_ListenSocket = INVALID_SOCKET;
  400. m_TSConnectSocket = INVALID_SOCKET;
  401. m_ListenTimeoutTimerID = (UINT_PTR) 0;
  402. m_ICSPort = 0;
  403. //
  404. // Not valid until unitialized.
  405. //
  406. SetValid(FALSE);
  407. }
  408. ~CTSRDPRemoteDesktopClient();
  409. HRESULT FinalConstruct();
  410. DECLARE_REGISTRY_RESOURCEID(IDR_TSRDPREMOTEDESKTOPCLIENT)
  411. DECLARE_PROTECT_FINAL_CONSTRUCT()
  412. //
  413. // Event Sinks
  414. //
  415. VOID OnRDPConnected();
  416. VOID OnLoginComplete();
  417. VOID OnDisconnected(long disconReason);
  418. VOID OnMSTSCReceiveData(BSTR data);
  419. VOID OnReceivedTSPublicKey(BSTR tsPublicKey, VARIANT_BOOL* bContinue);
  420. //
  421. // Interface Map
  422. //
  423. BEGIN_COM_MAP(CTSRDPRemoteDesktopClient)
  424. COM_INTERFACE_ENTRY(IViewObjectEx)
  425. COM_INTERFACE_ENTRY(IViewObject2)
  426. COM_INTERFACE_ENTRY(IViewObject)
  427. COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
  428. COM_INTERFACE_ENTRY(IOleInPlaceObject)
  429. COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
  430. COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
  431. COM_INTERFACE_ENTRY(IOleControl)
  432. COM_INTERFACE_ENTRY(IOleObject)
  433. COM_INTERFACE_ENTRY(IPersistStreamInit)
  434. COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
  435. COM_INTERFACE_ENTRY(ISpecifyPropertyPages)
  436. COM_INTERFACE_ENTRY(IQuickActivate)
  437. COM_INTERFACE_ENTRY(IPersistStorage)
  438. COM_INTERFACE_ENTRY(IDataObject)
  439. COM_INTERFACE_ENTRY(IProvideClassInfo)
  440. COM_INTERFACE_ENTRY(IProvideClassInfo2)
  441. COM_INTERFACE_ENTRY(ISAFRemoteDesktopClient)
  442. COM_INTERFACE_ENTRY(ISAFRemoteDesktopTestExtension)
  443. COM_INTERFACE_ENTRY2(IDispatch, ISAFRemoteDesktopClient)
  444. COM_INTERFACE_ENTRY(IDataChannelIO)
  445. COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
  446. END_COM_MAP()
  447. //
  448. // Property Map
  449. //
  450. BEGIN_PROP_MAP(CTSRDPRemoteDesktopClient)
  451. PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
  452. PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
  453. // Example entries
  454. // PROP_ENTRY("Property Description", dispid, clsid)
  455. // PROP_PAGE(CLSID_StockColorPage)
  456. END_PROP_MAP()
  457. //
  458. // Connection Point Map
  459. //
  460. BEGIN_CONNECTION_POINT_MAP(CTSRDPRemoteDesktopClient)
  461. CONNECTION_POINT_ENTRY(DIID__ISAFRemoteDesktopClientEvents)
  462. CONNECTION_POINT_ENTRY(DIID__IDataChannelIOEvents)
  463. END_CONNECTION_POINT_MAP()
  464. //
  465. // Message Map
  466. //
  467. BEGIN_MSG_MAP(CTSRDPRemoteDesktopClient)
  468. CHAIN_MSG_MAP(CComControl<CTSRDPRemoteDesktopClient>)
  469. DEFAULT_REFLECTION_HANDLER()
  470. MESSAGE_HANDLER(WM_CREATE, OnCreate)
  471. MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
  472. MESSAGE_HANDLER(WM_SIZE, OnSize)
  473. MESSAGE_HANDLER(WM_TSCONNECT, OnTSConnect)
  474. MESSAGE_HANDLER(WM_TIMER, OnTimer)
  475. END_MSG_MAP()
  476. // Handler prototypes:
  477. // LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  478. // LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  479. // LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);
  480. //
  481. // IViewObjectEx Methods
  482. //
  483. DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)
  484. public:
  485. LRESULT OnTSConnect(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  486. LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  487. LRESULT OnStartListen(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  488. //
  489. // OnDraw
  490. //
  491. HRESULT OnDraw(ATL_DRAWINFO& di)
  492. {
  493. RECT& rc = *(RECT*)di.prcBounds;
  494. Rectangle(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom);
  495. HRESULT hr = S_FALSE;
  496. if (!m_Initialized) {
  497. hr = S_OK;
  498. SetTextAlign(di.hdcDraw, TA_CENTER|TA_BASELINE);
  499. LPCTSTR pszText = _T("TSRDP Remote Desktop Client");
  500. TextOut(di.hdcDraw,
  501. (rc.left + rc.right) / 2,
  502. (rc.top + rc.bottom) / 2,
  503. pszText,
  504. lstrlen(pszText));
  505. }
  506. return hr;
  507. }
  508. LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  509. {
  510. //
  511. // Hide our window, by default.
  512. //
  513. //ShowWindow(SW_HIDE);
  514. if (!m_Initialized) {
  515. LPCREATESTRUCT pCreateStruct = (LPCREATESTRUCT)lParam;
  516. Initialize(pCreateStruct);
  517. }
  518. return 0;
  519. }
  520. LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  521. {
  522. DC_BEGIN_FN("CTSRDPRemoteDesktopClient::OnSetFocus");
  523. //
  524. // Set focus back to the client window, if it exists.
  525. //
  526. if (m_TSClientWnd != NULL) {
  527. ::PostMessage(m_TSClientWnd, uMsg, wParam, lParam);
  528. }
  529. DC_END_FN();
  530. return 0;
  531. }
  532. //
  533. // OnSize
  534. //
  535. LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  536. {
  537. DC_BEGIN_FN("CTSRDPRemoteDesktopClient::OnSize");
  538. if (m_TSClientWnd != NULL) {
  539. RECT rect;
  540. GetClientRect(&rect);
  541. ::MoveWindow(m_TSClientWnd, rect.left, rect.top,
  542. rect.right, rect.bottom, TRUE);
  543. }
  544. DC_END_FN();
  545. return 0;
  546. }
  547. LRESULT OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  548. {
  549. bHandled = TRUE;
  550. return 0;
  551. //return DefWindowProc(uMsg, wParam, lParam);
  552. }
  553. //
  554. // ISAFRemoteDesktopClient Methods
  555. //
  556. STDMETHOD(ConnectToServer)(BSTR Server);
  557. STDMETHOD(DisconnectFromServer)();
  558. STDMETHOD(ConnectRemoteDesktop)();
  559. STDMETHOD(DisconnectRemoteDesktop)();
  560. STDMETHOD(get_IsRemoteDesktopConnected)(BOOL * pVal);
  561. STDMETHOD(get_IsServerConnected)(BOOL * pVal);
  562. STDMETHOD(put_EnableSmartSizing)(BOOL val);
  563. STDMETHOD(get_EnableSmartSizing)(BOOL *pVal);
  564. STDMETHOD(put_ColorDepth)(LONG Val);
  565. STDMETHOD(get_ColorDepth)(LONG* pVal);
  566. STDMETHOD(get_ExtendedErrorInfo)(LONG *error) {
  567. *error = m_LastExtendedErrorInfo;
  568. return S_OK;
  569. }
  570. STDMETHOD(get_ChannelManager)(ISAFRemoteDesktopChannelMgr **mgr) {
  571. *mgr = m_ChannelMgr;
  572. return S_OK;
  573. }
  574. STDMETHOD(put_ConnectParms)(/*[in]*/BSTR parms) {
  575. m_ConnectParms = parms;
  576. return S_OK;
  577. }
  578. STDMETHOD(get_ConnectParms)(/*[out, retval]*/BSTR *parms) {
  579. CComBSTR tmp;
  580. tmp = m_ConnectParms;
  581. *parms = tmp.Detach();
  582. return S_OK;
  583. }
  584. //
  585. // Scriptable Event Object Registration Properties (not supported)
  586. //
  587. STDMETHOD(put_OnConnected)(/*[in]*/IDispatch *iDisp) { return E_FAIL; }
  588. STDMETHOD(put_OnDisconnected)(/*[in]*/IDispatch *iDisp) { return E_FAIL; }
  589. STDMETHOD(put_OnConnectRemoteDesktopComplete)(/*[in]*/IDispatch *iDisp) { return E_FAIL; }
  590. STDMETHOD(put_OnListenConnect)(/*[in]*/IDispatch *iDisp) { return E_FAIL; }
  591. STDMETHOD(put_OnBeginConnect)(/*[in]*/IDispatch *iDisp) { return E_FAIL; }
  592. //
  593. // IDataChannelIO Methods
  594. //
  595. STDMETHOD(SendData)(/*[in]*/BSTR data);
  596. STDMETHOD(put_ChannelMgr)(/*[in]*/ISAFRemoteDesktopChannelMgr *newVal);
  597. //
  598. // Return the name of this class.
  599. //
  600. virtual const LPTSTR ClassName() {
  601. return TEXT("CTSRDPRemoteDesktopServer");
  602. }
  603. //
  604. // ISAFRemoteDesktopTestExtension
  605. //
  606. STDMETHOD(put_TestExtDllName)(/*[in]*/BSTR newVal);
  607. STDMETHOD(put_TestExtParams)(/*[in]*/BSTR newVal);
  608. STDMETHOD(get_ConnectedServer)(/*[in]*/BSTR* Val) {
  609. HRESULT hr = S_OK;
  610. if( m_ConnectedToServer ) {
  611. *Val = m_ConnectedServer.Copy();
  612. }
  613. else {
  614. hr = E_FAIL;
  615. }
  616. return hr;
  617. }
  618. STDMETHOD(get_ConnectedPort)(/*[in]*/LONG* Val) {
  619. HRESULT hr = S_OK;
  620. if( m_ConnectedToServer ) {
  621. *Val = m_ConnectedPort;
  622. }
  623. else {
  624. hr = E_FAIL;
  625. }
  626. return hr;
  627. }
  628. STDMETHOD(CreateListenEndpoint)(
  629. /*[in]*/ LONG port,
  630. /*[out, retval]*/ BSTR* pConnectParm
  631. );
  632. STDMETHOD(StartListen)(
  633. /*[in]*/ LONG timeout
  634. );
  635. STDMETHOD(AcceptListenConnection)(
  636. /*[in]*/BSTR expertBlob
  637. );
  638. //
  639. // Stop listening waiting for TS server (helpee, user) to connect.
  640. //
  641. STDMETHOD(StopListen)() {
  642. return StopListenInternal();
  643. };
  644. };
  645. ///////////////////////////////////////////////////////
  646. //
  647. // CTSRDPRemoteDesktopClient Inline Methods
  648. //
  649. inline STDMETHODIMP
  650. CTSRDPRemoteDesktopClient::get_IsServerConnected(
  651. BOOL *pVal
  652. )
  653. /*++
  654. Routine Description:
  655. Indicates whether the client is connected to the server, excluding
  656. control over the remote user's desktop.
  657. Arguments:
  658. pVal - Set to TRUE if the client is connected to the server.
  659. Return Value:
  660. S_OK on success. Otherwise, an error code is returned.
  661. --*/
  662. {
  663. DC_BEGIN_FN("CTSRDPRemoteDesktopClient::get_IsServerConnected");
  664. HRESULT hr = S_OK;
  665. if (IsValid()) {
  666. *pVal = m_ConnectedToServer;
  667. }
  668. else {
  669. ASSERT(FALSE);
  670. hr = E_FAIL;
  671. }
  672. DC_END_FN();
  673. return hr;
  674. }
  675. inline STDMETHODIMP
  676. CTSRDPRemoteDesktopClient::get_IsRemoteDesktopConnected(
  677. BOOL *pVal
  678. )
  679. /*++
  680. Routine Description:
  681. Indicates whether the control is currently controlling the remote user's
  682. desktop.
  683. Arguments:
  684. pVal - Sets to TRUE if the control is currently connected to the server.
  685. Return Value:
  686. S_OK on success. Otherwise, an error code is returned.
  687. --*/
  688. {
  689. DC_BEGIN_FN("CTSRDPRemoteDesktopClient::get_IsRemoteDesktopConnected");
  690. HRESULT hr = S_OK;
  691. if (IsValid()) {
  692. *pVal = m_RemoteControlRequestInProgress;
  693. }
  694. else {
  695. ASSERT(FALSE);
  696. hr = E_FAIL;
  697. }
  698. DC_END_FN();
  699. return hr;
  700. }
  701. #endif //__TSRDPREMOTEDESKTOPCLIENT_H_