| // 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" |
| #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" |
| |
| #import "PROGID:MsTscAx.MsTscAx" \ |
| exclude("wireHWND", "_RemotableHandle", "__MIDL_IWinTypes_0009"), \ |
| rename_namespace("mstsc") raw_interfaces_only no_implementation |
| |
| 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_ |