diff -r 000000000000 -r 6474c204b198 security/sandbox/chromium/base/win/scoped_process_information.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/security/sandbox/chromium/base/win/scoped_process_information.cc Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,110 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/win/scoped_process_information.h" + +#include "base/logging.h" +#include "base/win/scoped_handle.h" + +namespace base { +namespace win { + +namespace { + +// Duplicates source into target, returning true upon success. |target| is +// guaranteed to be untouched in case of failure. Succeeds with no side-effects +// if source is NULL. +bool CheckAndDuplicateHandle(HANDLE source, HANDLE* 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 = temp; + return true; +} + +} // namespace + +ScopedProcessInformation::ScopedProcessInformation() + : process_id_(0), thread_id_(0) { +} + +ScopedProcessInformation::~ScopedProcessInformation() { + Close(); +} + +ScopedProcessInformation::Receiver ScopedProcessInformation::Receive() { + DCHECK(!IsValid()) << "process_information_ must be NULL"; + return Receiver(this); +} + +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_.Receive()) && + CheckAndDuplicateHandle(other.thread_handle(), + thread_handle_.Receive())) { + 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(); +} + +} // namespace win +} // namespace base