OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/win/scoped_process_information.h" | 5 #include "base/win/scoped_process_information.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/win/scoped_handle.h" | 8 #include "base/win/scoped_handle.h" |
9 | 9 |
10 namespace base { | 10 namespace base { |
11 namespace win { | 11 namespace win { |
12 | 12 |
13 namespace { | 13 namespace { |
14 | 14 |
15 // Duplicates source into target, returning true upon success. |target| is | 15 // Duplicates source into target, returning true upon success. |target| is |
16 // guaranteed to be untouched in case of failure. Succeeds with no side-effects | 16 // guaranteed to be untouched in case of failure. Succeeds with no side-effects |
17 // if source is NULL. | 17 // if source is NULL. |
18 bool CheckAndDuplicateHandle(HANDLE source, ScopedHandle* target) { | 18 bool CheckAndDuplicateHandle(HANDLE source, HANDLE* target) { |
19 if (!source) | 19 if (!source) |
20 return true; | 20 return true; |
21 | 21 |
22 HANDLE temp = NULL; | 22 HANDLE temp = NULL; |
23 if (!::DuplicateHandle(::GetCurrentProcess(), source, | 23 if (!::DuplicateHandle(::GetCurrentProcess(), source, |
24 ::GetCurrentProcess(), &temp, 0, FALSE, | 24 ::GetCurrentProcess(), &temp, 0, FALSE, |
25 DUPLICATE_SAME_ACCESS)) { | 25 DUPLICATE_SAME_ACCESS)) { |
26 DPLOG(ERROR) << "Failed to duplicate a handle."; | 26 DPLOG(ERROR) << "Failed to duplicate a handle."; |
27 return false; | 27 return false; |
28 } | 28 } |
29 target->Set(temp); | 29 *target = temp; |
30 return true; | 30 return true; |
31 } | 31 } |
32 | 32 |
33 } // namespace | 33 } // namespace |
34 | 34 |
35 ScopedProcessInformation::ScopedProcessInformation() | 35 ScopedProcessInformation::ScopedProcessInformation() |
36 : process_id_(0), thread_id_(0) { | 36 : process_id_(0), thread_id_(0) { |
37 } | 37 } |
38 | 38 |
39 ScopedProcessInformation::ScopedProcessInformation( | |
40 const PROCESS_INFORMATION& process_info) : process_id_(0), thread_id_(0) { | |
41 Set(process_info); | |
42 } | |
43 | |
44 ScopedProcessInformation::~ScopedProcessInformation() { | 39 ScopedProcessInformation::~ScopedProcessInformation() { |
45 Close(); | 40 Close(); |
46 } | 41 } |
47 | 42 |
| 43 ScopedProcessInformation::Receiver ScopedProcessInformation::Receive() { |
| 44 DCHECK(!IsValid()) << "process_information_ must be NULL"; |
| 45 return Receiver(this); |
| 46 } |
| 47 |
48 bool ScopedProcessInformation::IsValid() const { | 48 bool ScopedProcessInformation::IsValid() const { |
49 return process_id_ || process_handle_.Get() || | 49 return process_id_ || process_handle_.Get() || |
50 thread_id_ || thread_handle_.Get(); | 50 thread_id_ || thread_handle_.Get(); |
51 } | 51 } |
52 | 52 |
53 void ScopedProcessInformation::Close() { | 53 void ScopedProcessInformation::Close() { |
54 process_handle_.Close(); | 54 process_handle_.Close(); |
55 thread_handle_.Close(); | 55 thread_handle_.Close(); |
56 process_id_ = 0; | 56 process_id_ = 0; |
57 thread_id_ = 0; | 57 thread_id_ = 0; |
58 } | 58 } |
59 | 59 |
60 void ScopedProcessInformation::Set(const PROCESS_INFORMATION& process_info) { | 60 void ScopedProcessInformation::Set(const PROCESS_INFORMATION& process_info) { |
61 if (IsValid()) | 61 if (IsValid()) |
62 Close(); | 62 Close(); |
63 | 63 |
64 process_handle_.Set(process_info.hProcess); | 64 process_handle_.Set(process_info.hProcess); |
65 thread_handle_.Set(process_info.hThread); | 65 thread_handle_.Set(process_info.hThread); |
66 process_id_ = process_info.dwProcessId; | 66 process_id_ = process_info.dwProcessId; |
67 thread_id_ = process_info.dwThreadId; | 67 thread_id_ = process_info.dwThreadId; |
68 } | 68 } |
69 | 69 |
70 bool ScopedProcessInformation::DuplicateFrom( | 70 bool ScopedProcessInformation::DuplicateFrom( |
71 const ScopedProcessInformation& other) { | 71 const ScopedProcessInformation& other) { |
72 DCHECK(!IsValid()) << "target ScopedProcessInformation must be NULL"; | 72 DCHECK(!IsValid()) << "target ScopedProcessInformation must be NULL"; |
73 DCHECK(other.IsValid()) << "source ScopedProcessInformation must be valid"; | 73 DCHECK(other.IsValid()) << "source ScopedProcessInformation must be valid"; |
74 | 74 |
75 if (CheckAndDuplicateHandle(other.process_handle(), &process_handle_) && | 75 if (CheckAndDuplicateHandle(other.process_handle(), |
76 CheckAndDuplicateHandle(other.thread_handle(), &thread_handle_)) { | 76 process_handle_.Receive()) && |
| 77 CheckAndDuplicateHandle(other.thread_handle(), |
| 78 thread_handle_.Receive())) { |
77 process_id_ = other.process_id(); | 79 process_id_ = other.process_id(); |
78 thread_id_ = other.thread_id(); | 80 thread_id_ = other.thread_id(); |
79 return true; | 81 return true; |
80 } | 82 } |
81 | 83 |
82 return false; | 84 return false; |
83 } | 85 } |
84 | 86 |
85 PROCESS_INFORMATION ScopedProcessInformation::Take() { | 87 PROCESS_INFORMATION ScopedProcessInformation::Take() { |
86 PROCESS_INFORMATION process_information = {}; | 88 PROCESS_INFORMATION process_information = {}; |
(...skipping 12 matching lines...) Expand all Loading... |
99 return process_handle_.Take(); | 101 return process_handle_.Take(); |
100 } | 102 } |
101 | 103 |
102 HANDLE ScopedProcessInformation::TakeThreadHandle() { | 104 HANDLE ScopedProcessInformation::TakeThreadHandle() { |
103 thread_id_ = 0; | 105 thread_id_ = 0; |
104 return thread_handle_.Take(); | 106 return thread_handle_.Take(); |
105 } | 107 } |
106 | 108 |
107 } // namespace win | 109 } // namespace win |
108 } // namespace base | 110 } // namespace base |
OLD | NEW |