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

Unified Diff: remoting/host/win/unprivileged_process_delegate.cc

Issue 15077010: [Chromoting] Refactored worker process launching code and speeded up the desktop process launch. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 7 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
Index: remoting/host/win/unprivileged_process_delegate.cc
diff --git a/remoting/host/win/unprivileged_process_delegate.cc b/remoting/host/win/unprivileged_process_delegate.cc
index ef597d1e4a28332045ef86b89c293545d9300a0b..251a06dd9c589b32cb75cfde58f59d029a14072e 100644
--- a/remoting/host/win/unprivileged_process_delegate.cc
+++ b/remoting/host/win/unprivileged_process_delegate.cc
@@ -25,7 +25,6 @@
#include "ipc/ipc_channel_proxy.h"
#include "ipc/ipc_message.h"
#include "remoting/base/typed_buffer.h"
-#include "remoting/host/host_exit_codes.h"
#include "remoting/host/ipc_constants.h"
#include "remoting/host/win/launch_process_with_token.h"
#include "remoting/host/win/security_descriptor.h"
@@ -214,69 +213,25 @@ bool CreateWindowStationAndDesktop(ScopedSid logon_sid,
} // namespace
UnprivilegedProcessDelegate::UnprivilegedProcessDelegate(
- scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
scoped_ptr<CommandLine> target_command)
- : main_task_runner_(main_task_runner),
- io_task_runner_(io_task_runner),
+ : io_task_runner_(io_task_runner),
+ event_handler_(NULL),
target_command_(target_command.Pass()) {
}
UnprivilegedProcessDelegate::~UnprivilegedProcessDelegate() {
- KillProcess(CONTROL_C_EXIT);
+ DCHECK(CalledOnValidThread());
+ DCHECK(!channel_);
+ DCHECK(!worker_process_.IsValid());
}
-bool UnprivilegedProcessDelegate::Send(IPC::Message* message) {
- DCHECK(main_task_runner_->BelongsToCurrentThread());
+void UnprivilegedProcessDelegate::LaunchProcess(
+ WorkerProcessLauncher* event_handler) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(!event_handler_);
- return channel_->Send(message);
-}
-
-void UnprivilegedProcessDelegate::CloseChannel() {
- DCHECK(main_task_runner_->BelongsToCurrentThread());
-
- channel_.reset();
-}
-
-DWORD UnprivilegedProcessDelegate::GetProcessId() const {
- if (worker_process_.IsValid()) {
- return ::GetProcessId(worker_process_);
- } else {
- return 0;
- }
-}
-
-bool UnprivilegedProcessDelegate::IsPermanentError(int failure_count) const {
- // Get exit code of the worker process if it is available.
- DWORD exit_code = CONTROL_C_EXIT;
- if (worker_process_.IsValid()) {
- if (!::GetExitCodeProcess(worker_process_, &exit_code)) {
- LOG_GETLASTERROR(INFO)
- << "Failed to query the exit code of the worker process";
- exit_code = CONTROL_C_EXIT;
- }
- }
-
- // Stop trying to restart the worker process if it exited due to
- // misconfiguration.
- return (kMinPermanentErrorExitCode <= exit_code &&
- exit_code <= kMaxPermanentErrorExitCode);
-}
-
-void UnprivilegedProcessDelegate::KillProcess(DWORD exit_code) {
- DCHECK(main_task_runner_->BelongsToCurrentThread());
-
- channel_.reset();
-
- if (worker_process_.IsValid()) {
- TerminateProcess(worker_process_, exit_code);
- }
-}
-
-bool UnprivilegedProcessDelegate::LaunchProcess(
- IPC::Listener* delegate,
- ScopedHandle* process_exit_event_out) {
- DCHECK(main_task_runner_->BelongsToCurrentThread());
+ event_handler_ = event_handler;
scoped_ptr<IPC::ChannelProxy> server;
@@ -288,7 +243,8 @@ bool UnprivilegedProcessDelegate::LaunchProcess(
if (!CreateRestrictedToken(&token)) {
LOG_GETLASTERROR(ERROR)
<< "Failed to create a restricted LocalService token";
- return false;
+ ReportFatalError();
+ return;
}
// Determine our logon SID, so we can grant it access to our window station
@@ -296,7 +252,8 @@ bool UnprivilegedProcessDelegate::LaunchProcess(
ScopedSid logon_sid = GetLogonSid(token);
if (!logon_sid) {
LOG_GETLASTERROR(ERROR) << "Failed to retrieve the logon SID";
- return false;
+ ReportFatalError();
+ return;
}
// Create the process and thread security descriptors.
@@ -304,7 +261,8 @@ bool UnprivilegedProcessDelegate::LaunchProcess(
ScopedSd thread_sd = ConvertSddlToSd(kWorkerThreadSd);
if (!process_sd || !thread_sd) {
LOG_GETLASTERROR(ERROR) << "Failed to create a security descriptor";
- return false;
+ ReportFatalError();
+ return;
}
SECURITY_ATTRIBUTES process_attributes;
@@ -317,6 +275,7 @@ bool UnprivilegedProcessDelegate::LaunchProcess(
thread_attributes.lpSecurityDescriptor = thread_sd.get();
thread_attributes.bInheritHandle = FALSE;
+ ScopedHandle worker_process;
{
// Take a lock why any inheritable handles are open to make sure that only
// one process inherits them.
@@ -325,8 +284,9 @@ bool UnprivilegedProcessDelegate::LaunchProcess(
// Create a connected IPC channel.
ScopedHandle client;
if (!CreateConnectedIpcChannel(channel_name, kDaemonIpcSd, io_task_runner_,
- delegate, &client, &server)) {
- return false;
+ this, &client, &server)) {
+ ReportFatalError();
+ return;
}
// Convert the handle value into a decimal integer. Handle values are 32bit
@@ -343,13 +303,13 @@ bool UnprivilegedProcessDelegate::LaunchProcess(
if (!CreateWindowStationAndDesktop(logon_sid.Pass(), &handles)) {
LOG_GETLASTERROR(ERROR)
<< "Failed to create a window station and desktop";
- return false;
+ ReportFatalError();
+ return;
}
// Try to launch the worker process. The launched process inherits
// the window station, desktop and pipe handles, created above.
ScopedHandle worker_thread;
- worker_process_.Close();
if (!LaunchProcessWithToken(command_line.GetProgram(),
command_line.GetCommandLineString(),
token,
@@ -358,30 +318,107 @@ bool UnprivilegedProcessDelegate::LaunchProcess(
true,
0,
NULL,
- &worker_process_,
+ &worker_process,
&worker_thread)) {
- return false;
+ ReportFatalError();
+ return;
}
}
- // Return a handle that the caller can wait on to get notified when
- // the process terminates.
- ScopedHandle process_exit_event;
+ channel_ = server.Pass();
+ ReportProcessLaunched(worker_process.Pass());
+}
+
+void UnprivilegedProcessDelegate::Send(IPC::Message* message) {
+ DCHECK(CalledOnValidThread());
+
+ if (channel_) {
+ channel_->Send(message);
+ } else {
+ delete message;
+ }
+}
+
+void UnprivilegedProcessDelegate::CloseChannel() {
+ DCHECK(CalledOnValidThread());
+
+ channel_.reset();
+}
+
+void UnprivilegedProcessDelegate::KillProcess() {
+ DCHECK(CalledOnValidThread());
+
+ channel_.reset();
+
+ if (worker_process_.IsValid()) {
+ TerminateProcess(worker_process_, CONTROL_C_EXIT);
+ worker_process_.Close();
+ }
+}
+
+bool UnprivilegedProcessDelegate::OnMessageReceived(
+ const IPC::Message& message) {
+ DCHECK(CalledOnValidThread());
+
+ return event_handler_->OnMessageReceived(message);
+}
+
+void UnprivilegedProcessDelegate::OnChannelConnected(int32 peer_pid) {
+ DCHECK(CalledOnValidThread());
+
+ DWORD pid = GetProcessId(worker_process_);
+ if (pid != static_cast<DWORD>(peer_pid)) {
+ LOG(ERROR) << "The actual client PID " << pid
+ << " does not match the one reported by the client: "
+ << peer_pid;
+ ReportFatalError();
+ return;
+ }
+
+ event_handler_->OnChannelConnected(peer_pid);
+}
+
+void UnprivilegedProcessDelegate::OnChannelError() {
+ DCHECK(CalledOnValidThread());
+
+ event_handler_->OnChannelError();
+}
+
+void UnprivilegedProcessDelegate::ReportFatalError() {
+ DCHECK(CalledOnValidThread());
+
+ channel_.reset();
+
+ WorkerProcessLauncher* event_handler = event_handler_;
+ event_handler_ = NULL;
+ event_handler->OnFatalError();
+}
+
+void UnprivilegedProcessDelegate::ReportProcessLaunched(
+ base::win::ScopedHandle worker_process) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(!worker_process_.IsValid());
+
+ worker_process_ = worker_process.Pass();
+
+ // Report a handle that can be used to wait for the worker process completion,
+ // query information about the process and duplicate handles.
+ DWORD desired_access =
+ SYNCHRONIZE | PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION;
+ ScopedHandle limited_handle;
if (!DuplicateHandle(GetCurrentProcess(),
worker_process_,
GetCurrentProcess(),
- process_exit_event.Receive(),
- SYNCHRONIZE,
+ limited_handle.Receive(),
+ desired_access,
FALSE,
0)) {
LOG_GETLASTERROR(ERROR) << "Failed to duplicate a handle";
- KillProcess(CONTROL_C_EXIT);
- return false;
+ ReportFatalError();
+ return;
}
- channel_ = server.Pass();
- *process_exit_event_out = process_exit_event.Pass();
- return true;
+ event_handler_->OnProcessLaunched(limited_handle.Pass());
}
} // namespace remoting

Powered by Google App Engine
This is Rietveld 408576698