Chromium Code Reviews| 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 74d539dec0f1408d9e4df0b23bd877bebcd57ca0..b746f81e0a9b60179ca35b9e078abdd64bfd5f26 100644 |
| --- a/remoting/host/win/unprivileged_process_delegate.cc |
| +++ b/remoting/host/win/unprivileged_process_delegate.cc |
| @@ -11,16 +11,27 @@ |
| #include "base/command_line.h" |
| #include "base/logging.h" |
| #include "base/single_thread_task_runner.h" |
| +#include "base/stringprintf.h" |
| #include "base/utf_string_conversions.h" |
| #include "base/win/scoped_handle.h" |
| +#include "ipc/ipc_channel_proxy.h" |
| +#include "ipc/ipc_message.h" |
| #include "remoting/host/win/launch_process_with_token.h" |
| using base::win::ScopedHandle; |
| namespace { |
| -// The command line switch specifying the name of the daemon IPC endpoint. |
| -const char kDaemonIpcSwitchName[] = "daemon-pipe"; |
| +// Match the pipe name prefix used by Chrome IPC channels so that the client |
| +// could use Chrome IPC APIs instead of connecting manually. |
|
simonmorris
2012/10/12 16:31:13
Both of these constants appear in more than one fi
alexeypa (please no reviews)
2012/10/12 18:44:39
Done.
|
| +const char kChromePipeNamePrefix[] = "\\\\.\\pipe\\chrome."; |
| + |
| +// The command line switches specifying the daemon IPC endpoint. |
|
simonmorris
2012/10/12 16:31:13
switches -> switch?
alexeypa (please no reviews)
2012/10/12 18:44:39
Done.
|
| +const char kDaemonPipeSwitchName[] = "daemon-pipe"; |
| + |
| +// The security descriptor of the daemon IPC endpoint. It gives full access |
| +// to LocalSystem and denies access by anyone else. |
| +const char kDaemonIpcSecurityDescriptor[] = "O:SYG:SYD:(A;;GA;;;SY)"; |
| // The command line parameters that should be copied from the service's command |
| // line to the host process. |
| @@ -44,6 +55,12 @@ UnprivilegedProcessDelegate::~UnprivilegedProcessDelegate() { |
| KillProcess(CONTROL_C_EXIT); |
| } |
| +bool UnprivilegedProcessDelegate::Send(IPC::Message* message) { |
| + DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| + |
| + return channel_->Send(message); |
| +} |
| + |
| DWORD UnprivilegedProcessDelegate::GetExitCode() { |
| DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| @@ -62,21 +79,35 @@ DWORD UnprivilegedProcessDelegate::GetExitCode() { |
| 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( |
| - const std::string& channel_name, |
| + IPC::Listener* delegate, |
| ScopedHandle* process_exit_event_out) { |
| DCHECK(main_task_runner_->BelongsToCurrentThread()); |
| + // Generate a unique name of the channel. |
|
simonmorris
2012/10/12 16:31:13
of -> for
alexeypa (please no reviews)
2012/10/12 18:44:39
Done.
|
| + std::string channel_name = GenerateIpcChannelName(this); |
| + |
| + // Create a connected IPC channel. |
| + ScopedHandle client; |
| + scoped_ptr<IPC::ChannelProxy> server; |
| + if (!CreateConnectedIpcChannel(channel_name, delegate, &client, &server)) |
| + return false; |
| + |
| + // Convert the handle value into a decimal integer. Handle values are 32bit |
| + // even on 64bit platforms. |
| + std::string pipe_handle = base::StringPrintf( |
| + "%d", reinterpret_cast<ULONG_PTR>(client.Get())); |
| // Create the command line passing the name of the IPC channel to use and |
| // copying known switches from the caller's command line. |
| CommandLine command_line(binary_path_); |
| - command_line.AppendSwitchNative(kDaemonIpcSwitchName, |
| - UTF8ToWide(channel_name)); |
| + command_line.AppendSwitchASCII(kDaemonPipeSwitchName, pipe_handle); |
| command_line.CopySwitchesFrom(*CommandLine::ForCurrentProcess(), |
| kCopiedSwitchNames, |
| arraysize(kCopiedSwitchNames)); |
| @@ -89,6 +120,7 @@ bool UnprivilegedProcessDelegate::LaunchProcess( |
| if (!LaunchProcessWithToken(command_line.GetProgram(), |
| command_line.GetCommandLineString(), |
| NULL, |
| + true, |
| 0, |
| &worker_process_, |
| &worker_thread)) { |
| @@ -110,8 +142,46 @@ bool UnprivilegedProcessDelegate::LaunchProcess( |
| return false; |
| } |
| + channel_ = server.Pass(); |
| *process_exit_event_out = process_exit_event.Pass(); |
| return true; |
| } |
| +bool UnprivilegedProcessDelegate::CreateConnectedIpcChannel( |
| + std::string channel_name, |
|
simonmorris
2012/10/12 16:31:13
std::string -> const std::string& ?
alexeypa (please no reviews)
2012/10/12 18:44:39
Done.
|
| + IPC::Listener* delegate, |
| + ScopedHandle* client_out, |
| + scoped_ptr<IPC::ChannelProxy>* server_out) { |
| + // Create the server end of the channel. |
| + scoped_ptr<IPC::ChannelProxy> server; |
| + if (!CreateIpcChannel(channel_name, kDaemonIpcSecurityDescriptor, |
| + io_task_runner_, delegate, &server)) { |
| + return false; |
| + } |
| + |
| + // Convert the channel name to the pipe name. |
| + std::string pipe_name(kChromePipeNamePrefix); |
| + pipe_name.append(channel_name); |
| + |
| + // Create the client end of the channel. This code should match the code in |
| + // IPC::Channel. |
| + ScopedHandle client; |
| + SECURITY_ATTRIBUTES security_attributes = { sizeof(security_attributes), NULL, |
| + TRUE }; |
|
simonmorris
2012/10/12 16:31:13
This seems an unnecessarily opaque way to initiali
alexeypa (please no reviews)
2012/10/12 18:44:39
Done.
|
| + client.Set(CreateFile(UTF8ToUTF16(pipe_name).c_str(), |
| + GENERIC_READ | GENERIC_WRITE, |
| + 0, |
| + &security_attributes, |
| + OPEN_EXISTING, |
| + SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION | |
| + FILE_FLAG_OVERLAPPED, |
| + NULL)); |
| + if (!client.IsValid()) |
| + return false; |
| + |
| + *client_out = client.Pass(); |
| + *server_out = server.Pass(); |
| + return true; |
| +} |
| + |
| } // namespace remoting |