- add sources.
[platform/framework/web/crosswalk.git] / src / base / win / scoped_process_information.cc
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.
4
5 #include "base/win/scoped_process_information.h"
6
7 #include "base/logging.h"
8 #include "base/win/scoped_handle.h"
9
10 namespace base {
11 namespace win {
12
13 namespace {
14
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
17 // if source is NULL.
18 bool CheckAndDuplicateHandle(HANDLE source, HANDLE* target) {
19   if (!source)
20     return true;
21
22   HANDLE temp = NULL;
23   if (!::DuplicateHandle(::GetCurrentProcess(), source,
24                          ::GetCurrentProcess(), &temp, 0, FALSE,
25                          DUPLICATE_SAME_ACCESS)) {
26     DPLOG(ERROR) << "Failed to duplicate a handle.";
27     return false;
28   }
29   *target = temp;
30   return true;
31 }
32
33 }  // namespace
34
35 ScopedProcessInformation::ScopedProcessInformation()
36     : process_id_(0), thread_id_(0) {
37 }
38
39 ScopedProcessInformation::~ScopedProcessInformation() {
40   Close();
41 }
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 {
49   return process_id_ || process_handle_.Get() ||
50          thread_id_ || thread_handle_.Get();
51 }
52
53 void ScopedProcessInformation::Close() {
54   process_handle_.Close();
55   thread_handle_.Close();
56   process_id_ = 0;
57   thread_id_ = 0;
58 }
59
60 void ScopedProcessInformation::Set(const PROCESS_INFORMATION& process_info) {
61   if (IsValid())
62     Close();
63
64   process_handle_.Set(process_info.hProcess);
65   thread_handle_.Set(process_info.hThread);
66   process_id_ = process_info.dwProcessId;
67   thread_id_ = process_info.dwThreadId;
68 }
69
70 bool ScopedProcessInformation::DuplicateFrom(
71     const ScopedProcessInformation& other) {
72   DCHECK(!IsValid()) << "target ScopedProcessInformation must be NULL";
73   DCHECK(other.IsValid()) << "source ScopedProcessInformation must be valid";
74
75   if (CheckAndDuplicateHandle(other.process_handle(),
76                               process_handle_.Receive()) &&
77       CheckAndDuplicateHandle(other.thread_handle(),
78                               thread_handle_.Receive())) {
79     process_id_ = other.process_id();
80     thread_id_ = other.thread_id();
81     return true;
82   }
83
84   return false;
85 }
86
87 PROCESS_INFORMATION ScopedProcessInformation::Take() {
88   PROCESS_INFORMATION process_information = {};
89   process_information.hProcess = process_handle_.Take();
90   process_information.hThread = thread_handle_.Take();
91   process_information.dwProcessId = process_id();
92   process_information.dwThreadId = thread_id();
93   process_id_ = 0;
94   thread_id_ = 0;
95
96   return process_information;
97 }
98
99 HANDLE ScopedProcessInformation::TakeProcessHandle() {
100   process_id_ = 0;
101   return process_handle_.Take();
102 }
103
104 HANDLE ScopedProcessInformation::TakeThreadHandle() {
105   thread_id_ = 0;
106   return thread_handle_.Take();
107 }
108
109 }  // namespace win
110 }  // namespace base