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) { |