blob: dc1db770b358e4288444c41d4ddcceb92d24088b [file] [log] [blame]
// 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_