Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: base/win/scoped_process_information.cc

Issue 9700038: ScopedProcessInformation protects against process/thread handle leaks from CreateProcess calls. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add tests for new functions. Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/win/scoped_process_information.h ('k') | base/win/scoped_process_information_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 // Closes the provided handle if it is not NULL.
16 void CheckAndCloseHandle(HANDLE handle) {
17 if (!handle)
18 return;
19 if (::CloseHandle(handle))
20 return;
21 DPCHECK(false) << "Failed to close a handle.";
22 }
23
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
26 // if source is NULL.
27 bool CheckAndDuplicateHandle(HANDLE source, HANDLE* target) {
28 if (!source)
29 return true;
30
31 HANDLE temp = NULL;
32 if (!::DuplicateHandle(::GetCurrentProcess(), source,
33 ::GetCurrentProcess(), &temp, 0, FALSE,
34 DUPLICATE_SAME_ACCESS)) {
35 DPLOG(ERROR) << "Failed to duplicate a handle.";
36 return false;
37 }
38 *target = temp;
39 return true;
40 }
41
42 } // namespace
43
44 ScopedProcessInformation::ScopedProcessInformation()
45 : process_information_() {
46 }
47
48 ScopedProcessInformation::~ScopedProcessInformation() {
49 Close();
50 }
51
52 PROCESS_INFORMATION* ScopedProcessInformation::Receive() {
53 DCHECK(!IsValid()) << "process_information_ must be NULL";
54 return &process_information_;
55 }
56
57 bool ScopedProcessInformation::IsValid() const {
58 return process_information_.hThread || process_information_.hProcess ||
59 process_information_.dwProcessId || process_information_.dwThreadId;
60 }
61
62
63 void ScopedProcessInformation::Close() {
64 CheckAndCloseHandle(process_information_.hThread);
65 CheckAndCloseHandle(process_information_.hProcess);
66 Reset();
67 }
68
69 void ScopedProcessInformation::Swap(ScopedProcessInformation* other) {
brettw 2012/03/30 17:23:09 Do you need this for anything? Unless you have a n
70 DCHECK(other);
71 PROCESS_INFORMATION temp = other->process_information_;
72 other->process_information_ = process_information_;
73 process_information_ = temp;
74 }
75
76 bool ScopedProcessInformation::DuplicateFrom(
brettw 2012/03/30 17:23:09 I'm also wondering about the use case for this fun
77 const ScopedProcessInformation& other) {
78 DCHECK(!IsValid()) << "target ScopedProcessInformation must be NULL";
79 DCHECK(other.IsValid()) << "source ScopedProcessInformation must be valid";
80
81 ScopedHandle duplicate_process;
82 ScopedHandle duplicate_thread;
83
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();
92 return true;
93 }
94
95 return false;
96 }
97
98 PROCESS_INFORMATION ScopedProcessInformation::Take() {
99 PROCESS_INFORMATION process_information = process_information_;
100 Reset();
101 return process_information;
102 }
103
104 HANDLE ScopedProcessInformation::TakeProcessHandle() {
105 HANDLE process = process_information_.hProcess;
106 process_information_.hProcess = NULL;
107 process_information_.dwProcessId = 0;
108 return process;
109 }
110
111 HANDLE ScopedProcessInformation::TakeThreadHandle() {
112 HANDLE thread = process_information_.hThread;
113 process_information_.hThread = NULL;
114 process_information_.dwThreadId = 0;
115 return thread;
116 }
117
118 void ScopedProcessInformation::Reset() {
119 process_information_.hThread = NULL;
120 process_information_.hProcess = NULL;
121 process_information_.dwProcessId = 0;
122 process_information_.dwThreadId = 0;
123 }
124
125 } // namespace win
126 } // namespace base
OLDNEW
« no previous file with comments | « base/win/scoped_process_information.h ('k') | base/win/scoped_process_information_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698