rdp_client_window.h revision 9ab5563a3196760eb381d102cbb2bc0f7abc6a50
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" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/skia/include/core/SkSize.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#import "PROGID:MsTscAx.MsTscAx" \ 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) exclude("wireHWND", "_RemotableHandle", "__MIDL_IWinTypes_0009"), \ 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rename_namespace("mstsc") raw_interfaces_only no_implementation 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace remoting { 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// RdpClientWindow is used to establish a connection to the given RDP endpoint. 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// It is a GUI window class that hosts Microsoft RDP ActiveX control, which 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// takes care of handling RDP properly. RdpClientWindow must be used only on 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// a UI thread. 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RdpClientWindow 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public CWindowImpl<RdpClientWindow, CWindow, CFrameWinTraits>, 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public IDispEventImpl<1, RdpClientWindow, 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &__uuidof(mstsc::IMsTscAxEvents), 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &__uuidof(mstsc::__MSTSCLib), 1, 0> { 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Receives connect/disconnect notifications. The notifications can be 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // delivered after RdpClientWindow::Connect() returned success. 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // RdpClientWindow guarantees that OnDisconnected() is the last notification 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the event handler receives. OnDisconnected() is guaranteed to be called 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // only once. 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) class EventHandler { 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~EventHandler() {} 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Invoked when the RDP control has established a connection. 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnConnected() = 0; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Invoked when the RDP control has been disconnected from the RDP server. 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This includes both graceful shutdown and any fatal error condition. 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Once RdpClientWindow::Connect() returns success the owner of the 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |RdpClientWindow| object must keep it alive until OnDisconnected() is 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // called. 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // OnDisconnected() should not delete |RdpClientWindow| object directly. 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Instead it should post a task to delete the object. The ActiveX code 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expects the window be alive until the currently handled window message is 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // completely processed. 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnDisconnected() = 0; 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DECLARE_WND_CLASS(L"RdpClientWindow") 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Specifies the endpoint to connect to and passes the event handler pointer 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to be notified about connection events. 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RdpClientWindow(const net::IPEndPoint& server_endpoint, 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& terminal_id, 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EventHandler* event_handler); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~RdpClientWindow(); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Creates the window along with the ActiveX control and initiates the 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // connection. |screen_size| specifies resolution of the screen. Returns false 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // if an error occurs. 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool Connect(const SkISize& screen_size); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Initiates shutdown of the connection. The caller must not delete |this| 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // until it receives OnDisconnected() notification. 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Disconnect(); 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Emulates pressing Ctrl+Alt+End combination that is translated to Secure 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Attention Sequence by the ActiveX control. 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void InjectSas(); 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef IDispEventImpl<1, RdpClientWindow, 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &__uuidof(mstsc::IMsTscAxEvents), 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &__uuidof(mstsc::__MSTSCLib), 1, 0> RdpEventsSink; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Handled window messages. 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BEGIN_MSG_MAP_EX(RdpClientWindow) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MSG_WM_CLOSE(OnClose) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MSG_WM_CREATE(OnCreate) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MSG_WM_DESTROY(OnDestroy) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) END_MSG_MAP() 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Requests the RDP ActiveX control to close the connection gracefully. 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void OnClose(); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Creates the RDP ActiveX control, configures it, and initiates an RDP 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // connection to |server_endpoint_|. 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LRESULT OnCreate(CREATESTRUCT* create_struct); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Releases the RDP ActiveX control interfaces. 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void OnDestroy(); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BEGIN_SINK_MAP(RdpClientWindow) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 2, OnConnected) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 4, OnDisconnected) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 10, OnFatalError) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 15, OnConfirmClose) 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 18, 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OnAuthenticationWarningDisplayed) 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 19, 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OnAuthenticationWarningDismissed) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) END_SINK_MAP() 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // mstsc::IMsTscAxEvents notifications. 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) STDMETHOD(OnAuthenticationWarningDisplayed)(); 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) STDMETHOD(OnAuthenticationWarningDismissed)(); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) STDMETHOD(OnConnected)(); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) STDMETHOD(OnDisconnected)(long reason); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) STDMETHOD(OnFatalError)(long error_code); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) STDMETHOD(OnConfirmClose)(VARIANT_BOOL* allow_close); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Wrappers for the event handler's methods that make sure that 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // OnDisconnected() is the last notification delivered and is delevered 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // only once. 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void NotifyConnected(); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void NotifyDisconnected(); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Invoked to report connect/disconnect events. 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EventHandler* event_handler_; 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Contains the requested dimensions of the screen. 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkISize screen_size_; 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The endpoint to connect to. 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::IPEndPoint server_endpoint_; 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // The terminal ID assigned to this connection. 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string terminal_id_; 143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Interfaces exposed by the RDP ActiveX control. 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::win::ScopedComPtr<mstsc::IMsRdpClient> client_; 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::win::ScopedComPtr<mstsc::IMsRdpClientAdvancedSettings> client_settings_; 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Used to cancel modal dialog boxes shown by the RDP control. 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) class WindowHook; 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<WindowHook> window_activate_hook_; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace remoting 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // REMOTING_HOST_WIN_RDP_HOST_WINDOW_H_ 156