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

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

Issue 651253002: Enforce handle ownership in base::Process (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 months 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/process.h" 5 #include "base/process/process.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/win/windows_version.h" 9 #include "base/win/windows_version.h"
10 10
11 namespace base { 11 namespace base {
12 12
13 ProcessObject::ProcessObject(ProcessHandle handle)
14 : is_current_process_(false),
15 process_(handle) {
16 CHECK_NE(handle, ::GetCurrentProcess());
scottmg 2014/10/14 18:51:03 why does the current process need to be handled sp
rvargas (doing something else) 2014/10/14 19:56:54 It doesn't _have_to_, but once we have a dedicated
17 }
18
19 ProcessObject::ProcessObject(RValue other)
20 : is_current_process_(other.object->is_current_process_),
21 process_(other.object->process_.Take()) {
22 other.object->Close();
23 }
24
25 ProcessObject& ProcessObject::operator=(RValue other) {
26 if (this != other.object) {
27 process_.Set(other.object->process_.Take());
28 is_current_process_ = other.object->is_current_process_;
29 other.object->Close();
30 }
31 return *this;
32 }
33
34 // static
35 ProcessObject ProcessObject::Current() {
36 ProcessObject process;
37 process.is_current_process_ = true;
38 return process.Pass();
39 }
40
41 // static
42 bool ProcessObject::CanBackgroundProcesses() {
43 return true;
44 }
45
46 bool ProcessObject::IsValid() const {
47 return process_.IsValid() || is_current();
48 }
49
50 ProcessHandle ProcessObject::Handle() const {
51 return is_current_process_ ? GetCurrentProcess() : process_.Get();
52 }
53
54 ProcessObject ProcessObject::Duplicate() const {
55 if (is_current())
56 return Current();
57
58 ProcessHandle out_handle;
59 if (!IsValid() || !::DuplicateHandle(GetCurrentProcess(),
60 Handle(),
61 GetCurrentProcess(),
62 &out_handle,
63 0,
64 FALSE,
65 DUPLICATE_SAME_ACCESS)) {
66 return ProcessObject();
67 }
68 return ProcessObject(out_handle);
69 }
70
71 ProcessId ProcessObject::pid() const {
72 DCHECK(IsValid());
73 return GetProcId(Handle());
74 }
75
76 bool ProcessObject::is_current() const {
77 return is_current_process_;
78 }
79
80 void ProcessObject::Close() {
81 is_current_process_ = false;
82 if (!process_.IsValid())
83 return;
84
85 process_.Close();
86 }
87
88 void ProcessObject::Terminate(int result_code) {
89 DCHECK(IsValid());
90
91 // Call NtTerminateProcess directly, without going through the import table,
92 // which might have been hooked with a buggy replacement by third party
93 // software. http://crbug.com/81449.
94 HMODULE module = GetModuleHandle(L"ntdll.dll");
95 typedef UINT (WINAPI *TerminateProcessPtr)(HANDLE handle, UINT code);
96 TerminateProcessPtr terminate_process = reinterpret_cast<TerminateProcessPtr>(
97 GetProcAddress(module, "NtTerminateProcess"));
98 terminate_process(Handle(), result_code);
99 }
100
101 bool ProcessObject::IsProcessBackgrounded() const {
102 DCHECK(IsValid());
103 DWORD priority = GetPriority();
104 if (priority == 0)
105 return false; // Failure case.
106 return ((priority == BELOW_NORMAL_PRIORITY_CLASS) ||
107 (priority == IDLE_PRIORITY_CLASS));
108 }
109
110 bool ProcessObject::SetProcessBackgrounded(bool value) {
111 DCHECK(IsValid());
112 // Vista and above introduce a real background mode, which not only
113 // sets the priority class on the threads but also on the IO generated
114 // by it. Unfortunately it can only be set for the calling process.
115 DWORD priority;
116 if ((base::win::GetVersion() >= base::win::VERSION_VISTA) && (is_current())) {
117 priority = value ? PROCESS_MODE_BACKGROUND_BEGIN :
118 PROCESS_MODE_BACKGROUND_END;
119 } else {
120 priority = value ? BELOW_NORMAL_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS;
121 }
122
123 return (::SetPriorityClass(Handle(), priority) != 0);
124 }
125
126 int ProcessObject::GetPriority() const {
127 DCHECK(IsValid());
128 return ::GetPriorityClass(Handle());
129 }
130
131 // -----------------------------------------------------------------------------
132 // TODO(rvargas) crbug.com/417532: Remove Process::*
133
134 // static
135 Process Process::Current() {
136 return Process(::GetCurrentProcess());
137 }
138
139 // static
140 bool Process::CanBackgroundProcesses() {
141 return true;
142 }
143
144 ProcessId Process::pid() const {
145 if (process_ == 0)
146 return 0;
147
148 return GetProcId(process_);
149 }
150
151 bool Process::is_current() const {
152 return process_ == GetCurrentProcess();
153 }
154
13 void Process::Close() { 155 void Process::Close() {
14 if (!process_) 156 if (!process_)
15 return; 157 return;
16 158
17 // Don't call CloseHandle on a pseudo-handle. 159 // Don't call CloseHandle on a pseudo-handle.
18 if (process_ != ::GetCurrentProcess()) 160 if (process_ != ::GetCurrentProcess())
19 ::CloseHandle(process_); 161 ::CloseHandle(process_);
20 162
21 process_ = NULL; 163 process_ = NULL;
22 } 164 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 (process_ == ::GetCurrentProcess())) { 198 (process_ == ::GetCurrentProcess())) {
57 priority = value ? PROCESS_MODE_BACKGROUND_BEGIN : 199 priority = value ? PROCESS_MODE_BACKGROUND_BEGIN :
58 PROCESS_MODE_BACKGROUND_END; 200 PROCESS_MODE_BACKGROUND_END;
59 } else { 201 } else {
60 priority = value ? BELOW_NORMAL_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS; 202 priority = value ? BELOW_NORMAL_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS;
61 } 203 }
62 204
63 return (::SetPriorityClass(process_, priority) != 0); 205 return (::SetPriorityClass(process_, priority) != 0);
64 } 206 }
65 207
66 ProcessId Process::pid() const {
67 if (process_ == 0)
68 return 0;
69
70 return GetProcId(process_);
71 }
72
73 bool Process::is_current() const {
74 return process_ == GetCurrentProcess();
75 }
76
77 // static
78 Process Process::Current() {
79 return Process(::GetCurrentProcess());
80 }
81
82 // static
83 bool Process::CanBackgroundProcesses() {
84 return true;
85 }
86
87 int Process::GetPriority() const { 208 int Process::GetPriority() const {
88 DCHECK(process_); 209 DCHECK(process_);
89 return ::GetPriorityClass(process_); 210 return ::GetPriorityClass(process_);
90 } 211 }
91 212
92 } // namespace base 213 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698