Wed, 31 Dec 2014 07:16:47 +0100
Revert simplistic fix pending revisit of Mozilla integration attempt.
michael@0 | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
michael@0 | 2 | // Use of this source code is governed by a BSD-style license that can be |
michael@0 | 3 | // found in the LICENSE file. |
michael@0 | 4 | |
michael@0 | 5 | #include "base/win/scoped_process_information.h" |
michael@0 | 6 | |
michael@0 | 7 | #include "base/logging.h" |
michael@0 | 8 | #include "base/win/scoped_handle.h" |
michael@0 | 9 | |
michael@0 | 10 | namespace base { |
michael@0 | 11 | namespace win { |
michael@0 | 12 | |
michael@0 | 13 | namespace { |
michael@0 | 14 | |
michael@0 | 15 | // Duplicates source into target, returning true upon success. |target| is |
michael@0 | 16 | // guaranteed to be untouched in case of failure. Succeeds with no side-effects |
michael@0 | 17 | // if source is NULL. |
michael@0 | 18 | bool CheckAndDuplicateHandle(HANDLE source, HANDLE* target) { |
michael@0 | 19 | if (!source) |
michael@0 | 20 | return true; |
michael@0 | 21 | |
michael@0 | 22 | HANDLE temp = NULL; |
michael@0 | 23 | if (!::DuplicateHandle(::GetCurrentProcess(), source, |
michael@0 | 24 | ::GetCurrentProcess(), &temp, 0, FALSE, |
michael@0 | 25 | DUPLICATE_SAME_ACCESS)) { |
michael@0 | 26 | DPLOG(ERROR) << "Failed to duplicate a handle."; |
michael@0 | 27 | return false; |
michael@0 | 28 | } |
michael@0 | 29 | *target = temp; |
michael@0 | 30 | return true; |
michael@0 | 31 | } |
michael@0 | 32 | |
michael@0 | 33 | } // namespace |
michael@0 | 34 | |
michael@0 | 35 | ScopedProcessInformation::ScopedProcessInformation() |
michael@0 | 36 | : process_id_(0), thread_id_(0) { |
michael@0 | 37 | } |
michael@0 | 38 | |
michael@0 | 39 | ScopedProcessInformation::~ScopedProcessInformation() { |
michael@0 | 40 | Close(); |
michael@0 | 41 | } |
michael@0 | 42 | |
michael@0 | 43 | ScopedProcessInformation::Receiver ScopedProcessInformation::Receive() { |
michael@0 | 44 | DCHECK(!IsValid()) << "process_information_ must be NULL"; |
michael@0 | 45 | return Receiver(this); |
michael@0 | 46 | } |
michael@0 | 47 | |
michael@0 | 48 | bool ScopedProcessInformation::IsValid() const { |
michael@0 | 49 | return process_id_ || process_handle_.Get() || |
michael@0 | 50 | thread_id_ || thread_handle_.Get(); |
michael@0 | 51 | } |
michael@0 | 52 | |
michael@0 | 53 | void ScopedProcessInformation::Close() { |
michael@0 | 54 | process_handle_.Close(); |
michael@0 | 55 | thread_handle_.Close(); |
michael@0 | 56 | process_id_ = 0; |
michael@0 | 57 | thread_id_ = 0; |
michael@0 | 58 | } |
michael@0 | 59 | |
michael@0 | 60 | void ScopedProcessInformation::Set(const PROCESS_INFORMATION& process_info) { |
michael@0 | 61 | if (IsValid()) |
michael@0 | 62 | Close(); |
michael@0 | 63 | |
michael@0 | 64 | process_handle_.Set(process_info.hProcess); |
michael@0 | 65 | thread_handle_.Set(process_info.hThread); |
michael@0 | 66 | process_id_ = process_info.dwProcessId; |
michael@0 | 67 | thread_id_ = process_info.dwThreadId; |
michael@0 | 68 | } |
michael@0 | 69 | |
michael@0 | 70 | bool ScopedProcessInformation::DuplicateFrom( |
michael@0 | 71 | const ScopedProcessInformation& other) { |
michael@0 | 72 | DCHECK(!IsValid()) << "target ScopedProcessInformation must be NULL"; |
michael@0 | 73 | DCHECK(other.IsValid()) << "source ScopedProcessInformation must be valid"; |
michael@0 | 74 | |
michael@0 | 75 | if (CheckAndDuplicateHandle(other.process_handle(), |
michael@0 | 76 | process_handle_.Receive()) && |
michael@0 | 77 | CheckAndDuplicateHandle(other.thread_handle(), |
michael@0 | 78 | thread_handle_.Receive())) { |
michael@0 | 79 | process_id_ = other.process_id(); |
michael@0 | 80 | thread_id_ = other.thread_id(); |
michael@0 | 81 | return true; |
michael@0 | 82 | } |
michael@0 | 83 | |
michael@0 | 84 | return false; |
michael@0 | 85 | } |
michael@0 | 86 | |
michael@0 | 87 | PROCESS_INFORMATION ScopedProcessInformation::Take() { |
michael@0 | 88 | PROCESS_INFORMATION process_information = {}; |
michael@0 | 89 | process_information.hProcess = process_handle_.Take(); |
michael@0 | 90 | process_information.hThread = thread_handle_.Take(); |
michael@0 | 91 | process_information.dwProcessId = process_id(); |
michael@0 | 92 | process_information.dwThreadId = thread_id(); |
michael@0 | 93 | process_id_ = 0; |
michael@0 | 94 | thread_id_ = 0; |
michael@0 | 95 | |
michael@0 | 96 | return process_information; |
michael@0 | 97 | } |
michael@0 | 98 | |
michael@0 | 99 | HANDLE ScopedProcessInformation::TakeProcessHandle() { |
michael@0 | 100 | process_id_ = 0; |
michael@0 | 101 | return process_handle_.Take(); |
michael@0 | 102 | } |
michael@0 | 103 | |
michael@0 | 104 | HANDLE ScopedProcessInformation::TakeThreadHandle() { |
michael@0 | 105 | thread_id_ = 0; |
michael@0 | 106 | return thread_handle_.Take(); |
michael@0 | 107 | } |
michael@0 | 108 | |
michael@0 | 109 | } // namespace win |
michael@0 | 110 | } // namespace base |