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