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