summaryrefslogtreecommitdiffstats
path: root/remoting/host/win/rdp_client_window.h
blob: c68f39935b150d4b909399b0bf51ff4394e7cd3e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// 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/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/win/scoped_comptr.h"
#include "net/base/ip_endpoint.h"
// The following header was generated by Visual Studio. We had to check it in
// due to a bug in VS2013. See crbug.com/318952 for details.
#include "remoting/host/win/com_imported_mstscax.tlh"
#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"

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() override;

  // 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,
                  &RdpClientWindow::OnConnected)
    SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 4,
                  &RdpClientWindow::OnDisconnected)
    SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 10,
                  &RdpClientWindow::OnFatalError)
    SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 15,
                  &RdpClientWindow::OnConfirmClose)
    SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 18,
                  &RdpClientWindow::OnAuthenticationWarningDisplayed)
    SINK_ENTRY_EX(1, __uuidof(mstsc::IMsTscAxEvents), 19,
                  &RdpClientWindow::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);

  int LogOnCreateError(HRESULT error);

  // 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_