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

Side by Side Diff: chrome/browser/extensions/api/messaging/native_process_launcher_win.cc

Issue 12406002: Pass ID of the calling extension to the native messaging host. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 #include "chrome/browser/extensions/api/messaging/native_process_launcher.h" 5 #include "chrome/browser/extensions/api/messaging/native_process_launcher.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 " is not registered"; 57 " is not registered";
58 return scoped_ptr<NativeMessagingHostManifest>(); 58 return scoped_ptr<NativeMessagingHostManifest>();
59 } 59 }
60 60
61 return NativeMessagingHostManifest::Load( 61 return NativeMessagingHostManifest::Load(
62 base::FilePath(manifest_path), error_message); 62 base::FilePath(manifest_path), error_message);
63 } 63 }
64 64
65 // static 65 // static
66 bool NativeProcessLauncher::LaunchNativeProcess( 66 bool NativeProcessLauncher::LaunchNativeProcess(
67 const base::FilePath& path, 67 const CommandLine& command_line,
68 base::PlatformFile* read_file, 68 base::PlatformFile* read_file,
69 base::PlatformFile* write_file) { 69 base::PlatformFile* write_file) {
70 // Timeout for the IO pipes. 70 // Timeout for the IO pipes.
71 const DWORD kTimeoutMs = 5000; 71 const DWORD kTimeoutMs = 5000;
72 72
73 // Windows will use default buffer size when 0 is passed to 73 // Windows will use default buffer size when 0 is passed to
74 // CreateNamedPipeW(). 74 // CreateNamedPipeW().
75 const DWORD kBufferSize = 0; 75 const DWORD kBufferSize = 0;
76 76
77 if (!path.IsAbsolute()) { 77 if (!command_line.GetProgram().IsAbsolute()) {
78 LOG(ERROR) << "Native Messaging host path must be absolute."; 78 LOG(ERROR) << "Native Messaging host path must be absolute.";
79 return false; 79 return false;
80 } 80 }
81 81
82 uint64 pipe_name_token; 82 uint64 pipe_name_token;
83 crypto::RandBytes(&pipe_name_token, sizeof(pipe_name_token)); 83 crypto::RandBytes(&pipe_name_token, sizeof(pipe_name_token));
84 string16 out_pipe_name = base::StringPrintf( 84 string16 out_pipe_name = base::StringPrintf(
85 L"\\\\.\\pipe\\chrome.nativeMessaging.out.%llx", pipe_name_token); 85 L"\\\\.\\pipe\\chrome.nativeMessaging.out.%llx", pipe_name_token);
86 string16 in_pipe_name = base::StringPrintf( 86 string16 in_pipe_name = base::StringPrintf(
87 L"\\\\.\\pipe\\chrome.nativeMessaging.in.%llx", pipe_name_token); 87 L"\\\\.\\pipe\\chrome.nativeMessaging.in.%llx", pipe_name_token);
(...skipping 22 matching lines...) Expand all
110 } 110 }
111 111
112 DWORD comspec_length = ::GetEnvironmentVariable(L"COMSPEC", NULL, 0); 112 DWORD comspec_length = ::GetEnvironmentVariable(L"COMSPEC", NULL, 0);
113 if (comspec_length == 0) { 113 if (comspec_length == 0) {
114 LOG(ERROR) << "COMSPEC is not set"; 114 LOG(ERROR) << "COMSPEC is not set";
115 return false; 115 return false;
116 } 116 }
117 scoped_ptr<wchar_t[]> comspec(new wchar_t[comspec_length]); 117 scoped_ptr<wchar_t[]> comspec(new wchar_t[comspec_length]);
118 ::GetEnvironmentVariable(L"COMSPEC", comspec.get(), comspec_length); 118 ::GetEnvironmentVariable(L"COMSPEC", comspec.get(), comspec_length);
119 119
120 string16 command_line_string = command_line.GetCommandLineString();
121
120 // 'start' command has a moronic syntax: if first argument is quoted then it 122 // 'start' command has a moronic syntax: if first argument is quoted then it
121 // interprets it as a command title. Host path must always be in quotes, so 123 // interprets it as a command title. Host path may need to be in quotes, so
122 // we always need to specify the title as the first argument. 124 // we always need to specify the title as the first argument.
123 string16 command = base::StringPrintf( 125 string16 command = base::StringPrintf(
124 L"%ls /c start \"Chrome Native Messaging Host\" /b " 126 L"%ls /c start \"Chrome Native Messaging Host\" /b "
125 L"\"%ls\" < %ls > %ls", 127 L"%ls < %ls > %ls",
126 comspec.get(), path.value().c_str(), 128 comspec.get(), command_line_string.c_str(),
127 in_pipe_name.c_str(), out_pipe_name.c_str()); 129 in_pipe_name.c_str(), out_pipe_name.c_str());
128 130
129 base::LaunchOptions options; 131 base::LaunchOptions options;
130 options.start_hidden = true; 132 options.start_hidden = true;
131 base::ProcessHandle cmd_handle; 133 base::ProcessHandle cmd_handle;
132 if (!base::LaunchProcess(command.c_str(), options, &cmd_handle)) { 134 if (!base::LaunchProcess(command.c_str(), options, &cmd_handle)) {
133 LOG(ERROR) << "Error launching process " << path.MaybeAsASCII(); 135 LOG(ERROR) << "Error launching process "
136 << command_line.GetProgram().MaybeAsASCII();
134 return false; 137 return false;
135 } 138 }
136 139
137 bool stdout_connected = ConnectNamedPipe(stdout_pipe.Get(), NULL) ? 140 bool stdout_connected = ConnectNamedPipe(stdout_pipe.Get(), NULL) ?
138 TRUE : GetLastError() == ERROR_PIPE_CONNECTED; 141 TRUE : GetLastError() == ERROR_PIPE_CONNECTED;
139 bool stdin_connected = ConnectNamedPipe(stdin_pipe.Get(), NULL) ? 142 bool stdin_connected = ConnectNamedPipe(stdin_pipe.Get(), NULL) ?
140 TRUE : GetLastError() == ERROR_PIPE_CONNECTED; 143 TRUE : GetLastError() == ERROR_PIPE_CONNECTED;
141 if (!stdout_connected || !stdin_connected) { 144 if (!stdout_connected || !stdin_connected) {
142 base::KillProcess(cmd_handle, 0, false); 145 base::KillProcess(cmd_handle, 0, false);
143 base::CloseProcessHandle(cmd_handle); 146 base::CloseProcessHandle(cmd_handle);
144 LOG(ERROR) << "Failed to connect IO pipes when starting " 147 LOG(ERROR) << "Failed to connect IO pipes when starting "
145 << path.MaybeAsASCII(); 148 << command_line.GetProgram().MaybeAsASCII();
146 return false; 149 return false;
147 } 150 }
148 151
149 // Check that cmd.exe has completed with 0 exit code to make sure it was 152 // Check that cmd.exe has completed with 0 exit code to make sure it was
150 // able to connect IO pipes. 153 // able to connect IO pipes.
151 int error_code; 154 int error_code;
152 if (!base::WaitForExitCodeWithTimeout( 155 if (!base::WaitForExitCodeWithTimeout(
153 cmd_handle, &error_code, 156 cmd_handle, &error_code,
154 base::TimeDelta::FromMilliseconds(kTimeoutMs)) || 157 base::TimeDelta::FromMilliseconds(kTimeoutMs)) ||
155 error_code != 0) { 158 error_code != 0) {
156 LOG(ERROR) << "cmd.exe did not exit cleanly"; 159 LOG(ERROR) << "cmd.exe did not exit cleanly";
157 base::KillProcess(cmd_handle, 0, false); 160 base::KillProcess(cmd_handle, 0, false);
158 base::CloseProcessHandle(cmd_handle); 161 base::CloseProcessHandle(cmd_handle);
159 return false; 162 return false;
160 } 163 }
161 164
162 base::CloseProcessHandle(cmd_handle); 165 base::CloseProcessHandle(cmd_handle);
163 166
164 *read_file = stdout_pipe.Take(); 167 *read_file = stdout_pipe.Take();
165 *write_file = stdin_pipe.Take(); 168 *write_file = stdin_pipe.Take();
166 169
167 return true; 170 return true;
168 } 171 }
169 172
170 } // namespace extensions 173 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698