OLD | NEW |
1 /** | 1 /** |
2 * \file process.h | 2 * \file process.h |
3 */ | 3 */ |
4 | 4 |
5 #ifndef PROCESS_H | 5 #ifndef PROCESS_H |
6 #define PROCESS_H | 6 #define PROCESS_H |
7 | 7 |
8 #include "installer-lib.h" | 8 #include "installer-lib.h" |
9 #include "handle.h" | 9 #include "handle.h" |
10 #include "session.h" | 10 #include "session.h" |
11 | 11 |
12 #include <string> | 12 #include <string> |
13 #include <cctype> | 13 #include <cctype> |
14 #include <vector> | 14 #include <vector> |
15 #include <set> | 15 #include <set> |
16 #include <algorithm> | 16 #include <algorithm> |
17 #include <memory> | 17 #include <memory> |
18 | 18 |
19 #include <Windows.h> | 19 #include <Windows.h> |
20 #include <TlHelp32.h> | 20 #include <TlHelp32.h> |
21 | 21 |
22 //------------------------------------------------------- | 22 //------------------------------------------------------- |
23 // wstring_ci: case-insensitive wide string | 23 // WstringCaseInsensitive: case-insensitive wide string |
24 //------------------------------------------------------- | 24 //------------------------------------------------------- |
25 | 25 |
26 /** | 26 /** |
27 * Traits class for case-insensitive strings. | 27 * Traits class for case-insensitive strings. |
28 */ | 28 */ |
29 template< class T > | 29 template< class T > |
30 struct ci_traits: std::char_traits< T > | 30 struct CaseInsensitiveTraits: std::char_traits< T > |
31 { | 31 { |
32 static bool eq( T c1, T c2 ) | 32 static bool eq( T c1, T c2 ) |
33 { | 33 { |
34 return std::tolower( c1 ) == std::tolower( c2 ) ; | 34 return std::tolower( c1 ) == std::tolower( c2 ) ; |
35 } | 35 } |
36 | 36 |
37 static bool lt( T c1, T c2 ) | 37 static bool lt( T c1, T c2 ) |
38 { | 38 { |
39 return std::tolower( c1 ) < std::tolower( c2 ) ; | 39 return std::tolower( c1 ) < std::tolower( c2 ) ; |
40 } | 40 } |
(...skipping 15 matching lines...) Expand all Loading... |
56 if ( l1 == l2 ) | 56 if ( l1 == l2 ) |
57 { | 57 { |
58 continue ; | 58 continue ; |
59 } | 59 } |
60 return ( l1 < l2 ) ? -1 : +1 ; | 60 return ( l1 < l2 ) ? -1 : +1 ; |
61 } | 61 } |
62 return 0 ; | 62 return 0 ; |
63 } | 63 } |
64 } ; | 64 } ; |
65 | 65 |
66 typedef std::basic_string< wchar_t, ci_traits< wchar_t > > wstring_ci ; | 66 typedef std::basic_string< wchar_t, CaseInsensitiveTraits< wchar_t > > WstringCa
seInsensitive ; |
67 | 67 |
68 //------------------------------------------------------- | 68 //------------------------------------------------------- |
69 // file_name_set: case-insensitive wide-string set | 69 // FileNameSet: case-insensitive wide-string set |
70 //------------------------------------------------------- | 70 //------------------------------------------------------- |
71 struct file_name_set | 71 struct FileNameSet |
72 : public std::set< wstring_ci > | 72 : public std::set< WstringCaseInsensitive > |
73 { | 73 { |
74 /** | 74 /** |
75 * Empty set constructor. | 75 * Empty set constructor. |
76 */ | 76 */ |
77 file_name_set() | 77 FileNameSet() |
78 {} | 78 {} |
79 | 79 |
80 /** | 80 /** |
81 * Constructor initialization from an array. | 81 * Constructor initialization from an array. |
82 */ | 82 */ |
83 template< size_t n_file_names > | 83 template< size_t nFileNames > |
84 file_name_set( const wchar_t * ( & file_name_list )[ n_file_names ] ) | 84 FileNameSet( const wchar_t * ( & fileNameList )[ nFileNames ] ) |
85 { | 85 { |
86 for ( unsigned int j = 0 ; j < n_file_names ; ++ j ) | 86 for ( unsigned int j = 0 ; j < nFileNames ; ++ j ) |
87 { | 87 { |
88 insert( wstring_ci( file_name_list[ j ] ) ) ; | 88 insert( WstringCaseInsensitive( fileNameList[ j ] ) ) ; |
89 } | 89 } |
90 } | 90 } |
91 } ; | 91 } ; |
92 | 92 |
93 //------------------------------------------------------- | 93 //------------------------------------------------------- |
94 //------------------------------------------------------- | 94 //------------------------------------------------------- |
95 /** | 95 /** |
96 * Filter by process name. Comparison is case-insensitive. Windows Store app pro
cesses excluded | 96 * Filter by process name. Comparison is case-insensitive. Windows Store app pro
cesses excluded |
97 */ | 97 */ |
98 class process_by_any_exe_not_immersive | 98 class ProcessByAnyExeNotImmersive |
99 : public std::unary_function<PROCESSENTRY32W, bool> | 99 : public std::unary_function<PROCESSENTRY32W, bool> |
100 { | 100 { |
101 /** | 101 /** |
102 * Set of file names from which to match candidate process names. | 102 * Set of file names from which to match candidate process names. |
103 * | 103 * |
104 * This is a reference to, not a copy of, the set. | 104 * This is a reference to, not a copy of, the set. |
105 * The lifetime of this object must be subordinate to that of its referent. | 105 * The lifetime of this object must be subordinate to that of its referent. |
106 * The set used to instantiate this class is a member of ProcessCloser, | 106 * The set used to instantiate this class is a member of ProcessCloser, |
107 * and so also is this class. | 107 * and so also is this class. |
108 * Hence the lifetimes are coterminous, and the reference is not problematic. | 108 * Hence the lifetimes are coterminous, and the reference is not problematic. |
109 */ | 109 */ |
110 const file_name_set & processNames; | 110 const FileNameSet & processNames; |
111 public: | 111 public: |
112 bool operator()( const PROCESSENTRY32W & ); | 112 bool operator()( const PROCESSENTRY32W & ); |
113 process_by_any_exe_not_immersive(const file_name_set & names) : processNames(
names ) {} | 113 ProcessByAnyExeNotImmersive(const FileNameSet & names) : processNames( names )
{} |
114 } ; | 114 } ; |
115 | 115 |
116 | 116 |
117 //------------------------------------------------------- | 117 //------------------------------------------------------- |
118 // Process utility functions. | 118 // Process utility functions. |
119 //------------------------------------------------------- | 119 //------------------------------------------------------- |
120 /** | 120 /** |
121 * A promiscuous filter admits everything. | 121 * A promiscuous filter admits everything. |
122 */ | 122 */ |
123 struct every_process | 123 struct EveryProcess |
124 : public std::unary_function< PROCESSENTRY32W, bool > | 124 : public std::unary_function< PROCESSENTRY32W, bool > |
125 { | 125 { |
126 bool operator()( const PROCESSENTRY32W & ) { return true ; } ; | 126 bool operator()( const PROCESSENTRY32W & ) { return true ; } ; |
127 } ; | 127 } ; |
128 | 128 |
129 /** | 129 /** |
130 * Extractor that copies the entire process structure. | 130 * Extractor that copies the entire process structure. |
131 */ | 131 */ |
132 struct copy_all | 132 struct CopyAll |
133 : public std::unary_function< PROCESSENTRY32W, PROCESSENTRY32W > | 133 : public std::unary_function< PROCESSENTRY32W, PROCESSENTRY32W > |
134 { | 134 { |
135 PROCESSENTRY32W operator()( const PROCESSENTRY32W & process ) { return process
; } | 135 PROCESSENTRY32W operator()( const PROCESSENTRY32W & process ) { return process
; } |
136 } ; | 136 } ; |
137 | 137 |
138 /** | 138 /** |
139 * Extractor that copies only the PID. | 139 * Extractor that copies only the PID. |
140 */ | 140 */ |
141 struct copy_PID | 141 struct CopyPID |
142 : public std::unary_function< PROCESSENTRY32W, DWORD > | 142 : public std::unary_function< PROCESSENTRY32W, DWORD > |
143 { | 143 { |
144 inline DWORD operator()( const PROCESSENTRY32W & process ) { return process.th
32ProcessID ; } | 144 inline DWORD operator()( const PROCESSENTRY32W & process ) { return process.th
32ProcessID ; } |
145 } ; | 145 } ; |
146 | 146 |
147 /** | 147 /** |
148 * Retrieve the process ID that created a window. | 148 * Retrieve the process ID that created a window. |
149 * | 149 * |
150 * Wrapper around GetWindowThreadProcessId. | 150 * Wrapper around GetWindowThreadProcessId. |
151 * Converts an error return from the system call into an exception. | 151 * Converts an error return from the system call into an exception. |
152 * The system call can also retrieve the creating thread; we ignore it. | 152 * The system call can also retrieve the creating thread; we ignore it. |
153 * | 153 * |
154 * \param window | 154 * \param window |
155 * Handle of the window | 155 * Handle of the window |
156 * \return | 156 * \return |
157 * ID of the process that created the argument window | 157 * ID of the process that created the argument window |
158 * | 158 * |
159 * \sa | 159 * \sa |
160 * MSDN [GetWindowThreadProcessId function](http://msdn.microsoft.com/en-us/li
brary/windows/desktop/ms633522%28v=vs.85%29.aspx) | 160 * MSDN [GetWindowThreadProcessId function](http://msdn.microsoft.com/en-us/li
brary/windows/desktop/ms633522%28v=vs.85%29.aspx) |
161 */ | 161 */ |
162 DWORD creator_process( HWND window ) ; | 162 DWORD CreatorProcess( HWND window ) ; |
163 | 163 |
164 //------------------------------------------------------- | 164 //------------------------------------------------------- |
165 // Snapshot | 165 // Snapshot |
166 //------------------------------------------------------- | 166 //------------------------------------------------------- |
167 /** | 167 /** |
168 * Traits class for snapshots of all processes on the system. | 168 * Traits class for snapshots of all processes on the system. |
169 */ | 169 */ |
170 struct Process_Snapshot_Traits | 170 struct ProcessSnapshotTraits |
171 { | 171 { |
172 /** | 172 /** |
173 * The type of the data resulting from CreateToolhelp32Snapshot. | 173 * The type of the data resulting from CreateToolhelp32Snapshot. |
174 */ | 174 */ |
175 typedef PROCESSENTRY32W result_type ; | 175 typedef PROCESSENTRY32W ResultType ; |
176 | 176 |
177 /** | 177 /** |
178 * Flags used to call CreateToolhelp32Snapshot. | 178 * Flags used to call CreateToolhelp32Snapshot. |
179 */ | 179 */ |
180 const static DWORD snapshot_flags = TH32CS_SNAPPROCESS ; | 180 const static DWORD SnapshotFlags = TH32CS_SNAPPROCESS ; |
181 | 181 |
182 /** | 182 /** |
183 * Wrapper for 'first' function for processes | 183 * Wrapper for 'first' function for processes |
184 */ | 184 */ |
185 static BOOL first( HANDLE arg1, LPPROCESSENTRY32 arg2 ) | 185 static BOOL First( HANDLE arg1, LPPROCESSENTRY32 arg2 ) |
186 { | 186 { |
187 return ::Process32First( arg1, arg2 ) ; | 187 return ::Process32First( arg1, arg2 ) ; |
188 } | 188 } |
189 | 189 |
190 /** | 190 /** |
191 * Wrapper for 'next' function for processes | 191 * Wrapper for 'next' function for processes |
192 */ | 192 */ |
193 static BOOL next( HANDLE arg1, LPPROCESSENTRY32 arg2 ) | 193 static BOOL Next( HANDLE arg1, LPPROCESSENTRY32 arg2 ) |
194 { | 194 { |
195 return ::Process32Next( arg1, arg2 ) ; | 195 return ::Process32Next( arg1, arg2 ) ; |
196 } | 196 } |
197 } ; | 197 } ; |
198 | 198 |
199 /** | 199 /** |
200 * Traits class for snapshots of all modules loaded by a process. | 200 * Traits class for snapshots of all modules loaded by a process. |
201 */ | 201 */ |
202 struct Module_Snapshot_Traits | 202 struct ModuleSnapshotTraits |
203 { | 203 { |
204 /** | 204 /** |
205 * The type of the data resulting from CreateToolhelp32Snapshot. | 205 * The type of the data resulting from CreateToolhelp32Snapshot. |
206 */ | 206 */ |
207 typedef MODULEENTRY32W result_type ; | 207 typedef MODULEENTRY32W ResultType ; |
208 | 208 |
209 /** | 209 /** |
210 * Flags used to call CreateToolhelp32Snapshot. | 210 * Flags used to call CreateToolhelp32Snapshot. |
211 */ | 211 */ |
212 const static DWORD snapshot_flags = TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32 ; | 212 const static DWORD SnapshotFlags = TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32 ; |
213 | 213 |
214 /** | 214 /** |
215 * Wrapper for 'first' function for modules | 215 * Wrapper for 'first' function for modules |
216 */ | 216 */ |
217 static BOOL first( HANDLE arg1, LPMODULEENTRY32 arg2 ) | 217 static BOOL First( HANDLE arg1, LPMODULEENTRY32 arg2 ) |
218 { | 218 { |
219 return ::Module32First( arg1, arg2 ) ; | 219 return ::Module32First( arg1, arg2 ) ; |
220 } | 220 } |
221 | 221 |
222 /** | 222 /** |
223 * Wrapper for 'next' function for modules | 223 * Wrapper for 'next' function for modules |
224 */ | 224 */ |
225 static BOOL next( HANDLE arg1, LPMODULEENTRY32 arg2 ) | 225 static BOOL Next( HANDLE arg1, LPMODULEENTRY32 arg2 ) |
226 { | 226 { |
227 return ::Module32Next( arg1, arg2 ) ; | 227 return ::Module32Next( arg1, arg2 ) ; |
228 } | 228 } |
229 } ; | 229 } ; |
230 | 230 |
231 /** | 231 /** |
232 * A snapshot wrapping the results of CreateToolhelp32Snapshot system call. | 232 * A snapshot wrapping the results of CreateToolhelp32Snapshot system call. |
233 * | 233 * |
234 * Unfortunately, we cannot provide standard iterator for this class. | 234 * Unfortunately, we cannot provide standard iterator for this class. |
235 * Standard iterators must be copy-constructible, which entails the possibility
of multiple, coexisting iteration states. | 235 * Standard iterators must be copy-constructible, which entails the possibility
of multiple, coexisting iteration states. |
236 * The iteration behavior provided by Process32First and Process32Next relies up
on state held within the snapshot itself. | 236 * The iteration behavior provided by Process32First and Process32Next relies up
on state held within the snapshot itself. |
237 * Thus, there can be only one iterator at a time for the snapshot. | 237 * Thus, there can be only one iterator at a time for the snapshot. |
238 * The two requirements are not simultaneously satisfiable. | 238 * The two requirements are not simultaneously satisfiable. |
239 * | 239 * |
240 * Instead of a standard iterator, we provide a first() and next() functions wra
pping the corresponding system calls. | 240 * Instead of a standard iterator, we provide a First() and Next() functions wra
pping the corresponding system calls. |
241 * | 241 * |
242 * \par Implementation | 242 * \par Implementation |
243 * | 243 * |
244 * - MSDN [CreateToolhelp32Snapshot function](http://msdn.microsoft.com/en-us/li
brary/windows/desktop/ms682489%28v=vs.85%29.aspx) | 244 * - MSDN [CreateToolhelp32Snapshot function](http://msdn.microsoft.com/en-us/li
brary/windows/desktop/ms682489%28v=vs.85%29.aspx) |
245 * - MSDN [Process32First function](http://msdn.microsoft.com/en-us/library/wind
ows/desktop/ms684834%28v=vs.85%29.aspx) | 245 * - MSDN [Process32First function](http://msdn.microsoft.com/en-us/library/wind
ows/desktop/ms684834%28v=vs.85%29.aspx) |
246 * - MSDN [Process32Next function](http://msdn.microsoft.com/en-us/library/windo
ws/desktop/ms684836%28v=vs.85%29.aspx) | 246 * - MSDN [Process32Next function](http://msdn.microsoft.com/en-us/library/windo
ws/desktop/ms684836%28v=vs.85%29.aspx) |
247 * - MSDN [PROCESSENTRY32 structure](http://msdn.microsoft.com/en-us/library/win
dows/desktop/ms684839%28v=vs.85%29.aspx) | 247 * - MSDN [PROCESSENTRY32 structure](http://msdn.microsoft.com/en-us/library/win
dows/desktop/ms684839%28v=vs.85%29.aspx) |
248 * | 248 * |
249 * \par Design Note | 249 * \par Design Note |
250 * The traits class defines first() and next() functions instead of using func
tion pointers. | 250 * The traits class defines First() and Next() functions instead of using func
tion pointers. |
251 * This arises from a limitation in the compiler. | 251 * This arises from a limitation in the compiler. |
252 * The system calls are declared 'WINAPI', which is a compiler-specific extens
ion. | 252 * The system calls are declared 'WINAPI', which is a compiler-specific extens
ion. |
253 * That extension, however, does not go far enough to be able to declare a poi
nter with the same modifier. | 253 * That extension, however, does not go far enough to be able to declare a poi
nter with the same modifier. |
254 * Hence the system calls must be called directly; they are wrapped in the tra
it functions. | 254 * Hence the system calls must be called directly; they are wrapped in the tra
it functions. |
255 */ | 255 */ |
256 template< class Traits > | 256 template< class Traits > |
257 class Snapshot | 257 class Snapshot |
258 { | 258 { |
259 public: | 259 public: |
260 /** | 260 /** |
261 * Expose the result type from the traits class as our own. | 261 * Expose the result type from the traits class as our own. |
262 */ | 262 */ |
263 typedef typename Traits::result_type result_type ; | 263 typedef typename Traits::ResultType ResultType ; |
264 | 264 |
265 private: | 265 private: |
266 /** | 266 /** |
267 * Process ID argument for CreateToolhelp32Snapshot. | 267 * Process ID argument for CreateToolhelp32Snapshot. |
268 */ | 268 */ |
269 DWORD _id ; | 269 DWORD id ; |
270 | 270 |
271 /** | 271 /** |
272 * Handle to the underlying snapshot. | 272 * Handle to the underlying snapshot. |
273 */ | 273 */ |
274 Windows_Handle handle ; | 274 WindowsHandle handle ; |
275 | 275 |
276 /** | 276 /** |
277 * Buffer for reading a single process entry out of the snapshot. | 277 * Buffer for reading a single process entry out of the snapshot. |
278 * | 278 * |
279 * This buffer is constant insofar as the code outside this class is concerned
. | 279 * This buffer is constant insofar as the code outside this class is concerned
. |
280 * The accessor functions first() and next() return pointers to constant resul
t_type. | 280 * The accessor functions First() and Next() return pointers to constant Resul
tType. |
281 */ | 281 */ |
282 result_type buffer; | 282 ResultType buffer; |
283 | 283 |
284 /** | 284 /** |
285 * Copy constructor declared private and not defined. | 285 * Copy constructor declared private and not defined. |
286 * | 286 * |
287 * \par Implementation | 287 * \par Implementation |
288 * Add "= delete" for C++11. | 288 * Add "= delete" for C++11. |
289 */ | 289 */ |
290 Snapshot( const Snapshot & ) ; | 290 Snapshot( const Snapshot & ) ; |
291 | 291 |
292 /** | 292 /** |
293 * Copy assignment declared private and not defined. | 293 * Copy assignment declared private and not defined. |
294 * | 294 * |
295 * \par Implementation | 295 * \par Implementation |
296 * Add "= delete" for C++11. | 296 * Add "= delete" for C++11. |
297 */ | 297 */ |
298 Snapshot operator=( const Snapshot & ) ; | 298 Snapshot operator=( const Snapshot & ) ; |
299 | 299 |
300 /** | 300 /** |
301 * Create a new snapshot and return its handle. | 301 * Create a new snapshot and return its handle. |
302 */ | 302 */ |
303 Windows_Handle::handle_type make_handle() | 303 WindowsHandle::HandleType MakeHandle() |
304 { | 304 { |
305 Windows_Handle::handle_type h = ::CreateToolhelp32Snapshot( Traits::snapshot
_flags, _id ) ; | 305 WindowsHandle::HandleType h = ::CreateToolhelp32Snapshot( Traits::SnapshotFl
ags, id ) ; |
306 if ( h == INVALID_HANDLE_VALUE ) | 306 if ( h == INVALID_HANDLE_VALUE ) |
307 { | 307 { |
308 throw windows_api_error( "CreateToolhelp32Snapshot", "INVALID_HANDLE_VALUE
" ) ; | 308 throw WindowsApiError( "CreateToolhelp32Snapshot", "INVALID_HANDLE_VALUE"
) ; |
309 } | 309 } |
310 return h ; | 310 return h ; |
311 } | 311 } |
312 | 312 |
313 protected: | 313 protected: |
314 /** | 314 /** |
315 * Constructor takes a snapshot. | 315 * Constructor takes a snapshot. |
316 */ | 316 */ |
317 Snapshot( DWORD id ) | 317 Snapshot( DWORD id ) |
318 : _id( id ), handle( make_handle() ) | 318 : id( id ), handle( MakeHandle() ) |
319 { | 319 { |
320 // The various result types all define 'dwSize' with the same semantics. | 320 // The various result types all define 'dwSize' with the same semantics. |
321 buffer.dwSize = sizeof( result_type ) ; | 321 buffer.dwSize = sizeof( ResultType ) ; |
322 } | 322 } |
323 | 323 |
324 public: | 324 public: |
325 /** | 325 /** |
326 * Reconstruct the current instance with a new system snapshot. | 326 * Reconstruct the current instance with a new system snapshot. |
327 * | 327 * |
328 * This function uses reinitialization assignment in the Windows_Handle class, | 328 * This function uses reinitialization assignment in the WindowsHandle class, |
329 * which takes care of closing the old handle. | 329 * which takes care of closing the old handle. |
330 */ | 330 */ |
331 void Refresh() | 331 void Refresh() |
332 { | 332 { |
333 handle = make_handle(); | 333 handle = MakeHandle(); |
334 } | 334 } |
335 | 335 |
336 /** | 336 /** |
337 * Retrieve the first snapshot item into our member buffer. | 337 * Retrieve the first snapshot item into our member buffer. |
338 * | 338 * |
339 * \return | 339 * \return |
340 * Pointer to our member buffer if there was a first item | 340 * Pointer to our member buffer if there was a first item |
341 * 0 otherwise | 341 * 0 otherwise |
342 * | 342 * |
343 * \par Design Note | 343 * \par Design Note |
344 * There's no error handling in the present version of this function. | 344 * There's no error handling in the present version of this function. |
345 * In part that's because the underlying system call returns either true or
false, both of which are ordinarily valid answers. | 345 * In part that's because the underlying system call returns either true or
false, both of which are ordinarily valid answers. |
346 * The trouble is that a false return is overloaded. | 346 * The trouble is that a false return is overloaded. |
347 * It can mean either that (ordinary) there are no more items or (exceptiona
l) the snapshot did not contain the right kind of item. | 347 * It can mean either that (ordinary) there are no more items or (exceptiona
l) the snapshot did not contain the right kind of item. |
348 * GetLastError is no help here; it doesn't distinguish between these cases. | 348 * GetLastError is no help here; it doesn't distinguish between these cases. |
349 * The upshot is that we rely that our implementation calls the right functi
ons on the snapshot, | 349 * The upshot is that we rely that our implementation calls the right functi
ons on the snapshot, |
350 * and so we ignore the case where we've passed bad arguments to the syste
m call. | 350 * and so we ignore the case where we've passed bad arguments to the syste
m call. |
351 */ | 351 */ |
352 const result_type * first() | 352 const ResultType * First() |
353 { | 353 { |
354 return Traits::first(handle, &buffer) ? &buffer : 0; | 354 return Traits::First(handle, &buffer) ? &buffer : 0; |
355 } | 355 } |
356 | 356 |
357 /** | 357 /** |
358 * Retrieve the next snapshot item into our member buffer and return a pointer
to it. | 358 * Retrieve the next snapshot item into our member buffer and return a pointer
to it. |
359 * begin() must have been called first. | 359 * begin() must have been called first. |
360 * | 360 * |
361 * \return | 361 * \return |
362 * Pointer to our member buffer if there was a first item | 362 * Pointer to our member buffer if there was a first item |
363 * 0 otherwise | 363 * 0 otherwise |
364 * | 364 * |
365 * \par Design Note | 365 * \par Design Note |
366 * See the Design Note for first(); the same considerations apply here. | 366 * See the Design Note for First(); the same considerations apply here. |
367 */ | 367 */ |
368 const result_type * next() | 368 const ResultType * Next() |
369 { | 369 { |
370 return Traits::next(handle, &buffer) ? &buffer : 0; | 370 return Traits::Next(handle, &buffer) ? &buffer : 0; |
371 } | 371 } |
372 } ; | 372 } ; |
373 | 373 |
374 /** | 374 /** |
375 * A snapshot of all processes running on the system. | 375 * A snapshot of all processes running on the system. |
376 */ | 376 */ |
377 struct ProcessSnapshot | 377 struct ProcessSnapshot |
378 : public Snapshot< Process_Snapshot_Traits > | 378 : public Snapshot< ProcessSnapshotTraits > |
379 { | 379 { |
380 ProcessSnapshot() | 380 ProcessSnapshot() |
381 : Snapshot( 0 ) | 381 : Snapshot( 0 ) |
382 {} | 382 {} |
383 } ; | 383 } ; |
384 | 384 |
385 /** | 385 /** |
386 * A snapshot of all modules loaded for a given process. | 386 * A snapshot of all modules loaded for a given process. |
387 */ | 387 */ |
388 struct Module_Snapshot | 388 struct ModuleSnapshot |
389 : public Snapshot< Module_Snapshot_Traits > | 389 : public Snapshot< ModuleSnapshotTraits > |
390 { | 390 { |
391 Module_Snapshot( DWORD process_id ) | 391 ModuleSnapshot( DWORD processId ) |
392 : Snapshot( process_id ) | 392 : Snapshot( processId ) |
393 {} | 393 {} |
394 } ; | 394 } ; |
395 | 395 |
396 //------------------------------------------------------- | 396 //------------------------------------------------------- |
397 // initialize_process_list | 397 // InitializeProcessList |
398 //------------------------------------------------------- | 398 //------------------------------------------------------- |
399 /** | 399 /** |
400 * \tparam T The type into which a PROCESSENTRY32W struture is extracted. | 400 * \tparam T The type into which a PROCESSENTRY32W struture is extracted. |
401 * \tparam Admittance Function type for argument 'admit' | 401 * \tparam Admittance Function type for argument 'admit' |
402 * \tparam Extractor Function type for argument 'extract' | 402 * \tparam Extractor Function type for argument 'extract' |
403 * \param admit A unary predicate function class that determines what's included | 403 * \param admit A unary predicate function class that determines what's included |
404 * A process appears in the list only if the predicate returns true. | 404 * A process appears in the list only if the predicate returns true. |
405 * The use of this predicate is analogous to that in std::copy_if. | 405 * The use of this predicate is analogous to that in std::copy_if. |
406 * \param convert A conversion function that takes a PROCESSENTRY32W as input ar
gument and returns an element of type T. | 406 * \param convert A conversion function that takes a PROCESSENTRY32W as input ar
gument and returns an element of type T. |
407 */ | 407 */ |
408 template<class T, class Admittance, class Extractor> | 408 template<class T, class Admittance, class Extractor> |
409 void initialize_process_list(std::vector<T>& v, ProcessSnapshot &snap, Admittanc
e admit = Admittance(), Extractor extract = Extractor()) | 409 void InitializeProcessList(std::vector<T>& v, ProcessSnapshot &snap, Admittance
admit = Admittance(), Extractor extract = Extractor()) |
410 { | 410 { |
411 const PROCESSENTRY32W* p = snap.first(); | 411 const PROCESSENTRY32W* p = snap.First(); |
412 while (p != 0) | 412 while (p != 0) |
413 { | 413 { |
414 if (admit(*p )) | 414 if (admit(*p )) |
415 { | 415 { |
416 /* | 416 /* |
417 » * We don't have C++11 emplace_back, which can construct the element in p
lace. | 417 * We don't have C++11 emplace_back, which can construct the element in pl
ace. |
418 » * Instead, we copy the return value of the converter. | 418 * Instead, we copy the return value of the converter. |
419 » */ | 419 */ |
420 v.push_back(extract(*p)); | 420 v.push_back(extract(*p)); |
421 } | 421 } |
422 p = snap.next(); | 422 p = snap.Next(); |
423 } | 423 } |
424 }; | 424 }; |
425 | 425 |
426 //------------------------------------------------------- | 426 //------------------------------------------------------- |
427 // initialize_process_set | 427 // InitializeProcessSet |
428 //------------------------------------------------------- | 428 //------------------------------------------------------- |
429 /** | 429 /** |
430 * \tparam T The type into which a PROCESSENTRY32W struture is extracted. | 430 * \tparam T The type into which a PROCESSENTRY32W struture is extracted. |
431 * \tparam Admittance Function type for argument 'admit' | 431 * \tparam Admittance Function type for argument 'admit' |
432 * \tparam Extractor Function type for argument 'extract' | 432 * \tparam Extractor Function type for argument 'extract' |
433 * \param admit A unary predicate function class that determines what's included | 433 * \param admit A unary predicate function class that determines what's included |
434 * A process appears in the list only if the predicate returns true. | 434 * A process appears in the list only if the predicate returns true. |
435 * The use of this predicate is analogous to that in std::copy_if. | 435 * The use of this predicate is analogous to that in std::copy_if. |
436 * \param convert A conversion function that takes a PROCESSENTRY32W as input ar
gument and returns an element of type T. | 436 * \param convert A conversion function that takes a PROCESSENTRY32W as input ar
gument and returns an element of type T. |
437 */ | 437 */ |
438 template<class T, class Admittance, class Extractor> | 438 template<class T, class Admittance, class Extractor> |
439 void initialize_process_set(std::set< T > & set, ProcessSnapshot &snap, Admittan
ce admit = Admittance(), Extractor extract = Extractor()) | 439 void InitializeProcessSet(std::set< T > & set, ProcessSnapshot &snap, Admittance
admit = Admittance(), Extractor extract = Extractor()) |
440 { | 440 { |
441 const PROCESSENTRY32W* p = snap.first(); | 441 const PROCESSENTRY32W* p = snap.First(); |
442 while (p != 0) | 442 while (p != 0) |
443 { | 443 { |
444 if (admit(*p)) | 444 if (admit(*p)) |
445 { | 445 { |
446 set.insert(extract(*p)); | 446 set.insert(extract(*p)); |
447 } | 447 } |
448 p = snap.next(); | 448 p = snap.Next(); |
449 } | 449 } |
450 }; | 450 }; |
451 | 451 |
452 //------------------------------------------------------- | 452 //------------------------------------------------------- |
453 // enumerate_windows | 453 // EnumerateWindows |
454 //------------------------------------------------------- | 454 //------------------------------------------------------- |
455 | 455 |
456 /** | 456 /** |
457 * States of a window enumeration. | 457 * States of a window enumeration. |
458 */ | 458 */ |
459 typedef enum | 459 typedef enum |
460 { | 460 { |
461 started, ///< The iteration is currently running | 461 started, ///< The iteration is currently running |
462 normal, ///< Iteration terminated without error. | 462 normal, ///< Iteration terminated without error. |
463 early, ///< Callback returned false and terminated iteration early. | 463 early, ///< Callback returned false and terminated iteration early. |
464 exception, ///< Callback threw an exception and thereby terminated iterat
ion. | 464 exception, ///< Callback threw an exception and thereby terminated iterat
ion. |
465 error ///< Callback always return true but EnumWindows failed. | 465 error ///< Callback always return true but EnumWindows failed. |
466 } enumerate_windows_state ; | 466 } EnumerateWindowsState ; |
467 | 467 |
468 /** | 468 /** |
469 * Data to perform a window enumeration, shared between the main function and th
e callback function. | 469 * Data to perform a window enumeration, shared between the main function and th
e callback function. |
470 */ | 470 */ |
471 template< class F > | 471 template< class F > |
472 struct ew_data | 472 struct EWData |
473 { | 473 { |
474 /** | 474 /** |
475 * Function to be applied to each enumerated window. | 475 * Function to be applied to each enumerated window. |
476 */ | 476 */ |
477 F & f ; | 477 F & f ; |
478 | 478 |
479 /** | 479 /** |
480 * Completion status of the enumeration. | 480 * Completion status of the enumeration. |
481 */ | 481 */ |
482 enumerate_windows_state status ; | 482 EnumerateWindowsState status ; |
483 | 483 |
484 /** | 484 /** |
485 * An exception to be transported across the callback. | 485 * An exception to be transported across the callback. |
486 * | 486 * |
487 * The enumerator and the callback are not guaranteed to share a call stack, | 487 * The enumerator and the callback are not guaranteed to share a call stack, |
488 * nor need they even share compatible exception conventions, | 488 * nor need they even share compatible exception conventions, |
489 * and might not even be in the same thread. | 489 * and might not even be in the same thread. |
490 * Thus, if the applied function throws an exception, | 490 * Thus, if the applied function throws an exception, |
491 * we catch it in the callback and re-throw it in the enumerator. | 491 * we catch it in the callback and re-throw it in the enumerator. |
492 * This member holds such an exception. | 492 * This member holds such an exception. |
493 * | 493 * |
494 * This member holds an exception only if 'status' has the value 'exception'. | 494 * This member holds an exception only if 'status' has the value 'exception'. |
495 * Otherwise it's a null pointer. | 495 * Otherwise it's a null pointer. |
496 */ | 496 */ |
497 std::unique_ptr< std::exception > ee ; | 497 std::unique_ptr< std::exception > ee ; |
498 | 498 |
499 /** | 499 /** |
500 * Ordinary constructor. | 500 * Ordinary constructor. |
501 */ | 501 */ |
502 ew_data( F & f ) | 502 EWData( F & f ) |
503 : f( f ), status( started ) | 503 : f( f ), status( started ) |
504 {} | 504 {} |
505 } ; | 505 } ; |
506 | 506 |
507 /** | 507 /** |
508 * Callback function for EnumWindows. | 508 * Callback function for EnumWindows. |
509 * | 509 * |
510 * This function provides two standard behaviors. | 510 * This function provides two standard behaviors. |
511 * It records early termination of the enumeration, should that happen by the ap
plied function returning false. | 511 * It records early termination of the enumeration, should that happen by the ap
plied function returning false. |
512 * It captures any exception thrown for transport back to the enumerator. | 512 * It captures any exception thrown for transport back to the enumerator. |
513 */ | 513 */ |
514 template< class F > | 514 template< class F > |
515 BOOL CALLBACK enumeration_callback( HWND window, LPARAM x ) | 515 BOOL CALLBACK EnumerationCallback( HWND window, LPARAM x ) |
516 { | 516 { |
517 // LPARAM is always the same size as a pointer | 517 // LPARAM is always the same size as a pointer |
518 ew_data< F > * data = reinterpret_cast< ew_data< F > * >( x ) ; | 518 EWData< F > * data = reinterpret_cast< EWData< F > * >( x ) ; |
519 /* | 519 /* |
520 * Top-level try statement prevents exception from propagating back to system. | 520 * Top-level try statement prevents exception from propagating back to system. |
521 */ | 521 */ |
522 try | 522 try |
523 { | 523 { |
524 bool r = data -> f( window ) ; | 524 bool r = data -> f( window ) ; |
525 if ( ! r ) | 525 if ( ! r ) |
526 { | 526 { |
527 data -> status = early ; | 527 data -> status = early ; |
528 } | 528 } |
(...skipping 10 matching lines...) Expand all Loading... |
539 data -> ee = std::unique_ptr< std::exception >() ; | 539 data -> ee = std::unique_ptr< std::exception >() ; |
540 data -> status = exception ; | 540 data -> status = exception ; |
541 return FALSE ; | 541 return FALSE ; |
542 } | 542 } |
543 } | 543 } |
544 | 544 |
545 /** | 545 /** |
546 * Enumerate windows, applying a function to each one. | 546 * Enumerate windows, applying a function to each one. |
547 */ | 547 */ |
548 template< class F > | 548 template< class F > |
549 bool enumerate_windows( F f ) | 549 bool EnumerateWindows( F f ) |
550 { | 550 { |
551 ew_data< F > data( f ) ; | 551 EWData< F > data( f ) ; |
552 BOOL x( ::EnumWindows( enumeration_callback< F >, reinterpret_cast< LPARAM >(
& data ) ) ) ; | 552 BOOL x( ::EnumWindows( EnumerationCallback< F >, reinterpret_cast< LPARAM >( &
data ) ) ) ; |
553 bool r ; | 553 bool r ; |
554 if ( data.status != started ) | 554 if ( data.status != started ) |
555 { | 555 { |
556 // Assert status was changed within the callback | 556 // Assert status was changed within the callback |
557 if ( data.status == exception ) | 557 if ( data.status == exception ) |
558 { | 558 { |
559 /* | 559 /* |
560 * The callback threw an exception of some sort. | 560 * The callback threw an exception of some sort. |
561 * We forward it to the extent we are able. | 561 * We forward it to the extent we are able. |
562 */ | 562 */ |
(...skipping 26 matching lines...) Expand all Loading... |
589 } | 589 } |
590 | 590 |
591 //------------------------------------------------------- | 591 //------------------------------------------------------- |
592 // ProcessCloser | 592 // ProcessCloser |
593 //------------------------------------------------------- | 593 //------------------------------------------------------- |
594 class ProcessCloser | 594 class ProcessCloser |
595 { | 595 { |
596 /** | 596 /** |
597 * Set of process identifiers matching one of the executable names. | 597 * Set of process identifiers matching one of the executable names. |
598 */ | 598 */ |
599 std::set< DWORD > pid_set ; | 599 std::set< DWORD > pidSet ; |
600 | 600 |
601 /** | 601 /** |
602 * Set of executable names by which to filter. | 602 * Set of executable names by which to filter. |
603 * | 603 * |
604 * The argument of the filter constructor is a set by reference. | 604 * The argument of the filter constructor is a set by reference. |
605 * Since it does not make a copy for itself, we define it as a class member to
provide its allocation. | 605 * Since it does not make a copy for itself, we define it as a class member to
provide its allocation. |
606 */ | 606 */ |
607 file_name_set process_names ; | 607 FileNameSet processNames ; |
608 | 608 |
609 process_by_any_exe_not_immersive filter ; | 609 ProcessByAnyExeNotImmersive filter ; |
610 | 610 |
611 /** | 611 /** |
612 * Copy function object copies just the process ID. | 612 * Copy function object copies just the process ID. |
613 */ | 613 */ |
614 copy_PID copy ; | 614 CopyPID copy ; |
615 | 615 |
616 /** | 616 /** |
617 * Snapshot of running processes. | 617 * Snapshot of running processes. |
618 */ | 618 */ |
619 ProcessSnapshot & snapshot ; | 619 ProcessSnapshot & snapshot ; |
620 | 620 |
621 void update() | 621 void update() |
622 { | 622 { |
623 initialize_process_set( pid_set, snapshot, filter, copy ) ; | 623 InitializeProcessSet( pidSet, snapshot, filter, copy ) ; |
624 } ; | 624 } ; |
625 | 625 |
626 template< class F > | 626 template< class F > |
627 class only_our_processes | 627 class OnlyOurProcesses |
628 { | 628 { |
629 ProcessCloser & self ; | 629 ProcessCloser & self ; |
630 | 630 |
631 F f ; | 631 F f ; |
632 | 632 |
633 public: | 633 public: |
634 only_our_processes( ProcessCloser & self, F f ) | 634 OnlyOurProcesses( ProcessCloser & self, F f ) |
635 : f( f ), self( self ) | 635 : f( f ), self( self ) |
636 {} | 636 {} |
637 | 637 |
638 bool operator()( HWND window ) | 638 bool operator()( HWND window ) |
639 { | 639 { |
640 bool b ; | 640 bool b ; |
641 try | 641 try |
642 { | 642 { |
643 » b = self.contains( creator_process( window ) ) ; | 643 b = self.Contains( CreatorProcess( window ) ) ; |
644 } | 644 } |
645 catch ( ... ) | 645 catch ( ... ) |
646 { | 646 { |
647 » // ignore window handles that are no longer valid | 647 // ignore window handles that are no longer valid |
648 » return true ; | 648 return true ; |
649 } | 649 } |
650 if ( ! b ) | 650 if ( ! b ) |
651 { | 651 { |
652 » // Assert the process that created the window is not in our pid_set | 652 // Assert the process that created the window is not in our pidSet |
653 » return true ; | 653 return true ; |
654 } | 654 } |
655 return f( window ) ; | 655 return f( window ) ; |
656 } | 656 } |
657 } ; | 657 } ; |
658 | 658 |
659 public: | 659 public: |
660 template <size_t n_file_names> | 660 template <size_t nFileNames> |
661 ProcessCloser(ProcessSnapshot & snapshot, const wchar_t * (&file_name_list)[n_
file_names]) | 661 ProcessCloser(ProcessSnapshot & snapshot, const wchar_t * (&fileNameList)[nFil
eNames]) |
662 : snapshot(snapshot), process_names(file_name_list), filter(process_names) | 662 : snapshot(snapshot), processNames(fileNameList), filter(processNames) |
663 { | 663 { |
664 update() ; | 664 update() ; |
665 } | 665 } |
666 | 666 |
667 /** | 667 /** |
668 * Refresh our state to match the snapshot state. | 668 * Refresh our state to match the snapshot state. |
669 */ | 669 */ |
670 void Refresh() | 670 void Refresh() |
671 { | 671 { |
672 pid_set.clear() ; | 672 pidSet.clear() ; |
673 update() ; | 673 update() ; |
674 } | 674 } |
675 | 675 |
676 bool IsRunning() { return ! pid_set.empty() ; } ; | 676 bool IsRunning() { return ! pidSet.empty() ; } ; |
677 | 677 |
678 bool contains( DWORD pid ) const { return pid_set.find( pid ) != pid_set.end()
; } ; | 678 bool Contains( DWORD pid ) const { return pidSet.find( pid ) != pidSet.end() ;
} ; |
679 | 679 |
680 template< class F > | 680 template< class F > |
681 bool iterate_our_windows( F f ) | 681 bool IterateOurWindows( F f ) |
682 { | 682 { |
683 only_our_processes< F > g( * this, f ) ; | 683 OnlyOurProcesses< F > g( * this, f ) ; |
684 return enumerate_windows( g ) ; | 684 return EnumerateWindows( g ) ; |
685 } | 685 } |
686 | 686 |
687 /* | 687 /* |
688 * Shut down every process in the pid_set. | 688 * Shut down every process in the pidSet. |
689 */ | 689 */ |
690 bool ShutDown(ImmediateSession& session); | 690 bool ShutDown(ImmediateSession& session); |
691 | 691 |
692 } ; | 692 } ; |
693 | 693 |
694 #endif | 694 #endif |
OLD | NEW |