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

Side by Side Diff: base/process/launch_win.cc

Issue 98603007: Launches a privileged utility process. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Actually works now. Removes unnecessary logging. Created 7 years 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
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 "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 <windows.h> 9 #include <windows.h>
10 #include <userenv.h> 10 #include <userenv.h>
11 #include <psapi.h> 11 #include <psapi.h>
12 #include <Shellapi.h>
12 13
13 #include <ios> 14 #include <ios>
14 15
15 #include "base/bind.h" 16 #include "base/bind.h"
16 #include "base/bind_helpers.h" 17 #include "base/bind_helpers.h"
17 #include "base/command_line.h" 18 #include "base/command_line.h"
18 #include "base/debug/stack_trace.h" 19 #include "base/debug/stack_trace.h"
19 #include "base/logging.h" 20 #include "base/logging.h"
20 #include "base/memory/scoped_ptr.h" 21 #include "base/memory/scoped_ptr.h"
21 #include "base/message_loop/message_loop.h" 22 #include "base/message_loop/message_loop.h"
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 if (freopen("CONOUT$", "w", stderr)) { 96 if (freopen("CONOUT$", "w", stderr)) {
96 setvbuf(stderr, NULL, _IOLBF, kOutputBufferSize); 97 setvbuf(stderr, NULL, _IOLBF, kOutputBufferSize);
97 _dup2(_fileno(stderr), 2); 98 _dup2(_fileno(stderr), 2);
98 } 99 }
99 100
100 // Fix all cout, wcout, cin, wcin, cerr, wcerr, clog and wclog. 101 // Fix all cout, wcout, cin, wcin, cerr, wcerr, clog and wclog.
101 std::ios::sync_with_stdio(); 102 std::ios::sync_with_stdio();
102 } 103 }
103 104
104 bool LaunchProcess(const string16& cmdline, 105 bool LaunchProcess(const string16& cmdline,
106 const string16& file,
107 const string16& arguments,
105 const LaunchOptions& options, 108 const LaunchOptions& options,
106 ProcessHandle* process_handle) { 109 ProcessHandle* process_handle) {
107 STARTUPINFO startup_info = {}; 110 STARTUPINFO startup_info = {};
108 startup_info.cb = sizeof(startup_info); 111 startup_info.cb = sizeof(startup_info);
109 if (options.empty_desktop_name) 112 if (options.empty_desktop_name)
110 startup_info.lpDesktop = L""; 113 startup_info.lpDesktop = L"";
111 startup_info.dwFlags = STARTF_USESHOWWINDOW; 114 startup_info.dwFlags = STARTF_USESHOWWINDOW;
112 startup_info.wShowWindow = options.start_hidden ? SW_HIDE : SW_SHOW; 115 startup_info.wShowWindow = options.start_hidden ? SW_HIDE : SW_SHOW;
113 116
114 if (options.stdin_handle || options.stdout_handle || options.stderr_handle) { 117 if (options.stdin_handle || options.stdout_handle || options.stderr_handle) {
(...skipping 16 matching lines...) Expand all
131 // automatically associated with a job object created by the debugger. 134 // automatically associated with a job object created by the debugger.
132 // The CREATE_BREAKAWAY_FROM_JOB flag is used to prevent this. 135 // The CREATE_BREAKAWAY_FROM_JOB flag is used to prevent this.
133 flags |= CREATE_BREAKAWAY_FROM_JOB; 136 flags |= CREATE_BREAKAWAY_FROM_JOB;
134 } 137 }
135 138
136 if (options.force_breakaway_from_job_) 139 if (options.force_breakaway_from_job_)
137 flags |= CREATE_BREAKAWAY_FROM_JOB; 140 flags |= CREATE_BREAKAWAY_FROM_JOB;
138 141
139 base::win::ScopedProcessInformation process_info; 142 base::win::ScopedProcessInformation process_info;
140 143
141 if (options.as_user) { 144 if (options.run_elevated) {
142 flags |= CREATE_UNICODE_ENVIRONMENT; 145 SHELLEXECUTEINFO shex_info = {0};
143 void* enviroment_block = NULL; 146 shex_info.cbSize = sizeof(shex_info);
147 shex_info.fMask = SEE_MASK_NOCLOSEPROCESS;
148 shex_info.hwnd = NULL;
mef 2013/12/10 15:25:18 We may have to set hwnd to something meaningful, o
149 shex_info.lpVerb = L"runas";
150 shex_info.lpFile = file.c_str();
151 shex_info.lpParameters = arguments.c_str();
152 shex_info.lpDirectory = NULL;
153 shex_info.nShow = SW_HIDE;
154 shex_info.hInstApp = NULL;
144 155
145 if (!CreateEnvironmentBlock(&enviroment_block, options.as_user, FALSE)) { 156 if (!ShellExecuteEx(&shex_info)) {
146 DPLOG(ERROR); 157 DPLOG(ERROR);
147 return false; 158 return false;
148 } 159 }
149 160
150 BOOL launched = 161 HANDLE p_handle = shex_info.hProcess;
151 CreateProcessAsUser(options.as_user, NULL, 162
152 const_cast<wchar_t*>(cmdline.c_str()), 163 if (options.wait)
153 NULL, NULL, options.inherit_handles, flags, 164 WaitForSingleObject(shex_info.hProcess, INFINITE);
154 enviroment_block, NULL, &startup_info, 165
155 process_info.Receive()); 166 // If the caller wants the process handle, we won't close it.
156 DestroyEnvironmentBlock(enviroment_block); 167 if (process_handle)
157 if (!launched) { 168 *process_handle = p_handle;
158 DPLOG(ERROR); 169
159 return false;
160 }
161 } else { 170 } else {
162 if (!CreateProcess(NULL, 171 if (options.as_user) {
163 const_cast<wchar_t*>(cmdline.c_str()), NULL, NULL, 172 flags |= CREATE_UNICODE_ENVIRONMENT;
164 options.inherit_handles, flags, NULL, NULL, 173 void* enviroment_block = NULL;
165 &startup_info, process_info.Receive())) {
166 DPLOG(ERROR);
167 return false;
168 }
169 }
170 174
171 if (options.job_handle) { 175 if (!CreateEnvironmentBlock(&enviroment_block, options.as_user, FALSE)) {
172 if (0 == AssignProcessToJobObject(options.job_handle, 176 DPLOG(ERROR);
173 process_info.process_handle())) { 177 return false;
174 DLOG(ERROR) << "Could not AssignProcessToObject."; 178 }
175 KillProcess(process_info.process_handle(), kProcessKilledExitCode, true); 179
176 return false; 180 BOOL launched =
181 CreateProcessAsUser(options.as_user, NULL,
182 const_cast<wchar_t*>(cmdline.c_str()),
183 NULL, NULL, options.inherit_handles, flags,
184 enviroment_block, NULL, &startup_info,
185 process_info.Receive());
186 DestroyEnvironmentBlock(enviroment_block);
187 if (!launched) {
188 DPLOG(ERROR);
189 return false;
190 }
191 } else {
192 if (!CreateProcess(NULL,
193 const_cast<wchar_t*>(cmdline.c_str()), NULL, NULL,
194 options.inherit_handles, flags, NULL, NULL,
195 &startup_info, process_info.Receive())) {
196 DPLOG(ERROR);
197 return false;
198 }
177 } 199 }
178 200
179 ResumeThread(process_info.thread_handle()); 201 if (options.job_handle) {
202 if (0 == AssignProcessToJobObject(options.job_handle,
203 process_info.process_handle())) {
204 DLOG(ERROR) << "Could not AssignProcessToObject.";
205 KillProcess(process_info.process_handle(),
206 kProcessKilledExitCode,
207 true);
208 return false;
209 }
210
211 ResumeThread(process_info.thread_handle());
212 }
213
214 if (options.wait)
215 WaitForSingleObject(process_info.process_handle(), INFINITE);
216
217 // If the caller wants the process handle, we won't close it.
218 if (process_handle)
219 *process_handle = process_info.TakeProcessHandle();
180 } 220 }
181 221
182 if (options.wait)
183 WaitForSingleObject(process_info.process_handle(), INFINITE);
184
185 // If the caller wants the process handle, we won't close it.
186 if (process_handle)
187 *process_handle = process_info.TakeProcessHandle();
188
189 return true; 222 return true;
190 } 223 }
191 224
192 bool LaunchProcess(const CommandLine& cmdline, 225 bool LaunchProcess(const CommandLine& cmdline,
193 const LaunchOptions& options, 226 const LaunchOptions& options,
194 ProcessHandle* process_handle) { 227 ProcessHandle* process_handle) {
195 return LaunchProcess(cmdline.GetCommandLineString(), options, process_handle); 228 return LaunchProcess(cmdline.GetCommandLineString(),
229 cmdline.GetProgram().value(),
230 cmdline.GetArgumentsString(),
231 options, process_handle);
196 } 232 }
197 233
198 bool SetJobObjectLimitFlags(HANDLE job_object, DWORD limit_flags) { 234 bool SetJobObjectLimitFlags(HANDLE job_object, DWORD limit_flags) {
199 JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info = {0}; 235 JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info = {0};
200 limit_info.BasicLimitInformation.LimitFlags = limit_flags; 236 limit_info.BasicLimitInformation.LimitFlags = limit_flags;
201 return 0 != SetInformationJobObject( 237 return 0 != SetInformationJobObject(
202 job_object, 238 job_object,
203 JobObjectExtendedLimitInformation, 239 JobObjectExtendedLimitInformation,
204 &limit_info, 240 &limit_info,
205 sizeof(limit_info)); 241 sizeof(limit_info));
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 WaitForSingleObject(proc_info.process_handle(), INFINITE); 309 WaitForSingleObject(proc_info.process_handle(), INFINITE);
274 310
275 return true; 311 return true;
276 } 312 }
277 313
278 void RaiseProcessToHighPriority() { 314 void RaiseProcessToHighPriority() {
279 SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); 315 SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
280 } 316 }
281 317
282 } // namespace base 318 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698