Left: | ||
Right: |
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 "handle.h" | 8 #include "handle.h" |
9 | 9 |
10 #include <string> | |
11 #include <cctype> | |
10 #include <vector> | 12 #include <vector> |
11 #include <set> | 13 #include <set> |
12 #include <algorithm> | 14 #include <algorithm> |
13 #include <memory> | 15 #include <memory> |
14 | 16 |
15 #include <Windows.h> | 17 #include <Windows.h> |
16 #include <TlHelp32.h> | 18 #include <TlHelp32.h> |
17 | 19 |
20 //------------------------------------------------------- | |
21 // wstring_ci: case-insensitive wide string | |
22 //------------------------------------------------------- | |
18 | 23 |
19 //------------------------------------------------------- | 24 /** |
20 // exe_name_set: case-insensitive wide-string set | 25 * Traits class for case-insensitive strings. |
21 //------------------------------------------------------- | 26 */ |
22 int wcscmpi( const wchar_t * s1, const wchar_t * s2 ) ; | 27 template< class T > |
Wladimir Palant
2014/03/31 05:58:35
Style nit: excessive whitespace. There should be n
| |
28 struct ci_traits: std::char_traits< T > | |
29 { | |
30 static bool eq( T c1, T c2 ) | |
31 { | |
32 return std::tolower( c1 ) == std::tolower( c2 ) ; | |
33 } | |
23 | 34 |
24 struct exe_name | 35 static bool lt( T c1, T c2 ) |
25 { | 36 { |
37 return std::tolower( c1 ) < std::tolower( c2 ) ; | |
38 } | |
39 | |
26 /** | 40 /** |
27 * Pointer to wide-character string, which is supposed to be null-terminated. | 41 * Trait comparison function. |
42 * | |
43 * Note that this is not a comparison of C-style strings. | |
44 * In particular, there's no concern over null characters '\0'. | |
45 * The argument 'n' is the minimum length of the two strings being compared. | |
46 * We may assume that the intervals p1[0..n) and p2[0..n) are both valid subst rings. | |
28 */ | 47 */ |
29 const wchar_t * name ; | 48 static int compare( const T * p1, const T * p2, size_t n ) |
Oleksandr
2014/03/31 07:03:03
Once again, I think it would be much easier to jus
Wladimir Palant
2014/03/31 09:33:34
That's the standard way of doing this actually. Wh
Eric
2014/03/31 14:13:54
It would work, obviously, since that's what we wer
| |
30 | |
31 exe_name( const wchar_t * name ) : name( name ) {} ; | |
32 } ; | |
33 | |
34 template <> | |
35 struct std::less< exe_name > | |
36 : std::binary_function< exe_name, exe_name, bool > | |
37 { | |
38 bool operator()( const exe_name & a, const exe_name & b ) const | |
39 { | 49 { |
40 return wcscmpi( a.name, b.name ) < 0 ; | 50 while ( n-- > 0 ) |
Wladimir Palant
2014/03/31 05:58:35
Style nit: excessive whitespace. There should be n
| |
51 { | |
52 T l1 = std::tolower( * p1 ++ ) ; | |
53 T l2 = std::tolower( * p2 ++ ) ; | |
Wladimir Palant
2014/03/31 05:58:35
Style nit: excessive whitespace. There should be n
| |
54 if ( l1 == l2 ) | |
55 { | |
56 » continue ; | |
Wladimir Palant
2014/03/31 09:33:34
Didn't notice it originally - please use spaces fo
Eric
2014/03/31 14:13:54
That's Visual Studio acting up again. I thought I
| |
57 } | |
58 return ( l1 < l2 ) ? -1 : +1 ; | |
59 } | |
60 return 0 ; | |
41 } | 61 } |
42 } ; | 62 } ; |
43 | 63 |
44 struct exe_name_set | 64 typedef std::basic_string< wchar_t, ci_traits< wchar_t > > wstring_ci ; |
45 : public std::set< exe_name > | 65 |
66 | |
67 //------------------------------------------------------- | |
68 // file_name_set: case-insensitive wide-string set | |
69 //------------------------------------------------------- | |
70 struct file_name_set | |
71 : public std::set< wstring_ci > | |
46 { | 72 { |
47 exe_name_set( const wchar_t * exe_name_list[], size_t n_exe_names ) | 73 /** |
74 * Constructor initialization from an array. | |
75 */ | |
76 template< size_t n_file_names > | |
77 file_name_set( const wchar_t * ( & file_name_list )[ n_file_names ] ) | |
Wladimir Palant
2014/03/31 05:58:35
Style nit: excessive whitespace. There should be n
Wladimir Palant
2014/03/31 05:58:35
We might want to have a non-templated version of t
Eric
2014/03/31 14:13:54
We're also getting an empty-set constructor for th
| |
48 { | 78 { |
49 for ( unsigned int j = 0 ; j < n_exe_names ; ++ j ) | 79 for ( unsigned int j = 0 ; j < n_file_names ; ++ j ) |
50 { | 80 { |
51 insert( exe_name( exe_name_list[ j ] ) ) ; | 81 insert( wstring_ci( file_name_list[ j ] ) ) ; |
52 } | 82 } |
53 } | 83 } |
84 | |
85 /** | |
86 * Empty set constructor has no arguments. | |
87 */ | |
88 file_name_set() | |
89 {} | |
Wladimir Palant
2014/03/31 05:58:35
Style nit: closing bracket should go on a new line
| |
54 } ; | 90 } ; |
55 | 91 |
56 //------------------------------------------------------- | 92 //------------------------------------------------------- |
57 //------------------------------------------------------- | 93 //------------------------------------------------------- |
58 /** | 94 /** |
59 * Filter by process name. Comparison is case-insensitive. | 95 * Filter by process name. Comparison is case-insensitive. |
60 */ | 96 */ |
61 class process_by_any_exe_name_CI | 97 class process_by_any_exe_name_CI |
62 : public std::unary_function< PROCESSENTRY32W, bool > | 98 : public std::unary_function< PROCESSENTRY32W, bool > |
63 { | 99 { |
64 const exe_name_set & names ; | 100 const file_name_set & names ; |
Wladimir Palant
2014/03/31 05:58:35
Please don't use references as class members, crea
Eric
2014/03/31 14:13:54
In this case, we can. This class is entirely subor
| |
65 public: | 101 public: |
66 bool operator()( const PROCESSENTRY32W & ) ; | 102 bool operator()( const PROCESSENTRY32W & process ) |
67 process_by_any_exe_name_CI( const exe_name_set & names ) | 103 { |
104 return names.find( process.szExeFile ) != names.end() ; | |
105 } | |
Wladimir Palant
2014/03/31 05:58:35
Nothing wrong with keeping implementations out of
Eric
2014/03/31 14:13:54
No, there's not. There's nothing wrong with puttin
| |
106 | |
107 process_by_any_exe_name_CI( const file_name_set & names ) | |
68 : names( names ) | 108 : names( names ) |
69 {} | 109 {} |
70 } ; | 110 } ; |
71 | 111 |
72 //------------------------------------------------------- | 112 //------------------------------------------------------- |
73 // Process utility functions. | 113 // Process utility functions. |
74 //------------------------------------------------------- | 114 //------------------------------------------------------- |
75 /** | 115 /** |
76 * A promiscuous filter admits everything. | 116 * A promiscuous filter admits everything. |
77 */ | 117 */ |
78 struct every_process | 118 struct every_process |
79 : public std::unary_function< PROCESSENTRY32W, bool > | 119 : public std::unary_function< PROCESSENTRY32W, bool > |
80 { | 120 { |
81 bool operator()( const PROCESSENTRY32W & ) { return true ; } ; | 121 bool operator()( const PROCESSENTRY32W & ) { return true ; } ; |
82 } ; | 122 } ; |
83 | 123 |
84 /** | 124 /** |
85 * Filter by process name. Comparison is case-insensitive. | |
86 */ | |
87 class process_by_name_CI | |
88 : public std::unary_function< PROCESSENTRY32W, bool > | |
89 { | |
90 const wchar_t * name ; | |
91 const size_t length ; | |
92 process_by_name_CI() ; | |
93 public: | |
94 bool operator()( const PROCESSENTRY32W & ) ; | |
95 process_by_name_CI( const wchar_t * name ) ; | |
96 } ; | |
97 | |
98 /** | |
99 * Extractor that copies the entire process structure. | 125 * Extractor that copies the entire process structure. |
100 */ | 126 */ |
101 struct copy_all | 127 struct copy_all |
102 : public std::unary_function< PROCESSENTRY32W, PROCESSENTRY32W > | 128 : public std::unary_function< PROCESSENTRY32W, PROCESSENTRY32W > |
103 { | 129 { |
104 PROCESSENTRY32W operator()( const PROCESSENTRY32W & process ) { return process ; } | 130 PROCESSENTRY32W operator()( const PROCESSENTRY32W & process ) { return process ; } |
105 } ; | 131 } ; |
106 | 132 |
107 /** | 133 /** |
108 * Extractor that copies only the PID. | 134 * Extractor that copies only the PID. |
109 */ | 135 */ |
110 struct copy_PID | 136 struct copy_PID |
111 : public std::unary_function< PROCESSENTRY32W, DWORD > | 137 : public std::unary_function< PROCESSENTRY32W, DWORD > |
112 { | 138 { |
113 inline DWORD operator()( const PROCESSENTRY32W & process ) { return process.th 32ProcessID ; } | 139 inline DWORD operator()( const PROCESSENTRY32W & process ) { return process.th 32ProcessID ; } |
114 } ; | 140 } ; |
115 | 141 |
116 /** | 142 /** |
117 * Case-insensitive wide-character C-style string comparison, fixed-length | |
118 */ | |
119 int wcsncmpi( const wchar_t * a, const wchar_t * b, unsigned int length ) ; | |
120 | |
121 /** | |
122 * Retrieve the process ID that created a window. | 143 * Retrieve the process ID that created a window. |
123 * | 144 * |
124 * Wrapper around GetWindowThreadProcessId. | 145 * Wrapper around GetWindowThreadProcessId. |
125 * Converts an error return from the system call into an exception. | 146 * Converts an error return from the system call into an exception. |
126 * The system call can also retrieve the creating thread; we ignore it. | 147 * The system call can also retrieve the creating thread; we ignore it. |
127 * | 148 * |
128 * \param window | 149 * \param window |
129 * Handle of the window | 150 * Handle of the window |
130 * \return | 151 * \return |
131 * ID of the process that created the argument window | 152 * ID of the process that created the argument window |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
424 * Set of process identifiers matching one of the executable names. | 445 * Set of process identifiers matching one of the executable names. |
425 */ | 446 */ |
426 std::set< DWORD > pid_set ; | 447 std::set< DWORD > pid_set ; |
427 | 448 |
428 /** | 449 /** |
429 * Set of executable names by which to filter. | 450 * Set of executable names by which to filter. |
430 * | 451 * |
431 * The argument of the filter constructor is a set by reference. | 452 * The argument of the filter constructor is a set by reference. |
432 * Since it does not make a copy for itself, we define it as a class member to provide its allocation. | 453 * Since it does not make a copy for itself, we define it as a class member to provide its allocation. |
433 */ | 454 */ |
434 exe_name_set exe_names ; | 455 file_name_set process_names ; |
435 | 456 |
436 /** | 457 /** |
437 * Filter function object matches on any of the exe names specified in the con structor. | 458 * Filter function object matches on any of the exe names specified in the con structor. |
438 */ | 459 */ |
439 process_by_any_exe_name_CI filter ; | 460 process_by_any_exe_name_CI filter ; |
440 | 461 |
441 /** | 462 /** |
442 * Copy function object copies just the process ID. | 463 * Copy function object copies just the process ID. |
443 */ | 464 */ |
444 copy_PID copy ; | 465 copy_PID copy ; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
480 if ( ! b ) | 501 if ( ! b ) |
481 { | 502 { |
482 // Assert the process that created the window is not in our pid_set | 503 // Assert the process that created the window is not in our pid_set |
483 return true ; | 504 return true ; |
484 } | 505 } |
485 return f( window ) ; | 506 return f( window ) ; |
486 } | 507 } |
487 } ; | 508 } ; |
488 | 509 |
489 public: | 510 public: |
490 Process_Closer( Snapshot & snapshot, const wchar_t * exe_name_list[], size_t n _exe_names ) | 511 template< size_t n_process_names > |
491 : snapshot( snapshot ), exe_names( exe_name_list, n_exe_names ), filter( exe _names ) | 512 Process_Closer( Snapshot & snapshot, const wchar_t * ( & process_name_list )[ n_process_names ] ) |
513 : snapshot( snapshot ), process_names( process_name_list ), filter( process_ names ) | |
492 { | 514 { |
493 update() ; | 515 update() ; |
494 } | 516 } |
495 | 517 |
496 /** | 518 /** |
497 * Refresh our state to match the snapshot state. | 519 * Refresh our state to match the snapshot state. |
498 */ | 520 */ |
499 void refresh() | 521 void refresh() |
500 { | 522 { |
501 pid_set.clear() ; | 523 pid_set.clear() ; |
(...skipping 12 matching lines...) Expand all Loading... | |
514 } | 536 } |
515 | 537 |
516 /* | 538 /* |
517 * Shut down every process in the pid_set. | 539 * Shut down every process in the pid_set. |
518 */ | 540 */ |
519 bool shut_down() ; | 541 bool shut_down() ; |
520 | 542 |
521 } ; | 543 } ; |
522 | 544 |
523 #endif | 545 #endif |
OLD | NEW |