[email protected] | 3b63f8f4 | 2011-03-28 01:54:15 | [diff] [blame] | 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. | ||||
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 4 | |
5 | #include "base/process.h" | ||||
6 | #include "base/logging.h" | ||||
[email protected] | 3b63f8f4 | 2011-03-28 01:54:15 | [diff] [blame] | 7 | #include "base/memory/scoped_ptr.h" |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 8 | #include "base/process_util.h" |
[email protected] | 568bfb0 | 2011-04-28 23:51:53 | [diff] [blame] | 9 | #include "base/win/windows_version.h" |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 10 | |
[email protected] | 176aa48 | 2008-11-14 03:25:15 | [diff] [blame] | 11 | namespace base { |
12 | |||||
13 | void Process::Close() { | ||||
14 | if (!process_) | ||||
15 | return; | ||||
[email protected] | b987e90e | 2011-08-15 19:22:44 | [diff] [blame] | 16 | |
[email protected] | c4ed802 | 2011-08-19 01:36:21 | [diff] [blame] | 17 | // Don't call CloseHandle on a pseudo-handle. |
18 | if (process_ != ::GetCurrentProcess()) | ||||
19 | ::CloseHandle(process_); | ||||
[email protected] | b987e90e | 2011-08-15 19:22:44 | [diff] [blame] | 20 | |
[email protected] | 176aa48 | 2008-11-14 03:25:15 | [diff] [blame] | 21 | process_ = NULL; |
22 | } | ||||
23 | |||||
24 | void Process::Terminate(int result_code) { | ||||
25 | if (!process_) | ||||
26 | return; | ||||
[email protected] | b987e90e | 2011-08-15 19:22:44 | [diff] [blame] | 27 | |
[email protected] | c4ed802 | 2011-08-19 01:36:21 | [diff] [blame] | 28 | // Call NtTerminateProcess directly, without going through the import table, |
29 | // which might have been hooked with a buggy replacement by third party | ||||
30 | // software. http://crbug.com/81449. | ||||
[email protected] | b987e90e | 2011-08-15 19:22:44 | [diff] [blame] | 31 | HMODULE module = GetModuleHandle(L"ntdll.dll"); |
32 | typedef UINT (WINAPI *TerminateProcessPtr)(HANDLE handle, UINT code); | ||||
33 | TerminateProcessPtr terminate_process = reinterpret_cast<TerminateProcessPtr>( | ||||
34 | GetProcAddress(module, "NtTerminateProcess")); | ||||
35 | terminate_process(process_, result_code); | ||||
[email protected] | 176aa48 | 2008-11-14 03:25:15 | [diff] [blame] | 36 | } |
37 | |||||
[email protected] | 2f15de4 | 2008-11-11 22:35:19 | [diff] [blame] | 38 | bool Process::IsProcessBackgrounded() const { |
[email protected] | b195ea8 | 2009-07-16 03:49:28 | [diff] [blame] | 39 | if (!process_) |
40 | return false; // Failure case. | ||||
[email protected] | 276aa6a | 2009-10-29 17:43:44 | [diff] [blame] | 41 | DWORD priority = GetPriority(); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 42 | if (priority == 0) |
43 | return false; // Failure case. | ||||
[email protected] | 568bfb0 | 2011-04-28 23:51:53 | [diff] [blame] | 44 | return ((priority == BELOW_NORMAL_PRIORITY_CLASS) || |
45 | (priority == IDLE_PRIORITY_CLASS)); | ||||
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 46 | } |
47 | |||||
48 | bool Process::SetProcessBackgrounded(bool value) { | ||||
[email protected] | b195ea8 | 2009-07-16 03:49:28 | [diff] [blame] | 49 | if (!process_) |
50 | return false; | ||||
[email protected] | 568bfb0 | 2011-04-28 23:51:53 | [diff] [blame] | 51 | // Vista and above introduce a real background mode, which not only |
52 | // sets the priority class on the threads but also on the IO generated | ||||
53 | // by it. Unfortunately it can only be set for the calling process. | ||||
54 | DWORD priority; | ||||
55 | if ((base::win::GetVersion() >= base::win::VERSION_VISTA) && | ||||
56 | (process_ == ::GetCurrentProcess())) { | ||||
57 | priority = value ? PROCESS_MODE_BACKGROUND_BEGIN : | ||||
58 | PROCESS_MODE_BACKGROUND_END; | ||||
59 | } else { | ||||
60 | priority = value ? BELOW_NORMAL_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS; | ||||
61 | } | ||||
62 | |||||
63 | return (::SetPriorityClass(process_, priority) != 0); | ||||
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 64 | } |
65 | |||||
[email protected] | 43cf325 | 2009-04-01 09:19:37 | [diff] [blame] | 66 | ProcessId Process::pid() const { |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 67 | if (process_ == 0) |
68 | return 0; | ||||
69 | |||||
[email protected] | 176aa48 | 2008-11-14 03:25:15 | [diff] [blame] | 70 | return GetProcId(process_); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 71 | } |
72 | |||||
73 | bool Process::is_current() const { | ||||
74 | return process_ == GetCurrentProcess(); | ||||
75 | } | ||||
76 | |||||
77 | // static | ||||
78 | Process Process::Current() { | ||||
[email protected] | 568bfb0 | 2011-04-28 23:51:53 | [diff] [blame] | 79 | return Process(::GetCurrentProcess()); |
initial.commit | d7cae12 | 2008-07-26 21:49:38 | [diff] [blame] | 80 | } |
license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 81 | |
[email protected] | 8a42080 | 2011-12-02 16:14:46 | [diff] [blame] | 82 | // static |
83 | bool Process::CanBackgroundProcesses() { | ||||
84 | return true; | ||||
85 | } | ||||
86 | |||||
[email protected] | 276aa6a | 2009-10-29 17:43:44 | [diff] [blame] | 87 | int Process::GetPriority() const { |
88 | DCHECK(process_); | ||||
[email protected] | 568bfb0 | 2011-04-28 23:51:53 | [diff] [blame] | 89 | return ::GetPriorityClass(process_); |
[email protected] | 276aa6a | 2009-10-29 17:43:44 | [diff] [blame] | 90 | } |
91 | |||||
[email protected] | 176aa48 | 2008-11-14 03:25:15 | [diff] [blame] | 92 | } // namespace base |