12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef REMOTING_HOST_WIN_RDP_HOST_WINDOW_H_ 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define REMOTING_HOST_WIN_RDP_HOST_WINDOW_H_ 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <atlbase.h> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <atlcom.h> 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <atlcrack.h> 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <atlctl.h> 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/ref_counted.h" 159ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/win/scoped_comptr.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/ip_endpoint.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The following header was generated by Visual Studio. We had to check it in 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// due to a bug in VS2013. See crbug.com/318952 for details. 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "remoting/host/win/com_imported_mstscax.tlh" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace remoting { 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// RdpClientWindow is used to establish a connection to the given RDP endpoint. 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// It is a GUI window class that hosts Microsoft RDP ActiveX control, which 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// takes care of handling RDP properly. RdpClientWindow must be used only on 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// a UI thread. 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RdpClientWindow 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public CWindowImpl<RdpClientWindow, CWindow, CFrameWinTraits>, 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public IDispEventImpl<1, RdpClientWindow, 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &__uuidof(mstsc::IMsTscAxEvents), 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &__uuidof(mstsc::__MSTSCLib), 1, 0> { 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Receives connect/disconnect notifications. The notifications can be 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // delivered after RdpClientWindow::Connect() returned success. 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // RdpClientWindow guarantees that OnDisconnected() is the last notification 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the event handler receives. OnDisconnected() is guaranteed to be called 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // only once. 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class EventHandler { 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~EventHandler() {} 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Invoked when the RDP control has established a connection. 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnConnected() = 0; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Invoked when the RDP control has been disconnected from the RDP server. 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This includes both graceful shutdown and any fatal error condition. 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Once RdpClientWindow::Connect() returns success the owner of the 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |RdpClientWindow| object must keep it alive until OnDisconnected() is 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // called. 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // OnDisconnected() should not delete |RdpClientWindow| object directly. 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Instead it should post a task to delete the object. The ActiveX code 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expects the window be alive until the currently handled window message is 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // completely processed. 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnDisconnected() = 0; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DECLARE_WND_CLASS(L"RdpClientWindow") 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Specifies the endpoint to connect to and passes the event handler pointer 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to be notified about connection events. 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RdpClientWindow(const net::IPEndPoint& server_endpoint, 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& terminal_id, 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EventHandler* event_handler); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~RdpClientWindow(); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Creates the window along with the ActiveX control and initiates the 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // connection. |screen_size| specifies resolution of the screen. Returns false 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // if an error occurs. 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool Connect(const webrtc::DesktopSize& screen_size); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Initiates shutdown of the connection. The caller must not delete |this| 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // until it receives OnDisconnected() notification. 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Disconnect(); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Emulates pressing Ctrl+Alt+End combination that is translated to Secure 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Attention Sequence by the ActiveX control. 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void InjectSas(); 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef IDispEventImpl<1, RdpClientWindow, 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &__uuidof(mstsc::IMsTscAxEvents), 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &__uuidof(mstsc::__MSTSCLib), 1, 0> RdpEventsSink; 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Handled window messages. 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BEGIN_MSG_MAP_EX(RdpClientWindow) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MSG_WM_CLOSE(OnClose) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MSG_WM_CREATE(OnCreate) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MSG_WM_DESTROY(OnDestroy) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) END_MSG_MAP() 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Requests the RDP ActiveX control to close the connection gracefully. 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void OnClose(); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Creates the RDP ActiveX control, configures it, and initiates an RDP 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // connection to |server_endpoint_|. 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LRESULT OnCreate(CREATESTRUCT* create_struct); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Releases the RDP ActiveX control interfaces. 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void OnDestroy(); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BEGIN_SINK_MAP(RdpClientWindow) 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 2, 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &RdpClientWindow::OnConnected) 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 4, 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &RdpClientWindow::OnDisconnected) 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 10, 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &RdpClientWindow::OnFatalError) 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 15, 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &RdpClientWindow::OnConfirmClose) 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 18, 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &RdpClientWindow::OnAuthenticationWarningDisplayed) 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 19, 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &RdpClientWindow::OnAuthenticationWarningDismissed) 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) END_SINK_MAP() 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // mstsc::IMsTscAxEvents notifications. 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) STDMETHOD(OnAuthenticationWarningDisplayed)(); 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) STDMETHOD(OnAuthenticationWarningDismissed)(); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) STDMETHOD(OnConnected)(); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) STDMETHOD(OnDisconnected)(long reason); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) STDMETHOD(OnFatalError)(long error_code); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) STDMETHOD(OnConfirmClose)(VARIANT_BOOL* allow_close); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Wrappers for the event handler's methods that make sure that 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // OnDisconnected() is the last notification delivered and is delevered 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // only once. 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void NotifyConnected(); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void NotifyDisconnected(); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Invoked to report connect/disconnect events. 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EventHandler* event_handler_; 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Contains the requested dimensions of the screen. 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) webrtc::DesktopSize screen_size_; 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The endpoint to connect to. 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::IPEndPoint server_endpoint_; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // The terminal ID assigned to this connection. 145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string terminal_id_; 146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Interfaces exposed by the RDP ActiveX control. 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::win::ScopedComPtr<mstsc::IMsRdpClient> client_; 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::win::ScopedComPtr<mstsc::IMsRdpClientAdvancedSettings> client_settings_; 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Used to cancel modal dialog boxes shown by the RDP control. 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) class WindowHook; 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<WindowHook> window_activate_hook_; 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace remoting 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // REMOTING_HOST_WIN_RDP_HOST_WINDOW_H_ 159