Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(143)

Unified Diff: remoting/host/desktop_session_win.cc

Issue 12544020: Remote RDP sessions, rather than the console, if curtain-mode is configured. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« remoting/host/desktop_session_win.h ('K') | « remoting/host/desktop_session_win.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: remoting/host/desktop_session_win.cc
diff --git a/remoting/host/desktop_session_win.cc b/remoting/host/desktop_session_win.cc
index 10fb011bb52db82fe14079cef71eca8e0106eea2..bd8d7f2083933c14e6f454035c962f3b430b0ad2 100644
--- a/remoting/host/desktop_session_win.cc
+++ b/remoting/host/desktop_session_win.cc
@@ -4,63 +4,260 @@
#include "remoting/host/desktop_session_win.h"
+#include <limits>
+#include <sddl.h>
+
#include "base/base_switches.h"
#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
#include "base/path_service.h"
+#include "base/threading/thread_checker.h"
+#include "base/timer.h"
+#include "base/utf_string_conversions.h"
+#include "base/win/scoped_comptr.h"
+#include "base/win/scoped_handle.h"
#include "ipc/ipc_message_macros.h"
+#include "ipc/ipc_platform_file.h"
#include "net/base/ip_endpoint.h"
#include "remoting/base/auto_thread_task_runner.h"
+// MIDL-generated declarations and definitions.
+#include "remoting/host/chromoting_lib.h"
#include "remoting/host/chromoting_messages.h"
#include "remoting/host/daemon_process.h"
+#include "remoting/host/desktop_session.h"
#include "remoting/host/host_main.h"
#include "remoting/host/ipc_constants.h"
#include "remoting/host/sas_injector.h"
+#include "remoting/host/win/host_service.h"
#include "remoting/host/win/worker_process_launcher.h"
#include "remoting/host/win/wts_session_process_delegate.h"
#include "remoting/host/win/wts_terminal_monitor.h"
+#include "remoting/host/win/wts_terminal_observer.h"
+#include "remoting/host/worker_process_ipc_delegate.h"
using base::win::ScopedHandle;
+namespace remoting {
+
namespace {
// The security descriptor of the daemon IPC endpoint. It gives full access
// to SYSTEM and denies access by anyone else.
-const char kDaemonIpcSecurityDescriptor[] = "O:SYG:SYD:(A;;GA;;;SY)";
+const wchar_t kDaemonIpcSecurityDescriptor[] =
+ SDDL_OWNER L":" SDDL_LOCAL_SYSTEM
+ SDDL_GROUP L":" SDDL_LOCAL_SYSTEM
+ SDDL_DACL L":("
+ SDDL_ACCESS_ALLOWED L";;" SDDL_GENERIC_ALL L";;;" SDDL_LOCAL_SYSTEM
+ L")";
// The command line parameters that should be copied from the service's command
// line to the host process.
const char* kCopiedSwitchNames[] = { switches::kV, switches::kVModule };
-} // namespace
+// RDC 6.1 (W2K8) supports resolution up to 4096x2048.
Wez 2013/03/12 01:21:11 nit: resolution -> dimensions of
alexeypa (please no reviews) 2013/03/12 20:21:15 Done.
+const int kMaxRdpScreenWidth = 4096;
+const int kMaxRdpScreenHeight = 2048;
+const int kMinRdpScreenWidth = 800;
+const int kMinRdpScreenHeight = 600;
Wez 2013/03/12 01:21:11 nit: Comment on why we have a minimum.
alexeypa (please no reviews) 2013/03/12 20:21:15 Done.
+
+const int kDefaultDpiX = 96;
+const int kDefaultDpiY = 96;
Wez 2013/03/12 01:21:11 nit: Comment on what these are used for.
alexeypa (please no reviews) 2013/03/12 20:21:15 Done.
+
+// The session attach notification should arrive within 30 seconds.
+const int kSessionAttachTimeoutSeconds = 30;
+
+// Implements functionality shared by ConsoleSession and RdpSession classes.
+class DesktopSessionWin
+ : public DesktopSession,
+ public WorkerProcessIpcDelegate,
+ public WtsTerminalObserver {
+ public:
+ // Passes the owning |daemon_process|, a unique identifier of the desktop
+ // session |id| and the interface for monitoring console session attach/detach
Wez 2013/03/12 01:21:11 nit: console session -> session
alexeypa (please no reviews) 2013/03/12 20:21:15 Done.
+ // events. Both |daemon_process| and |monitor| must outlive |this|.
+ DesktopSessionWin(
+ scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
+ scoped_refptr<AutoThreadTaskRunner> io_task_runner,
+ DaemonProcess* daemon_process,
+ int id,
Wez 2013/03/12 01:21:11 nit: |session_id|? or |desktop_session_id|?
alexeypa (please no reviews) 2013/03/12 20:21:15 I prefer |id| without any prefix because this is t
+ WtsTerminalMonitor* monitor);
+ virtual ~DesktopSessionWin();
-namespace remoting {
+ // WorkerProcessIpcDelegate implementation.
+ virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+ virtual void OnPermanentError() OVERRIDE;
Wez 2013/03/12 01:21:11 nit: Both of these interfaces can move to private,
alexeypa (please no reviews) 2013/03/12 20:21:15 Done.
+
+ // WtsTerminalObserver implementation.
+ virtual void OnSessionAttached(uint32 session_id) OVERRIDE;
+ virtual void OnSessionDetached() OVERRIDE;
+
+ protected:
+ const scoped_refptr<AutoThreadTaskRunner>& caller_task_runner() const {
+ return caller_task_runner_;
+ }
+
+ // Called when |session_attach_timer_| expires.
+ void OnSessionAttachTimeout();
+
+ // Start monitoring session attach/detach notification for the given endpoint.
Wez 2013/03/12 01:21:11 nit: Start -> Starts e.g. Starts monitoring for s
alexeypa (please no reviews) 2013/03/12 20:21:15 Done.
+ void StartMonitoring(const net::IPEndPoint& client_endpoint);
+
+ // Stop monitoring session attach/detach notifications.
+ void StopMonitoring();
+
+ // ChromotingDesktopDaemonMsg_InjectSas handler.
Wez 2013/03/12 01:21:11 nit: OnInjectSas() -> InjectSas() w/ comment "Inje
alexeypa (please no reviews) 2013/03/12 20:21:15 Done.
+ virtual void OnInjectSas() = 0;
+
+ private:
+ // ChromotingDesktopDaemonMsg_DesktopAttached handler.
+ void OnDesktopSessionAgentAttached(IPC::PlatformFileForTransit desktop_pipe);
+
+ // Restarts the desktop process.
+ void RestartDesktopProcess(const tracked_objects::Location& location);
+
+ // Task runner on which public methods of this class should be called.
+ scoped_refptr<AutoThreadTaskRunner> caller_task_runner_;
+
+ // Message loop used by the IPC channel.
Wez 2013/03/12 01:21:11 nit: Does the IPC channel use it, or do we use it
alexeypa (please no reviews) 2013/03/12 20:21:15 It is used by the IPC channel.
+ scoped_refptr<AutoThreadTaskRunner> io_task_runner_;
+
+ // Handle of the desktop process.
Wez 2013/03/12 01:21:11 nit: Is the desktop process the DesktopSessionAgen
alexeypa (please no reviews) 2013/03/12 20:21:15 The desktop process is the process running in the
Wez 2013/03/13 22:30:27 What I'm really looking for is clarity as to what
+ base::win::ScopedHandle desktop_process_;
+
+ // Launches and monitors the desktop process.
+ scoped_ptr<WorkerProcessLauncher> launcher_;
+
+ // Pointer used to unsubscribe from session attach and detach events.
+ WtsTerminalMonitor* monitor_;
+
+ // True if |this| is subsribed to receive session attach/detach notifications.
+ bool monitoring_notifications_;
+
+ // Used to report an error if the session attach notification does not arrives
+ // for too long.
+ base::OneShotTimer<DesktopSessionWin> session_attach_timer_;
+
+ DISALLOW_COPY_AND_ASSIGN(DesktopSessionWin);
+};
+
+// DesktopSession implementation which attaches to the host's physical console.
+// Receives IPC messages from the desktop process, running in the console
+// session, via |WorkerProcessIpcDelegate|, and monitors console session
+// attach/detach events via |WtsConsoleObserer|.
+class ConsoleSession : public DesktopSessionWin {
+ public:
+ // Passes the owning |daemon_process|, a unique identifier of the desktop
+ // session |id| and the interface for monitoring console session attach/detach
+ // events. Both |daemon_process| and |monitor| must outlive |this|.
+ ConsoleSession(
+ scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
+ scoped_refptr<AutoThreadTaskRunner> io_task_runner,
+ DaemonProcess* daemon_process,
+ int id,
+ WtsTerminalMonitor* monitor);
+ virtual ~ConsoleSession();
+
+ protected:
+ // DesktopSessionWin overrides.
+ virtual void OnInjectSas() OVERRIDE;
+
+ private:
+ scoped_ptr<SasInjector> sas_injector_;
+
+ DISALLOW_COPY_AND_ASSIGN(ConsoleSession);
+};
+
+// DesktopSession implementation which attaches to virtual RDP console.
+// Receives IPC messages from the desktop process, running in the console
+// session, via |WorkerProcessIpcDelegate|, and monitors console session
+// attach/detach events via |WtsConsoleObserer|.
+class RdpSession : public DesktopSessionWin {
+ public:
+ // Passes the owning |daemon_process|, a unique identifier of the desktop
+ // session |id| and the interface for monitoring console session attach/detach
+ // events. Both |daemon_process| and |monitor| must outlive |this|.
+ RdpSession(
+ scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
+ scoped_refptr<AutoThreadTaskRunner> io_task_runner,
+ DaemonProcess* daemon_process,
+ int id,
+ WtsTerminalMonitor* monitor);
+ virtual ~RdpSession();
+
+ // Performs the part of initialization that can fail.
+ bool Initialize(const DesktopSessionParams& params);
+
+ // Mirrors IRdpDesktopSessionEventHandler.
+ void OnRdpConnected(const net::IPEndPoint& client_endpoint);
+ void OnRdpClosed();
+
+ protected:
+ // DesktopSessionWin overrides.
+ virtual void OnInjectSas() OVERRIDE;
+
+ private:
+ // An implementation of IRdpDesktopSessionEventHandler interface that forwards
+ // notifications to the owning desktop session.
+ class EventHandler : public IRdpDesktopSessionEventHandler {
+ public:
+ explicit EventHandler(base::WeakPtr<RdpSession> desktop_session);
+ virtual ~EventHandler();
+
+ // IUnknown interface.
+ STDMETHOD_(ULONG, AddRef)() OVERRIDE;
+ STDMETHOD_(ULONG, Release)() OVERRIDE;
+ STDMETHOD(QueryInterface)(REFIID riid, void** ppv) OVERRIDE;
+
+ // IRdpDesktopSessionEventHandler interface.
+ STDMETHOD(OnRdpConnected)(byte* client_endpoint, long length) OVERRIDE;
+ STDMETHOD(OnRdpClosed)() OVERRIDE;
+
+ private:
+ ULONG ref_count_;
+
+ // Points to the desktop session object receiving OnRdpXxx() notifications.
+ base::WeakPtr<RdpSession> desktop_session_;
+
+ // This class must be used on a single thread.
+ base::ThreadChecker thread_checker_;
+
+ DISALLOW_COPY_AND_ASSIGN(EventHandler);
+ };
+
+ // Used to create an RDP desktop session.
+ base::win::ScopedComPtr<IRdpDesktopSession> rdp_desktop_session_;
+
+ base::WeakPtrFactory<RdpSession> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(RdpSession);
+};
DesktopSessionWin::DesktopSessionWin(
- scoped_refptr<AutoThreadTaskRunner> main_task_runner,
+ scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
scoped_refptr<AutoThreadTaskRunner> io_task_runner,
DaemonProcess* daemon_process,
int id,
- const DesktopSessionParams& params,
- bool virtual_terminal,
WtsTerminalMonitor* monitor)
: DesktopSession(daemon_process, id),
- main_task_runner_(main_task_runner),
+ caller_task_runner_(caller_task_runner),
io_task_runner_(io_task_runner),
- monitor_(monitor) {
- DCHECK(main_task_runner_->BelongsToCurrentThread());
-
- monitor_->AddWtsTerminalObserver(net::IPEndPoint(), this);
+ monitor_(monitor),
+ monitoring_notifications_(false) {
+ DCHECK(caller_task_runner_->BelongsToCurrentThread());
}
DesktopSessionWin::~DesktopSessionWin() {
- DCHECK(main_task_runner_->BelongsToCurrentThread());
+ DCHECK(caller_task_runner_->BelongsToCurrentThread());
- launcher_.reset();
- monitor_->RemoveWtsTerminalObserver(this);
+ StopMonitoring();
}
void DesktopSessionWin::OnChannelConnected(int32 peer_pid) {
- DCHECK(main_task_runner_->BelongsToCurrentThread());
+ DCHECK(caller_task_runner_->BelongsToCurrentThread());
// Obtain the handle of the desktop process. It will be passed to the network
// process so it would be able to duplicate handles of shared memory objects
@@ -75,7 +272,7 @@ void DesktopSessionWin::OnChannelConnected(int32 peer_pid) {
}
bool DesktopSessionWin::OnMessageReceived(const IPC::Message& message) {
- DCHECK(main_task_runner_->BelongsToCurrentThread());
+ DCHECK(caller_task_runner_->BelongsToCurrentThread());
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(DesktopSessionWin, message)
@@ -95,17 +292,18 @@ bool DesktopSessionWin::OnMessageReceived(const IPC::Message& message) {
}
void DesktopSessionWin::OnPermanentError() {
- DCHECK(main_task_runner_->BelongsToCurrentThread());
+ DCHECK(caller_task_runner_->BelongsToCurrentThread());
- launcher_.reset();
+ StopMonitoring();
// This call will delete |this| so it should be at the very end of the method.
daemon_process()->CloseDesktopSession(id());
}
void DesktopSessionWin::OnSessionAttached(uint32 session_id) {
- DCHECK(main_task_runner_->BelongsToCurrentThread());
- DCHECK(launcher_.get() == NULL);
+ DCHECK(caller_task_runner_->BelongsToCurrentThread());
+ DCHECK(!launcher_);
+ DCHECK(monitoring_notifications_);
// Get the desktop binary name.
base::FilePath desktop_binary;
@@ -114,6 +312,8 @@ void DesktopSessionWin::OnSessionAttached(uint32 session_id) {
return;
}
+ session_attach_timer_.Stop();
+
scoped_ptr<CommandLine> target(new CommandLine(desktop_binary));
target->AppendSwitchASCII(kProcessTypeSwitchName, kProcessTypeDesktop);
target->CopySwitchesFrom(*CommandLine::ForCurrentProcess(),
@@ -122,20 +322,59 @@ void DesktopSessionWin::OnSessionAttached(uint32 session_id) {
// Create a delegate to launch a process into the session.
scoped_ptr<WtsSessionProcessDelegate> delegate(
- new WtsSessionProcessDelegate(main_task_runner_, io_task_runner_,
- target.Pass(), session_id,
- true, kDaemonIpcSecurityDescriptor));
+ new WtsSessionProcessDelegate(
+ caller_task_runner_, io_task_runner_, target.Pass(), session_id, true,
+ WideToUTF8(kDaemonIpcSecurityDescriptor)));
// Create a launcher for the desktop process, using the per-session delegate.
launcher_.reset(new WorkerProcessLauncher(
- main_task_runner_, delegate.Pass(), this));
+ caller_task_runner_, delegate.Pass(), this));
}
void DesktopSessionWin::OnSessionDetached() {
- DCHECK(main_task_runner_->BelongsToCurrentThread());
- DCHECK(launcher_.get() != NULL);
+ DCHECK(caller_task_runner_->BelongsToCurrentThread());
launcher_.reset();
+
+ if (monitoring_notifications_) {
+ session_attach_timer_.Start(
+ FROM_HERE, base::TimeDelta::FromSeconds(kSessionAttachTimeoutSeconds),
+ this, &DesktopSessionWin::OnSessionAttachTimeout);
+ }
+}
+
+void DesktopSessionWin::OnSessionAttachTimeout() {
+ DCHECK(caller_task_runner_->BelongsToCurrentThread());
+
+ LOG(ERROR) << "Session attach notification hasn't arrived within "
+ << kSessionAttachTimeoutSeconds << " seconds.";
+ OnPermanentError();
+}
+
+void DesktopSessionWin::StartMonitoring(
+ const net::IPEndPoint& client_endpoint) {
+ DCHECK(caller_task_runner_->BelongsToCurrentThread());
+ DCHECK(!monitoring_notifications_);
+ DCHECK(!session_attach_timer_.IsRunning());
+
+ session_attach_timer_.Start(
+ FROM_HERE, base::TimeDelta::FromSeconds(kSessionAttachTimeoutSeconds),
+ this, &DesktopSessionWin::OnSessionAttachTimeout);
+
+ monitoring_notifications_ = true;
+ monitor_->AddWtsTerminalObserver(client_endpoint, this);
+}
+
+void DesktopSessionWin::StopMonitoring() {
+ DCHECK(caller_task_runner_->BelongsToCurrentThread());
+
+ if (monitoring_notifications_) {
+ monitoring_notifications_ = false;
+ monitor_->RemoveWtsTerminalObserver(this);
+ }
+
+ session_attach_timer_.Stop();
+ OnSessionDetached();
}
void DesktopSessionWin::OnDesktopSessionAgentAttached(
@@ -147,26 +386,228 @@ void DesktopSessionWin::OnDesktopSessionAgentAttached(
}
}
-void DesktopSessionWin::OnInjectSas() {
- DCHECK(main_task_runner_->BelongsToCurrentThread());
+void DesktopSessionWin::RestartDesktopProcess(
+ const tracked_objects::Location& location) {
+ DCHECK(caller_task_runner_->BelongsToCurrentThread());
- // Do not try to inject SAS if the desktop process is not running. This can
- // happen when the session has detached from the console for instance.
- if (!launcher_)
- return;
+ launcher_->Send(new ChromotingDaemonDesktopMsg_Crash(
+ location.function_name(), location.file_name(), location.line_number()));
+}
+ConsoleSession::ConsoleSession(
+ scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
+ scoped_refptr<AutoThreadTaskRunner> io_task_runner,
+ DaemonProcess* daemon_process,
+ int id,
+ WtsTerminalMonitor* monitor)
+ : DesktopSessionWin(caller_task_runner, io_task_runner, daemon_process, id,
+ monitor) {
+ StartMonitoring(net::IPEndPoint());
+}
+
+ConsoleSession::~ConsoleSession() {
+}
+
+void ConsoleSession::OnInjectSas() {
if (!sas_injector_)
sas_injector_ = SasInjector::Create();
if (!sas_injector_->InjectSas())
LOG(ERROR) << "Failed to inject Secure Attention Sequence.";
}
-void DesktopSessionWin::RestartDesktopProcess(
- const tracked_objects::Location& location) {
- DCHECK(main_task_runner_->BelongsToCurrentThread());
+RdpSession::RdpSession(
+ scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
+ scoped_refptr<AutoThreadTaskRunner> io_task_runner,
+ DaemonProcess* daemon_process,
+ int id,
+ WtsTerminalMonitor* monitor)
+ : DesktopSessionWin(caller_task_runner, io_task_runner, daemon_process, id,
+ monitor),
+ ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
+}
- launcher_->Send(new ChromotingDaemonDesktopMsg_Crash(
- location.function_name(), location.file_name(), location.line_number()));
+RdpSession::~RdpSession() {
+}
+
+bool RdpSession::Initialize(const DesktopSessionParams& params) {
+ DCHECK(caller_task_runner()->BelongsToCurrentThread());
+
+ // Create the RDP wrapper object.
+ HRESULT result = rdp_desktop_session_.CreateInstance(
+ __uuidof(RdpDesktopSession));
+ if (FAILED(result)) {
+ LOG(ERROR) << "Failed to create RdpSession object, 0x"
+ << std::hex << result << std::dec << ".";
+ return false;
+ }
+
+ // DaemonProcess::CreateDesktopSession() varifies that |client_dpi_| and
+ // |client_size_| are positive.
+ DCHECK(params.client_dpi_.x() >= 0 && params.client_dpi_.y() >= 0);
+ DCHECK(params.client_size_.width() >= 0 && params.client_size_.height() >= 0);
+
+ // Handle the default DPI.
+ SkIPoint client_dpi = params.client_dpi_;
+ if (!client_dpi.x())
+ client_dpi.setX(kDefaultDpiX);
+ if (!client_dpi.y())
+ client_dpi.setY(kDefaultDpiY);
+
+ // Make sure there will be no integer overflow while scaling the client
+ // resolution.
+ SkISize client_size = SkISize::Make(
+ std::min(params.client_size_.width(),
+ std::numeric_limits<int32_t>::max() / kDefaultDpiX),
+ std::min(params.client_size_.height(),
+ std::numeric_limits<int32_t>::max() / kDefaultDpiY));
+
+ // Scale the client resolution assiming RDP gives us the default 96 DPI.
+ SkISize host_size = SkISize::Make(
+ client_size.width() * kDefaultDpiX / client_dpi.x(),
+ client_size.height() * kDefaultDpiY / client_dpi.y());
+
+ // Make sure that the host resolution is within the limits supported by RDP.
+ host_size = SkISize::Make(
+ std::min(kMaxRdpScreenWidth,
+ std::max(kMinRdpScreenWidth, host_size.width())),
+ std::min(kMaxRdpScreenHeight,
+ std::max(kMinRdpScreenHeight, host_size.height())));
+
+ // Create an RDP session.
+ base::win::ScopedComPtr<IRdpDesktopSessionEventHandler> event_handler(
+ new EventHandler(weak_factory_.GetWeakPtr()));
+ result = rdp_desktop_session_->Connect(host_size.width(),
+ host_size.height(),
+ event_handler);
+ if (FAILED(result)) {
+ LOG(ERROR) << "RdpSession::Create() failed, 0x"
+ << std::hex << result << std::dec << ".";
+ return false;
+ }
+
+ return true;
+}
+
+void RdpSession::OnRdpConnected(const net::IPEndPoint& client_endpoint) {
+ DCHECK(caller_task_runner()->BelongsToCurrentThread());
+
+ StopMonitoring();
+ StartMonitoring(client_endpoint);
+}
+
+void RdpSession::OnRdpClosed() {
+ DCHECK(caller_task_runner()->BelongsToCurrentThread());
+
+ OnPermanentError();
+}
+
+void RdpSession::OnInjectSas() {
+ DCHECK(caller_task_runner()->BelongsToCurrentThread());
+
+ NOTIMPLEMENTED();
+}
+
+RdpSession::EventHandler::EventHandler(
+ base::WeakPtr<RdpSession> desktop_session)
+ : ref_count_(0),
+ desktop_session_(desktop_session) {
+}
+
+RdpSession::EventHandler::~EventHandler() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (desktop_session_)
+ desktop_session_->OnRdpClosed();
+}
+
+ULONG STDMETHODCALLTYPE RdpSession::EventHandler::AddRef() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ return ++ref_count_;
+}
+
+ULONG STDMETHODCALLTYPE RdpSession::EventHandler::Release() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (--ref_count_ == 0) {
+ delete this;
+ return 0;
+ }
+
+ return ref_count_;
+}
+
+STDMETHODIMP RdpSession::EventHandler::QueryInterface(REFIID riid, void** ppv) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (riid == IID_IUnknown ||
+ riid == IID_IRdpDesktopSessionEventHandler) {
+ *ppv = static_cast<IRdpDesktopSessionEventHandler*>(this);
+ AddRef();
+ return S_OK;
+ }
+
+ *ppv = NULL;
+ return E_NOINTERFACE;
+}
+
+STDMETHODIMP RdpSession::EventHandler::OnRdpConnected(
+ byte* client_endpoint,
+ long length) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (!desktop_session_)
+ return S_OK;
+
+ net::IPEndPoint endpoint;
+ if (!endpoint.FromSockAddr(reinterpret_cast<sockaddr*>(client_endpoint),
+ length)) {
+ LOG(ERROR) << "Failed to parse the endpoint passed to OnRdpConnected().";
+ OnRdpClosed();
+ return S_OK;
+ }
+
+ desktop_session_->OnRdpConnected(endpoint);
+ return S_OK;
+}
+
+STDMETHODIMP RdpSession::EventHandler::OnRdpClosed() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (!desktop_session_)
+ return S_OK;
+
+ base::WeakPtr<RdpSession> desktop_session = desktop_session_;
+ desktop_session_.reset();
+ desktop_session->OnRdpClosed();
+ return S_OK;
+}
+
+} // namespace
+
+scoped_ptr<DesktopSession> CreateDesktopSessionWin(
+ scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
+ scoped_refptr<AutoThreadTaskRunner> io_task_runner,
+ DaemonProcess* daemon_process,
+ int id,
+ const DesktopSessionParams& params,
+ bool virtual_terminal) {
+ if (virtual_terminal) {
+ scoped_ptr<RdpSession> session(new RdpSession(
+ caller_task_runner, io_task_runner, daemon_process, id,
+ HostService::GetInstance()));
+
+ if (!session->Initialize(params))
+ return scoped_ptr<DesktopSession>();
+
+ return session.PassAs<DesktopSession>();
+ } else {
+ scoped_ptr<ConsoleSession> session(new ConsoleSession(
+ caller_task_runner, io_task_runner, daemon_process, id,
+ HostService::GetInstance()));
+
+ return session.PassAs<DesktopSession>();
+ }
}
} // namespace remoting
« remoting/host/desktop_session_win.h ('K') | « remoting/host/desktop_session_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698