1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/chromium/base/win/scoped_process_information.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,110 @@ 1.4 +// Copyright (c) 2012 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include "base/win/scoped_process_information.h" 1.9 + 1.10 +#include "base/logging.h" 1.11 +#include "base/win/scoped_handle.h" 1.12 + 1.13 +namespace base { 1.14 +namespace win { 1.15 + 1.16 +namespace { 1.17 + 1.18 +// Duplicates source into target, returning true upon success. |target| is 1.19 +// guaranteed to be untouched in case of failure. Succeeds with no side-effects 1.20 +// if source is NULL. 1.21 +bool CheckAndDuplicateHandle(HANDLE source, HANDLE* target) { 1.22 + if (!source) 1.23 + return true; 1.24 + 1.25 + HANDLE temp = NULL; 1.26 + if (!::DuplicateHandle(::GetCurrentProcess(), source, 1.27 + ::GetCurrentProcess(), &temp, 0, FALSE, 1.28 + DUPLICATE_SAME_ACCESS)) { 1.29 + DPLOG(ERROR) << "Failed to duplicate a handle."; 1.30 + return false; 1.31 + } 1.32 + *target = temp; 1.33 + return true; 1.34 +} 1.35 + 1.36 +} // namespace 1.37 + 1.38 +ScopedProcessInformation::ScopedProcessInformation() 1.39 + : process_id_(0), thread_id_(0) { 1.40 +} 1.41 + 1.42 +ScopedProcessInformation::~ScopedProcessInformation() { 1.43 + Close(); 1.44 +} 1.45 + 1.46 +ScopedProcessInformation::Receiver ScopedProcessInformation::Receive() { 1.47 + DCHECK(!IsValid()) << "process_information_ must be NULL"; 1.48 + return Receiver(this); 1.49 +} 1.50 + 1.51 +bool ScopedProcessInformation::IsValid() const { 1.52 + return process_id_ || process_handle_.Get() || 1.53 + thread_id_ || thread_handle_.Get(); 1.54 +} 1.55 + 1.56 +void ScopedProcessInformation::Close() { 1.57 + process_handle_.Close(); 1.58 + thread_handle_.Close(); 1.59 + process_id_ = 0; 1.60 + thread_id_ = 0; 1.61 +} 1.62 + 1.63 +void ScopedProcessInformation::Set(const PROCESS_INFORMATION& process_info) { 1.64 + if (IsValid()) 1.65 + Close(); 1.66 + 1.67 + process_handle_.Set(process_info.hProcess); 1.68 + thread_handle_.Set(process_info.hThread); 1.69 + process_id_ = process_info.dwProcessId; 1.70 + thread_id_ = process_info.dwThreadId; 1.71 +} 1.72 + 1.73 +bool ScopedProcessInformation::DuplicateFrom( 1.74 + const ScopedProcessInformation& other) { 1.75 + DCHECK(!IsValid()) << "target ScopedProcessInformation must be NULL"; 1.76 + DCHECK(other.IsValid()) << "source ScopedProcessInformation must be valid"; 1.77 + 1.78 + if (CheckAndDuplicateHandle(other.process_handle(), 1.79 + process_handle_.Receive()) && 1.80 + CheckAndDuplicateHandle(other.thread_handle(), 1.81 + thread_handle_.Receive())) { 1.82 + process_id_ = other.process_id(); 1.83 + thread_id_ = other.thread_id(); 1.84 + return true; 1.85 + } 1.86 + 1.87 + return false; 1.88 +} 1.89 + 1.90 +PROCESS_INFORMATION ScopedProcessInformation::Take() { 1.91 + PROCESS_INFORMATION process_information = {}; 1.92 + process_information.hProcess = process_handle_.Take(); 1.93 + process_information.hThread = thread_handle_.Take(); 1.94 + process_information.dwProcessId = process_id(); 1.95 + process_information.dwThreadId = thread_id(); 1.96 + process_id_ = 0; 1.97 + thread_id_ = 0; 1.98 + 1.99 + return process_information; 1.100 +} 1.101 + 1.102 +HANDLE ScopedProcessInformation::TakeProcessHandle() { 1.103 + process_id_ = 0; 1.104 + return process_handle_.Take(); 1.105 +} 1.106 + 1.107 +HANDLE ScopedProcessInformation::TakeThreadHandle() { 1.108 + thread_id_ = 0; 1.109 + return thread_handle_.Take(); 1.110 +} 1.111 + 1.112 +} // namespace win 1.113 +} // namespace base