1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/win/scoped_process_information.h"
7 #include "base/logging.h"
8 #include "base/win/scoped_handle.h"
15 // Closes the provided handle if it is not NULL.
16 void CheckAndCloseHandle(HANDLE handle
) {
19 if (::CloseHandle(handle
))
24 // Duplicates source into target, returning true upon success. |target| is
25 // guaranteed to be untouched in case of failure. Succeeds with no side-effects
27 bool CheckAndDuplicateHandle(HANDLE source
, HANDLE
* target
) {
32 if (!::DuplicateHandle(::GetCurrentProcess(), source
,
33 ::GetCurrentProcess(), &temp
, 0, FALSE
,
34 DUPLICATE_SAME_ACCESS
)) {
35 DPLOG(ERROR
) << "Failed to duplicate a handle.";
44 ScopedProcessInformation::ScopedProcessInformation()
45 : process_information_() {
48 ScopedProcessInformation::~ScopedProcessInformation() {
52 PROCESS_INFORMATION
* ScopedProcessInformation::Receive() {
53 DCHECK(!IsValid()) << "process_information_ must be NULL";
54 return &process_information_
;
57 bool ScopedProcessInformation::IsValid() const {
58 return process_information_
.hThread
|| process_information_
.hProcess
||
59 process_information_
.dwProcessId
|| process_information_
.dwThreadId
;
63 void ScopedProcessInformation::Close() {
64 CheckAndCloseHandle(process_information_
.hThread
);
65 CheckAndCloseHandle(process_information_
.hProcess
);
69 void ScopedProcessInformation::Swap(ScopedProcessInformation
* other
) {
71 PROCESS_INFORMATION temp
= other
->process_information_
;
72 other
->process_information_
= process_information_
;
73 process_information_
= temp
;
76 bool ScopedProcessInformation::DuplicateFrom(
77 const ScopedProcessInformation
& other
) {
78 DCHECK(!IsValid()) << "target ScopedProcessInformation must be NULL";
79 DCHECK(other
.IsValid()) << "source ScopedProcessInformation must be valid";
81 ScopedHandle duplicate_process
;
82 ScopedHandle duplicate_thread
;
84 if (CheckAndDuplicateHandle(other
.process_handle(),
85 duplicate_process
.Receive()) &&
86 CheckAndDuplicateHandle(other
.thread_handle(),
87 duplicate_thread
.Receive())) {
88 process_information_
.dwProcessId
= other
.process_id();
89 process_information_
.dwThreadId
= other
.thread_id();
90 process_information_
.hProcess
= duplicate_process
.Take();
91 process_information_
.hThread
= duplicate_thread
.Take();
98 PROCESS_INFORMATION
ScopedProcessInformation::Take() {
99 PROCESS_INFORMATION process_information
= process_information_
;
101 return process_information
;
104 HANDLE
ScopedProcessInformation::TakeProcessHandle() {
105 HANDLE process
= process_information_
.hProcess
;
106 process_information_
.hProcess
= NULL
;
107 process_information_
.dwProcessId
= 0;
111 HANDLE
ScopedProcessInformation::TakeThreadHandle() {
112 HANDLE thread
= process_information_
.hThread
;
113 process_information_
.hThread
= NULL
;
114 process_information_
.dwThreadId
= 0;
118 void ScopedProcessInformation::Reset() {
119 process_information_
.hThread
= NULL
;
120 process_information_
.hProcess
= NULL
;
121 process_information_
.dwProcessId
= 0;
122 process_information_
.dwThreadId
= 0;