1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef REMOTING_HOST_WIN_RDP_HOST_WINDOW_H_ 6 #define REMOTING_HOST_WIN_RDP_HOST_WINDOW_H_ 7 8 #include <atlbase.h> 9 #include <atlcom.h> 10 #include <atlcrack.h> 11 #include <atlctl.h> 12 13 #include "base/basictypes.h" 14 #include "base/memory/ref_counted.h" 15 #include "base/message_loop/message_loop.h" 16 #include "base/win/scoped_comptr.h" 17 #include "net/base/ip_endpoint.h" 18 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" 19 20 #import "PROGID:MsTscAx.MsTscAx" \ 21 exclude("wireHWND", "_RemotableHandle", "__MIDL_IWinTypes_0009"), \ 22 rename_namespace("mstsc") raw_interfaces_only no_implementation 23 24 namespace remoting { 25 26 // RdpClientWindow is used to establish a connection to the given RDP endpoint. 27 // It is a GUI window class that hosts Microsoft RDP ActiveX control, which 28 // takes care of handling RDP properly. RdpClientWindow must be used only on 29 // a UI thread. 30 class RdpClientWindow 31 : public CWindowImpl<RdpClientWindow, CWindow, CFrameWinTraits>, 32 public IDispEventImpl<1, RdpClientWindow, 33 &__uuidof(mstsc::IMsTscAxEvents), 34 &__uuidof(mstsc::__MSTSCLib), 1, 0> { 35 public: 36 // Receives connect/disconnect notifications. The notifications can be 37 // delivered after RdpClientWindow::Connect() returned success. 38 // 39 // RdpClientWindow guarantees that OnDisconnected() is the last notification 40 // the event handler receives. OnDisconnected() is guaranteed to be called 41 // only once. 42 class EventHandler { 43 public: 44 virtual ~EventHandler() {} 45 46 // Invoked when the RDP control has established a connection. 47 virtual void OnConnected() = 0; 48 49 // Invoked when the RDP control has been disconnected from the RDP server. 50 // This includes both graceful shutdown and any fatal error condition. 51 // 52 // Once RdpClientWindow::Connect() returns success the owner of the 53 // |RdpClientWindow| object must keep it alive until OnDisconnected() is 54 // called. 55 // 56 // OnDisconnected() should not delete |RdpClientWindow| object directly. 57 // Instead it should post a task to delete the object. The ActiveX code 58 // expects the window be alive until the currently handled window message is 59 // completely processed. 60 virtual void OnDisconnected() = 0; 61 }; 62 63 DECLARE_WND_CLASS(L"RdpClientWindow") 64 65 // Specifies the endpoint to connect to and passes the event handler pointer 66 // to be notified about connection events. 67 RdpClientWindow(const net::IPEndPoint& server_endpoint, 68 const std::string& terminal_id, 69 EventHandler* event_handler); 70 ~RdpClientWindow(); 71 72 // Creates the window along with the ActiveX control and initiates the 73 // connection. |screen_size| specifies resolution of the screen. Returns false 74 // if an error occurs. 75 bool Connect(const webrtc::DesktopSize& screen_size); 76 77 // Initiates shutdown of the connection. The caller must not delete |this| 78 // until it receives OnDisconnected() notification. 79 void Disconnect(); 80 81 // Emulates pressing Ctrl+Alt+End combination that is translated to Secure 82 // Attention Sequence by the ActiveX control. 83 void InjectSas(); 84 85 private: 86 typedef IDispEventImpl<1, RdpClientWindow, 87 &__uuidof(mstsc::IMsTscAxEvents), 88 &__uuidof(mstsc::__MSTSCLib), 1, 0> RdpEventsSink; 89 90 // Handled window messages. 91 BEGIN_MSG_MAP_EX(RdpClientWindow) 92 MSG_WM_CLOSE(OnClose) 93 MSG_WM_CREATE(OnCreate) 94 MSG_WM_DESTROY(OnDestroy) 95 END_MSG_MAP() 96 97 // Requests the RDP ActiveX control to close the connection gracefully. 98 void OnClose(); 99 100 // Creates the RDP ActiveX control, configures it, and initiates an RDP 101 // connection to |server_endpoint_|. 102 LRESULT OnCreate(CREATESTRUCT* create_struct); 103 104 // Releases the RDP ActiveX control interfaces. 105 void OnDestroy(); 106 107 BEGIN_SINK_MAP(RdpClientWindow) 108 SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 2, OnConnected) 109 SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 4, OnDisconnected) 110 SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 10, OnFatalError) 111 SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 15, OnConfirmClose) 112 SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 18, 113 OnAuthenticationWarningDisplayed) 114 SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 19, 115 OnAuthenticationWarningDismissed) 116 END_SINK_MAP() 117 118 // mstsc::IMsTscAxEvents notifications. 119 STDMETHOD(OnAuthenticationWarningDisplayed)(); 120 STDMETHOD(OnAuthenticationWarningDismissed)(); 121 STDMETHOD(OnConnected)(); 122 STDMETHOD(OnDisconnected)(long reason); 123 STDMETHOD(OnFatalError)(long error_code); 124 STDMETHOD(OnConfirmClose)(VARIANT_BOOL* allow_close); 125 126 // Wrappers for the event handler's methods that make sure that 127 // OnDisconnected() is the last notification delivered and is delevered 128 // only once. 129 void NotifyConnected(); 130 void NotifyDisconnected(); 131 132 // Invoked to report connect/disconnect events. 133 EventHandler* event_handler_; 134 135 // Contains the requested dimensions of the screen. 136 webrtc::DesktopSize screen_size_; 137 138 // The endpoint to connect to. 139 net::IPEndPoint server_endpoint_; 140 141 // The terminal ID assigned to this connection. 142 std::string terminal_id_; 143 144 // Interfaces exposed by the RDP ActiveX control. 145 base::win::ScopedComPtr<mstsc::IMsRdpClient> client_; 146 base::win::ScopedComPtr<mstsc::IMsRdpClientAdvancedSettings> client_settings_; 147 148 // Used to cancel modal dialog boxes shown by the RDP control. 149 class WindowHook; 150 scoped_refptr<WindowHook> window_activate_hook_; 151 }; 152 153 } // namespace remoting 154 155 #endif // REMOTING_HOST_WIN_RDP_HOST_WINDOW_H_ 156