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

Side by Side Diff: tools/goopdump/process_monitor.cc

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 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
« no previous file with comments | « tools/goopdump/process_monitor.h ('k') | tools/goopdump/process_monitor_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 2008-2009 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ========================================================================
15
16 #include "omaha/tools/goopdump/process_monitor.h"
17
18 #include <tlhelp32.h>
19 #include <map>
20 #include <vector>
21
22 #include "omaha/common/debug.h"
23 #include "omaha/common/error.h"
24 #include "omaha/common/logging.h"
25 #include "omaha/tools/goopdump/process_commandline.h"
26
27 namespace omaha {
28
29 ProcessMonitor::ProcessMonitor() : is_running_(false), callback_(NULL) {
30 }
31
32 ProcessMonitor::~ProcessMonitor() {
33 }
34
35 HRESULT ProcessMonitor::Start(ProcessMonitorCallbackInterface* callback,
36 const TCHAR* process_name_pattern) {
37 std::vector<CString> patterns;
38 patterns.push_back(CString(process_name_pattern));
39 return StartWithPatterns(callback, patterns);
40 }
41
42 HRESULT ProcessMonitor::StartWithPatterns(
43 ProcessMonitorCallbackInterface* callback,
44 const std::vector<CString>& process_name_patterns) {
45 SingleLock lock(&lock_);
46
47 if (is_running_) {
48 return E_UNEXPECTED;
49 }
50
51 EnableDebugPrivilege();
52
53 std::vector<CString>::const_iterator it = process_name_patterns.begin();
54 for (; it != process_name_patterns.end(); ++it) {
55 CString pattern = *it;
56 pattern.MakeLower();
57 process_name_patterns_.push_back(pattern);
58 }
59
60 callback_ = callback;
61
62 reset(event_thread_exit_, ::CreateEvent(NULL, FALSE, FALSE, NULL));
63 if (!valid(event_thread_exit_)) {
64 return HRESULTFromLastError();
65 }
66
67 reset(monitor_thread_, ::CreateThread(NULL,
68 0,
69 &ProcessMonitor::MonitorThreadProc,
70 this,
71 0,
72 NULL));
73 if (!valid(monitor_thread_)) {
74 return HRESULTFromLastError();
75 }
76
77 is_running_ = true;
78 return S_OK;
79 }
80
81 HRESULT ProcessMonitor::Stop() {
82 SingleLock lock(&lock_);
83
84 if (!is_running_) {
85 return E_UNEXPECTED;
86 }
87
88 ::SetEvent(get(event_thread_exit_));
89 ::WaitForSingleObject(get(monitor_thread_), INFINITE);
90
91 is_running_ = false;
92 return S_OK;
93 }
94
95 DWORD ProcessMonitor::MonitorThreadProc(void* param) {
96 ProcessMonitor* monitor = static_cast<ProcessMonitor*>(param);
97 if (monitor) {
98 return monitor->MonitorProc();
99 }
100 return 1;
101 }
102
103 DWORD ProcessMonitor::MonitorProc() {
104 // 200ms idle between polling for process creation.
105 const DWORD kWaitTimeoutMs = 200;
106
107 MapHandleToDword map_handle_pid;
108 bool keep_running = true;
109
110 do {
111 size_t map_count = map_handle_pid.size();
112 size_t pids_to_monitor = (map_count < MAXIMUM_WAIT_OBJECTS) ?
113 map_count : MAXIMUM_WAIT_OBJECTS;
114
115 std::vector<HANDLE> handles;
116 handles.push_back(get(event_thread_exit_));
117
118 MapHandleToDwordIterator iter = map_handle_pid.begin();
119 for (; (iter != map_handle_pid.end()) && (handles.size() < pids_to_monitor);
120 ++iter) {
121 handles.push_back(iter->first);
122 }
123
124 DWORD wait_result = ::WaitForMultipleObjects(handles.size(),
125 &handles.front(),
126 FALSE,
127 kWaitTimeoutMs);
128 if (wait_result < (WAIT_OBJECT_0 + handles.size())) {
129 HANDLE signalled = handles[wait_result - WAIT_OBJECT_0];
130
131 if (signalled == get(event_thread_exit_)) {
132 // We've been signalled to exit.
133 keep_running = false;
134 } else {
135 // One of the PIDs exited.
136 MapHandleToDwordIterator iter = map_handle_pid.begin();
137 for (; iter != map_handle_pid.end(); ++iter) {
138 if (iter->first == signalled) {
139 OnProcessRemoved(iter->second);
140 ::CloseHandle(iter->first);
141 map_handle_pid.erase(iter);
142 break;
143 }
144 }
145 }
146 } else if (wait_result == WAIT_TIMEOUT) {
147 // Our polling time is up. Go look for running instances of the
148 // process we're monitoring and look for differences in the list of PIDs.
149 UpdateProcessList(&map_handle_pid);
150 } else {
151 // Some type of failure occurred.
152 keep_running = false;
153 }
154 } while (keep_running);
155
156 return 0;
157 }
158
159 void ProcessMonitor::CleanupHandleMap(MapHandleToDword* map_handle_pid) {
160 ASSERT1(map_handle_pid);
161 MapHandleToDwordIterator iter = map_handle_pid->begin();
162 for (; iter != map_handle_pid->end(); ++iter) {
163 ::CloseHandle(iter->first);
164 }
165 map_handle_pid->clear();
166 }
167
168 bool ProcessMonitor::UpdateProcessList(MapHandleToDword* map_handle_pid) {
169 ASSERT1(map_handle_pid);
170 scoped_handle process_snap;
171 reset(process_snap, ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
172 if (!valid(process_snap)) {
173 return false;
174 }
175
176 PROCESSENTRY32 process_entry32 = {0};
177 process_entry32.dwSize = sizeof(PROCESSENTRY32);
178
179 if (!::Process32First(get(process_snap), &process_entry32)) {
180 return false;
181 }
182
183 do {
184 CString exe_file_name = process_entry32.szExeFile;
185 exe_file_name.MakeLower();
186
187 typedef std::vector<CString>::iterator VectorIterator;
188 VectorIterator pattern_iter = process_name_patterns_.begin();
189 for (; pattern_iter != process_name_patterns_.end(); ++pattern_iter) {
190 CString process_pattern = *pattern_iter;
191 if (exe_file_name.Find(process_pattern) >= 0) {
192 // We've found a match. See if this ProcessID is already in our list
193 bool is_found = false;
194 MapHandleToDwordIterator iter = map_handle_pid->begin();
195 for (; iter != map_handle_pid->end(); ++iter) {
196 if (iter->second == process_entry32.th32ProcessID) {
197 is_found = true;
198 break;
199 }
200 }
201
202 if (!is_found) {
203 // Opening this handle and we'll give ownership of this HANDLE to
204 // map_handle_pid.
205 HANDLE process_handle = ::OpenProcess(PROCESS_ALL_ACCESS,
206 FALSE,
207 process_entry32.th32ProcessID);
208 if (process_handle) {
209 (*map_handle_pid)[process_handle] = process_entry32.th32ProcessID;
210 OnProcessAdded(process_entry32.th32ProcessID, process_pattern);
211 }
212 }
213 }
214 }
215 } while (::Process32Next(get(process_snap), &process_entry32));
216
217 return true;
218 }
219
220 void ProcessMonitor::OnProcessAdded(DWORD process_id,
221 const CString& process_pattern) {
222 if (callback_) {
223 callback_->OnProcessAdded(process_id, process_pattern);
224 }
225 }
226
227 void ProcessMonitor::OnProcessRemoved(DWORD process_id) {
228 if (callback_) {
229 callback_->OnProcessRemoved(process_id);
230 }
231 }
232
233 } // namespace omaha
234
OLDNEW
« no previous file with comments | « tools/goopdump/process_monitor.h ('k') | tools/goopdump/process_monitor_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698