15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_process_information.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_handle.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace win { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Duplicates source into target, returning true upon success. |target| is 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// guaranteed to be untouched in case of failure. Succeeds with no side-effects 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if source is NULL. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckAndDuplicateHandle(HANDLE source, HANDLE* target) { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!source) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE temp = NULL; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!::DuplicateHandle(::GetCurrentProcess(), source, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GetCurrentProcess(), &temp, 0, FALSE, 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DUPLICATE_SAME_ACCESS)) { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DPLOG(ERROR) << "Failed to duplicate a handle."; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *target = temp; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedProcessInformation::ScopedProcessInformation() 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : process_id_(0), thread_id_(0) { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedProcessInformation::~ScopedProcessInformation() { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Close(); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ScopedProcessInformation::Receiver ScopedProcessInformation::Receive() { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!IsValid()) << "process_information_ must be NULL"; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Receiver(this); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ScopedProcessInformation::IsValid() const { 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return process_id_ || process_handle_.Get() || 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_id_ || thread_handle_.Get(); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScopedProcessInformation::Close() { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) process_handle_.Close(); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_handle_.Close(); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) process_id_ = 0; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_id_ = 0; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ScopedProcessInformation::Set(const PROCESS_INFORMATION& process_info) { 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (IsValid()) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Close(); 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) process_handle_.Set(process_info.hProcess); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_handle_.Set(process_info.hThread); 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) process_id_ = process_info.dwProcessId; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_id_ = process_info.dwThreadId; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ScopedProcessInformation::DuplicateFrom( 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ScopedProcessInformation& other) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!IsValid()) << "target ScopedProcessInformation must be NULL"; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(other.IsValid()) << "source ScopedProcessInformation must be valid"; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CheckAndDuplicateHandle(other.process_handle(), 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) process_handle_.Receive()) && 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckAndDuplicateHandle(other.thread_handle(), 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_handle_.Receive())) { 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) process_id_ = other.process_id(); 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_id_ = other.thread_id(); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PROCESS_INFORMATION ScopedProcessInformation::Take() { 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PROCESS_INFORMATION process_information = {}; 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) process_information.hProcess = process_handle_.Take(); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) process_information.hThread = thread_handle_.Take(); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) process_information.dwProcessId = process_id(); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) process_information.dwThreadId = thread_id(); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) process_id_ = 0; 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_id_ = 0; 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return process_information; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HANDLE ScopedProcessInformation::TakeProcessHandle() { 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) process_id_ = 0; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return process_handle_.Take(); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HANDLE ScopedProcessInformation::TakeThreadHandle() { 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_id_ = 0; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return thread_handle_.Take(); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace win 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 111