OLD | NEW |
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 // This file implements the Windows service controlling Me2Me host processes | 5 // This file implements the Windows service controlling Me2Me host processes |
6 // running within user sessions. | 6 // running within user sessions. |
7 | 7 |
8 #include "remoting/host/win/wts_session_process_launcher.h" | 8 #include "remoting/host/win/wts_session_process_launcher.h" |
9 | 9 |
10 #include <windows.h> | 10 #include <windows.h> |
11 #include <sddl.h> | 11 #include <sddl.h> |
12 #include <limits> | 12 #include <limits> |
13 | 13 |
14 #include "base/base_switches.h" | 14 #include "base/base_switches.h" |
15 #include "base/bind.h" | 15 #include "base/bind.h" |
16 #include "base/bind_helpers.h" | 16 #include "base/bind_helpers.h" |
17 #include "base/command_line.h" | 17 #include "base/command_line.h" |
18 #include "base/logging.h" | 18 #include "base/logging.h" |
19 #include "base/message_loop_proxy.h" | 19 #include "base/single_thread_task_runner.h" |
20 #include "base/process_util.h" | 20 #include "base/process_util.h" |
21 #include "base/rand_util.h" | 21 #include "base/rand_util.h" |
22 #include "base/stringprintf.h" | 22 #include "base/stringprintf.h" |
23 #include "base/win/scoped_handle.h" | 23 #include "base/win/scoped_handle.h" |
24 #include "ipc/ipc_channel_proxy.h" | 24 #include "ipc/ipc_channel_proxy.h" |
25 #include "ipc/ipc_message.h" | 25 #include "ipc/ipc_message.h" |
26 #include "ipc/ipc_message_macros.h" | 26 #include "ipc/ipc_message_macros.h" |
27 #include "remoting/host/constants.h" | 27 #include "remoting/host/constants.h" |
28 #include "remoting/host/chromoting_messages.h" | 28 #include "remoting/host/chromoting_messages.h" |
29 #include "remoting/host/sas_injector.h" | 29 #include "remoting/host/sas_injector.h" |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 } | 205 } |
206 | 206 |
207 } // namespace | 207 } // namespace |
208 | 208 |
209 namespace remoting { | 209 namespace remoting { |
210 | 210 |
211 // Session id that does not represent any session. | 211 // Session id that does not represent any session. |
212 const uint32 kInvalidSessionId = 0xffffffff; | 212 const uint32 kInvalidSessionId = 0xffffffff; |
213 | 213 |
214 WtsSessionProcessLauncher::WtsSessionProcessLauncher( | 214 WtsSessionProcessLauncher::WtsSessionProcessLauncher( |
| 215 const base::Closure& stopped_callback, |
215 WtsConsoleMonitor* monitor, | 216 WtsConsoleMonitor* monitor, |
216 const FilePath& host_binary, | 217 const FilePath& host_binary, |
217 scoped_refptr<base::MessageLoopProxy> main_message_loop, | 218 scoped_refptr<base::SingleThreadTaskRunner> main_message_loop, |
218 scoped_refptr<base::MessageLoopProxy> ipc_message_loop) | 219 scoped_refptr<base::SingleThreadTaskRunner> ipc_message_loop) |
219 : host_binary_(host_binary), | 220 : Stoppable(main_message_loop, stopped_callback), |
| 221 host_binary_(host_binary), |
220 main_message_loop_(main_message_loop), | 222 main_message_loop_(main_message_loop), |
221 ipc_message_loop_(ipc_message_loop), | 223 ipc_message_loop_(ipc_message_loop), |
222 monitor_(monitor), | 224 monitor_(monitor), |
223 state_(StateDetached) { | 225 state_(StateDetached) { |
224 monitor_->AddWtsConsoleObserver(this); | 226 monitor_->AddWtsConsoleObserver(this); |
225 } | 227 } |
226 | 228 |
227 WtsSessionProcessLauncher::~WtsSessionProcessLauncher() { | 229 WtsSessionProcessLauncher::~WtsSessionProcessLauncher() { |
| 230 monitor_->RemoveWtsConsoleObserver(this); |
| 231 if (state_ != StateDetached) { |
| 232 OnSessionDetached(); |
| 233 } |
| 234 |
228 DCHECK(state_ == StateDetached); | 235 DCHECK(state_ == StateDetached); |
229 DCHECK(!timer_.IsRunning()); | 236 DCHECK(!timer_.IsRunning()); |
230 DCHECK(process_.handle() == NULL); | 237 DCHECK(process_.handle() == NULL); |
231 DCHECK(process_watcher_.GetWatchedObject() == NULL); | 238 DCHECK(process_watcher_.GetWatchedObject() == NULL); |
232 DCHECK(chromoting_channel_.get() == NULL); | 239 DCHECK(chromoting_channel_.get() == NULL); |
233 if (monitor_ != NULL) { | |
234 monitor_->RemoveWtsConsoleObserver(this); | |
235 } | |
236 } | 240 } |
237 | 241 |
238 void WtsSessionProcessLauncher::LaunchProcess() { | 242 void WtsSessionProcessLauncher::LaunchProcess() { |
239 DCHECK(main_message_loop_->BelongsToCurrentThread()); | 243 DCHECK(main_message_loop_->BelongsToCurrentThread()); |
240 DCHECK(state_ == StateStarting); | 244 DCHECK(state_ == StateStarting); |
241 DCHECK(!timer_.IsRunning()); | 245 DCHECK(!timer_.IsRunning()); |
242 DCHECK(process_.handle() == NULL); | 246 DCHECK(process_.handle() == NULL); |
243 DCHECK(process_watcher_.GetWatchedObject() == NULL); | 247 DCHECK(process_watcher_.GetWatchedObject() == NULL); |
244 DCHECK(chromoting_channel_.get() == NULL); | 248 DCHECK(chromoting_channel_.get() == NULL); |
245 | 249 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 kMinPermanentErrorExitCode <= exit_code && | 325 kMinPermanentErrorExitCode <= exit_code && |
322 exit_code <= kMaxPermanentErrorExitCode; | 326 exit_code <= kMaxPermanentErrorExitCode; |
323 | 327 |
324 // The host process has been terminated for some reason. The handle can now be | 328 // The host process has been terminated for some reason. The handle can now be |
325 // closed. | 329 // closed. |
326 process_.Close(); | 330 process_.Close(); |
327 chromoting_channel_.reset(); | 331 chromoting_channel_.reset(); |
328 state_ = StateStarting; | 332 state_ = StateStarting; |
329 | 333 |
330 if (stop_trying) { | 334 if (stop_trying) { |
331 OnSessionDetached(); | 335 Stop(); |
332 | |
333 // N.B. The service will stop once the last observer is removed from | |
334 // the list. | |
335 monitor_->RemoveWtsConsoleObserver(this); | |
336 monitor_ = NULL; | |
337 return; | 336 return; |
338 } | 337 } |
339 | 338 |
340 // Expand the backoff interval if the process has died quickly or reset it if | 339 // Expand the backoff interval if the process has died quickly or reset it if |
341 // it was up longer than the maximum backoff delay. | 340 // it was up longer than the maximum backoff delay. |
342 base::TimeDelta delta = base::Time::Now() - launch_time_; | 341 base::TimeDelta delta = base::Time::Now() - launch_time_; |
343 if (delta < base::TimeDelta() || | 342 if (delta < base::TimeDelta() || |
344 delta >= base::TimeDelta::FromSeconds(kMaxLaunchDelaySeconds)) { | 343 delta >= base::TimeDelta::FromSeconds(kMaxLaunchDelaySeconds)) { |
345 launch_backoff_ = base::TimeDelta(); | 344 launch_backoff_ = base::TimeDelta(); |
346 } else { | 345 } else { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 } | 378 } |
380 | 379 |
381 if (sas_injector_.get() != NULL) { | 380 if (sas_injector_.get() != NULL) { |
382 sas_injector_->InjectSas(); | 381 sas_injector_->InjectSas(); |
383 } | 382 } |
384 } | 383 } |
385 } | 384 } |
386 | 385 |
387 void WtsSessionProcessLauncher::OnSessionAttached(uint32 session_id) { | 386 void WtsSessionProcessLauncher::OnSessionAttached(uint32 session_id) { |
388 DCHECK(main_message_loop_->BelongsToCurrentThread()); | 387 DCHECK(main_message_loop_->BelongsToCurrentThread()); |
| 388 |
| 389 if (stoppable_state() != Stoppable::kRunning) { |
| 390 return; |
| 391 } |
| 392 |
389 DCHECK(state_ == StateDetached); | 393 DCHECK(state_ == StateDetached); |
390 DCHECK(!timer_.IsRunning()); | 394 DCHECK(!timer_.IsRunning()); |
391 DCHECK(process_.handle() == NULL); | 395 DCHECK(process_.handle() == NULL); |
392 DCHECK(process_watcher_.GetWatchedObject() == NULL); | 396 DCHECK(process_watcher_.GetWatchedObject() == NULL); |
393 DCHECK(chromoting_channel_.get() == NULL); | 397 DCHECK(chromoting_channel_.get() == NULL); |
394 | 398 |
395 // Temporarily enable the SE_TCB_NAME privilege. The privileged token is | 399 // Temporarily enable the SE_TCB_NAME privilege. The privileged token is |
396 // created as needed and kept for later reuse. | 400 // created as needed and kept for later reuse. |
397 if (privileged_token_.Get() == NULL) { | 401 if (privileged_token_.Get() == NULL) { |
398 if (!CreatePrivilegedToken(&privileged_token_)) { | 402 if (!CreatePrivilegedToken(&privileged_token_)) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 process_.Terminate(0); | 460 process_.Terminate(0); |
457 process_.Close(); | 461 process_.Close(); |
458 chromoting_channel_.reset(); | 462 chromoting_channel_.reset(); |
459 state_ = StateDetached; | 463 state_ = StateDetached; |
460 break; | 464 break; |
461 } | 465 } |
462 | 466 |
463 session_token_.Close(); | 467 session_token_.Close(); |
464 } | 468 } |
465 | 469 |
| 470 void WtsSessionProcessLauncher::DoStop() { |
| 471 if (state_ != StateDetached) { |
| 472 OnSessionDetached(); |
| 473 } |
| 474 |
| 475 CompleteStopping(); |
| 476 } |
| 477 |
466 } // namespace remoting | 478 } // namespace remoting |
OLD | NEW |