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

Side by Side 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: fixing remoting_unittests 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/host/desktop_session_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/host/desktop_session_win.h" 5 #include "remoting/host/desktop_session_win.h"
6 6
7 #include <limits>
8 #include <sddl.h>
9
7 #include "base/base_switches.h" 10 #include "base/base_switches.h"
8 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/files/file_path.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/weak_ptr.h"
9 #include "base/path_service.h" 16 #include "base/path_service.h"
17 #include "base/threading/thread_checker.h"
18 #include "base/timer.h"
19 #include "base/utf_string_conversions.h"
20 #include "base/win/scoped_comptr.h"
21 #include "base/win/scoped_handle.h"
10 #include "ipc/ipc_message_macros.h" 22 #include "ipc/ipc_message_macros.h"
23 #include "ipc/ipc_platform_file.h"
11 #include "net/base/ip_endpoint.h" 24 #include "net/base/ip_endpoint.h"
12 #include "remoting/base/auto_thread_task_runner.h" 25 #include "remoting/base/auto_thread_task_runner.h"
26 // MIDL-generated declarations and definitions.
27 #include "remoting/host/chromoting_lib.h"
13 #include "remoting/host/chromoting_messages.h" 28 #include "remoting/host/chromoting_messages.h"
14 #include "remoting/host/daemon_process.h" 29 #include "remoting/host/daemon_process.h"
30 #include "remoting/host/desktop_session.h"
15 #include "remoting/host/host_main.h" 31 #include "remoting/host/host_main.h"
16 #include "remoting/host/ipc_constants.h" 32 #include "remoting/host/ipc_constants.h"
17 #include "remoting/host/sas_injector.h" 33 #include "remoting/host/sas_injector.h"
34 #include "remoting/host/win/host_service.h"
18 #include "remoting/host/win/worker_process_launcher.h" 35 #include "remoting/host/win/worker_process_launcher.h"
19 #include "remoting/host/win/wts_session_process_delegate.h" 36 #include "remoting/host/win/wts_session_process_delegate.h"
20 #include "remoting/host/win/wts_terminal_monitor.h" 37 #include "remoting/host/win/wts_terminal_monitor.h"
38 #include "remoting/host/win/wts_terminal_observer.h"
39 #include "remoting/host/worker_process_ipc_delegate.h"
21 40
22 using base::win::ScopedHandle; 41 using base::win::ScopedHandle;
23 42
43 namespace remoting {
44
24 namespace { 45 namespace {
25 46
26 // The security descriptor of the daemon IPC endpoint. It gives full access 47 // The security descriptor of the daemon IPC endpoint. It gives full access
27 // to SYSTEM and denies access by anyone else. 48 // to SYSTEM and denies access by anyone else.
28 const char kDaemonIpcSecurityDescriptor[] = "O:SYG:SYD:(A;;GA;;;SY)"; 49 const wchar_t kDaemonIpcSecurityDescriptor[] =
50 SDDL_OWNER L":" SDDL_LOCAL_SYSTEM
51 SDDL_GROUP L":" SDDL_LOCAL_SYSTEM
52 SDDL_DACL L":("
53 SDDL_ACCESS_ALLOWED L";;" SDDL_GENERIC_ALL L";;;" SDDL_LOCAL_SYSTEM
54 L")";
29 55
30 // The command line parameters that should be copied from the service's command 56 // The command line parameters that should be copied from the service's command
31 // line to the host process. 57 // line to the host process.
32 const char* kCopiedSwitchNames[] = { switches::kV, switches::kVModule }; 58 const char* kCopiedSwitchNames[] = { switches::kV, switches::kVModule };
33 59
60 // RDC 6.1 (W2K8) supports dimensions of up to 4096x2048.
61 const int kMaxRdpScreenWidth = 4096;
62 const int kMaxRdpScreenHeight = 2048;
63
64 // The minimum effective screen dimensions supported by Windows are 800x600.
65 const int kMinRdpScreenWidth = 800;
66 const int kMinRdpScreenHeight = 600;
67
68 // Default dots per inch is 96 DPI.
69 const int kDefaultDpiX = 96;
70 const int kDefaultDpiY = 96;
71
72 // The session attach notification should arrive within 30 seconds.
73 const int kSessionAttachTimeoutSeconds = 30;
74
75 // DesktopSession implementation which attaches to the host's physical console.
76 // Receives IPC messages from the desktop process, running in the console
77 // session, via |WorkerProcessIpcDelegate|, and monitors console session
78 // attach/detach events via |WtsConsoleObserer|.
79 class ConsoleSession : public DesktopSessionWin {
80 public:
81 // Same as DesktopSessionWin().
82 ConsoleSession(
83 scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
84 scoped_refptr<AutoThreadTaskRunner> io_task_runner,
85 DaemonProcess* daemon_process,
86 int id,
87 WtsTerminalMonitor* monitor);
88 virtual ~ConsoleSession();
89
90 protected:
91 // DesktopSessionWin overrides.
92 virtual void InjectSas() OVERRIDE;
93
94 private:
95 scoped_ptr<SasInjector> sas_injector_;
96
97 DISALLOW_COPY_AND_ASSIGN(ConsoleSession);
98 };
99
100 // DesktopSession implementation which attaches to virtual RDP console.
101 // Receives IPC messages from the desktop process, running in the console
102 // session, via |WorkerProcessIpcDelegate|, and monitors console session
103 // attach/detach events via |WtsConsoleObserer|.
104 class RdpSession : public DesktopSessionWin {
105 public:
106 // Same as DesktopSessionWin().
107 RdpSession(
108 scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
109 scoped_refptr<AutoThreadTaskRunner> io_task_runner,
110 DaemonProcess* daemon_process,
111 int id,
112 WtsTerminalMonitor* monitor);
113 virtual ~RdpSession();
114
115 // Performs the part of initialization that can fail.
116 bool Initialize(const DesktopSessionParams& params);
117
118 // Mirrors IRdpDesktopSessionEventHandler.
119 void OnRdpConnected(const net::IPEndPoint& client_endpoint);
120 void OnRdpClosed();
121
122 protected:
123 // DesktopSessionWin overrides.
124 virtual void InjectSas() OVERRIDE;
125
126 private:
127 // An implementation of IRdpDesktopSessionEventHandler interface that forwards
128 // notifications to the owning desktop session.
129 class EventHandler : public IRdpDesktopSessionEventHandler {
130 public:
131 explicit EventHandler(base::WeakPtr<RdpSession> desktop_session);
132 virtual ~EventHandler();
133
134 // IUnknown interface.
135 STDMETHOD_(ULONG, AddRef)() OVERRIDE;
136 STDMETHOD_(ULONG, Release)() OVERRIDE;
137 STDMETHOD(QueryInterface)(REFIID riid, void** ppv) OVERRIDE;
138
139 // IRdpDesktopSessionEventHandler interface.
140 STDMETHOD(OnRdpConnected)(byte* client_endpoint, long length) OVERRIDE;
141 STDMETHOD(OnRdpClosed)() OVERRIDE;
142
143 private:
144 ULONG ref_count_;
145
146 // Points to the desktop session object receiving OnRdpXxx() notifications.
147 base::WeakPtr<RdpSession> desktop_session_;
148
149 // This class must be used on a single thread.
150 base::ThreadChecker thread_checker_;
151
152 DISALLOW_COPY_AND_ASSIGN(EventHandler);
153 };
154
155 // Used to create an RDP desktop session.
156 base::win::ScopedComPtr<IRdpDesktopSession> rdp_desktop_session_;
157
158 base::WeakPtrFactory<RdpSession> weak_factory_;
159
160 DISALLOW_COPY_AND_ASSIGN(RdpSession);
161 };
162
163 ConsoleSession::ConsoleSession(
164 scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
165 scoped_refptr<AutoThreadTaskRunner> io_task_runner,
166 DaemonProcess* daemon_process,
167 int id,
168 WtsTerminalMonitor* monitor)
169 : DesktopSessionWin(caller_task_runner, io_task_runner, daemon_process, id,
170 monitor) {
171 StartMonitoring(net::IPEndPoint());
172 }
173
174 ConsoleSession::~ConsoleSession() {
175 }
176
177 void ConsoleSession::InjectSas() {
178 if (!sas_injector_)
179 sas_injector_ = SasInjector::Create();
180 if (!sas_injector_->InjectSas())
181 LOG(ERROR) << "Failed to inject Secure Attention Sequence.";
182 }
183
184 RdpSession::RdpSession(
185 scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
186 scoped_refptr<AutoThreadTaskRunner> io_task_runner,
187 DaemonProcess* daemon_process,
188 int id,
189 WtsTerminalMonitor* monitor)
190 : DesktopSessionWin(caller_task_runner, io_task_runner, daemon_process, id,
191 monitor),
192 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
193 }
194
195 RdpSession::~RdpSession() {
196 }
197
198 bool RdpSession::Initialize(const DesktopSessionParams& params) {
199 DCHECK(caller_task_runner()->BelongsToCurrentThread());
200
201 // Create the RDP wrapper object.
202 HRESULT result = rdp_desktop_session_.CreateInstance(
203 __uuidof(RdpDesktopSession));
204 if (FAILED(result)) {
205 LOG(ERROR) << "Failed to create RdpSession object, 0x"
206 << std::hex << result << std::dec << ".";
207 return false;
208 }
209
210 // DaemonProcess::CreateDesktopSession() varifies that |client_dpi_| and
211 // |client_size_| are positive.
212 DCHECK(params.client_dpi_.x() >= 0 && params.client_dpi_.y() >= 0);
213 DCHECK(params.client_size_.width() >= 0 && params.client_size_.height() >= 0);
214
215 // Handle the default DPI.
216 SkIPoint client_dpi = params.client_dpi_;
217 if (!client_dpi.x())
218 client_dpi.setX(kDefaultDpiX);
219 if (!client_dpi.y())
220 client_dpi.setY(kDefaultDpiY);
221
222 // Make sure there will be no integer overflow while scaling the client
223 // resolution.
224 SkISize client_size = SkISize::Make(
225 std::min(params.client_size_.width(),
226 std::numeric_limits<int32_t>::max() / kDefaultDpiX),
227 std::min(params.client_size_.height(),
228 std::numeric_limits<int32_t>::max() / kDefaultDpiY));
229
230 // Scale the client resolution assiming RDP gives us the default 96 DPI.
231 SkISize host_size = SkISize::Make(
232 client_size.width() * kDefaultDpiX / client_dpi.x(),
233 client_size.height() * kDefaultDpiY / client_dpi.y());
234
235 // Make sure that the host resolution is within the limits supported by RDP.
236 host_size = SkISize::Make(
237 std::min(kMaxRdpScreenWidth,
238 std::max(kMinRdpScreenWidth, host_size.width())),
239 std::min(kMaxRdpScreenHeight,
240 std::max(kMinRdpScreenHeight, host_size.height())));
241
242 // Create an RDP session.
243 base::win::ScopedComPtr<IRdpDesktopSessionEventHandler> event_handler(
244 new EventHandler(weak_factory_.GetWeakPtr()));
245 result = rdp_desktop_session_->Connect(host_size.width(),
246 host_size.height(),
247 event_handler);
248 if (FAILED(result)) {
249 LOG(ERROR) << "RdpSession::Create() failed, 0x"
250 << std::hex << result << std::dec << ".";
251 return false;
252 }
253
254 return true;
255 }
256
257 void RdpSession::OnRdpConnected(const net::IPEndPoint& client_endpoint) {
258 DCHECK(caller_task_runner()->BelongsToCurrentThread());
259
260 StopMonitoring();
261 StartMonitoring(client_endpoint);
262 }
263
264 void RdpSession::OnRdpClosed() {
265 DCHECK(caller_task_runner()->BelongsToCurrentThread());
266
267 OnPermanentError();
268 }
269
270 void RdpSession::InjectSas() {
271 DCHECK(caller_task_runner()->BelongsToCurrentThread());
272
273 NOTIMPLEMENTED();
274 }
275
276 RdpSession::EventHandler::EventHandler(
277 base::WeakPtr<RdpSession> desktop_session)
278 : ref_count_(0),
279 desktop_session_(desktop_session) {
280 }
281
282 RdpSession::EventHandler::~EventHandler() {
283 DCHECK(thread_checker_.CalledOnValidThread());
284
285 if (desktop_session_)
286 desktop_session_->OnRdpClosed();
287 }
288
289 ULONG STDMETHODCALLTYPE RdpSession::EventHandler::AddRef() {
290 DCHECK(thread_checker_.CalledOnValidThread());
291
292 return ++ref_count_;
293 }
294
295 ULONG STDMETHODCALLTYPE RdpSession::EventHandler::Release() {
296 DCHECK(thread_checker_.CalledOnValidThread());
297
298 if (--ref_count_ == 0) {
299 delete this;
300 return 0;
301 }
302
303 return ref_count_;
304 }
305
306 STDMETHODIMP RdpSession::EventHandler::QueryInterface(REFIID riid, void** ppv) {
307 DCHECK(thread_checker_.CalledOnValidThread());
308
309 if (riid == IID_IUnknown ||
310 riid == IID_IRdpDesktopSessionEventHandler) {
311 *ppv = static_cast<IRdpDesktopSessionEventHandler*>(this);
312 AddRef();
313 return S_OK;
314 }
315
316 *ppv = NULL;
317 return E_NOINTERFACE;
318 }
319
320 STDMETHODIMP RdpSession::EventHandler::OnRdpConnected(
321 byte* client_endpoint,
322 long length) {
323 DCHECK(thread_checker_.CalledOnValidThread());
324
325 if (!desktop_session_)
326 return S_OK;
327
328 net::IPEndPoint endpoint;
329 if (!endpoint.FromSockAddr(reinterpret_cast<sockaddr*>(client_endpoint),
330 length)) {
331 LOG(ERROR) << "Failed to parse the endpoint passed to OnRdpConnected().";
332 OnRdpClosed();
333 return S_OK;
334 }
335
336 desktop_session_->OnRdpConnected(endpoint);
337 return S_OK;
338 }
339
340 STDMETHODIMP RdpSession::EventHandler::OnRdpClosed() {
341 DCHECK(thread_checker_.CalledOnValidThread());
342
343 if (!desktop_session_)
344 return S_OK;
345
346 base::WeakPtr<RdpSession> desktop_session = desktop_session_;
347 desktop_session_.reset();
348 desktop_session->OnRdpClosed();
349 return S_OK;
350 }
351
34 } // namespace 352 } // namespace
35 353
36 namespace remoting { 354 // static
355 scoped_ptr<DesktopSession> DesktopSessionWin::CreateForConsole(
356 scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
357 scoped_refptr<AutoThreadTaskRunner> io_task_runner,
358 DaemonProcess* daemon_process,
359 int id,
360 const DesktopSessionParams& params) {
361 scoped_ptr<ConsoleSession> session(new ConsoleSession(
362 caller_task_runner, io_task_runner, daemon_process, id,
363 HostService::GetInstance()));
364
365 return session.PassAs<DesktopSession>();
366 }
367
368 // static
369 scoped_ptr<DesktopSession> DesktopSessionWin::CreateForVirtualTerminal(
370 scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
371 scoped_refptr<AutoThreadTaskRunner> io_task_runner,
372 DaemonProcess* daemon_process,
373 int id,
374 const DesktopSessionParams& params) {
375 scoped_ptr<RdpSession> session(new RdpSession(
376 caller_task_runner, io_task_runner, daemon_process, id,
377 HostService::GetInstance()));
378 if (!session->Initialize(params))
379 return scoped_ptr<DesktopSession>();
380
381 return session.PassAs<DesktopSession>();
382 }
37 383
38 DesktopSessionWin::DesktopSessionWin( 384 DesktopSessionWin::DesktopSessionWin(
39 scoped_refptr<AutoThreadTaskRunner> main_task_runner, 385 scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
40 scoped_refptr<AutoThreadTaskRunner> io_task_runner, 386 scoped_refptr<AutoThreadTaskRunner> io_task_runner,
41 DaemonProcess* daemon_process, 387 DaemonProcess* daemon_process,
42 int id, 388 int id,
43 const DesktopSessionParams& params,
44 bool virtual_terminal,
45 WtsTerminalMonitor* monitor) 389 WtsTerminalMonitor* monitor)
46 : DesktopSession(daemon_process, id), 390 : DesktopSession(daemon_process, id),
47 main_task_runner_(main_task_runner), 391 caller_task_runner_(caller_task_runner),
48 io_task_runner_(io_task_runner), 392 io_task_runner_(io_task_runner),
49 monitor_(monitor) { 393 monitor_(monitor),
50 DCHECK(main_task_runner_->BelongsToCurrentThread()); 394 monitoring_notifications_(false) {
51 395 DCHECK(caller_task_runner_->BelongsToCurrentThread());
52 monitor_->AddWtsTerminalObserver(net::IPEndPoint(), this);
53 } 396 }
54 397
55 DesktopSessionWin::~DesktopSessionWin() { 398 DesktopSessionWin::~DesktopSessionWin() {
56 DCHECK(main_task_runner_->BelongsToCurrentThread()); 399 DCHECK(caller_task_runner_->BelongsToCurrentThread());
57 400
58 launcher_.reset(); 401 StopMonitoring();
59 monitor_->RemoveWtsTerminalObserver(this); 402 }
403
404 void DesktopSessionWin::OnSessionAttachTimeout() {
405 DCHECK(caller_task_runner_->BelongsToCurrentThread());
406
407 LOG(ERROR) << "Session attach notification didn't arrived within "
408 << kSessionAttachTimeoutSeconds << " seconds.";
409 OnPermanentError();
410 }
411
412 void DesktopSessionWin::StartMonitoring(
413 const net::IPEndPoint& client_endpoint) {
414 DCHECK(caller_task_runner_->BelongsToCurrentThread());
415 DCHECK(!monitoring_notifications_);
416 DCHECK(!session_attach_timer_.IsRunning());
417
418 session_attach_timer_.Start(
419 FROM_HERE, base::TimeDelta::FromSeconds(kSessionAttachTimeoutSeconds),
420 this, &DesktopSessionWin::OnSessionAttachTimeout);
421
422 monitoring_notifications_ = true;
423 monitor_->AddWtsTerminalObserver(client_endpoint, this);
424 }
425
426 void DesktopSessionWin::StopMonitoring() {
427 DCHECK(caller_task_runner_->BelongsToCurrentThread());
428
429 if (monitoring_notifications_) {
430 monitoring_notifications_ = false;
431 monitor_->RemoveWtsTerminalObserver(this);
432 }
433
434 session_attach_timer_.Stop();
435 OnSessionDetached();
60 } 436 }
61 437
62 void DesktopSessionWin::OnChannelConnected(int32 peer_pid) { 438 void DesktopSessionWin::OnChannelConnected(int32 peer_pid) {
63 DCHECK(main_task_runner_->BelongsToCurrentThread()); 439 DCHECK(caller_task_runner_->BelongsToCurrentThread());
64 440
65 // Obtain the handle of the desktop process. It will be passed to the network 441 // Obtain the handle of the desktop process. It will be passed to the network
66 // process so it would be able to duplicate handles of shared memory objects 442 // process to use to duplicate handles of shared memory objects from
67 // from the desktop process. 443 // the desktop process.
68 desktop_process_.Set(OpenProcess(PROCESS_DUP_HANDLE, false, peer_pid)); 444 desktop_process_.Set(OpenProcess(PROCESS_DUP_HANDLE, false, peer_pid));
69 if (!desktop_process_.IsValid()) { 445 if (!desktop_process_.IsValid()) {
70 CrashDesktopProcess(FROM_HERE); 446 CrashDesktopProcess(FROM_HERE);
71 return; 447 return;
72 } 448 }
73 449
74 VLOG(1) << "IPC: daemon <- desktop (" << peer_pid << ")"; 450 VLOG(1) << "IPC: daemon <- desktop (" << peer_pid << ")";
75 } 451 }
76 452
77 bool DesktopSessionWin::OnMessageReceived(const IPC::Message& message) { 453 bool DesktopSessionWin::OnMessageReceived(const IPC::Message& message) {
78 DCHECK(main_task_runner_->BelongsToCurrentThread()); 454 DCHECK(caller_task_runner_->BelongsToCurrentThread());
79 455
80 bool handled = true; 456 bool handled = true;
81 IPC_BEGIN_MESSAGE_MAP(DesktopSessionWin, message) 457 IPC_BEGIN_MESSAGE_MAP(DesktopSessionWin, message)
82 IPC_MESSAGE_HANDLER(ChromotingDesktopDaemonMsg_DesktopAttached, 458 IPC_MESSAGE_HANDLER(ChromotingDesktopDaemonMsg_DesktopAttached,
83 OnDesktopSessionAgentAttached) 459 OnDesktopSessionAgentAttached)
84 IPC_MESSAGE_HANDLER(ChromotingDesktopDaemonMsg_InjectSas, 460 IPC_MESSAGE_HANDLER(ChromotingDesktopDaemonMsg_InjectSas,
85 OnInjectSas) 461 InjectSas)
86 IPC_MESSAGE_UNHANDLED(handled = false) 462 IPC_MESSAGE_UNHANDLED(handled = false)
87 IPC_END_MESSAGE_MAP() 463 IPC_END_MESSAGE_MAP()
88 464
89 if (!handled) { 465 if (!handled) {
90 LOG(ERROR) << "Received unexpected IPC type: " << message.type(); 466 LOG(ERROR) << "Received unexpected IPC type: " << message.type();
91 CrashDesktopProcess(FROM_HERE); 467 CrashDesktopProcess(FROM_HERE);
92 } 468 }
93 469
94 return handled; 470 return handled;
95 } 471 }
96 472
97 void DesktopSessionWin::OnPermanentError() { 473 void DesktopSessionWin::OnPermanentError() {
98 DCHECK(main_task_runner_->BelongsToCurrentThread()); 474 DCHECK(caller_task_runner_->BelongsToCurrentThread());
99 475
100 launcher_.reset(); 476 StopMonitoring();
101 477
102 // This call will delete |this| so it should be at the very end of the method. 478 // This call will delete |this| so it should be at the very end of the method.
103 daemon_process()->CloseDesktopSession(id()); 479 daemon_process()->CloseDesktopSession(id());
104 } 480 }
105 481
106 void DesktopSessionWin::OnSessionAttached(uint32 session_id) { 482 void DesktopSessionWin::OnSessionAttached(uint32 session_id) {
107 DCHECK(main_task_runner_->BelongsToCurrentThread()); 483 DCHECK(caller_task_runner_->BelongsToCurrentThread());
108 DCHECK(launcher_.get() == NULL); 484 DCHECK(!launcher_);
485 DCHECK(monitoring_notifications_);
109 486
110 // Get the desktop binary name. 487 // Get the name of the executable the desktop process will run.
111 base::FilePath desktop_binary; 488 base::FilePath desktop_binary;
112 if (!GetInstalledBinaryPath(kDesktopBinaryName, &desktop_binary)) { 489 if (!GetInstalledBinaryPath(kDesktopBinaryName, &desktop_binary)) {
113 OnPermanentError(); 490 OnPermanentError();
114 return; 491 return;
115 } 492 }
116 493
494 session_attach_timer_.Stop();
495
117 scoped_ptr<CommandLine> target(new CommandLine(desktop_binary)); 496 scoped_ptr<CommandLine> target(new CommandLine(desktop_binary));
118 target->AppendSwitchASCII(kProcessTypeSwitchName, kProcessTypeDesktop); 497 target->AppendSwitchASCII(kProcessTypeSwitchName, kProcessTypeDesktop);
498 // Copy the command line switches enabling verbose logging.
119 target->CopySwitchesFrom(*CommandLine::ForCurrentProcess(), 499 target->CopySwitchesFrom(*CommandLine::ForCurrentProcess(),
120 kCopiedSwitchNames, 500 kCopiedSwitchNames,
121 arraysize(kCopiedSwitchNames)); 501 arraysize(kCopiedSwitchNames));
122 502
123 // Create a delegate to launch a process into the session. 503 // Create a delegate capable of launching a process in a different session.
124 scoped_ptr<WtsSessionProcessDelegate> delegate( 504 scoped_ptr<WtsSessionProcessDelegate> delegate(
125 new WtsSessionProcessDelegate(main_task_runner_, io_task_runner_, 505 new WtsSessionProcessDelegate(
126 target.Pass(), session_id, 506 caller_task_runner_, io_task_runner_, target.Pass(), session_id, true,
127 true, kDaemonIpcSecurityDescriptor)); 507 WideToUTF8(kDaemonIpcSecurityDescriptor)));
128 508
129 // Create a launcher for the desktop process, using the per-session delegate. 509 // Create a launcher for the desktop process, using the per-session delegate.
130 launcher_.reset(new WorkerProcessLauncher( 510 launcher_.reset(new WorkerProcessLauncher(
131 main_task_runner_, delegate.Pass(), this)); 511 caller_task_runner_, delegate.Pass(), this));
132 } 512 }
133 513
134 void DesktopSessionWin::OnSessionDetached() { 514 void DesktopSessionWin::OnSessionDetached() {
135 DCHECK(main_task_runner_->BelongsToCurrentThread()); 515 DCHECK(caller_task_runner_->BelongsToCurrentThread());
136 DCHECK(launcher_.get() != NULL);
137 516
138 launcher_.reset(); 517 launcher_.reset();
518
519 if (monitoring_notifications_) {
520 session_attach_timer_.Start(
521 FROM_HERE, base::TimeDelta::FromSeconds(kSessionAttachTimeoutSeconds),
522 this, &DesktopSessionWin::OnSessionAttachTimeout);
523 }
139 } 524 }
140 525
141 void DesktopSessionWin::OnDesktopSessionAgentAttached( 526 void DesktopSessionWin::OnDesktopSessionAgentAttached(
142 IPC::PlatformFileForTransit desktop_pipe) { 527 IPC::PlatformFileForTransit desktop_pipe) {
143 if (!daemon_process()->OnDesktopSessionAgentAttached(id(), 528 if (!daemon_process()->OnDesktopSessionAgentAttached(id(),
144 desktop_process_, 529 desktop_process_,
145 desktop_pipe)) { 530 desktop_pipe)) {
146 CrashDesktopProcess(FROM_HERE); 531 CrashDesktopProcess(FROM_HERE);
147 } 532 }
148 } 533 }
149 534
150 void DesktopSessionWin::OnInjectSas() {
151 DCHECK(main_task_runner_->BelongsToCurrentThread());
152
153 // Do not try to inject SAS if the desktop process is not running. This can
154 // happen when the session has detached from the console for instance.
155 if (!launcher_)
156 return;
157
158 if (!sas_injector_)
159 sas_injector_ = SasInjector::Create();
160 if (!sas_injector_->InjectSas())
161 LOG(ERROR) << "Failed to inject Secure Attention Sequence.";
162 }
163
164 void DesktopSessionWin::CrashDesktopProcess( 535 void DesktopSessionWin::CrashDesktopProcess(
165 const tracked_objects::Location& location) { 536 const tracked_objects::Location& location) {
166 DCHECK(main_task_runner_->BelongsToCurrentThread()); 537 DCHECK(caller_task_runner_->BelongsToCurrentThread());
167 538
168 launcher_->Crash(location); 539 launcher_->Crash(location);
169 } 540 }
170 541
171 } // namespace remoting 542 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/desktop_session_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698