This source file includes following definitions.
- CheckAndDuplicateHandle
 
- thread_id_
 
- thread_id_
 
- IsValid
 
- Close
 
- Set
 
- DuplicateFrom
 
- Take
 
- TakeProcessHandle
 
- TakeThreadHandle
 
#include "base/win/scoped_process_information.h"
#include "base/logging.h"
#include "base/win/scoped_handle.h"
namespace base {
namespace win {
namespace {
bool CheckAndDuplicateHandle(HANDLE source, ScopedHandle* target) {
  if (!source)
    return true;
  HANDLE temp = NULL;
  if (!::DuplicateHandle(::GetCurrentProcess(), source,
                         ::GetCurrentProcess(), &temp, 0, FALSE,
                         DUPLICATE_SAME_ACCESS)) {
    DPLOG(ERROR) << "Failed to duplicate a handle.";
    return false;
  }
  target->Set(temp);
  return true;
}
}  
ScopedProcessInformation::ScopedProcessInformation()
    : process_id_(0), thread_id_(0) {
}
ScopedProcessInformation::ScopedProcessInformation(
    const PROCESS_INFORMATION& process_info) : process_id_(0), thread_id_(0) {
  Set(process_info);
}
ScopedProcessInformation::~ScopedProcessInformation() {
  Close();
}
bool ScopedProcessInformation::IsValid() const {
  return process_id_ || process_handle_.Get() ||
         thread_id_ || thread_handle_.Get();
}
void ScopedProcessInformation::Close() {
  process_handle_.Close();
  thread_handle_.Close();
  process_id_ = 0;
  thread_id_ = 0;
}
void ScopedProcessInformation::Set(const PROCESS_INFORMATION& process_info) {
  if (IsValid())
    Close();
  process_handle_.Set(process_info.hProcess);
  thread_handle_.Set(process_info.hThread);
  process_id_ = process_info.dwProcessId;
  thread_id_ = process_info.dwThreadId;
}
bool ScopedProcessInformation::DuplicateFrom(
    const ScopedProcessInformation& other) {
  DCHECK(!IsValid()) << "target ScopedProcessInformation must be NULL";
  DCHECK(other.IsValid()) << "source ScopedProcessInformation must be valid";
  if (CheckAndDuplicateHandle(other.process_handle(), &process_handle_) &&
      CheckAndDuplicateHandle(other.thread_handle(), &thread_handle_)) {
    process_id_ = other.process_id();
    thread_id_ = other.thread_id();
    return true;
  }
  return false;
}
PROCESS_INFORMATION ScopedProcessInformation::Take() {
  PROCESS_INFORMATION process_information = {};
  process_information.hProcess = process_handle_.Take();
  process_information.hThread = thread_handle_.Take();
  process_information.dwProcessId = process_id();
  process_information.dwThreadId = thread_id();
  process_id_ = 0;
  thread_id_ = 0;
  return process_information;
}
HANDLE ScopedProcessInformation::TakeProcessHandle() {
  process_id_ = 0;
  return process_handle_.Take();
}
HANDLE ScopedProcessInformation::TakeThreadHandle() {
  thread_id_ = 0;
  return thread_handle_.Take();
}
}  
}