OLD | NEW |
1 #include <stdexcept> | 1 #include <stdexcept> |
2 #include <functional> | 2 #include <functional> |
3 #include <wctype.h> | 3 #include <wctype.h> |
4 // <thread> is C++11, but implemented in VS2012 | 4 // <thread> is C++11, but implemented in VS2012 |
5 #include <thread> | 5 #include <thread> |
6 | 6 |
7 #include "installer-lib.h" | 7 #include "installer-lib.h" |
8 #include "process.h" | 8 #include "process.h" |
9 | 9 |
10 //------------------------------------------------------- | 10 //------------------------------------------------------- |
11 //------------------------------------------------------- | 11 //------------------------------------------------------- |
12 bool process_by_any_exe_with_any_module::operator()( const PROCESSENTRY32W & pro
cess ) | 12 bool process_by_any_exe_with_any_module::operator()( const PROCESSENTRY32W & pro
cess ) |
13 { | 13 { |
14 if (processNames.find(process.szExeFile) != processNames.end()) | 14 if (processNames.find(process.szExeFile) != processNames.end()) |
15 { | 15 { |
16 if (moduleNames.empty()) | 16 if (moduleNames.empty()) |
17 return true; | 17 return true; |
18 | 18 |
19 ModulesSnapshot ms(process.th32ProcessID); | 19 Module_Snapshot ms(process.th32ProcessID); |
20 MODULEENTRY32W* me = ms.first(); | 20 const MODULEENTRY32W* me = ms.first(); |
21 while (me != NULL) | 21 while (me != 0) |
22 { | 22 { |
23 if (moduleNames.find(me->szModule) != moduleNames.end()) | 23 if (moduleNames.find(me->szModule) != moduleNames.end()) |
24 { | 24 { |
25 return true; | 25 return true; |
26 } | 26 } |
27 me = ms.next(); | 27 me = ms.next(); |
28 } | 28 } |
29 } | 29 } |
30 return false; | 30 return false; |
31 } | 31 } |
32 | 32 |
33 //------------------------------------------------------- | 33 //------------------------------------------------------- |
34 // creator_process | 34 // creator_process |
35 //------------------------------------------------------- | 35 //------------------------------------------------------- |
36 DWORD creator_process( HWND window ) | 36 DWORD creator_process( HWND window ) |
37 { | 37 { |
38 DWORD pid ; | 38 DWORD pid ; |
39 DWORD r = GetWindowThreadProcessId( window, & pid ) ; | 39 DWORD r = GetWindowThreadProcessId( window, & pid ) ; |
40 if ( r == 0 ) | 40 if ( r == 0 ) |
41 { | 41 { |
42 // Assert GetWindowThreadProcessId returned an error | 42 // Assert GetWindowThreadProcessId returned an error |
43 // If the window handle is invalid, we end up here. | 43 // If the window handle is invalid, we end up here. |
44 throw windows_api_error( "GetWindowThreadProcessId", r ) ; | 44 throw windows_api_error( "GetWindowThreadProcessId", r ) ; |
45 } | 45 } |
46 return pid ; | 46 return pid ; |
47 } | 47 } |
48 | 48 |
49 //------------------------------------------------------- | 49 //------------------------------------------------------- |
50 // Snapshot | |
51 //------------------------------------------------------- | |
52 Snapshot::Snapshot() | |
53 : handle( ::CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ) ) | |
54 { | |
55 process.dwSize = sizeof( PROCESSENTRY32W ) ; | |
56 } | |
57 | |
58 PROCESSENTRY32W * Snapshot::first() | |
59 { | |
60 return ::Process32FirstW(handle, &process) ? (&process) : 0; | |
61 } | |
62 | |
63 PROCESSENTRY32W * Snapshot::next() | |
64 { | |
65 return ::Process32NextW(handle, &process) ? (&process) : 0; | |
66 } | |
67 | |
68 void Snapshot::refresh() | |
69 { | |
70 handle = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); | |
71 } | |
72 | |
73 //------------------------------------------------------- | |
74 // ModulesSnapshot | |
75 //------------------------------------------------------- | |
76 ModulesSnapshot::ModulesSnapshot(DWORD processId) | |
77 : handle(::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, p
rocessId)) | |
78 { | |
79 module.dwSize = sizeof(MODULEENTRY32); | |
80 } | |
81 | |
82 MODULEENTRY32W * ModulesSnapshot::first() | |
83 { | |
84 return ::Module32FirstW(handle, &module) ? (&module) : 0; | |
85 } | |
86 | |
87 MODULEENTRY32W * ModulesSnapshot::next() | |
88 { | |
89 return ::Module32NextW(handle, &module) ? (&module) : 0; | |
90 } | |
91 | |
92 //------------------------------------------------------- | |
93 // send_message, send_endsession_messages | 50 // send_message, send_endsession_messages |
94 //------------------------------------------------------- | 51 //------------------------------------------------------- |
95 /** | 52 /** |
96 * Default process exit wait time (per message) 5000 ms | 53 * Default process exit wait time (per message) 5000 ms |
97 * | 54 * |
98 * 5 seconds is time that the system will wait before it considers a process non
-responsive. | 55 * 5 seconds is time that the system will wait before it considers a process non
-responsive. |
99 */ | 56 */ |
100 static const unsigned int timeout = 5000 ; // milliseconds | 57 static const unsigned int timeout = 5000 ; // milliseconds |
101 | 58 |
102 /** | 59 /** |
103 * An function object to process the results of sending window messages in send_
message. | 60 * An function object to process the results of sending window messages in send_
message. |
104 * | 61 * |
105 * We are using send_message within a system iteration over windows. | 62 * We are using send_message within a system iteration over windows. |
106 * The system has its own convention for continuing/breaking the iteration. | 63 * The system has its own convention for continuing/breaking the iteration. |
107 * This convention is assured consistently in send_message, which also provides
default behavior. | 64 * This convention is assured consistently in send_message, which also provides
default behavior. |
108 * This class provides the base for any variation from the default behavior. | 65 * This class provides the base for any variation from the default behavior. |
109 */ | 66 */ |
110 struct message_accumulator | 67 struct message_accumulator |
111 : public std::binary_function< DWORD_PTR, BOOL, bool > | 68 : public std::binary_function< DWORD_PTR, bool, bool > |
112 { | 69 { |
113 virtual result_type operator()( first_argument_type result, second_argument_ty
pe return_value ) = 0 ; | 70 virtual result_type operator()( first_argument_type result, second_argument_ty
pe return_value ) = 0 ; |
114 virtual ~message_accumulator() {} ; | 71 virtual ~message_accumulator() {} ; |
115 } ; | 72 } ; |
116 | 73 |
117 /** | 74 /** |
118 * Iteration action to send a message to a window and accumulate results. | 75 * Iteration action to send a message to a window and accumulate results. |
119 * | 76 * |
120 * An error sending the message is not a failure for the function a whole. | 77 * An error sending the message is not a failure for the function a whole. |
121 * The goal is to close the process, and if the window is no longer present, the
n the process may have already closed. | 78 * The goal is to close the process, and if the window is no longer present, the
n the process may have already closed. |
(...skipping 21 matching lines...) Expand all Loading... |
143 send_message( UINT message, WPARAM p1, LPARAM p2 ) | 100 send_message( UINT message, WPARAM p1, LPARAM p2 ) |
144 : message( message ), p1( p1 ), p2( p2 ), f( 0 ) | 101 : message( message ), p1( p1 ), p2( p2 ), f( 0 ) |
145 {} | 102 {} |
146 | 103 |
147 /* | 104 /* |
148 * Enumeration function applied to each window. | 105 * Enumeration function applied to each window. |
149 */ | 106 */ |
150 bool operator()( HWND window ) | 107 bool operator()( HWND window ) |
151 { | 108 { |
152 DWORD_PTR result ; | 109 DWORD_PTR result ; |
153 BOOL rv = SendMessageTimeoutW( window, message, p1, p2, SMTO_BLOCK, timeout,
& result ) ; | 110 LRESULT rv = SendMessageTimeoutW( window, message, p1, p2, SMTO_BLOCK, timeo
ut, & result ) ; |
154 /* | 111 /* |
155 * If we have no message accumulator, the default behavior is to iterate eve
rything. | 112 * If we have no message accumulator, the default behavior is to iterate eve
rything. |
156 * If we do have one, we delegate to it the decision whether to break or to
continue. | 113 * If we do have one, we delegate to it the decision whether to break or to
continue. |
157 */ | 114 */ |
158 if ( ! f ) | 115 if ( ! f ) |
159 { | 116 { |
160 return true ; | 117 return true ; |
161 } | 118 } |
162 return ( * f )( result, rv ) ; | 119 return ( * f )( result, (rv != 0) ) ; |
163 } | 120 } |
164 } ; | 121 } ; |
165 | 122 |
166 /** | 123 /** |
167 * Send WM_QUERYENDSESSION and WM_ENDSESSION to a window. | 124 * Send WM_QUERYENDSESSION and WM_ENDSESSION to a window. |
168 * | 125 * |
169 * This window processor tries to shut down each application individually. | 126 * This window processor tries to shut down each application individually. |
170 * The alternative, gathering all the query results first and only then ending s
essions, cannot be done with a single window enumeration. | 127 * The alternative, gathering all the query results first and only then ending s
essions, cannot be done with a single window enumeration. |
171 */ | 128 */ |
172 class send_endsession_messages | 129 class send_endsession_messages |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 * As usual, errors sending messages are ignored. | 164 * As usual, errors sending messages are ignored. |
208 */ | 165 */ |
209 struct endsession_accumulator : | 166 struct endsession_accumulator : |
210 public message_accumulator | 167 public message_accumulator |
211 { | 168 { |
212 bool permit_end_session ; ///< Accumulator variable yields final result. | 169 bool permit_end_session ; ///< Accumulator variable yields final result. |
213 | 170 |
214 /** | 171 /** |
215 * Enumeration function applied to each window. | 172 * Enumeration function applied to each window. |
216 */ | 173 */ |
217 bool operator()( DWORD_PTR result, BOOL return_value ) | 174 bool operator()( DWORD_PTR result, bool return_value ) |
218 { | 175 { |
219 if ( ( ! return_value ) || result ) | 176 if ( ( ! return_value ) || result ) |
220 { | 177 { |
221 // 1. If the result is true, then the process will permit WM_ENDSESSION | 178 // 1. If the result is true, then the process will permit WM_ENDSESSION |
222 // 2. An error sending the message counts as "no new information" | 179 // 2. An error sending the message counts as "no new information" |
223 return true ; | 180 return true ; |
224 } | 181 } |
225 // The first false is the result of the calculation. | 182 // The first false is the result of the calculation. |
226 // The second false means to terminate enumeration early. | 183 // The second false means to terminate enumeration early. |
227 permit_end_session = false ; | 184 permit_end_session = false ; |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 if ( ! is_running() ) | 292 if ( ! is_running() ) |
336 { | 293 { |
337 return true ; | 294 return true ; |
338 } | 295 } |
339 } | 296 } |
340 // Assert is_running() | 297 // Assert is_running() |
341 } | 298 } |
342 // No control path leaves the for-loop. | 299 // No control path leaves the for-loop. |
343 } ; | 300 } ; |
344 | 301 |
OLD | NEW |