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