// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef REMOTING_HOST_WIN_RDP_HOST_WINDOW_H_ #define REMOTING_HOST_WIN_RDP_HOST_WINDOW_H_ #include <atlbase.h> #include <atlcom.h> #include <atlcrack.h> #include <atlctl.h> #include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "base/message_loop/message_loop.h" #include "base/win/scoped_comptr.h" #include "net/base/ip_endpoint.h" // The following header was generated by Visual Studio. We had to check it in // due to a bug in VS2013. See crbug.com/318952 for details. #include "remoting/host/win/com_imported_mstscax.tlh" #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" namespace remoting { // RdpClientWindow is used to establish a connection to the given RDP endpoint. // It is a GUI window class that hosts Microsoft RDP ActiveX control, which // takes care of handling RDP properly. RdpClientWindow must be used only on // a UI thread. class RdpClientWindow : public CWindowImpl<RdpClientWindow, CWindow, CFrameWinTraits>, public IDispEventImpl<1, RdpClientWindow, &__uuidof(mstsc::IMsTscAxEvents), &__uuidof(mstsc::__MSTSCLib), 1, 0> { public: // Receives connect/disconnect notifications. The notifications can be // delivered after RdpClientWindow::Connect() returned success. // // RdpClientWindow guarantees that OnDisconnected() is the last notification // the event handler receives. OnDisconnected() is guaranteed to be called // only once. class EventHandler { public: virtual ~EventHandler() {} // Invoked when the RDP control has established a connection. virtual void OnConnected() = 0; // Invoked when the RDP control has been disconnected from the RDP server. // This includes both graceful shutdown and any fatal error condition. // // Once RdpClientWindow::Connect() returns success the owner of the // |RdpClientWindow| object must keep it alive until OnDisconnected() is // called. // // OnDisconnected() should not delete |RdpClientWindow| object directly. // Instead it should post a task to delete the object. The ActiveX code // expects the window be alive until the currently handled window message is // completely processed. virtual void OnDisconnected() = 0; }; DECLARE_WND_CLASS(L"RdpClientWindow") // Specifies the endpoint to connect to and passes the event handler pointer // to be notified about connection events. RdpClientWindow(const net::IPEndPoint& server_endpoint, const std::string& terminal_id, EventHandler* event_handler); ~RdpClientWindow(); // Creates the window along with the ActiveX control and initiates the // connection. |screen_size| specifies resolution of the screen. Returns false // if an error occurs. bool Connect(const webrtc::DesktopSize& screen_size); // Initiates shutdown of the connection. The caller must not delete |this| // until it receives OnDisconnected() notification. void Disconnect(); // Emulates pressing Ctrl+Alt+End combination that is translated to Secure // Attention Sequence by the ActiveX control. void InjectSas(); private: typedef IDispEventImpl<1, RdpClientWindow, &__uuidof(mstsc::IMsTscAxEvents), &__uuidof(mstsc::__MSTSCLib), 1, 0> RdpEventsSink; // Handled window messages. BEGIN_MSG_MAP_EX(RdpClientWindow) MSG_WM_CLOSE(OnClose) MSG_WM_CREATE(OnCreate) MSG_WM_DESTROY(OnDestroy) END_MSG_MAP() // Requests the RDP ActiveX control to close the connection gracefully. void OnClose(); // Creates the RDP ActiveX control, configures it, and initiates an RDP // connection to |server_endpoint_|. LRESULT OnCreate(CREATESTRUCT* create_struct); // Releases the RDP ActiveX control interfaces. void OnDestroy(); BEGIN_SINK_MAP(RdpClientWindow) SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 2, OnConnected) SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 4, OnDisconnected) SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 10, OnFatalError) SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 15, OnConfirmClose) SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 18, OnAuthenticationWarningDisplayed) SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 19, OnAuthenticationWarningDismissed) END_SINK_MAP() // mstsc::IMsTscAxEvents notifications. STDMETHOD(OnAuthenticationWarningDisplayed)(); STDMETHOD(OnAuthenticationWarningDismissed)(); STDMETHOD(OnConnected)(); STDMETHOD(OnDisconnected)(long reason); STDMETHOD(OnFatalError)(long error_code); STDMETHOD(OnConfirmClose)(VARIANT_BOOL* allow_close); // Wrappers for the event handler's methods that make sure that // OnDisconnected() is the last notification delivered and is delevered // only once. void NotifyConnected(); void NotifyDisconnected(); // Invoked to report connect/disconnect events. EventHandler* event_handler_; // Contains the requested dimensions of the screen. webrtc::DesktopSize screen_size_; // The endpoint to connect to. net::IPEndPoint server_endpoint_; // The terminal ID assigned to this connection. std::string terminal_id_; // Interfaces exposed by the RDP ActiveX control. base::win::ScopedComPtr<mstsc::IMsRdpClient> client_; base::win::ScopedComPtr<mstsc::IMsRdpClientAdvancedSettings> client_settings_; // Used to cancel modal dialog boxes shown by the RDP control. class WindowHook; scoped_refptr<WindowHook> window_activate_hook_; }; } // namespace remoting #endif // REMOTING_HOST_WIN_RDP_HOST_WINDOW_H_