Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: installer/src/installer-lib/process.h

Issue 5665210325008384: Combine snapshot classes into a template class (Closed)
Patch Set: Created April 3, 2014, 4:51 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « installer/src/installer-lib/handle.h ('k') | installer/src/installer-lib/process.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "handle.h" 9 #include "handle.h"
9 10
10 #include <string> 11 #include <string>
11 #include <cctype> 12 #include <cctype>
12 #include <vector> 13 #include <vector>
13 #include <set> 14 #include <set>
14 #include <algorithm> 15 #include <algorithm>
15 #include <memory> 16 #include <memory>
16 17
17 #include <Windows.h> 18 #include <Windows.h>
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 continue ; 57 continue ;
57 } 58 }
58 return ( l1 < l2 ) ? -1 : +1 ; 59 return ( l1 < l2 ) ? -1 : +1 ;
59 } 60 }
60 return 0 ; 61 return 0 ;
61 } 62 }
62 } ; 63 } ;
63 64
64 typedef std::basic_string< wchar_t, ci_traits< wchar_t > > wstring_ci ; 65 typedef std::basic_string< wchar_t, ci_traits< wchar_t > > wstring_ci ;
65 66
66
67 //------------------------------------------------------- 67 //-------------------------------------------------------
68 // file_name_set: case-insensitive wide-string set 68 // file_name_set: case-insensitive wide-string set
69 //------------------------------------------------------- 69 //-------------------------------------------------------
70 struct file_name_set 70 struct file_name_set
71 : public std::set< wstring_ci > 71 : public std::set< wstring_ci >
72 { 72 {
73 /** 73 /**
74 * Empty set constructor. 74 * Empty set constructor.
75 */ 75 */
76 file_name_set() 76 file_name_set()
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 * 160 *
161 * \sa 161 * \sa
162 * MSDN [GetWindowThreadProcessId function](http://msdn.microsoft.com/en-us/li brary/windows/desktop/ms633522%28v=vs.85%29.aspx) 162 * MSDN [GetWindowThreadProcessId function](http://msdn.microsoft.com/en-us/li brary/windows/desktop/ms633522%28v=vs.85%29.aspx)
163 */ 163 */
164 DWORD creator_process( HWND window ) ; 164 DWORD creator_process( HWND window ) ;
165 165
166 //------------------------------------------------------- 166 //-------------------------------------------------------
167 // Snapshot 167 // Snapshot
168 //------------------------------------------------------- 168 //-------------------------------------------------------
169 /** 169 /**
170 * A snapshot of all the processes running on the system. 170 * Traits class for snapshots of all processes on the system.
171 */
172 struct Process_Snapshot_Traits
173 {
174 /**
175 * The type of the data resulting from CreateToolhelp32Snapshot.
176 */
177 typedef PROCESSENTRY32W result_type ;
178
179 /**
180 * Flags used to call CreateToolhelp32Snapshot.
181 */
182 const static DWORD snapshot_flags = TH32CS_SNAPPROCESS ;
183
184 /**
185 * Wrapper for 'first' function for processes
186 */
187 static BOOL first( HANDLE arg1, LPPROCESSENTRY32 arg2 )
188 {
189 return ::Process32First( arg1, arg2 ) ;
190 }
191
192 /**
193 * Wrapper for 'next' function for processes
194 */
195 static BOOL next( HANDLE arg1, LPPROCESSENTRY32 arg2 )
196 {
197 return ::Process32Next( arg1, arg2 ) ;
198 }
199 } ;
200
201 /**
202 * Traits class for snapshots of all modules loaded by a process.
203 */
204 struct Module_Snapshot_Traits
205 {
206 /**
207 * The type of the data resulting from CreateToolhelp32Snapshot.
208 */
209 typedef MODULEENTRY32W result_type ;
210
211 /**
212 * Flags used to call CreateToolhelp32Snapshot.
213 */
214 const static DWORD snapshot_flags = TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32 ;
215
216 /**
217 * Wrapper for 'first' function for modules
218 */
219 static BOOL first( HANDLE arg1, LPMODULEENTRY32 arg2 )
220 {
221 return ::Module32First( arg1, arg2 ) ;
222 }
223
224 /**
225 * Wrapper for 'next' function for modules
226 */
227 static BOOL next( HANDLE arg1, LPMODULEENTRY32 arg2 )
228 {
229 return ::Module32Next( arg1, arg2 ) ;
230 }
231 } ;
232
233 /**
234 * A snapshot wrapping the results of CreateToolhelp32Snapshot system call.
171 * 235 *
172 * Unfortunately, we cannot provide standard iterator for this class. 236 * Unfortunately, we cannot provide standard iterator for this class.
173 * Standard iterators must be copy-constructible, which entails the possibility of multiple, coexisting iteration states. 237 * Standard iterators must be copy-constructible, which entails the possibility of multiple, coexisting iteration states.
174 * The iteration behavior provided by Process32First and Process32Next relies up on state held within the snapshot itself. 238 * The iteration behavior provided by Process32First and Process32Next relies up on state held within the snapshot itself.
175 * Thus, there can be only one iterator at a time for the snapshot. 239 * Thus, there can be only one iterator at a time for the snapshot.
176 * The two requirements are not simultaneously satisfiable. 240 * The two requirements are not simultaneously satisfiable.
177 * 241 *
178 * As a substitute for a standard iterator, we provide a few functions mimicking the pattern of standard iterators. 242 * Instead of a standard iterator, we provide a first() and next() functions wra pping the corresponding system calls.
179 * This class acts as its own iterator.
180 * The pointer returned is either one to the member variable "process" or else 0 .
181 * 243 *
182 * \par Implementation 244 * \par Implementation
183 * 245 *
184 * - MSDN [CreateToolhelp32Snapshot function](http://msdn.microsoft.com/en-us/li brary/windows/desktop/ms682489%28v=vs.85%29.aspx) 246 * - MSDN [CreateToolhelp32Snapshot function](http://msdn.microsoft.com/en-us/li brary/windows/desktop/ms682489%28v=vs.85%29.aspx)
185 * - MSDN [Process32First function](http://msdn.microsoft.com/en-us/library/wind ows/desktop/ms684834%28v=vs.85%29.aspx) 247 * - MSDN [Process32First function](http://msdn.microsoft.com/en-us/library/wind ows/desktop/ms684834%28v=vs.85%29.aspx)
186 * - MSDN [Process32Next function](http://msdn.microsoft.com/en-us/library/windo ws/desktop/ms684836%28v=vs.85%29.aspx) 248 * - MSDN [Process32Next function](http://msdn.microsoft.com/en-us/library/windo ws/desktop/ms684836%28v=vs.85%29.aspx)
187 * - MSDN [PROCESSENTRY32 structure](http://msdn.microsoft.com/en-us/library/win dows/desktop/ms684839%28v=vs.85%29.aspx) 249 * - MSDN [PROCESSENTRY32 structure](http://msdn.microsoft.com/en-us/library/win dows/desktop/ms684839%28v=vs.85%29.aspx)
250 *
251 * \par Design Note
252 * The traits class defines first() and next() functions instead of using func tion pointers.
253 * This arises from a limitation in the compiler.
254 * The system calls are declared 'WINAPI', which is a compiler-specific extens ion.
255 * That extension, however, does not go far enough to be able to declare a poi nter with the same modifier.
256 * Hence the system calls must be called directly; they are wrapped in the tra it functions.
188 */ 257 */
258 template< class Traits >
189 class Snapshot 259 class Snapshot
190 { 260 {
261 public:
191 /** 262 /**
192 * Handle to the process snapshot. 263 * Expose the result type from the traits class as our own.
264 */
265 typedef typename Traits::result_type result_type ;
266
267 private:
268 /**
269 * Process ID argument for CreateToolhelp32Snapshot.
270 */
271 DWORD _id ;
272
273 /**
274 * Handle to the underlying snapshot.
193 */ 275 */
194 Windows_Handle handle ; 276 Windows_Handle handle ;
195 277
196 /** 278 /**
197 * Buffer for reading a single process entry out of the snapshot. 279 * Buffer for reading a single process entry out of the snapshot.
280 *
281 * This buffer is constant insofar as the code outside this class is concerned .
282 * The accessor functions first() and next() return pointers to constant resul t_type.
198 */ 283 */
199 PROCESSENTRY32W process; 284 result_type buffer;
200 285
201 /** 286 /**
202 * Copy constructor declared private and not defined. 287 * Copy constructor declared private and not defined.
203 * 288 *
204 * \par Implementation 289 * \par Implementation
205 * Add "= delete" for C++11. 290 * Add "= delete" for C++11.
206 */ 291 */
207 Snapshot( const Snapshot & ) ; 292 Snapshot( const Snapshot & ) ;
208 293
209 /** 294 /**
210 * Copy assignment declared private and not defined. 295 * Copy assignment declared private and not defined.
211 * 296 *
212 * \par Implementation 297 * \par Implementation
213 * Add "= delete" for C++11. 298 * Add "= delete" for C++11.
214 */ 299 */
215 Snapshot operator=( const Snapshot & ) ; 300 Snapshot operator=( const Snapshot & ) ;
216 301
302 /**
303 * Create a new snapshot and return its handle.
304 */
305 Windows_Handle::handle_type make_handle()
306 {
307 Windows_Handle::handle_type h = ::CreateToolhelp32Snapshot( Traits::snapshot _flags, _id ) ;
308 if ( h == INVALID_HANDLE_VALUE )
309 {
310 throw windows_api_error( "CreateToolhelp32Snapshot", "INVALID_HANDLE_VALUE " ) ;
311 }
312 return h ;
313 }
314
315 protected:
316 /**
317 * Constructor takes a snapshot.
318 */
319 Snapshot( DWORD id )
320 : _id( id ), handle( make_handle() )
321 {
322 // The various result types all define 'dwSize' with the same semantics.
323 buffer.dwSize = sizeof( result_type ) ;
324 }
217 325
218 public: 326 public:
219 /** 327 /**
220 * Default constructor takes the snapshot. 328 * Reconstruct the current instance with a new system snapshot.
329 *
330 * This function uses reinitialization assignment in the Windows_Handle class,
331 * which takes care of closing the old handle.
221 */ 332 */
222 Snapshot() ; 333 void refresh()
334 {
335 handle = make_handle();
336 }
223 337
224 /** 338 /**
225 * Reconstruct the current instance with a new system snapshot. 339 * Retrieve the first snapshot item into our member buffer.
340 *
341 * \return
342 * Pointer to our member buffer if there was a first item
343 * 0 otherwise
344 *
345 * \par Design Note
346 * There's no error handling in the present version of this function.
347 * In part that's because the underlying system call returns either true or false, both of which are ordinarily valid answers.
348 * The trouble is that a false return is overloaded.
349 * It can mean either that (ordinary) there are no more items or (exceptiona l) the snapshot did not contain the right kind of item.
350 * GetLastError is no help here; it doesn't distinguish between these cases.
351 * The upshot is that we rely that our implementation calls the right functi ons on the snapshot,
352 * and so we ignore the case where we've passed bad arguments to the syste m call.
226 */ 353 */
227 void refresh() ; 354 const result_type * first()
355 {
356 return Traits::first(handle, &buffer) ? &buffer : 0;
357 }
228 358
229 /** 359 /**
230 * Return a pointer to the first process in the snapshot. 360 * Retrieve the next snapshot item into our member buffer and return a pointer to it.
361 * begin() must have been called first.
362 *
363 * \return
364 * Pointer to our member buffer if there was a first item
365 * 0 otherwise
366 *
367 * \par Design Note
368 * See the Design Note for first(); the same considerations apply here.
231 */ 369 */
232 PROCESSENTRY32W * first() ; 370 const result_type * next()
233 371 {
234 /** 372 return Traits::next(handle, &buffer) ? &buffer : 0;
235 * Return a pointer to the next process in the snapshot. 373 }
236 * begin() must have been called first.
237 */
238 PROCESSENTRY32W * next() ;
239 } ; 374 } ;
240 375
241 class ModulesSnapshot 376 /**
377 * A snapshot of all processes running on the system.
378 */
379 struct Process_Snapshot
380 : public Snapshot< Process_Snapshot_Traits >
242 { 381 {
243 /** 382 Process_Snapshot()
244 * Handle to the process snapshot. 383 : Snapshot( 0 )
245 */ 384 {}
246 Windows_Handle handle; 385 } ;
247 386
248 /** 387 /**
249 * Buffer for reading a single module entry out of the snapshot. 388 * A snapshot of all modules loaded for a given process.
250 */ 389 */
251 MODULEENTRY32W module; 390 struct Module_Snapshot
252 391 : public Snapshot< Module_Snapshot_Traits >
253 /** 392 {
254 * Copy constructor declared private and not defined. 393 Module_Snapshot( DWORD process_id )
255 * 394 : Snapshot( process_id )
256 * \par Implementation 395 {}
257 * Add "= delete" for C++11. 396 } ;
258 */
259 ModulesSnapshot(const ModulesSnapshot&);
260
261 /**
262 * Copy assignment declared private and not defined.
263 *
264 * \par Implementation
265 * Add "= delete" for C++11.
266 */
267 ModulesSnapshot operator=(const ModulesSnapshot&);
268
269
270 public:
271 /**
272 * Default constructor takes the snapshot.
273 */
274 ModulesSnapshot(DWORD processId);
275
276 /**
277 * Return a pointer to the first process in the snapshot.
278 */
279 MODULEENTRY32W* first();
280
281 /**
282 * Return a pointer to the next process in the snapshot.
283 * begin() must have been called first.
284 */
285 MODULEENTRY32W* next();
286 };
287
288 397
289 //------------------------------------------------------- 398 //-------------------------------------------------------
290 // initialize_process_list 399 // initialize_process_list
291 //------------------------------------------------------- 400 //-------------------------------------------------------
292 /** 401 /**
293 * \tparam T The type into which a PROCESSENTRY32W struture is extracted. 402 * \tparam T The type into which a PROCESSENTRY32W struture is extracted.
294 * \tparam Admittance Function type for argument 'admit' 403 * \tparam Admittance Function type for argument 'admit'
295 * \tparam Extractor Function type for argument 'extract' 404 * \tparam Extractor Function type for argument 'extract'
296 * \param admit A unary predicate function class that determines what's included 405 * \param admit A unary predicate function class that determines what's included
297 * A process appears in the list only if the predicate returns true. 406 * A process appears in the list only if the predicate returns true.
298 * The use of this predicate is analogous to that in std::copy_if. 407 * The use of this predicate is analogous to that in std::copy_if.
299 * \param convert A conversion function that takes a PROCESSENTRY32W as input ar gument and returns an element of type T. 408 * \param convert A conversion function that takes a PROCESSENTRY32W as input ar gument and returns an element of type T.
300 */ 409 */
301 template<class T, class Admittance, class Extractor> 410 template<class T, class Admittance, class Extractor>
302 void initialize_process_list(std::vector<T>& v, Snapshot& snap, Admittance admit = Admittance(), Extractor extract = Extractor()) 411 void initialize_process_list(std::vector<T>& v, Process_Snapshot &snap, Admittan ce admit = Admittance(), Extractor extract = Extractor())
303 { 412 {
304 PROCESSENTRY32W* p = snap.first(); 413 const PROCESSENTRY32W* p = snap.first();
305 while (p != NULL) 414 while (p != 0)
306 { 415 {
307 if (admit(*p )) 416 if (admit(*p ))
308 { 417 {
309 /* 418 /*
310 * We don't have C++11 emplace_back, which can construct the element in p lace. 419 * We don't have C++11 emplace_back, which can construct the element in p lace.
311 * Instead, we copy the return value of the converter. 420 * Instead, we copy the return value of the converter.
312 */ 421 */
313 v.push_back(extract(*p)); 422 v.push_back(extract(*p));
314 } 423 }
315 p = snap.next(); 424 p = snap.next();
316 } 425 }
317 }; 426 };
318 427
319 //------------------------------------------------------- 428 //-------------------------------------------------------
320 // initialize_process_set 429 // initialize_process_set
321 //------------------------------------------------------- 430 //-------------------------------------------------------
322 /** 431 /**
323 * \tparam T The type into which a PROCESSENTRY32W struture is extracted. 432 * \tparam T The type into which a PROCESSENTRY32W struture is extracted.
324 * \tparam Admittance Function type for argument 'admit' 433 * \tparam Admittance Function type for argument 'admit'
325 * \tparam Extractor Function type for argument 'extract' 434 * \tparam Extractor Function type for argument 'extract'
326 * \param admit A unary predicate function class that determines what's included 435 * \param admit A unary predicate function class that determines what's included
327 * A process appears in the list only if the predicate returns true. 436 * A process appears in the list only if the predicate returns true.
328 * The use of this predicate is analogous to that in std::copy_if. 437 * The use of this predicate is analogous to that in std::copy_if.
329 * \param convert A conversion function that takes a PROCESSENTRY32W as input ar gument and returns an element of type T. 438 * \param convert A conversion function that takes a PROCESSENTRY32W as input ar gument and returns an element of type T.
330 */ 439 */
331 template<class T, class Admittance, class Extractor> 440 template<class T, class Admittance, class Extractor>
332 void initialize_process_set(std::set< T > & set, Snapshot& snap, Admittance admi t = Admittance(), Extractor extract = Extractor()) 441 void initialize_process_set(std::set< T > & set, Process_Snapshot &snap, Admitta nce admit = Admittance(), Extractor extract = Extractor())
333 { 442 {
334 PROCESSENTRY32W* p = snap.first(); 443 const PROCESSENTRY32W* p = snap.first();
335 while (p != NULL) 444 while (p != 0)
336 { 445 {
337 if (admit(*p)) 446 if (admit(*p))
338 { 447 {
339 set.insert(extract(*p)); 448 set.insert(extract(*p));
340 } 449 }
341 p = snap.next(); 450 p = snap.next();
342 } 451 }
343 }; 452 };
344 453
345 //------------------------------------------------------- 454 //-------------------------------------------------------
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 process_by_any_exe_with_any_module filter ; 616 process_by_any_exe_with_any_module filter ;
508 617
509 /** 618 /**
510 * Copy function object copies just the process ID. 619 * Copy function object copies just the process ID.
511 */ 620 */
512 copy_PID copy ; 621 copy_PID copy ;
513 622
514 /** 623 /**
515 * Snapshot of running processes. 624 * Snapshot of running processes.
516 */ 625 */
517 Snapshot & snapshot ; 626 Process_Snapshot & snapshot ;
518 627
519 void update() 628 void update()
520 { 629 {
521 initialize_process_set( pid_set, snapshot, filter, copy ) ; 630 initialize_process_set( pid_set, snapshot, filter, copy ) ;
522 } ; 631 } ;
523 632
524 template< class F > 633 template< class F >
525 class only_our_processes 634 class only_our_processes
526 { 635 {
527 Process_Closer & self ; 636 Process_Closer & self ;
(...skipping 21 matching lines...) Expand all
549 { 658 {
550 // Assert the process that created the window is not in our pid_set 659 // Assert the process that created the window is not in our pid_set
551 return true ; 660 return true ;
552 } 661 }
553 return f( window ) ; 662 return f( window ) ;
554 } 663 }
555 } ; 664 } ;
556 665
557 public: 666 public:
558 template <size_t n_file_names, size_t n_module_names> 667 template <size_t n_file_names, size_t n_module_names>
559 Process_Closer(Snapshot & snapshot, const wchar_t* (&file_name_list)[n_file_na mes], const wchar_t* (&module_name_list)[n_module_names]) 668 Process_Closer(Process_Snapshot & snapshot, const wchar_t* (&file_name_list)[n _file_names], const wchar_t* (&module_name_list)[n_module_names])
560 : snapshot(snapshot), process_names(file_name_list), module_names(module_nam e_list), filter(process_names, module_names) 669 : snapshot(snapshot), process_names(file_name_list), module_names(module_nam e_list), filter(process_names, module_names)
561 { 670 {
562 update() ; 671 update() ;
563 } 672 }
564 template <size_t n_file_names> 673 template <size_t n_file_names>
565 Process_Closer(Snapshot & snapshot, const wchar_t * (&file_name_list)[n_file_n ames]) 674 Process_Closer(Process_Snapshot & snapshot, const wchar_t * (&file_name_list)[ n_file_names])
566 : snapshot(snapshot), process_names(file_name_list), module_names(), filter( process_names, module_names) 675 : snapshot(snapshot), process_names(file_name_list), module_names(), filter( process_names, module_names)
567 { 676 {
568 update() ; 677 update() ;
569 } 678 }
570 679
571 /** 680 /**
572 * Refresh our state to match the snapshot state. 681 * Refresh our state to match the snapshot state.
573 */ 682 */
574 void refresh() 683 void refresh()
575 { 684 {
(...skipping 13 matching lines...) Expand all
589 } 698 }
590 699
591 /* 700 /*
592 * Shut down every process in the pid_set. 701 * Shut down every process in the pid_set.
593 */ 702 */
594 bool shut_down() ; 703 bool shut_down() ;
595 704
596 } ; 705 } ;
597 706
598 #endif 707 #endif
OLDNEW
« no previous file with comments | « installer/src/installer-lib/handle.h ('k') | installer/src/installer-lib/process.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld