Index: remoting/host/win/launch_process_with_token.cc |
diff --git a/remoting/host/win/launch_process_with_token.cc b/remoting/host/win/launch_process_with_token.cc |
index db2f40a3c56e1f4a008afd437af2b914d28babb5..60a883e670ce6c70214b7915fdb2b1418c4c0d7b 100644 |
--- a/remoting/host/win/launch_process_with_token.cc |
+++ b/remoting/host/win/launch_process_with_token.cc |
@@ -5,21 +5,32 @@ |
#include "remoting/host/win/launch_process_with_token.h" |
#include <windows.h> |
+#include <sddl.h> |
#include <winternl.h> |
+#include <limits> |
+ |
#include "base/logging.h" |
#include "base/memory/scoped_ptr.h" |
+#include "base/process_util.h" |
+#include "base/rand_util.h" |
#include "base/scoped_native_library.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 "base/win/scoped_process_information.h" |
#include "base/win/windows_version.h" |
+#include "ipc/ipc_channel_proxy.h" |
using base::win::ScopedHandle; |
namespace { |
+// Match the pipe name prefix used by Chrome IPC channels so that the client |
+// could use Chrome IPC APIs instead of connecting manually. |
+const char kChromePipeNamePrefix[] = "\\\\.\\pipe\\chrome."; |
+ |
const char kCreateProcessDefaultPipeNameFormat[] = |
"\\\\.\\Pipe\\TerminalServer\\SystemExecSrvr\\%d"; |
@@ -399,6 +410,63 @@ bool CreateRemoteSessionProcess( |
namespace remoting { |
+bool CreateIpcChannel( |
+ const std::string& channel_name, |
+ const std::string& pipe_security_descriptor, |
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, |
+ IPC::Listener* delegate, |
+ scoped_ptr<IPC::ChannelProxy>* channel_out) { |
+ // Create security descriptor for the channel. |
+ SECURITY_ATTRIBUTES security_attributes; |
+ security_attributes.nLength = sizeof(security_attributes); |
+ security_attributes.bInheritHandle = FALSE; |
+ |
+ ULONG security_descriptor_length = 0; |
+ if (!ConvertStringSecurityDescriptorToSecurityDescriptor( |
+ UTF8ToUTF16(pipe_security_descriptor).c_str(), |
+ SDDL_REVISION_1, |
+ reinterpret_cast<PSECURITY_DESCRIPTOR*>( |
+ &security_attributes.lpSecurityDescriptor), |
+ &security_descriptor_length)) { |
+ LOG_GETLASTERROR(ERROR) << |
+ "Failed to create a security descriptor for the Chromoting IPC channel"; |
+ return false; |
+ } |
+ |
+ // Convert the channel name to the pipe name. |
+ std::string pipe_name(kChromePipeNamePrefix); |
+ pipe_name.append(channel_name); |
+ |
+ // Create the server end of the pipe. This code should match the code in |
+ // IPC::Channel with exception of passing a non-default security descriptor. |
+ base::win::ScopedHandle pipe; |
+ pipe.Set(CreateNamedPipe( |
+ UTF8ToUTF16(pipe_name).c_str(), |
+ PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE, |
+ PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, |
+ 1, |
+ IPC::Channel::kReadBufferSize, |
+ IPC::Channel::kReadBufferSize, |
+ 5000, |
+ &security_attributes)); |
+ if (!pipe.IsValid()) { |
+ LOG_GETLASTERROR(ERROR) << |
+ "Failed to create the server end of the Chromoting IPC channel"; |
+ LocalFree(security_attributes.lpSecurityDescriptor); |
+ return false; |
+ } |
+ |
+ LocalFree(security_attributes.lpSecurityDescriptor); |
+ |
+ // Wrap the pipe into an IPC channel. |
+ channel_out->reset(new IPC::ChannelProxy( |
+ IPC::ChannelHandle(pipe), |
+ IPC::Channel::MODE_SERVER, |
+ delegate, |
+ io_task_runner)); |
+ return true; |
+} |
+ |
// Creates a copy of the current process token for the given |session_id| so |
// it can be used to launch a process in that session. |
bool CreateSessionToken(uint32 session_id, ScopedHandle* token_out) { |
@@ -441,9 +509,19 @@ bool CreateSessionToken(uint32 session_id, ScopedHandle* token_out) { |
return true; |
} |
+// Generates a unique IPC channel name. |
+std::string GenerateIpcChannelName(void* client) { |
+ // Generate the pipe name. This code is copied from |
+ // src/content/common/child_process_host_impl.cc |
+ return base::StringPrintf("%d.%p.%d", |
+ base::GetCurrentProcId(), client, |
+ base::RandInt(0, std::numeric_limits<int>::max())); |
+} |
+ |
bool LaunchProcessWithToken(const FilePath& binary, |
const CommandLine::StringType& command_line, |
HANDLE user_token, |
+ bool inherit_handles, |
DWORD creation_flags, |
ScopedHandle* process_out, |
ScopedHandle* thread_out) { |
@@ -463,7 +541,7 @@ bool LaunchProcessWithToken(const FilePath& binary, |
const_cast<LPWSTR>(command_line.c_str()), |
NULL, |
NULL, |
- FALSE, |
+ inherit_handles, |
creation_flags, |
NULL, |
NULL, |