OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 <windows.h> | 7 #include <windows.h> |
8 #include <winternl.h> | 8 #include <winternl.h> |
9 #include <psapi.h> | 9 #include <psapi.h> |
10 | 10 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 | 153 |
154 bool LaunchApp(const CommandLine& cl, | 154 bool LaunchApp(const CommandLine& cl, |
155 bool wait, bool start_hidden, ProcessHandle* process_handle) { | 155 bool wait, bool start_hidden, ProcessHandle* process_handle) { |
156 return LaunchApp(cl.command_line_string(), wait, | 156 return LaunchApp(cl.command_line_string(), wait, |
157 start_hidden, process_handle); | 157 start_hidden, process_handle); |
158 } | 158 } |
159 | 159 |
160 // Attempts to kill the process identified by the given process | 160 // Attempts to kill the process identified by the given process |
161 // entry structure, giving it the specified exit code. | 161 // entry structure, giving it the specified exit code. |
162 // Returns true if this is successful, false otherwise. | 162 // Returns true if this is successful, false otherwise. |
163 bool KillProcess(int process_id, int exit_code, bool wait) { | 163 bool KillProcessById(DWORD process_id, int exit_code, bool wait) { |
164 HANDLE process = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE, | 164 HANDLE process = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE, |
165 FALSE, // Don't inherit handle | 165 FALSE, // Don't inherit handle |
166 process_id); | 166 process_id); |
167 if (process) | 167 if (!process) |
168 return KillProcess(process, exit_code, wait); | 168 return false; |
169 return false; | 169 |
| 170 bool ret = KillProcess(process, exit_code, wait); |
| 171 CloseHandle(process); |
| 172 return ret; |
170 } | 173 } |
171 | 174 |
172 bool KillProcess(HANDLE process, int exit_code, bool wait) { | 175 bool KillProcess(ProcessHandle process, int exit_code, bool wait) { |
173 bool result = !!TerminateProcess(process, exit_code); | 176 bool result = (TerminateProcess(process, exit_code) != FALSE); |
174 if (result && wait) { | 177 if (result && wait) { |
175 // The process may not end immediately due to pending I/O | 178 // The process may not end immediately due to pending I/O |
176 if (WAIT_OBJECT_0 != WaitForSingleObject(process, 60 * 1000)) | 179 if (WAIT_OBJECT_0 != WaitForSingleObject(process, 60 * 1000)) |
177 DLOG(ERROR) << "Error waiting for process exit: " << GetLastError(); | 180 DLOG(ERROR) << "Error waiting for process exit: " << GetLastError(); |
178 } else { | 181 } else { |
179 DLOG(ERROR) << "Unable to terminate process: " << GetLastError(); | 182 DLOG(ERROR) << "Unable to terminate process: " << GetLastError(); |
180 } | 183 } |
181 CloseHandle(process); | |
182 return result; | 184 return result; |
183 } | 185 } |
184 | 186 |
185 bool DidProcessCrash(ProcessHandle handle) { | 187 bool DidProcessCrash(ProcessHandle handle) { |
186 DWORD exitcode = 0; | 188 DWORD exitcode = 0; |
187 if (!::GetExitCodeProcess(handle, &exitcode)) { | 189 if (!::GetExitCodeProcess(handle, &exitcode)) { |
188 NOTREACHED(); | 190 NOTREACHED(); |
189 return false; | 191 return false; |
190 } | 192 } |
191 if (exitcode == STILL_ACTIVE) { | 193 if (exitcode == STILL_ACTIVE) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 return false; | 247 return false; |
246 } | 248 } |
247 DWORD temp_code; // Don't clobber out-parameters in case of failure. | 249 DWORD temp_code; // Don't clobber out-parameters in case of failure. |
248 if (!::GetExitCodeProcess(handle, &temp_code)) | 250 if (!::GetExitCodeProcess(handle, &temp_code)) |
249 return false; | 251 return false; |
250 *exit_code = temp_code; | 252 *exit_code = temp_code; |
251 return true; | 253 return true; |
252 } | 254 } |
253 | 255 |
254 NamedProcessIterator::NamedProcessIterator(const std::wstring& executable_name, | 256 NamedProcessIterator::NamedProcessIterator(const std::wstring& executable_name, |
255 const ProcessFilter* filter) : | 257 const ProcessFilter* filter) |
256 started_iteration_(false), | 258 : started_iteration_(false), |
257 executable_name_(executable_name), | 259 executable_name_(executable_name), |
258 filter_(filter) { | 260 filter_(filter) { |
259 snapshot_ = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); | 261 snapshot_ = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); |
260 } | 262 } |
261 | 263 |
262 NamedProcessIterator::~NamedProcessIterator() { | 264 NamedProcessIterator::~NamedProcessIterator() { |
263 CloseHandle(snapshot_); | 265 CloseHandle(snapshot_); |
264 } | 266 } |
265 | 267 |
266 | 268 |
267 const ProcessEntry* NamedProcessIterator::NextProcessEntry() { | 269 const ProcessEntry* NamedProcessIterator::NextProcessEntry() { |
268 bool result = false; | 270 bool result = false; |
269 do { | 271 do { |
270 result = CheckForNextProcess(); | 272 result = CheckForNextProcess(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 ++count; | 310 ++count; |
309 return count; | 311 return count; |
310 } | 312 } |
311 | 313 |
312 bool KillProcesses(const std::wstring& executable_name, int exit_code, | 314 bool KillProcesses(const std::wstring& executable_name, int exit_code, |
313 const ProcessFilter* filter) { | 315 const ProcessFilter* filter) { |
314 bool result = true; | 316 bool result = true; |
315 const ProcessEntry* entry; | 317 const ProcessEntry* entry; |
316 | 318 |
317 NamedProcessIterator iter(executable_name, filter); | 319 NamedProcessIterator iter(executable_name, filter); |
318 while (entry = iter.NextProcessEntry()) | 320 while (entry = iter.NextProcessEntry()) { |
319 result = KillProcess((*entry).th32ProcessID, exit_code, true) && result; | 321 if (!KillProcessById((*entry).th32ProcessID, exit_code, true)) |
| 322 result = false; |
| 323 } |
320 | 324 |
321 return result; | 325 return result; |
322 } | 326 } |
323 | 327 |
324 bool WaitForProcessesToExit(const std::wstring& executable_name, | 328 bool WaitForProcessesToExit(const std::wstring& executable_name, |
325 int wait_milliseconds, | 329 int wait_milliseconds, |
326 const ProcessFilter* filter) { | 330 const ProcessFilter* filter) { |
327 const ProcessEntry* entry; | 331 const ProcessEntry* entry; |
328 bool result = true; | 332 bool result = true; |
329 DWORD start_time = GetTickCount(); | 333 DWORD start_time = GetTickCount(); |
330 | 334 |
331 NamedProcessIterator iter(executable_name, filter); | 335 NamedProcessIterator iter(executable_name, filter); |
332 while (entry = iter.NextProcessEntry()) { | 336 while (entry = iter.NextProcessEntry()) { |
333 DWORD remaining_wait = | 337 DWORD remaining_wait = |
334 std::max(0, wait_milliseconds - | 338 std::max(0, wait_milliseconds - |
335 static_cast<int>(GetTickCount() - start_time)); | 339 static_cast<int>(GetTickCount() - start_time)); |
336 HANDLE process = OpenProcess(SYNCHRONIZE, | 340 HANDLE process = OpenProcess(SYNCHRONIZE, |
337 FALSE, | 341 FALSE, |
338 entry->th32ProcessID); | 342 entry->th32ProcessID); |
339 DWORD wait_result = WaitForSingleObject(process, remaining_wait); | 343 DWORD wait_result = WaitForSingleObject(process, remaining_wait); |
340 CloseHandle(process); | 344 CloseHandle(process); |
341 result = result && (wait_result == WAIT_OBJECT_0); | 345 result = result && (wait_result == WAIT_OBJECT_0); |
342 } | 346 } |
343 | 347 |
344 return result; | 348 return result; |
345 } | 349 } |
346 | 350 |
347 bool WaitForSingleProcess(ProcessHandle handle, int wait_milliseconds) { | 351 bool WaitForSingleProcess(ProcessHandle handle, int wait_milliseconds) { |
348 bool retval = WaitForSingleObject(handle, wait_milliseconds) == WAIT_OBJECT_0; | 352 bool retval = WaitForSingleObject(handle, wait_milliseconds) == WAIT_OBJECT_0; |
349 CloseHandle(handle); | |
350 return retval; | 353 return retval; |
351 } | 354 } |
352 | 355 |
353 bool CleanupProcesses(const std::wstring& executable_name, | 356 bool CleanupProcesses(const std::wstring& executable_name, |
354 int wait_milliseconds, | 357 int wait_milliseconds, |
355 int exit_code, | 358 int exit_code, |
356 const ProcessFilter* filter) { | 359 const ProcessFilter* filter) { |
357 bool exited_cleanly = WaitForProcessesToExit(executable_name, | 360 bool exited_cleanly = WaitForProcessesToExit(executable_name, |
358 wait_milliseconds, | 361 wait_milliseconds, |
359 filter); | 362 filter); |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
634 void EnableTerminationOnHeapCorruption() { | 637 void EnableTerminationOnHeapCorruption() { |
635 // Ignore the result code. Supported on XP SP3 and Vista. | 638 // Ignore the result code. Supported on XP SP3 and Vista. |
636 HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0); | 639 HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0); |
637 } | 640 } |
638 | 641 |
639 void RaiseProcessToHighPriority() { | 642 void RaiseProcessToHighPriority() { |
640 SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); | 643 SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); |
641 } | 644 } |
642 | 645 |
643 } // namespace base | 646 } // namespace base |
OLD | NEW |