Chromium Code Reviews| Index: base/process/launch_win.cc |
| diff --git a/base/process/launch_win.cc b/base/process/launch_win.cc |
| index da913efba749089592644c627c2dc226dbfa6182..3be4a540fd5b43612f6533a08c0333dcbde7567b 100644 |
| --- a/base/process/launch_win.cc |
| +++ b/base/process/launch_win.cc |
| @@ -9,6 +9,7 @@ |
| #include <windows.h> |
| #include <userenv.h> |
| #include <psapi.h> |
| +#include <Shellapi.h> |
| #include <ios> |
| @@ -102,6 +103,8 @@ void RouteStdioToConsole() { |
| } |
| bool LaunchProcess(const string16& cmdline, |
| + const string16& file, |
| + const string16& arguments, |
| const LaunchOptions& options, |
| ProcessHandle* process_handle) { |
| STARTUPINFO startup_info = {}; |
| @@ -138,53 +141,83 @@ bool LaunchProcess(const string16& cmdline, |
| base::win::ScopedProcessInformation process_info; |
| - if (options.as_user) { |
| - flags |= CREATE_UNICODE_ENVIRONMENT; |
| - void* enviroment_block = NULL; |
| - |
| - if (!CreateEnvironmentBlock(&enviroment_block, options.as_user, FALSE)) { |
| + if (options.run_elevated) { |
| + SHELLEXECUTEINFO shex_info = {0}; |
| + shex_info.cbSize = sizeof(shex_info); |
| + shex_info.fMask = SEE_MASK_NOCLOSEPROCESS; |
| + shex_info.hwnd = NULL; |
|
mef
2013/12/10 15:25:18
We may have to set hwnd to something meaningful, o
|
| + shex_info.lpVerb = L"runas"; |
| + shex_info.lpFile = file.c_str(); |
| + shex_info.lpParameters = arguments.c_str(); |
| + shex_info.lpDirectory = NULL; |
| + shex_info.nShow = SW_HIDE; |
| + shex_info.hInstApp = NULL; |
| + |
| + if (!ShellExecuteEx(&shex_info)) { |
| DPLOG(ERROR); |
| return false; |
| } |
| - BOOL launched = |
| - CreateProcessAsUser(options.as_user, NULL, |
| - const_cast<wchar_t*>(cmdline.c_str()), |
| - NULL, NULL, options.inherit_handles, flags, |
| - enviroment_block, NULL, &startup_info, |
| - process_info.Receive()); |
| - DestroyEnvironmentBlock(enviroment_block); |
| - if (!launched) { |
| - DPLOG(ERROR); |
| - return false; |
| - } |
| + HANDLE p_handle = shex_info.hProcess; |
| + |
| + if (options.wait) |
| + WaitForSingleObject(shex_info.hProcess, INFINITE); |
| + |
| + // If the caller wants the process handle, we won't close it. |
| + if (process_handle) |
| + *process_handle = p_handle; |
| + |
| } else { |
| - if (!CreateProcess(NULL, |
| - const_cast<wchar_t*>(cmdline.c_str()), NULL, NULL, |
| - options.inherit_handles, flags, NULL, NULL, |
| - &startup_info, process_info.Receive())) { |
| - DPLOG(ERROR); |
| - return false; |
| + if (options.as_user) { |
| + flags |= CREATE_UNICODE_ENVIRONMENT; |
| + void* enviroment_block = NULL; |
| + |
| + if (!CreateEnvironmentBlock(&enviroment_block, options.as_user, FALSE)) { |
| + DPLOG(ERROR); |
| + return false; |
| + } |
| + |
| + BOOL launched = |
| + CreateProcessAsUser(options.as_user, NULL, |
| + const_cast<wchar_t*>(cmdline.c_str()), |
| + NULL, NULL, options.inherit_handles, flags, |
| + enviroment_block, NULL, &startup_info, |
| + process_info.Receive()); |
| + DestroyEnvironmentBlock(enviroment_block); |
| + if (!launched) { |
| + DPLOG(ERROR); |
| + return false; |
| + } |
| + } else { |
| + if (!CreateProcess(NULL, |
| + const_cast<wchar_t*>(cmdline.c_str()), NULL, NULL, |
| + options.inherit_handles, flags, NULL, NULL, |
| + &startup_info, process_info.Receive())) { |
| + DPLOG(ERROR); |
| + return false; |
| + } |
| } |
| - } |
| - if (options.job_handle) { |
| - if (0 == AssignProcessToJobObject(options.job_handle, |
| - process_info.process_handle())) { |
| - DLOG(ERROR) << "Could not AssignProcessToObject."; |
| - KillProcess(process_info.process_handle(), kProcessKilledExitCode, true); |
| - return false; |
| + if (options.job_handle) { |
| + if (0 == AssignProcessToJobObject(options.job_handle, |
| + process_info.process_handle())) { |
| + DLOG(ERROR) << "Could not AssignProcessToObject."; |
| + KillProcess(process_info.process_handle(), |
| + kProcessKilledExitCode, |
| + true); |
| + return false; |
| + } |
| + |
| + ResumeThread(process_info.thread_handle()); |
| } |
| - ResumeThread(process_info.thread_handle()); |
| - } |
| - |
| - if (options.wait) |
| - WaitForSingleObject(process_info.process_handle(), INFINITE); |
| + if (options.wait) |
| + WaitForSingleObject(process_info.process_handle(), INFINITE); |
| - // If the caller wants the process handle, we won't close it. |
| - if (process_handle) |
| - *process_handle = process_info.TakeProcessHandle(); |
| + // If the caller wants the process handle, we won't close it. |
| + if (process_handle) |
| + *process_handle = process_info.TakeProcessHandle(); |
| + } |
| return true; |
| } |
| @@ -192,7 +225,10 @@ bool LaunchProcess(const string16& cmdline, |
| bool LaunchProcess(const CommandLine& cmdline, |
| const LaunchOptions& options, |
| ProcessHandle* process_handle) { |
| - return LaunchProcess(cmdline.GetCommandLineString(), options, process_handle); |
| + return LaunchProcess(cmdline.GetCommandLineString(), |
| + cmdline.GetProgram().value(), |
| + cmdline.GetArgumentsString(), |
| + options, process_handle); |
| } |
| bool SetJobObjectLimitFlags(HANDLE job_object, DWORD limit_flags) { |