tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

scoped_process_information.cc (2953B)


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