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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: base/process/process_win.cc
diff --git a/base/process/process_win.cc b/base/process/process_win.cc
index 1217b509896b3a015f7636c94734416d469b4641..de29d90e0b2f675c508d6ea73827cfb95186f75a 100644
--- a/base/process/process_win.cc
+++ b/base/process/process_win.cc
@@ -10,6 +10,148 @@
namespace base {
+ProcessObject::ProcessObject(ProcessHandle handle)
+ : is_current_process_(false),
+ process_(handle) {
+ 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
+}
+
+ProcessObject::ProcessObject(RValue other)
+ : is_current_process_(other.object->is_current_process_),
+ process_(other.object->process_.Take()) {
+ other.object->Close();
+}
+
+ProcessObject& ProcessObject::operator=(RValue other) {
+ if (this != other.object) {
+ process_.Set(other.object->process_.Take());
+ is_current_process_ = other.object->is_current_process_;
+ other.object->Close();
+ }
+ return *this;
+}
+
+// static
+ProcessObject ProcessObject::Current() {
+ ProcessObject process;
+ process.is_current_process_ = true;
+ return process.Pass();
+}
+
+// static
+bool ProcessObject::CanBackgroundProcesses() {
+ return true;
+}
+
+bool ProcessObject::IsValid() const {
+ return process_.IsValid() || is_current();
+}
+
+ProcessHandle ProcessObject::Handle() const {
+ return is_current_process_ ? GetCurrentProcess() : process_.Get();
+}
+
+ProcessObject ProcessObject::Duplicate() const {
+ if (is_current())
+ return Current();
+
+ ProcessHandle out_handle;
+ if (!IsValid() || !::DuplicateHandle(GetCurrentProcess(),
+ Handle(),
+ GetCurrentProcess(),
+ &out_handle,
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS)) {
+ return ProcessObject();
+ }
+ return ProcessObject(out_handle);
+}
+
+ProcessId ProcessObject::pid() const {
+ DCHECK(IsValid());
+ return GetProcId(Handle());
+}
+
+bool ProcessObject::is_current() const {
+ return is_current_process_;
+}
+
+void ProcessObject::Close() {
+ is_current_process_ = false;
+ if (!process_.IsValid())
+ return;
+
+ process_.Close();
+}
+
+void ProcessObject::Terminate(int result_code) {
+ DCHECK(IsValid());
+
+ // Call NtTerminateProcess directly, without going through the import table,
+ // which might have been hooked with a buggy replacement by third party
+ // software. http://crbug.com/81449.
+ HMODULE module = GetModuleHandle(L"ntdll.dll");
+ typedef UINT (WINAPI *TerminateProcessPtr)(HANDLE handle, UINT code);
+ TerminateProcessPtr terminate_process = reinterpret_cast<TerminateProcessPtr>(
+ GetProcAddress(module, "NtTerminateProcess"));
+ terminate_process(Handle(), result_code);
+}
+
+bool ProcessObject::IsProcessBackgrounded() const {
+ DCHECK(IsValid());
+ DWORD priority = GetPriority();
+ if (priority == 0)
+ return false; // Failure case.
+ return ((priority == BELOW_NORMAL_PRIORITY_CLASS) ||
+ (priority == IDLE_PRIORITY_CLASS));
+}
+
+bool ProcessObject::SetProcessBackgrounded(bool value) {
+ DCHECK(IsValid());
+ // Vista and above introduce a real background mode, which not only
+ // sets the priority class on the threads but also on the IO generated
+ // by it. Unfortunately it can only be set for the calling process.
+ DWORD priority;
+ if ((base::win::GetVersion() >= base::win::VERSION_VISTA) && (is_current())) {
+ priority = value ? PROCESS_MODE_BACKGROUND_BEGIN :
+ PROCESS_MODE_BACKGROUND_END;
+ } else {
+ priority = value ? BELOW_NORMAL_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS;
+ }
+
+ return (::SetPriorityClass(Handle(), priority) != 0);
+}
+
+int ProcessObject::GetPriority() const {
+ DCHECK(IsValid());
+ return ::GetPriorityClass(Handle());
+}
+
+// -----------------------------------------------------------------------------
+// TODO(rvargas) crbug.com/417532: Remove Process::*
+
+// static
+Process Process::Current() {
+ return Process(::GetCurrentProcess());
+}
+
+// static
+bool Process::CanBackgroundProcesses() {
+ return true;
+}
+
+ProcessId Process::pid() const {
+ if (process_ == 0)
+ return 0;
+
+ return GetProcId(process_);
+}
+
+bool Process::is_current() const {
+ return process_ == GetCurrentProcess();
+}
+
void Process::Close() {
if (!process_)
return;
@@ -63,27 +205,6 @@ bool Process::SetProcessBackgrounded(bool value) {
return (::SetPriorityClass(process_, priority) != 0);
}
-ProcessId Process::pid() const {
- if (process_ == 0)
- return 0;
-
- return GetProcId(process_);
-}
-
-bool Process::is_current() const {
- return process_ == GetCurrentProcess();
-}
-
-// static
-Process Process::Current() {
- return Process(::GetCurrentProcess());
-}
-
-// static
-bool Process::CanBackgroundProcesses() {
- return true;
-}
-
int Process::GetPriority() const {
DCHECK(process_);
return ::GetPriorityClass(process_);

Powered by Google App Engine
This is Rietveld 408576698