OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_util.h" | 5 #include "base/process_util.h" |
6 | 6 |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <io.h> | 8 #include <io.h> |
9 #include <windows.h> | 9 #include <windows.h> |
10 #include <userenv.h> | 10 #include <userenv.h> |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
230 const LaunchOptions& options, | 230 const LaunchOptions& options, |
231 ProcessHandle* process_handle) { | 231 ProcessHandle* process_handle) { |
232 STARTUPINFO startup_info = {}; | 232 STARTUPINFO startup_info = {}; |
233 startup_info.cb = sizeof(startup_info); | 233 startup_info.cb = sizeof(startup_info); |
234 if (options.empty_desktop_name) | 234 if (options.empty_desktop_name) |
235 startup_info.lpDesktop = L""; | 235 startup_info.lpDesktop = L""; |
236 startup_info.dwFlags = STARTF_USESHOWWINDOW; | 236 startup_info.dwFlags = STARTF_USESHOWWINDOW; |
237 startup_info.wShowWindow = options.start_hidden ? SW_HIDE : SW_SHOW; | 237 startup_info.wShowWindow = options.start_hidden ? SW_HIDE : SW_SHOW; |
238 PROCESS_INFORMATION process_info; | 238 PROCESS_INFORMATION process_info; |
239 | 239 |
240 DWORD flags = 0; | |
241 | |
242 win::ScopedHandle job_handle; | |
243 if (options.job_handle) { | |
244 job_handle.Set(CreateJobObject(NULL, NULL)); | |
cpu_(ooo_6.6-7.5)
2011/09/07 20:07:22
so why do we create a job object if there is one a
Paweł Hajdan Jr.
2011/09/07 20:16:22
I create a job object because what's passed in the
| |
245 if (!job_handle.IsValid()) { | |
246 LOG(ERROR) << "Could not create JobObject."; | |
247 return false; | |
248 } | |
249 | |
250 JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info = {0}; | |
251 limit_info.BasicLimitInformation.LimitFlags = | |
252 JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; | |
253 if (0 == SetInformationJobObject(job_handle.Get(), | |
254 JobObjectExtendedLimitInformation, &limit_info, sizeof(limit_info))) { | |
255 LOG(ERROR) << "Could not SetInformationJobObject."; | |
256 return false; | |
257 } | |
258 | |
259 flags |= CREATE_SUSPENDED; | |
260 | |
261 // If this code is run under a debugger, the launched process is | |
262 // automatically associated with a job object created by the debugger. | |
263 // The CREATE_BREAKAWAY_FROM_JOB flag is used to prevent this. | |
264 flags |= CREATE_BREAKAWAY_FROM_JOB; | |
265 } | |
266 | |
240 if (options.as_user) { | 267 if (options.as_user) { |
241 DWORD flags = CREATE_UNICODE_ENVIRONMENT; | 268 flags |= CREATE_UNICODE_ENVIRONMENT; |
242 void* enviroment_block = NULL; | 269 void* enviroment_block = NULL; |
243 | 270 |
244 if (!CreateEnvironmentBlock(&enviroment_block, options.as_user, FALSE)) | 271 if (!CreateEnvironmentBlock(&enviroment_block, options.as_user, FALSE)) |
245 return false; | 272 return false; |
246 | 273 |
247 BOOL launched = | 274 BOOL launched = |
248 CreateProcessAsUser(options.as_user, NULL, | 275 CreateProcessAsUser(options.as_user, NULL, |
249 const_cast<wchar_t*>(cmdline.c_str()), | 276 const_cast<wchar_t*>(cmdline.c_str()), |
250 NULL, NULL, options.inherit_handles, flags, | 277 NULL, NULL, options.inherit_handles, flags, |
251 enviroment_block, NULL, &startup_info, | 278 enviroment_block, NULL, &startup_info, |
252 &process_info); | 279 &process_info); |
253 DestroyEnvironmentBlock(enviroment_block); | 280 DestroyEnvironmentBlock(enviroment_block); |
254 if (!launched) | 281 if (!launched) |
255 return false; | 282 return false; |
256 } else { | 283 } else { |
257 if (!CreateProcess(NULL, | 284 if (!CreateProcess(NULL, |
258 const_cast<wchar_t*>(cmdline.c_str()), NULL, NULL, | 285 const_cast<wchar_t*>(cmdline.c_str()), NULL, NULL, |
259 options.inherit_handles, 0, NULL, NULL, | 286 options.inherit_handles, flags, NULL, NULL, |
260 &startup_info, &process_info)) { | 287 &startup_info, &process_info)) { |
261 return false; | 288 return false; |
262 } | 289 } |
263 } | 290 } |
264 | 291 |
292 if (options.job_handle) { | |
293 if (0 == AssignProcessToJobObject(job_handle.Get(), | |
294 process_info.hProcess)) { | |
295 LOG(ERROR) << "Could not AssignProcessToObject."; | |
296 KillProcess(process_info.hProcess, 1, true); | |
297 return false; | |
298 } | |
299 | |
300 options.job_handle->Set(job_handle.Take()); | |
301 | |
302 ResumeThread(process_info.hThread); | |
303 } | |
304 | |
265 // Handles must be closed or they will leak. | 305 // Handles must be closed or they will leak. |
266 CloseHandle(process_info.hThread); | 306 CloseHandle(process_info.hThread); |
267 | 307 |
268 if (options.wait) | 308 if (options.wait) |
269 WaitForSingleObject(process_info.hProcess, INFINITE); | 309 WaitForSingleObject(process_info.hProcess, INFINITE); |
270 | 310 |
271 // If the caller wants the process handle, we won't close it. | 311 // If the caller wants the process handle, we won't close it. |
272 if (process_handle) { | 312 if (process_handle) { |
273 *process_handle = process_info.hProcess; | 313 *process_handle = process_info.hProcess; |
274 } else { | 314 } else { |
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
880 | 920 |
881 PERFORMANCE_INFORMATION info; | 921 PERFORMANCE_INFORMATION info; |
882 if (!InternalGetPerformanceInfo(&info, sizeof(info))) { | 922 if (!InternalGetPerformanceInfo(&info, sizeof(info))) { |
883 LOG(ERROR) << "Failed to fetch internal performance info."; | 923 LOG(ERROR) << "Failed to fetch internal performance info."; |
884 return 0; | 924 return 0; |
885 } | 925 } |
886 return (info.CommitTotal * system_info.dwPageSize) / 1024; | 926 return (info.CommitTotal * system_info.dwPageSize) / 1024; |
887 } | 927 } |
888 | 928 |
889 } // namespace base | 929 } // namespace base |
OLD | NEW |