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" |
| 9 |
8 #include <vector> | 10 #include <vector> |
9 #include <set> | 11 #include <set> |
10 #include <algorithm> | 12 #include <algorithm> |
11 #include <memory> | 13 #include <memory> |
12 | 14 |
13 #include <Windows.h> | 15 #include <Windows.h> |
14 #include <TlHelp32.h> | 16 #include <TlHelp32.h> |
15 | 17 |
16 //------------------------------------------------------- | |
17 // Windows_Handle | |
18 //------------------------------------------------------- | |
19 /** | |
20 * A handle to some Windows platform resource. | |
21 * | |
22 * Note, this is not the same as a Windows Installer handle (MSIHANDLE). | |
23 * The two handles have different underlying types and use different functions t
o close. | |
24 */ | |
25 class Windows_Handle | |
26 { | |
27 public: | |
28 /** | |
29 * Ordinary constructor. | |
30 * | |
31 * Validates argument against INVALID_HANDLE_VALUE. No other checks performed. | |
32 */ | |
33 Windows_Handle( HANDLE h ) ; | |
34 | |
35 /** | |
36 * Destructor | |
37 */ | |
38 ~Windows_Handle() ; | |
39 | |
40 /** | |
41 * Conversion operator to underlying HANDLE. | |
42 */ | |
43 operator HANDLE() const { return handle ; } ; | |
44 | |
45 /** | |
46 * Raw handle assignment. | |
47 * | |
48 * This is equivalent to destroying the old object and constructing a new one
in its place. | |
49 * In C++11 this would be handled by the move constructor on an rvalue referen
ce. | |
50 */ | |
51 void operator=( HANDLE h ) ; | |
52 | |
53 private: | |
54 /** | |
55 * \invariant The handle is an open handle to some system resource. | |
56 */ | |
57 HANDLE handle ; | |
58 | |
59 /** | |
60 * Validation function for the handle. Invoked at both construction and assign
ment. | |
61 */ | |
62 void validate_handle() ; | |
63 | |
64 /** | |
65 * Copy constructor declared private and not defined. | |
66 * | |
67 * \par Implementation | |
68 * Add "= delete" for C++11. | |
69 */ | |
70 Windows_Handle( const Windows_Handle & ) ; | |
71 | |
72 /** | |
73 * Copy assignment declared private and not defined. | |
74 * | |
75 * \par Implementation | |
76 * Add "= delete" for C++11. | |
77 */ | |
78 Windows_Handle operator=( const Windows_Handle & ) ; | |
79 | |
80 }; | |
81 | 18 |
82 //------------------------------------------------------- | 19 //------------------------------------------------------- |
83 // exe_name_set: case-insensitive wide-string set | 20 // exe_name_set: case-insensitive wide-string set |
84 //------------------------------------------------------- | 21 //------------------------------------------------------- |
85 int wcscmpi( const wchar_t * s1, const wchar_t * s2 ) ; | 22 int wcscmpi( const wchar_t * s1, const wchar_t * s2 ) ; |
86 | 23 |
87 struct exe_name | 24 struct exe_name |
88 { | 25 { |
89 /** | 26 /** |
90 * Pointer to wide-character string, which is supposed to be null-terminated. | 27 * Pointer to wide-character string, which is supposed to be null-terminated. |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 exception, ///< Callback threw an exception and thereby terminated iterat
ion. | 291 exception, ///< Callback threw an exception and thereby terminated iterat
ion. |
355 error ///< Callback always return true but EnumWindows failed. | 292 error ///< Callback always return true but EnumWindows failed. |
356 } enumerate_windows_state ; | 293 } enumerate_windows_state ; |
357 | 294 |
358 /** | 295 /** |
359 * Data to perform a window enumeration, shared between the main function and th
e callback function. | 296 * Data to perform a window enumeration, shared between the main function and th
e callback function. |
360 */ | 297 */ |
361 template< class F > | 298 template< class F > |
362 struct ew_data | 299 struct ew_data |
363 { | 300 { |
| 301 /** |
| 302 * Function to be applied to each enumerated window. |
| 303 */ |
364 F & f ; | 304 F & f ; |
365 | 305 |
| 306 /** |
| 307 * Completion status of the enumeration. |
| 308 */ |
366 enumerate_windows_state status ; | 309 enumerate_windows_state status ; |
367 | 310 |
| 311 /** |
| 312 * An exception to be transported across the callback. |
| 313 * |
| 314 * The enumerator and the callback are not guaranteed to share a call stack, |
| 315 * nor need they even share compatible exception conventions, |
| 316 * and might not even be in the same thread. |
| 317 * Thus, if the applied function throws an exception, |
| 318 * we catch it in the callback and re-throw it in the enumerator. |
| 319 * This member holds such an exception. |
| 320 * |
| 321 * This member holds an exception only if 'status' has the value 'exception'. |
| 322 * Otherwise it's a null pointer. |
| 323 */ |
368 std::unique_ptr< std::exception > ee ; | 324 std::unique_ptr< std::exception > ee ; |
369 | 325 |
| 326 /** |
| 327 * Ordinary constructor. |
| 328 */ |
370 ew_data( F & f ) | 329 ew_data( F & f ) |
371 : f( f ), status( started ) | 330 : f( f ), status( started ) |
372 {} | 331 {} |
373 } ; | 332 } ; |
374 | 333 |
375 /** | 334 /** |
376 * Callback function for EnumWindows. | 335 * Callback function for EnumWindows. |
| 336 * |
| 337 * This function provides two standard behaviors. |
| 338 * It records early termination of the enumeration, should that happen by the ap
plied function returning false. |
| 339 * It captures any exception thrown for transport back to the enumerator. |
377 */ | 340 */ |
378 template< class F > | 341 template< class F > |
379 BOOL CALLBACK enumeration_callback( HWND window, LPARAM x ) | 342 BOOL CALLBACK enumeration_callback( HWND window, LPARAM x ) |
380 { | 343 { |
381 // LPARAM is always the same size as a pointer | 344 // LPARAM is always the same size as a pointer |
382 ew_data< F > * data = reinterpret_cast< ew_data< F > * >( x ) ; | 345 ew_data< F > * data = reinterpret_cast< ew_data< F > * >( x ) ; |
| 346 /* |
| 347 * Top-level try statement prevents exception from propagating back to system. |
| 348 */ |
383 try | 349 try |
384 { | 350 { |
385 bool r = data -> f( window ) ; | 351 bool r = data -> f( window ) ; |
386 if ( ! r ) | 352 if ( ! r ) |
387 { | 353 { |
388 data -> status = early ; | 354 data -> status = early ; |
389 } | 355 } |
390 return r ; | 356 return r ; |
391 } | 357 } |
392 catch ( std::exception e ) | 358 catch ( std::exception e ) |
393 { | 359 { |
394 data -> ee = std::unique_ptr< std::exception >( new( std::nothrow ) std::exc
eption( e ) ) ; | 360 data -> ee = std::unique_ptr< std::exception >( new( std::nothrow ) std::exc
eption( e ) ) ; |
395 data -> status = exception ; | 361 data -> status = exception ; |
396 return FALSE ; | 362 return FALSE ; |
397 } | 363 } |
398 catch ( ... ) | 364 catch ( ... ) |
399 { | 365 { |
| 366 data -> ee = std::unique_ptr< std::exception >() ; |
400 data -> status = exception ; | 367 data -> status = exception ; |
401 return FALSE ; | 368 return FALSE ; |
402 } | 369 } |
403 return TRUE ; | |
404 } | 370 } |
405 | 371 |
406 /** | 372 /** |
407 * Enumerate windows, applying a function to each one. | 373 * Enumerate windows, applying a function to each one. |
408 */ | 374 */ |
409 template< class F > | 375 template< class F > |
410 bool enumerate_windows( F f ) | 376 bool enumerate_windows( F f ) |
411 { | 377 { |
412 ew_data< F > data( f ) ; | 378 ew_data< F > data( f ) ; |
413 BOOL x( ::EnumWindows( enumeration_callback< F >, reinterpret_cast< LPARAM >(
& data ) ) ) ; | 379 BOOL x( ::EnumWindows( enumeration_callback< F >, reinterpret_cast< LPARAM >(
& data ) ) ) ; |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
548 } | 514 } |
549 | 515 |
550 /* | 516 /* |
551 * Shut down every process in the pid_set. | 517 * Shut down every process in the pid_set. |
552 */ | 518 */ |
553 bool shut_down() ; | 519 bool shut_down() ; |
554 | 520 |
555 } ; | 521 } ; |
556 | 522 |
557 #endif | 523 #endif |
OLD | NEW |