OLD | NEW |
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 "base/process/launch.h" | 5 #include "base/process/launch.h" |
6 | 6 |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <io.h> | 8 #include <io.h> |
9 #include <shellapi.h> | 9 #include <shellapi.h> |
10 #include <windows.h> | 10 #include <windows.h> |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 } | 98 } |
99 if (freopen("CONOUT$", "w", stderr)) { | 99 if (freopen("CONOUT$", "w", stderr)) { |
100 setvbuf(stderr, NULL, _IOLBF, kOutputBufferSize); | 100 setvbuf(stderr, NULL, _IOLBF, kOutputBufferSize); |
101 _dup2(_fileno(stderr), 2); | 101 _dup2(_fileno(stderr), 2); |
102 } | 102 } |
103 | 103 |
104 // Fix all cout, wcout, cin, wcin, cerr, wcerr, clog and wclog. | 104 // Fix all cout, wcout, cin, wcin, cerr, wcerr, clog and wclog. |
105 std::ios::sync_with_stdio(); | 105 std::ios::sync_with_stdio(); |
106 } | 106 } |
107 | 107 |
108 bool LaunchProcess(const string16& cmdline, | 108 Process LaunchProcess(const CommandLine& cmdline, |
109 const LaunchOptions& options, | 109 const LaunchOptions& options) { |
110 win::ScopedHandle* process_handle) { | 110 return LaunchProcess(cmdline.GetCommandLineString(), options); |
| 111 } |
| 112 |
| 113 Process LaunchProcess(const string16& cmdline, |
| 114 const LaunchOptions& options) { |
111 win::StartupInformation startup_info_wrapper; | 115 win::StartupInformation startup_info_wrapper; |
112 STARTUPINFO* startup_info = startup_info_wrapper.startup_info(); | 116 STARTUPINFO* startup_info = startup_info_wrapper.startup_info(); |
113 | 117 |
114 bool inherit_handles = options.inherit_handles; | 118 bool inherit_handles = options.inherit_handles; |
115 DWORD flags = 0; | 119 DWORD flags = 0; |
116 if (options.handles_to_inherit) { | 120 if (options.handles_to_inherit) { |
117 if (options.handles_to_inherit->empty()) { | 121 if (options.handles_to_inherit->empty()) { |
118 inherit_handles = false; | 122 inherit_handles = false; |
119 } else { | 123 } else { |
120 if (base::win::GetVersion() < base::win::VERSION_VISTA) { | 124 if (base::win::GetVersion() < base::win::VERSION_VISTA) { |
121 DLOG(ERROR) << "Specifying handles to inherit requires Vista or later."; | 125 DLOG(ERROR) << "Specifying handles to inherit requires Vista or later."; |
122 return false; | 126 return Process(); |
123 } | 127 } |
124 | 128 |
125 if (options.handles_to_inherit->size() > | 129 if (options.handles_to_inherit->size() > |
126 std::numeric_limits<DWORD>::max() / sizeof(HANDLE)) { | 130 std::numeric_limits<DWORD>::max() / sizeof(HANDLE)) { |
127 DLOG(ERROR) << "Too many handles to inherit."; | 131 DLOG(ERROR) << "Too many handles to inherit."; |
128 return false; | 132 return Process(); |
129 } | 133 } |
130 | 134 |
131 if (!startup_info_wrapper.InitializeProcThreadAttributeList(1)) { | 135 if (!startup_info_wrapper.InitializeProcThreadAttributeList(1)) { |
132 DPLOG(ERROR); | 136 DPLOG(ERROR); |
133 return false; | 137 return Process(); |
134 } | 138 } |
135 | 139 |
136 if (!startup_info_wrapper.UpdateProcThreadAttribute( | 140 if (!startup_info_wrapper.UpdateProcThreadAttribute( |
137 PROC_THREAD_ATTRIBUTE_HANDLE_LIST, | 141 PROC_THREAD_ATTRIBUTE_HANDLE_LIST, |
138 const_cast<HANDLE*>(&options.handles_to_inherit->at(0)), | 142 const_cast<HANDLE*>(&options.handles_to_inherit->at(0)), |
139 static_cast<DWORD>(options.handles_to_inherit->size() * | 143 static_cast<DWORD>(options.handles_to_inherit->size() * |
140 sizeof(HANDLE)))) { | 144 sizeof(HANDLE)))) { |
141 DPLOG(ERROR); | 145 DPLOG(ERROR); |
142 return false; | 146 return Process(); |
143 } | 147 } |
144 | 148 |
145 inherit_handles = true; | 149 inherit_handles = true; |
146 flags |= EXTENDED_STARTUPINFO_PRESENT; | 150 flags |= EXTENDED_STARTUPINFO_PRESENT; |
147 } | 151 } |
148 } | 152 } |
149 | 153 |
150 if (options.empty_desktop_name) | 154 if (options.empty_desktop_name) |
151 startup_info->lpDesktop = const_cast<wchar_t*>(L""); | 155 startup_info->lpDesktop = const_cast<wchar_t*>(L""); |
152 startup_info->dwFlags = STARTF_USESHOWWINDOW; | 156 startup_info->dwFlags = STARTF_USESHOWWINDOW; |
(...skipping 24 matching lines...) Expand all Loading... |
177 | 181 |
178 PROCESS_INFORMATION temp_process_info = {}; | 182 PROCESS_INFORMATION temp_process_info = {}; |
179 | 183 |
180 string16 writable_cmdline(cmdline); | 184 string16 writable_cmdline(cmdline); |
181 if (options.as_user) { | 185 if (options.as_user) { |
182 flags |= CREATE_UNICODE_ENVIRONMENT; | 186 flags |= CREATE_UNICODE_ENVIRONMENT; |
183 void* enviroment_block = NULL; | 187 void* enviroment_block = NULL; |
184 | 188 |
185 if (!CreateEnvironmentBlock(&enviroment_block, options.as_user, FALSE)) { | 189 if (!CreateEnvironmentBlock(&enviroment_block, options.as_user, FALSE)) { |
186 DPLOG(ERROR); | 190 DPLOG(ERROR); |
187 return false; | 191 return Process(); |
188 } | 192 } |
189 | 193 |
190 BOOL launched = | 194 BOOL launched = |
191 CreateProcessAsUser(options.as_user, NULL, | 195 CreateProcessAsUser(options.as_user, NULL, |
192 &writable_cmdline[0], | 196 &writable_cmdline[0], |
193 NULL, NULL, inherit_handles, flags, | 197 NULL, NULL, inherit_handles, flags, |
194 enviroment_block, NULL, startup_info, | 198 enviroment_block, NULL, startup_info, |
195 &temp_process_info); | 199 &temp_process_info); |
196 DestroyEnvironmentBlock(enviroment_block); | 200 DestroyEnvironmentBlock(enviroment_block); |
197 if (!launched) { | 201 if (!launched) { |
198 DPLOG(ERROR) << "Command line:" << std::endl << UTF16ToUTF8(cmdline) | 202 DPLOG(ERROR) << "Command line:" << std::endl << UTF16ToUTF8(cmdline) |
199 << std::endl;; | 203 << std::endl;; |
200 return false; | 204 return Process(); |
201 } | 205 } |
202 } else { | 206 } else { |
203 if (!CreateProcess(NULL, | 207 if (!CreateProcess(NULL, |
204 &writable_cmdline[0], NULL, NULL, | 208 &writable_cmdline[0], NULL, NULL, |
205 inherit_handles, flags, NULL, NULL, | 209 inherit_handles, flags, NULL, NULL, |
206 startup_info, &temp_process_info)) { | 210 startup_info, &temp_process_info)) { |
207 DPLOG(ERROR) << "Command line:" << std::endl << UTF16ToUTF8(cmdline) | 211 DPLOG(ERROR) << "Command line:" << std::endl << UTF16ToUTF8(cmdline) |
208 << std::endl;; | 212 << std::endl;; |
209 return false; | 213 return Process(); |
210 } | 214 } |
211 } | 215 } |
212 base::win::ScopedProcessInformation process_info(temp_process_info); | 216 base::win::ScopedProcessInformation process_info(temp_process_info); |
213 | 217 |
214 if (options.job_handle) { | 218 if (options.job_handle) { |
215 if (0 == AssignProcessToJobObject(options.job_handle, | 219 if (0 == AssignProcessToJobObject(options.job_handle, |
216 process_info.process_handle())) { | 220 process_info.process_handle())) { |
217 DLOG(ERROR) << "Could not AssignProcessToObject."; | 221 DLOG(ERROR) << "Could not AssignProcessToObject."; |
218 KillProcess(process_info.process_handle(), kProcessKilledExitCode, true); | 222 KillProcess(process_info.process_handle(), kProcessKilledExitCode, true); |
219 return false; | 223 return Process(); |
220 } | 224 } |
221 | 225 |
222 ResumeThread(process_info.thread_handle()); | 226 ResumeThread(process_info.thread_handle()); |
223 } | 227 } |
224 | 228 |
225 if (options.wait) | 229 if (options.wait) |
226 WaitForSingleObject(process_info.process_handle(), INFINITE); | 230 WaitForSingleObject(process_info.process_handle(), INFINITE); |
227 | 231 |
228 // If the caller wants the process handle, we won't close it. | 232 return Process(process_info.TakeProcessHandle()); |
229 if (process_handle) | |
230 process_handle->Set(process_info.TakeProcessHandle()); | |
231 | |
232 return true; | |
233 } | |
234 | |
235 // TODO(rvargas) crbug.com/416721: Remove this stub after LaunchProcess is | |
236 // fully migrated to use Process. | |
237 Process LaunchProcess(const string16& cmdline, | |
238 const LaunchOptions& options) { | |
239 win::ScopedHandle process_handle; | |
240 if (LaunchProcess(cmdline, options, &process_handle)) | |
241 return Process(process_handle.Take()); | |
242 | |
243 return Process(); | |
244 } | |
245 | |
246 bool LaunchProcess(const CommandLine& cmdline, | |
247 const LaunchOptions& options, | |
248 ProcessHandle* process_handle) { | |
249 if (!process_handle) | |
250 return LaunchProcess(cmdline.GetCommandLineString(), options, NULL); | |
251 | |
252 win::ScopedHandle process; | |
253 bool rv = LaunchProcess(cmdline.GetCommandLineString(), options, &process); | |
254 *process_handle = process.Take(); | |
255 return rv; | |
256 } | |
257 | |
258 Process LaunchProcess(const CommandLine& cmdline, | |
259 const LaunchOptions& options) { | |
260 ProcessHandle process_handle; | |
261 if (LaunchProcess(cmdline, options, &process_handle)) | |
262 return Process(process_handle); | |
263 | |
264 return Process(); | |
265 } | 233 } |
266 | 234 |
267 Process LaunchElevatedProcess(const CommandLine& cmdline, | 235 Process LaunchElevatedProcess(const CommandLine& cmdline, |
268 const LaunchOptions& options) { | 236 const LaunchOptions& options) { |
269 const string16 file = cmdline.GetProgram().value(); | 237 const string16 file = cmdline.GetProgram().value(); |
270 const string16 arguments = cmdline.GetArgumentsString(); | 238 const string16 arguments = cmdline.GetArgumentsString(); |
271 | 239 |
272 SHELLEXECUTEINFO shex_info = {0}; | 240 SHELLEXECUTEINFO shex_info = {0}; |
273 shex_info.cbSize = sizeof(shex_info); | 241 shex_info.cbSize = sizeof(shex_info); |
274 shex_info.fMask = SEE_MASK_NOCLOSEPROCESS; | 242 shex_info.fMask = SEE_MASK_NOCLOSEPROCESS; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 WaitForSingleObject(proc_info.process_handle(), INFINITE); | 343 WaitForSingleObject(proc_info.process_handle(), INFINITE); |
376 | 344 |
377 return true; | 345 return true; |
378 } | 346 } |
379 | 347 |
380 void RaiseProcessToHighPriority() { | 348 void RaiseProcessToHighPriority() { |
381 SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); | 349 SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); |
382 } | 350 } |
383 | 351 |
384 } // namespace base | 352 } // namespace base |
OLD | NEW |