Index: chrome/browser/extensions/api/messaging/native_process_launcher_win.cc |
diff --git a/chrome/browser/extensions/api/messaging/native_process_launcher_win.cc b/chrome/browser/extensions/api/messaging/native_process_launcher_win.cc |
index 7d1fe69a283923f37908ef7cf7f1899e88c8c50b..cb787893bbe579210d3a845cc30ca109f002e5fa 100644 |
--- a/chrome/browser/extensions/api/messaging/native_process_launcher_win.cc |
+++ b/chrome/browser/extensions/api/messaging/native_process_launcher_win.cc |
@@ -6,10 +6,18 @@ |
#include <windows.h> |
+#include "base/command_line.h" |
#include "base/logging.h" |
#include "base/process_util.h" |
#include "base/stringprintf.h" |
#include "base/string_number_conversions.h" |
+#include "base/utf_string_conversions.h" |
+ |
+namespace { |
+ |
+int pipe_counter = 0; |
+ |
+} // namespace |
namespace extensions { |
@@ -18,8 +26,90 @@ bool NativeProcessLauncher::LaunchNativeProcess( |
base::ProcessHandle* native_process_handle, |
NativeMessageProcessHost::FileHandle* read_file, |
NativeMessageProcessHost::FileHandle* write_file) const { |
- NOTREACHED(); |
- return false; |
+ SECURITY_ATTRIBUTES sa_attr; |
+ // Set the bInheritHandle flag so pipe handles are inherited. |
+ sa_attr.nLength = sizeof(SECURITY_ATTRIBUTES); |
+ sa_attr.bInheritHandle = TRUE; |
+ sa_attr.lpSecurityDescriptor = NULL; |
+ |
+ DWORD pipe_open_mode = PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED; |
+ DWORD pipe_mode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE; |
+ DWORD max_instances = 1; |
+ DWORD buffer_size = NativeMessageProcessHost::kMaxMessageDataLength; |
+ DWORD timeout = NativeMessageProcessHost::kExitTimeoutMS; |
+ |
+ string16 out_pipe_name = ASCIIToWide(base::StringPrintf( |
+ "\\\\.\\pipe\\chrome.nativeMessage.out.%d", ++pipe_counter)); |
+ string16 in_pipe_name = ASCIIToWide(base::StringPrintf( |
+ "\\\\.\\pipe\\chrome.nativeMessage.in.%d", ++pipe_counter)); |
+ |
+ HANDLE stdin_parent_pipe = NULL; |
+ HANDLE stdout_parent_pipe = NULL; |
+ |
+ HANDLE stdin_child_pipe = NULL; |
+ HANDLE stdout_child_pipe = NULL; |
+ |
+ // Create the pipes to read and write from. |
+ stdout_parent_pipe = CreateNamedPipeW(out_pipe_name.c_str(), pipe_open_mode, |
+ pipe_mode, max_instances, buffer_size, |
+ buffer_size, timeout, &sa_attr); |
+ if (stdout_parent_pipe == INVALID_HANDLE_VALUE) { |
+ DPLOG(ERROR) << "Failed to create pipe"; |
+ return false; |
+ } |
+ |
+ DWORD desired_access = GENERIC_READ | GENERIC_WRITE; |
+ DWORD share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE; |
+ |
+ stdout_child_pipe = CreateFileW(out_pipe_name.c_str(), desired_access, |
+ share_mode, &sa_attr, OPEN_EXISTING, |
+ FILE_FLAG_OVERLAPPED, NULL); |
+ if (stdout_child_pipe == INVALID_HANDLE_VALUE) { |
+ DPLOG(ERROR) << "Failed to create pipe"; |
+ return false; |
+ } |
+ |
+ stdin_parent_pipe = CreateNamedPipeW(in_pipe_name.c_str(), pipe_open_mode, |
+ pipe_mode, max_instances, buffer_size, |
+ buffer_size, timeout, &sa_attr); |
+ if (stdin_parent_pipe == INVALID_HANDLE_VALUE) { |
+ DPLOG(ERROR) << "Failed to create pipe"; |
+ return false; |
+ } |
+ |
+ stdin_child_pipe = CreateFileW(in_pipe_name.c_str(), desired_access, |
+ share_mode, &sa_attr, OPEN_EXISTING, |
+ FILE_FLAG_OVERLAPPED, NULL); |
+ if (stdin_child_pipe == INVALID_HANDLE_VALUE) { |
+ DPLOG(ERROR) << "Failed to create pipe"; |
+ return false; |
+ } |
+ |
+ // Don't inherit the parents' |
+ if (!SetHandleInformation(stdin_parent_pipe, HANDLE_FLAG_INHERIT, 0) || |
+ !SetHandleInformation(stdout_parent_pipe, HANDLE_FLAG_INHERIT, 0)) { |
+ DPLOG(ERROR) << "Failed to enable pipe inheritance"; |
+ return false; |
+ } |
+ |
+ CommandLine line(path); |
+ base::LaunchOptions options; |
+ // Need to inherit the file handles. |
+ options.inherit_handles = true; |
+ options.stdin_handle = stdin_child_pipe; |
+ options.stdout_handle = stdout_child_pipe; |
+ options.start_hidden = true; |
+ |
+ if (!base::LaunchProcess(line.GetCommandLineString(), options, |
+ native_process_handle)) { |
+ LOG(ERROR) << "Error launching process"; |
+ return false; |
+ } |
+ |
+ *read_file = stdout_parent_pipe; |
+ *write_file = stdin_parent_pipe; |
+ |
+ return true; |
} |
} // namespace extensions |