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

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: Remove old class 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 Process::Process(ProcessHandle handle)
14 : is_current_process_(false),
15 process_(handle) {
16 CHECK_NE(handle, ::GetCurrentProcess());
17 }
18
19 Process::Process(RValue other)
20 : is_current_process_(other.object->is_current_process_),
21 process_(other.object->process_.Take()) {
22 other.object->Close();
23 }
24
25 Process& Process::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 Process Process::Current() {
36 Process process;
37 process.is_current_process_ = true;
38 return process.Pass();
39 }
40
41 // static
42 bool Process::CanBackgroundProcesses() {
43 return true;
44 }
45
46 bool Process::IsValid() const {
47 return process_.IsValid() || is_current();
48 }
49
50 ProcessHandle Process::Handle() const {
51 return is_current_process_ ? GetCurrentProcess() : process_.Get();
52 }
53
54 Process Process::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 Process();
67 }
68 return Process(out_handle);
69 }
70
71 ProcessId Process::pid() const {
72 DCHECK(IsValid());
73 return GetProcId(Handle());
74 }
75
76 bool Process::is_current() const {
77 return is_current_process_;
78 }
79
13 void Process::Close() { 80 void Process::Close() {
14 if (!process_) 81 is_current_process_ = false;
82 if (!process_.IsValid())
15 return; 83 return;
16 84
17 // Don't call CloseHandle on a pseudo-handle. 85 process_.Close();
18 if (process_ != ::GetCurrentProcess())
19 ::CloseHandle(process_);
20
21 process_ = NULL;
22 } 86 }
23 87
24 void Process::Terminate(int result_code) { 88 void Process::Terminate(int result_code) {
25 if (!process_) 89 DCHECK(IsValid());
Lei Zhang 2014/10/16 02:50:08 Can you give some reassurances that these DCHECKs
rvargas (doing something else) 2014/10/16 19:06:10 The DCHECKs are going through internal state only
26 return;
27 90
28 // Call NtTerminateProcess directly, without going through the import table, 91 // Call NtTerminateProcess directly, without going through the import table,
29 // which might have been hooked with a buggy replacement by third party 92 // which might have been hooked with a buggy replacement by third party
30 // software. http://crbug.com/81449. 93 // software. http://crbug.com/81449.
31 HMODULE module = GetModuleHandle(L"ntdll.dll"); 94 HMODULE module = GetModuleHandle(L"ntdll.dll");
32 typedef UINT (WINAPI *TerminateProcessPtr)(HANDLE handle, UINT code); 95 typedef UINT (WINAPI *TerminateProcessPtr)(HANDLE handle, UINT code);
33 TerminateProcessPtr terminate_process = reinterpret_cast<TerminateProcessPtr>( 96 TerminateProcessPtr terminate_process = reinterpret_cast<TerminateProcessPtr>(
34 GetProcAddress(module, "NtTerminateProcess")); 97 GetProcAddress(module, "NtTerminateProcess"));
35 terminate_process(process_, result_code); 98 terminate_process(Handle(), result_code);
36 } 99 }
37 100
38 bool Process::IsProcessBackgrounded() const { 101 bool Process::IsProcessBackgrounded() const {
39 if (!process_) 102 DCHECK(IsValid());
40 return false; // Failure case.
41 DWORD priority = GetPriority(); 103 DWORD priority = GetPriority();
42 if (priority == 0) 104 if (priority == 0)
43 return false; // Failure case. 105 return false; // Failure case.
44 return ((priority == BELOW_NORMAL_PRIORITY_CLASS) || 106 return ((priority == BELOW_NORMAL_PRIORITY_CLASS) ||
45 (priority == IDLE_PRIORITY_CLASS)); 107 (priority == IDLE_PRIORITY_CLASS));
46 } 108 }
47 109
48 bool Process::SetProcessBackgrounded(bool value) { 110 bool Process::SetProcessBackgrounded(bool value) {
49 if (!process_) 111 DCHECK(IsValid());
50 return false;
51 // Vista and above introduce a real background mode, which not only 112 // 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 113 // 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. 114 // by it. Unfortunately it can only be set for the calling process.
54 DWORD priority; 115 DWORD priority;
55 if ((base::win::GetVersion() >= base::win::VERSION_VISTA) && 116 if ((base::win::GetVersion() >= base::win::VERSION_VISTA) && (is_current())) {
56 (process_ == ::GetCurrentProcess())) {
57 priority = value ? PROCESS_MODE_BACKGROUND_BEGIN : 117 priority = value ? PROCESS_MODE_BACKGROUND_BEGIN :
58 PROCESS_MODE_BACKGROUND_END; 118 PROCESS_MODE_BACKGROUND_END;
59 } else { 119 } else {
60 priority = value ? BELOW_NORMAL_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS; 120 priority = value ? BELOW_NORMAL_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS;
61 } 121 }
62 122
63 return (::SetPriorityClass(process_, priority) != 0); 123 return (::SetPriorityClass(Handle(), priority) != 0);
64 }
65
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 } 124 }
86 125
87 int Process::GetPriority() const { 126 int Process::GetPriority() const {
88 DCHECK(process_); 127 DCHECK(IsValid());
89 return ::GetPriorityClass(process_); 128 return ::GetPriorityClass(Handle());
90 } 129 }
91 130
92 } // namespace base 131 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698