| 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 | 
|---|