| 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 "installer-lib.h" | 8 #include "installer-lib.h" | 
| 9 #include "handle.h" | 9 #include "handle.h" | 
| 10 #include "session.h" | 10 #include "session.h" | 
| 11 | 11 | 
| 12 #include <string> | 12 #include <string> | 
| 13 #include <cctype> | 13 #include <cctype> | 
| 14 #include <vector> | 14 #include <vector> | 
| 15 #include <set> | 15 #include <set> | 
| 16 #include <algorithm> | 16 #include <algorithm> | 
| 17 #include <memory> | 17 #include <memory> | 
| 18 | 18 | 
| 19 #include <Windows.h> | 19 #include <Windows.h> | 
| 20 #include <TlHelp32.h> | 20 #include <TlHelp32.h> | 
| 21 | 21 | 
| 22 //------------------------------------------------------- | 22 //------------------------------------------------------- | 
| 23 // WstringCaseInsensitive: case-insensitive wide string | 23 // WstringCaseInsensitive: case-insensitive wide string | 
| 24 //------------------------------------------------------- | 24 //------------------------------------------------------- | 
| 25 | 25 | 
| 26 /** | 26 /** | 
| 27  * Traits class for case-insensitive strings. | 27  * Traits class for case-insensitive strings. | 
| 28  */ | 28  */ | 
| 29 template< class T > | 29 template<class T> | 
| 30 struct CaseInsensitiveTraits: std::char_traits< T > | 30 struct CaseInsensitiveTraits: std::char_traits<T> | 
| 31 { | 31 { | 
| 32   static bool eq( T c1, T c2 ) | 32   static bool eq(T c1, T c2) | 
| 33   { | 33   { | 
| 34     return std::tolower( c1 ) == std::tolower( c2 ) ; | 34     return std::tolower(c1) == std::tolower(c2); | 
| 35   } | 35   } | 
| 36 | 36 | 
| 37   static bool lt( T c1, T c2 ) | 37   static bool lt(T c1, T c2) | 
| 38   { | 38   { | 
| 39     return std::tolower( c1 ) < std::tolower( c2 ) ; | 39     return std::tolower(c1) < std::tolower(c2); | 
| 40   } | 40   } | 
| 41 | 41 | 
| 42   /** | 42   /** | 
| 43    * Trait comparison function. | 43    * Trait comparison function. | 
| 44    * | 44    * | 
| 45    * Note that this is not a comparison of C-style strings. | 45    * Note that this is not a comparison of C-style strings. | 
| 46    * In particular, there's no concern over null characters '\0'. | 46    * In particular, there's no concern over null characters '\0'. | 
| 47    * The argument 'n' is the minimum length of the two strings being compared. | 47    * The argument 'n' is the minimum length of the two strings being compared. | 
| 48    * We may assume that the intervals p1[0..n) and p2[0..n) are both valid subst
     rings. | 48    * We may assume that the intervals p1[0..n) and p2[0..n) are both valid subst
     rings. | 
| 49    */ | 49    */ | 
| 50   static int compare( const T * p1, const T * p2, size_t n ) | 50   static int compare(const T* p1, const T* p2, size_t n) | 
| 51   { | 51   { | 
| 52     while ( n-- > 0 ) | 52     while (n-- > 0) | 
| 53     { | 53     { | 
| 54       T l1 = std::tolower( * p1 ++ ) ; | 54       T l1 = std::tolower(* p1 ++); | 
| 55       T l2 = std::tolower( * p2 ++ ) ; | 55       T l2 = std::tolower(* p2 ++); | 
| 56       if ( l1 == l2 ) | 56       if (l1 == l2) | 
| 57       { | 57       { | 
| 58         continue ; | 58         continue; | 
| 59       } | 59       } | 
| 60       return ( l1 < l2 ) ? -1 : +1 ; | 60       return (l1 < l2) ? -1 : +1; | 
| 61     } | 61     } | 
| 62     return 0  ; | 62     return 0; | 
| 63   } | 63   } | 
| 64 } ; | 64 }; | 
| 65 | 65 | 
| 66 typedef std::basic_string< wchar_t, CaseInsensitiveTraits< wchar_t > > WstringCa
     seInsensitive ; | 66 typedef std::basic_string<wchar_t, CaseInsensitiveTraits<wchar_t>> WstringCaseIn
     sensitive; | 
| 67 | 67 | 
| 68 //------------------------------------------------------- | 68 //------------------------------------------------------- | 
| 69 // FileNameSet: case-insensitive wide-string set | 69 // FileNameSet: case-insensitive wide-string set | 
| 70 //------------------------------------------------------- | 70 //------------------------------------------------------- | 
| 71 struct FileNameSet | 71 struct FileNameSet | 
| 72   : public std::set< WstringCaseInsensitive > | 72   : public std::set<WstringCaseInsensitive> | 
| 73 { | 73 { | 
| 74   /** | 74   /** | 
| 75    * Empty set constructor. | 75    * Empty set constructor. | 
| 76    */ | 76    */ | 
| 77   FileNameSet() | 77   FileNameSet() | 
| 78   {} | 78   {} | 
| 79 | 79 | 
| 80   /** | 80   /** | 
| 81    * Constructor initialization from an array. | 81    * Constructor initialization from an array. | 
| 82    */ | 82    */ | 
| 83   template< size_t nFileNames > | 83   template<size_t nFileNames> | 
| 84   FileNameSet( const wchar_t * ( & fileNameList )[ nFileNames ] ) | 84   FileNameSet(const wchar_t* (& fileNameList)[nFileNames]) | 
| 85   { | 85   { | 
| 86     for ( unsigned int j = 0 ; j < nFileNames ; ++ j ) | 86     for (unsigned int j = 0 ; j < nFileNames ; ++ j) | 
| 87     { | 87     { | 
| 88       insert( WstringCaseInsensitive( fileNameList[ j ] ) ) ; | 88       insert(WstringCaseInsensitive(fileNameList[j])); | 
| 89     } | 89     } | 
| 90   } | 90   } | 
| 91 } ; | 91 }; | 
| 92 | 92 | 
| 93 //------------------------------------------------------- | 93 //------------------------------------------------------- | 
| 94 //------------------------------------------------------- | 94 //------------------------------------------------------- | 
| 95 /** | 95 /** | 
| 96  * Filter by process name. Comparison is case-insensitive. Windows Store app pro
     cesses excluded | 96  * Filter by process name. Comparison is case-insensitive. Windows Store app pro
     cesses excluded | 
| 97  */ | 97  */ | 
| 98 class ProcessByAnyExeNotImmersive | 98 class ProcessByAnyExeNotImmersive | 
| 99   : public std::unary_function<PROCESSENTRY32W, bool> | 99   : public std::unary_function<PROCESSENTRY32W, bool> | 
| 100 { | 100 { | 
| 101   /** | 101   /** | 
| 102    * Set of file names from which to match candidate process names. | 102    * Set of file names from which to match candidate process names. | 
| 103    * | 103    * | 
| 104    * This is a reference to, not a copy of, the set. | 104    * This is a reference to, not a copy of, the set. | 
| 105    * The lifetime of this object must be subordinate to that of its referent. | 105    * The lifetime of this object must be subordinate to that of its referent. | 
| 106    * The set used to instantiate this class is a member of ProcessCloser, | 106    * The set used to instantiate this class is a member of ProcessCloser, | 
| 107    *   and so also is this class. | 107    *   and so also is this class. | 
| 108    * Hence the lifetimes are coterminous, and the reference is not problematic. | 108    * Hence the lifetimes are coterminous, and the reference is not problematic. | 
| 109    */ | 109    */ | 
| 110   const FileNameSet & processNames; | 110   const FileNameSet& processNames; | 
| 111 public: | 111 public: | 
| 112   bool operator()( const PROCESSENTRY32W & ); | 112   bool operator()(const PROCESSENTRY32W&); | 
| 113   ProcessByAnyExeNotImmersive(const FileNameSet & names) : processNames( names )
      {} | 113   ProcessByAnyExeNotImmersive(const FileNameSet& names) : processNames(names) {} | 
| 114 } ; | 114 }; | 
| 115 | 115 | 
| 116 | 116 | 
| 117 //------------------------------------------------------- | 117 //------------------------------------------------------- | 
| 118 // Process utility functions. | 118 // Process utility functions. | 
| 119 //------------------------------------------------------- | 119 //------------------------------------------------------- | 
| 120 /** | 120 /** | 
| 121  * A promiscuous filter admits everything. | 121  * A promiscuous filter admits everything. | 
| 122  */ | 122  */ | 
| 123 struct EveryProcess | 123 struct EveryProcess | 
| 124   : public std::unary_function< PROCESSENTRY32W, bool > | 124   : public std::unary_function<PROCESSENTRY32W, bool> | 
| 125 { | 125 { | 
| 126   bool operator()( const PROCESSENTRY32W & ) { return true ; } ; | 126   bool operator()(const PROCESSENTRY32W&) | 
| 127 } ; | 127   { | 
|  | 128     return true ; | 
|  | 129   }; | 
|  | 130 }; | 
| 128 | 131 | 
| 129 /** | 132 /** | 
| 130  * Extractor that copies the entire process structure. | 133  * Extractor that copies the entire process structure. | 
| 131  */ | 134  */ | 
| 132 struct CopyAll | 135 struct CopyAll | 
| 133   : public std::unary_function< PROCESSENTRY32W, PROCESSENTRY32W > | 136   : public std::unary_function<PROCESSENTRY32W, PROCESSENTRY32W> | 
| 134 { | 137 { | 
| 135   PROCESSENTRY32W operator()( const PROCESSENTRY32W & process ) { return process
      ; } | 138   PROCESSENTRY32W operator()(const PROCESSENTRY32W& process) | 
| 136 } ; | 139   { | 
|  | 140     return process ; | 
|  | 141   } | 
|  | 142 }; | 
| 137 | 143 | 
| 138 /** | 144 /** | 
| 139  * Extractor that copies only the PID. | 145  * Extractor that copies only the PID. | 
| 140  */ | 146  */ | 
| 141 struct CopyPID | 147 struct CopyPID | 
| 142   : public std::unary_function< PROCESSENTRY32W, DWORD > | 148   : public std::unary_function<PROCESSENTRY32W, DWORD> | 
| 143 { | 149 { | 
| 144   inline DWORD operator()( const PROCESSENTRY32W & process ) { return process.th
     32ProcessID ; } | 150   inline DWORD operator()(const PROCESSENTRY32W& process) | 
| 145 } ; | 151   { | 
|  | 152     return process.th32ProcessID ; | 
|  | 153   } | 
|  | 154 }; | 
| 146 | 155 | 
| 147 /** | 156 /** | 
| 148  * Retrieve the process ID that created a window. | 157  * Retrieve the process ID that created a window. | 
| 149  * | 158  * | 
| 150  * Wrapper around GetWindowThreadProcessId. | 159  * Wrapper around GetWindowThreadProcessId. | 
| 151  * Converts an error return from the system call into an exception. | 160  * Converts an error return from the system call into an exception. | 
| 152  * The system call can also retrieve the creating thread; we ignore it. | 161  * The system call can also retrieve the creating thread; we ignore it. | 
| 153  * | 162  * | 
| 154  * \param window | 163  * \param window | 
| 155  *   Handle of the window | 164  *   Handle of the window | 
| 156  * \return | 165  * \return | 
| 157  *   ID of the process that created the argument window | 166  *   ID of the process that created the argument window | 
| 158  * | 167  * | 
| 159  * \sa | 168  * \sa | 
| 160  *   MSDN [GetWindowThreadProcessId function](http://msdn.microsoft.com/en-us/li
     brary/windows/desktop/ms633522%28v=vs.85%29.aspx) | 169  *   MSDN [GetWindowThreadProcessId function](http://msdn.microsoft.com/en-us/li
     brary/windows/desktop/ms633522%28v=vs.85%29.aspx) | 
| 161  */ | 170  */ | 
| 162 DWORD CreatorProcess( HWND window ) ; | 171 DWORD CreatorProcess(HWND window); | 
| 163 | 172 | 
| 164 //------------------------------------------------------- | 173 //------------------------------------------------------- | 
| 165 // Snapshot | 174 // Snapshot | 
| 166 //------------------------------------------------------- | 175 //------------------------------------------------------- | 
| 167 /** | 176 /** | 
| 168  * Traits class for snapshots of all processes on the system. | 177  * Traits class for snapshots of all processes on the system. | 
| 169  */ | 178  */ | 
| 170 struct ProcessSnapshotTraits | 179 struct ProcessSnapshotTraits | 
| 171 { | 180 { | 
| 172   /** | 181   /** | 
| 173    * The type of the data resulting from CreateToolhelp32Snapshot. | 182    * The type of the data resulting from CreateToolhelp32Snapshot. | 
| 174    */ | 183    */ | 
| 175   typedef PROCESSENTRY32W ResultType ; | 184   typedef PROCESSENTRY32W ResultType; | 
| 176 | 185 | 
| 177   /** | 186   /** | 
| 178    * Flags used to call CreateToolhelp32Snapshot. | 187    * Flags used to call CreateToolhelp32Snapshot. | 
| 179    */ | 188    */ | 
| 180   const static DWORD SnapshotFlags = TH32CS_SNAPPROCESS ; | 189   const static DWORD SnapshotFlags = TH32CS_SNAPPROCESS; | 
| 181 | 190 | 
| 182   /** | 191   /** | 
| 183    * Wrapper for 'first' function for processes | 192    * Wrapper for 'first' function for processes | 
| 184    */ | 193    */ | 
| 185   static BOOL First( HANDLE arg1, LPPROCESSENTRY32 arg2 ) | 194   static BOOL First(HANDLE arg1, LPPROCESSENTRY32 arg2) | 
| 186   { | 195   { | 
| 187     return ::Process32First( arg1, arg2 ) ; | 196     return ::Process32First(arg1, arg2); | 
| 188   } | 197   } | 
| 189 | 198 | 
| 190   /** | 199   /** | 
| 191    * Wrapper for 'next' function for processes | 200    * Wrapper for 'next' function for processes | 
| 192    */ | 201    */ | 
| 193   static BOOL Next( HANDLE arg1, LPPROCESSENTRY32 arg2 ) | 202   static BOOL Next(HANDLE arg1, LPPROCESSENTRY32 arg2) | 
| 194   { | 203   { | 
| 195     return ::Process32Next( arg1, arg2 ) ; | 204     return ::Process32Next(arg1, arg2); | 
| 196   } | 205   } | 
| 197 } ; | 206 }; | 
| 198 | 207 | 
| 199 /** | 208 /** | 
| 200  * Traits class for snapshots of all modules loaded by a process. | 209  * Traits class for snapshots of all modules loaded by a process. | 
| 201  */ | 210  */ | 
| 202 struct ModuleSnapshotTraits | 211 struct ModuleSnapshotTraits | 
| 203 { | 212 { | 
| 204   /** | 213   /** | 
| 205    * The type of the data resulting from CreateToolhelp32Snapshot. | 214    * The type of the data resulting from CreateToolhelp32Snapshot. | 
| 206    */ | 215    */ | 
| 207   typedef MODULEENTRY32W ResultType ; | 216   typedef MODULEENTRY32W ResultType; | 
| 208 | 217 | 
| 209   /** | 218   /** | 
| 210    * Flags used to call CreateToolhelp32Snapshot. | 219    * Flags used to call CreateToolhelp32Snapshot. | 
| 211    */ | 220    */ | 
| 212   const static DWORD SnapshotFlags = TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32 ; | 221   const static DWORD SnapshotFlags = TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32; | 
| 213 | 222 | 
| 214   /** | 223   /** | 
| 215    * Wrapper for 'first' function for modules | 224    * Wrapper for 'first' function for modules | 
| 216    */ | 225    */ | 
| 217   static BOOL First( HANDLE arg1, LPMODULEENTRY32 arg2 ) | 226   static BOOL First(HANDLE arg1, LPMODULEENTRY32 arg2) | 
| 218   { | 227   { | 
| 219     return ::Module32First( arg1, arg2 ) ; | 228     return ::Module32First(arg1, arg2); | 
| 220   } | 229   } | 
| 221 | 230 | 
| 222   /** | 231   /** | 
| 223    * Wrapper for 'next' function for modules | 232    * Wrapper for 'next' function for modules | 
| 224    */ | 233    */ | 
| 225   static BOOL Next( HANDLE arg1, LPMODULEENTRY32 arg2 ) | 234   static BOOL Next(HANDLE arg1, LPMODULEENTRY32 arg2) | 
| 226   { | 235   { | 
| 227     return ::Module32Next( arg1, arg2 ) ; | 236     return ::Module32Next(arg1, arg2); | 
| 228   } | 237   } | 
| 229 } ; | 238 }; | 
| 230 | 239 | 
| 231 /** | 240 /** | 
| 232  * A snapshot wrapping the results of CreateToolhelp32Snapshot system call. | 241  * A snapshot wrapping the results of CreateToolhelp32Snapshot system call. | 
| 233  * | 242  * | 
| 234  * Unfortunately, we cannot provide standard iterator for this class. | 243  * Unfortunately, we cannot provide standard iterator for this class. | 
| 235  * Standard iterators must be copy-constructible, which entails the possibility 
     of multiple, coexisting iteration states. | 244  * Standard iterators must be copy-constructible, which entails the possibility 
     of multiple, coexisting iteration states. | 
| 236  * The iteration behavior provided by Process32First and Process32Next relies up
     on state held within the snapshot itself. | 245  * The iteration behavior provided by Process32First and Process32Next relies up
     on state held within the snapshot itself. | 
| 237  * Thus, there can be only one iterator at a time for the snapshot. | 246  * Thus, there can be only one iterator at a time for the snapshot. | 
| 238  * The two requirements are not simultaneously satisfiable. | 247  * The two requirements are not simultaneously satisfiable. | 
| 239  * | 248  * | 
| 240  * Instead of a standard iterator, we provide a First() and Next() functions wra
     pping the corresponding system calls. | 249  * Instead of a standard iterator, we provide a First() and Next() functions wra
     pping the corresponding system calls. | 
| 241  * | 250  * | 
| 242  * \par Implementation | 251  * \par Implementation | 
| 243  * | 252  * | 
| 244  * - MSDN [CreateToolhelp32Snapshot function](http://msdn.microsoft.com/en-us/li
     brary/windows/desktop/ms682489%28v=vs.85%29.aspx) | 253  * - MSDN [CreateToolhelp32Snapshot function](http://msdn.microsoft.com/en-us/li
     brary/windows/desktop/ms682489%28v=vs.85%29.aspx) | 
| 245  * - MSDN [Process32First function](http://msdn.microsoft.com/en-us/library/wind
     ows/desktop/ms684834%28v=vs.85%29.aspx) | 254  * - MSDN [Process32First function](http://msdn.microsoft.com/en-us/library/wind
     ows/desktop/ms684834%28v=vs.85%29.aspx) | 
| 246  * - MSDN [Process32Next function](http://msdn.microsoft.com/en-us/library/windo
     ws/desktop/ms684836%28v=vs.85%29.aspx) | 255  * - MSDN [Process32Next function](http://msdn.microsoft.com/en-us/library/windo
     ws/desktop/ms684836%28v=vs.85%29.aspx) | 
| 247  * - MSDN [PROCESSENTRY32 structure](http://msdn.microsoft.com/en-us/library/win
     dows/desktop/ms684839%28v=vs.85%29.aspx) | 256  * - MSDN [PROCESSENTRY32 structure](http://msdn.microsoft.com/en-us/library/win
     dows/desktop/ms684839%28v=vs.85%29.aspx) | 
| 248  * | 257  * | 
| 249  * \par Design Note | 258  * \par Design Note | 
| 250  *   The traits class defines First() and Next() functions instead of using func
     tion pointers. | 259  *   The traits class defines First() and Next() functions instead of using func
     tion pointers. | 
| 251  *   This arises from a limitation in the compiler. | 260  *   This arises from a limitation in the compiler. | 
| 252  *   The system calls are declared 'WINAPI', which is a compiler-specific extens
     ion. | 261  *   The system calls are declared 'WINAPI', which is a compiler-specific extens
     ion. | 
| 253  *   That extension, however, does not go far enough to be able to declare a poi
     nter with the same modifier. | 262  *   That extension, however, does not go far enough to be able to declare a poi
     nter with the same modifier. | 
| 254  *   Hence the system calls must be called directly; they are wrapped in the tra
     it functions. | 263  *   Hence the system calls must be called directly; they are wrapped in the tra
     it functions. | 
| 255  */ | 264  */ | 
| 256 template< class Traits > | 265 template<class Traits> | 
| 257 class Snapshot | 266 class Snapshot | 
| 258 { | 267 { | 
| 259 public: | 268 public: | 
| 260   /** | 269   /** | 
| 261    * Expose the result type from the traits class as our own. | 270    * Expose the result type from the traits class as our own. | 
| 262    */ | 271    */ | 
| 263   typedef typename Traits::ResultType ResultType ; | 272   typedef typename Traits::ResultType ResultType; | 
| 264 | 273 | 
| 265 private: | 274 private: | 
| 266   /** | 275   /** | 
| 267    * Process ID argument for CreateToolhelp32Snapshot. | 276    * Process ID argument for CreateToolhelp32Snapshot. | 
| 268    */ | 277    */ | 
| 269   DWORD id ; | 278   DWORD id; | 
| 270 | 279 | 
| 271   /** | 280   /** | 
| 272    * Handle to the underlying snapshot. | 281    * Handle to the underlying snapshot. | 
| 273    */ | 282    */ | 
| 274   WindowsHandle handle ; | 283   WindowsHandle handle; | 
| 275 | 284 | 
| 276   /** | 285   /** | 
| 277    * Buffer for reading a single process entry out of the snapshot. | 286    * Buffer for reading a single process entry out of the snapshot. | 
| 278    * | 287    * | 
| 279    * This buffer is constant insofar as the code outside this class is concerned
     . | 288    * This buffer is constant insofar as the code outside this class is concerned
     . | 
| 280    * The accessor functions First() and Next() return pointers to constant Resul
     tType. | 289    * The accessor functions First() and Next() return pointers to constant Resul
     tType. | 
| 281    */ | 290    */ | 
| 282   ResultType buffer; | 291   ResultType buffer; | 
| 283 | 292 | 
| 284   /** | 293   /** | 
| 285    * Copy constructor declared private and not defined. | 294    * Copy constructor declared private and not defined. | 
| 286    * | 295    * | 
| 287    * \par Implementation | 296    * \par Implementation | 
| 288    *   Add "= delete" for C++11. | 297    *   Add "= delete" for C++11. | 
| 289    */ | 298    */ | 
| 290   Snapshot( const Snapshot & ) ; | 299   Snapshot(const Snapshot&); | 
| 291 | 300 | 
| 292   /** | 301   /** | 
| 293    * Copy assignment declared private and not defined. | 302    * Copy assignment declared private and not defined. | 
| 294    * | 303    * | 
| 295    * \par Implementation | 304    * \par Implementation | 
| 296    *   Add "= delete" for C++11. | 305    *   Add "= delete" for C++11. | 
| 297    */ | 306    */ | 
| 298   Snapshot operator=( const Snapshot & ) ; | 307   Snapshot operator=(const Snapshot&); | 
| 299 | 308 | 
| 300   /** | 309   /** | 
| 301    * Create a new snapshot and return its handle. | 310    * Create a new snapshot and return its handle. | 
| 302    */ | 311    */ | 
| 303   WindowsHandle::HandleType MakeHandle() | 312   WindowsHandle::HandleType MakeHandle() | 
| 304   { | 313   { | 
| 305     WindowsHandle::HandleType h = ::CreateToolhelp32Snapshot( Traits::SnapshotFl
     ags, id ) ; | 314     WindowsHandle::HandleType h = ::CreateToolhelp32Snapshot(Traits::SnapshotFla
     gs, id); | 
| 306     if ( h == INVALID_HANDLE_VALUE ) | 315     if (h == INVALID_HANDLE_VALUE) | 
| 307     { | 316     { | 
| 308       throw WindowsApiError( "CreateToolhelp32Snapshot", "INVALID_HANDLE_VALUE" 
     ) ; | 317       throw WindowsApiError("CreateToolhelp32Snapshot", "INVALID_HANDLE_VALUE"); | 
| 309     } | 318     } | 
| 310     return h ; | 319     return h; | 
| 311   } | 320   } | 
| 312 | 321 | 
| 313 protected: | 322 protected: | 
| 314   /** | 323   /** | 
| 315    * Constructor takes a snapshot. | 324    * Constructor takes a snapshot. | 
| 316    */ | 325    */ | 
| 317   Snapshot( DWORD id ) | 326   Snapshot(DWORD id) | 
| 318     : id( id ), handle( MakeHandle() ) | 327     : id(id), handle(MakeHandle()) | 
| 319   { | 328   { | 
| 320     // The various result types all define 'dwSize' with the same semantics. | 329     // The various result types all define 'dwSize' with the same semantics. | 
| 321     buffer.dwSize = sizeof( ResultType ) ; | 330     buffer.dwSize = sizeof(ResultType); | 
| 322   } | 331   } | 
| 323 | 332 | 
| 324 public: | 333 public: | 
| 325   /** | 334   /** | 
| 326    * Reconstruct the current instance with a new system snapshot. | 335    * Reconstruct the current instance with a new system snapshot. | 
| 327    * | 336    * | 
| 328    * This function uses reinitialization assignment in the WindowsHandle class, | 337    * This function uses reinitialization assignment in the WindowsHandle class, | 
| 329    *   which takes care of closing the old handle. | 338    *   which takes care of closing the old handle. | 
| 330    */ | 339    */ | 
| 331   void Refresh() | 340   void Refresh() | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 342    * | 351    * | 
| 343    * \par Design Note | 352    * \par Design Note | 
| 344    *   There's no error handling in the present version of this function. | 353    *   There's no error handling in the present version of this function. | 
| 345    *   In part that's because the underlying system call returns either true or 
     false, both of which are ordinarily valid answers. | 354    *   In part that's because the underlying system call returns either true or 
     false, both of which are ordinarily valid answers. | 
| 346    *   The trouble is that a false return is overloaded. | 355    *   The trouble is that a false return is overloaded. | 
| 347    *   It can mean either that (ordinary) there are no more items or (exceptiona
     l) the snapshot did not contain the right kind of item. | 356    *   It can mean either that (ordinary) there are no more items or (exceptiona
     l) the snapshot did not contain the right kind of item. | 
| 348    *   GetLastError is no help here; it doesn't distinguish between these cases. | 357    *   GetLastError is no help here; it doesn't distinguish between these cases. | 
| 349    *   The upshot is that we rely that our implementation calls the right functi
     ons on the snapshot, | 358    *   The upshot is that we rely that our implementation calls the right functi
     ons on the snapshot, | 
| 350    *     and so we ignore the case where we've passed bad arguments to the syste
     m call. | 359    *     and so we ignore the case where we've passed bad arguments to the syste
     m call. | 
| 351    */ | 360    */ | 
| 352   const ResultType * First() | 361   const ResultType* First() | 
| 353   { | 362   { | 
| 354     return Traits::First(handle, &buffer) ? &buffer : 0; | 363     return Traits::First(handle, &buffer) ? &buffer : 0; | 
| 355   } | 364   } | 
| 356 | 365 | 
| 357   /** | 366   /** | 
| 358    * Retrieve the next snapshot item into our member buffer and return a pointer
      to it. | 367    * Retrieve the next snapshot item into our member buffer and return a pointer
      to it. | 
| 359    * begin() must have been called first. | 368    * begin() must have been called first. | 
| 360    * | 369    * | 
| 361    * \return | 370    * \return | 
| 362    *   Pointer to our member buffer if there was a first item | 371    *   Pointer to our member buffer if there was a first item | 
| 363    *   0 otherwise | 372    *   0 otherwise | 
| 364    * | 373    * | 
| 365    * \par Design Note | 374    * \par Design Note | 
| 366    *   See the Design Note for First(); the same considerations apply here. | 375    *   See the Design Note for First(); the same considerations apply here. | 
| 367    */ | 376    */ | 
| 368   const ResultType * Next() | 377   const ResultType* Next() | 
| 369   { | 378   { | 
| 370     return Traits::Next(handle, &buffer) ? &buffer : 0; | 379     return Traits::Next(handle, &buffer) ? &buffer : 0; | 
| 371   } | 380   } | 
| 372 } ; | 381 }; | 
| 373 | 382 | 
| 374 /** | 383 /** | 
| 375  * A snapshot of all processes running on the system. | 384  * A snapshot of all processes running on the system. | 
| 376  */ | 385  */ | 
| 377 struct ProcessSnapshot | 386 struct ProcessSnapshot | 
| 378   : public Snapshot< ProcessSnapshotTraits > | 387   : public Snapshot<ProcessSnapshotTraits> | 
| 379 { | 388 { | 
| 380   ProcessSnapshot() | 389   ProcessSnapshot() | 
| 381     : Snapshot( 0 ) | 390     : Snapshot(0) | 
| 382   {} | 391   {} | 
| 383 } ; | 392 }; | 
| 384 | 393 | 
| 385 /** | 394 /** | 
| 386  * A snapshot of all modules loaded for a given process. | 395  * A snapshot of all modules loaded for a given process. | 
| 387  */ | 396  */ | 
| 388 struct ModuleSnapshot | 397 struct ModuleSnapshot | 
| 389   : public Snapshot< ModuleSnapshotTraits > | 398   : public Snapshot<ModuleSnapshotTraits> | 
| 390 { | 399 { | 
| 391   ModuleSnapshot( DWORD processId ) | 400   ModuleSnapshot(DWORD processId) | 
| 392     : Snapshot( processId ) | 401     : Snapshot(processId) | 
| 393   {} | 402   {} | 
| 394 } ; | 403 }; | 
| 395 | 404 | 
| 396 //------------------------------------------------------- | 405 //------------------------------------------------------- | 
| 397 // InitializeProcessList | 406 // InitializeProcessList | 
| 398 //------------------------------------------------------- | 407 //------------------------------------------------------- | 
| 399 /** | 408 /** | 
| 400  * \tparam T The type into which a PROCESSENTRY32W struture is extracted. | 409  * \tparam T The type into which a PROCESSENTRY32W struture is extracted. | 
| 401  * \tparam Admittance Function type for argument 'admit' | 410  * \tparam Admittance Function type for argument 'admit' | 
| 402  * \tparam Extractor Function type for argument 'extract' | 411  * \tparam Extractor Function type for argument 'extract' | 
| 403  * \param admit A unary predicate function class that determines what's included | 412  * \param admit A unary predicate function class that determines what's included | 
| 404  *»     A process appears in the list only if the predicate returns true. | 413  *   A process appears in the list only if the predicate returns true. | 
| 405  *»     The use of this predicate is analogous to that in std::copy_if. | 414  *   The use of this predicate is analogous to that in std::copy_if. | 
| 406  * \param convert A conversion function that takes a PROCESSENTRY32W as input ar
     gument and returns an element of type T. | 415  * \param convert A conversion function that takes a PROCESSENTRY32W as input ar
     gument and returns an element of type T. | 
| 407  */ | 416  */ | 
| 408 template<class T, class Admittance, class Extractor> | 417 template<class T, class Admittance, class Extractor> | 
| 409 void InitializeProcessList(std::vector<T>& v, ProcessSnapshot &snap, Admittance 
     admit = Admittance(), Extractor extract = Extractor()) | 418 void InitializeProcessList(std::vector<T>& v, ProcessSnapshot& snap, Admittance 
     admit = Admittance(), Extractor extract = Extractor()) | 
| 410 { | 419 { | 
| 411   const PROCESSENTRY32W* p = snap.First(); | 420   const PROCESSENTRY32W* p = snap.First(); | 
| 412   while (p != 0) | 421   while (p != 0) | 
| 413   { | 422   { | 
| 414     if (admit(*p )) | 423     if (admit(*p)) | 
| 415     { | 424     { | 
| 416       /* | 425       /* | 
| 417        * We don't have C++11 emplace_back, which can construct the element in pl
     ace. | 426        * We don't have C++11 emplace_back, which can construct the element in pl
     ace. | 
| 418        * Instead, we copy the return value of the converter. | 427        * Instead, we copy the return value of the converter. | 
| 419        */ | 428        */ | 
| 420       v.push_back(extract(*p)); | 429       v.push_back(extract(*p)); | 
| 421     } | 430     } | 
| 422     p = snap.Next(); | 431     p = snap.Next(); | 
| 423   } | 432   } | 
| 424 }; | 433 }; | 
| 425 | 434 | 
| 426 //------------------------------------------------------- | 435 //------------------------------------------------------- | 
| 427 // InitializeProcessSet | 436 // InitializeProcessSet | 
| 428 //------------------------------------------------------- | 437 //------------------------------------------------------- | 
| 429 /** | 438 /** | 
| 430  * \tparam T The type into which a PROCESSENTRY32W struture is extracted. | 439  * \tparam T The type into which a PROCESSENTRY32W struture is extracted. | 
| 431  * \tparam Admittance Function type for argument 'admit' | 440  * \tparam Admittance Function type for argument 'admit' | 
| 432  * \tparam Extractor Function type for argument 'extract' | 441  * \tparam Extractor Function type for argument 'extract' | 
| 433  * \param admit A unary predicate function class that determines what's included | 442  * \param admit A unary predicate function class that determines what's included | 
| 434  *»     A process appears in the list only if the predicate returns true. | 443  *   A process appears in the list only if the predicate returns true. | 
| 435  *»     The use of this predicate is analogous to that in std::copy_if. | 444  *   The use of this predicate is analogous to that in std::copy_if. | 
| 436  * \param convert A conversion function that takes a PROCESSENTRY32W as input ar
     gument and returns an element of type T. | 445  * \param convert A conversion function that takes a PROCESSENTRY32W as input ar
     gument and returns an element of type T. | 
| 437  */ | 446  */ | 
| 438 template<class T, class Admittance, class Extractor> | 447 template<class T, class Admittance, class Extractor> | 
| 439 void InitializeProcessSet(std::set< T > & set, ProcessSnapshot &snap, Admittance
      admit = Admittance(), Extractor extract = Extractor()) | 448 void InitializeProcessSet(std::set<T>& set, ProcessSnapshot& snap, Admittance ad
     mit = Admittance(), Extractor extract = Extractor()) | 
| 440 { | 449 { | 
| 441   const PROCESSENTRY32W* p = snap.First(); | 450   const PROCESSENTRY32W* p = snap.First(); | 
| 442   while (p != 0) | 451   while (p != 0) | 
| 443   { | 452   { | 
| 444     if (admit(*p)) | 453     if (admit(*p)) | 
| 445     { | 454     { | 
| 446       set.insert(extract(*p)); | 455       set.insert(extract(*p)); | 
| 447     } | 456     } | 
| 448     p = snap.Next(); | 457     p = snap.Next(); | 
| 449   } | 458   } | 
| 450 }; | 459 }; | 
| 451 | 460 | 
| 452 //------------------------------------------------------- | 461 //------------------------------------------------------- | 
| 453 // EnumerateWindows | 462 // EnumerateWindows | 
| 454 //------------------------------------------------------- | 463 //------------------------------------------------------- | 
| 455 | 464 | 
| 456 /** | 465 /** | 
| 457  * States of a window enumeration. | 466  * States of a window enumeration. | 
| 458  */ | 467  */ | 
| 459 typedef enum | 468 typedef enum | 
| 460 { | 469 { | 
| 461   started,»       ///< The iteration is currently running | 470   started,    ///< The iteration is currently running | 
| 462   normal,»        ///< Iteration terminated without error. | 471   normal,     ///< Iteration terminated without error. | 
| 463   early,»         ///< Callback returned false and terminated iteration early. | 472   early,      ///< Callback returned false and terminated iteration early. | 
| 464   exception,»     ///< Callback threw an exception and thereby terminated iterat
     ion. | 473   exception,  ///< Callback threw an exception and thereby terminated iteration. | 
| 465   error»»         ///< Callback always return true but EnumWindows failed. | 474   error       ///< Callback always return true but EnumWindows failed. | 
| 466 } EnumerateWindowsState ; | 475 } EnumerateWindowsState; | 
| 467 | 476 | 
| 468 /** | 477 /** | 
| 469  * Data to perform a window enumeration, shared between the main function and th
     e callback function. | 478  * Data to perform a window enumeration, shared between the main function and th
     e callback function. | 
| 470  */ | 479  */ | 
| 471 template< class F > | 480 template<class F> | 
| 472 struct EWData | 481 struct EWData | 
| 473 { | 482 { | 
| 474   /** | 483   /** | 
| 475    * Function to be applied to each enumerated window. | 484    * Function to be applied to each enumerated window. | 
| 476    */ | 485    */ | 
| 477   F & f ; | 486   F& f; | 
| 478 | 487 | 
| 479   /** | 488   /** | 
| 480    * Completion status of the enumeration. | 489    * Completion status of the enumeration. | 
| 481    */ | 490    */ | 
| 482   EnumerateWindowsState status ; | 491   EnumerateWindowsState status; | 
| 483 | 492 | 
| 484   /** | 493   /** | 
| 485    * An exception to be transported across the callback. | 494    * An exception to be transported across the callback. | 
| 486    * | 495    * | 
| 487    * The enumerator and the callback are not guaranteed to share a call stack, | 496    * The enumerator and the callback are not guaranteed to share a call stack, | 
| 488    *   nor need they even share compatible exception conventions, | 497    *   nor need they even share compatible exception conventions, | 
| 489    *   and might not even be in the same thread. | 498    *   and might not even be in the same thread. | 
| 490    * Thus, if the applied function throws an exception, | 499    * Thus, if the applied function throws an exception, | 
| 491    *   we catch it in the callback and re-throw it in the enumerator. | 500    *   we catch it in the callback and re-throw it in the enumerator. | 
| 492    * This member holds such an exception. | 501    * This member holds such an exception. | 
| 493    * | 502    * | 
| 494    * This member holds an exception only if 'status' has the value 'exception'. | 503    * This member holds an exception only if 'status' has the value 'exception'. | 
| 495    * Otherwise it's a null pointer. | 504    * Otherwise it's a null pointer. | 
| 496    */ | 505    */ | 
| 497   std::unique_ptr< std::exception > ee ; | 506   std::unique_ptr<std::exception> ee; | 
| 498 | 507 | 
| 499   /** | 508   /** | 
| 500    * Ordinary constructor. | 509    * Ordinary constructor. | 
| 501    */ | 510    */ | 
| 502   EWData( F & f ) | 511   EWData(F& f) | 
| 503     : f( f ), status( started ) | 512     : f(f), status(started) | 
| 504   {} | 513   {} | 
| 505 } ; | 514 }; | 
| 506 | 515 | 
| 507 /** | 516 /** | 
| 508  * Callback function for EnumWindows. | 517  * Callback function for EnumWindows. | 
| 509  * | 518  * | 
| 510  * This function provides two standard behaviors. | 519  * This function provides two standard behaviors. | 
| 511  * It records early termination of the enumeration, should that happen by the ap
     plied function returning false. | 520  * It records early termination of the enumeration, should that happen by the ap
     plied function returning false. | 
| 512  * It captures any exception thrown for transport back to the enumerator. | 521  * It captures any exception thrown for transport back to the enumerator. | 
| 513  */ | 522  */ | 
| 514 template< class F > | 523 template<class F> | 
| 515 BOOL CALLBACK EnumerationCallback( HWND window, LPARAM x ) | 524 BOOL CALLBACK EnumerationCallback(HWND window, LPARAM x) | 
| 516 { | 525 { | 
| 517   // LPARAM is always the same size as a pointer | 526   // LPARAM is always the same size as a pointer | 
| 518   EWData< F > * data = reinterpret_cast< EWData< F > * >( x ) ; | 527   EWData<F>* data = reinterpret_cast<EWData<F> *>(x); | 
| 519   /* | 528   /* | 
| 520    * Top-level try statement prevents exception from propagating back to system. | 529    * Top-level try statement prevents exception from propagating back to system. | 
| 521    */ | 530    */ | 
| 522   try | 531   try | 
| 523   { | 532   { | 
| 524     bool r = data -> f( window ) ; | 533     bool r = data -> f(window); | 
| 525     if ( ! r ) | 534     if (! r) | 
| 526     { | 535     { | 
| 527       data -> status = early ; | 536       data -> status = early; | 
| 528     } | 537     } | 
| 529     return r ; | 538     return r; | 
| 530   } | 539   } | 
| 531   catch ( std::exception e ) | 540   catch (std::exception e) | 
| 532   { | 541   { | 
| 533     data -> ee = std::unique_ptr< std::exception >( new( std::nothrow ) std::exc
     eption( e ) ) ; | 542     data -> ee = std::unique_ptr<std::exception>(new(std::nothrow) std::exceptio
     n(e)); | 
| 534     data -> status = exception ; | 543     data -> status = exception; | 
| 535     return FALSE ; | 544     return FALSE; | 
| 536   } | 545   } | 
| 537   catch ( ... ) | 546   catch (...) | 
| 538   { | 547   { | 
| 539     data -> ee = std::unique_ptr< std::exception >() ; | 548     data -> ee = std::unique_ptr<std::exception>(); | 
| 540     data -> status = exception ; | 549     data -> status = exception; | 
| 541     return FALSE ; | 550     return FALSE; | 
| 542   } | 551   } | 
| 543 } | 552 } | 
| 544 | 553 | 
| 545 /** | 554 /** | 
| 546  * Enumerate windows, applying a function to each one. | 555  * Enumerate windows, applying a function to each one. | 
| 547  */ | 556  */ | 
| 548 template< class F > | 557 template<class F> | 
| 549 bool EnumerateWindows( F f ) | 558 bool EnumerateWindows(F f) | 
| 550 { | 559 { | 
| 551   EWData< F > data( f ) ; | 560   EWData<F> data(f); | 
| 552   BOOL x( ::EnumWindows( EnumerationCallback< F >, reinterpret_cast< LPARAM >( &
      data ) ) ) ; | 561   BOOL x(::EnumWindows(EnumerationCallback<F>, reinterpret_cast<LPARAM>(& data))
     ); | 
| 553   bool r ; | 562   bool r; | 
| 554   if ( data.status != started ) | 563   if (data.status != started) | 
| 555   { | 564   { | 
| 556     // Assert status was changed within the callback | 565     // Assert status was changed within the callback | 
| 557     if ( data.status == exception ) | 566     if (data.status == exception) | 
| 558     { | 567     { | 
| 559       /* | 568       /* | 
| 560        * The callback threw an exception of some sort. | 569        * The callback threw an exception of some sort. | 
| 561        * We forward it to the extent we are able. | 570        * We forward it to the extent we are able. | 
| 562        */ | 571        */ | 
| 563       if ( data.ee ) | 572       if (data.ee) | 
| 564       { | 573       { | 
| 565 »       throw * data.ee ; | 574         throw* data.ee; | 
| 566       } | 575       } | 
| 567       else | 576       else | 
| 568       { | 577       { | 
| 569 »       throw std::runtime_error( "Unknown exception thrown in callback function
     ." ) ; | 578         throw std::runtime_error("Unknown exception thrown in callback function.
     "); | 
| 570       } | 579       } | 
| 571     } | 580     } | 
| 572     r = false ; | 581     r = false; | 
| 573   } | 582   } | 
| 574   else | 583   else | 
| 575   { | 584   { | 
| 576     if ( x ) | 585     if (x) | 
| 577     { | 586     { | 
| 578       data.status = normal ; | 587       data.status = normal; | 
| 579       r = true ; | 588       r = true; | 
| 580     } | 589     } | 
| 581     else | 590     else | 
| 582     { | 591     { | 
| 583       // Assert EnumWindows failed | 592       // Assert EnumWindows failed | 
| 584       data.status = error ; | 593       data.status = error; | 
| 585       r = false ; | 594       r = false; | 
| 586     } | 595     } | 
| 587   } | 596   } | 
| 588   return r ; | 597   return r; | 
| 589 } | 598 } | 
| 590 | 599 | 
| 591 //------------------------------------------------------- | 600 //------------------------------------------------------- | 
| 592 // ProcessCloser | 601 // ProcessCloser | 
| 593 //------------------------------------------------------- | 602 //------------------------------------------------------- | 
| 594 class ProcessCloser | 603 class ProcessCloser | 
| 595 { | 604 { | 
| 596   /** | 605   /** | 
| 597    * Set of process identifiers matching one of the executable names. | 606    * Set of process identifiers matching one of the executable names. | 
| 598    */ | 607    */ | 
| 599   std::set< DWORD > pidSet ; | 608   std::set<DWORD> pidSet; | 
| 600 | 609 | 
| 601   /** | 610   /** | 
| 602    * Set of executable names by which to filter. | 611    * Set of executable names by which to filter. | 
| 603    * | 612    * | 
| 604    * The argument of the filter constructor is a set by reference. | 613    * The argument of the filter constructor is a set by reference. | 
| 605    * Since it does not make a copy for itself, we define it as a class member to
      provide its allocation. | 614    * Since it does not make a copy for itself, we define it as a class member to
      provide its allocation. | 
| 606    */ | 615    */ | 
| 607   FileNameSet processNames ; | 616   FileNameSet processNames; | 
| 608 | 617 | 
| 609   ProcessByAnyExeNotImmersive filter ; | 618   ProcessByAnyExeNotImmersive filter; | 
| 610 | 619 | 
| 611   /** | 620   /** | 
| 612    * Copy function object copies just the process ID. | 621    * Copy function object copies just the process ID. | 
| 613    */ | 622    */ | 
| 614   CopyPID copy ; | 623   CopyPID copy; | 
| 615 | 624 | 
| 616   /** | 625   /** | 
| 617    * Snapshot of running processes. | 626    * Snapshot of running processes. | 
| 618    */ | 627    */ | 
| 619   ProcessSnapshot & snapshot ; | 628   ProcessSnapshot& snapshot; | 
| 620 | 629 | 
| 621   void update() | 630   void update() | 
| 622   { | 631   { | 
| 623     InitializeProcessSet( pidSet, snapshot, filter, copy ) ; | 632     InitializeProcessSet(pidSet, snapshot, filter, copy); | 
| 624   } ; | 633   }; | 
| 625 | 634 | 
| 626   template< class F > | 635   template<class F> | 
| 627   class OnlyOurProcesses | 636   class OnlyOurProcesses | 
| 628   { | 637   { | 
| 629     ProcessCloser & self ; | 638     ProcessCloser& self; | 
| 630 | 639 | 
| 631     F f ; | 640     F f; | 
| 632 | 641 | 
| 633   public: | 642   public: | 
| 634     OnlyOurProcesses( ProcessCloser & self, F f ) | 643     OnlyOurProcesses(ProcessCloser& self, F f) | 
| 635       : f( f ), self( self ) | 644       : f(f), self(self) | 
| 636     {} | 645     {} | 
| 637 | 646 | 
| 638     bool operator()( HWND window ) | 647     bool operator()(HWND window) | 
| 639     { | 648     { | 
| 640       bool b ; | 649       bool b; | 
| 641       try | 650       try | 
| 642       { | 651       { | 
| 643         b = self.Contains( CreatorProcess( window ) ) ; | 652         b = self.Contains(CreatorProcess(window)); | 
| 644       } | 653       } | 
| 645       catch ( ... ) | 654       catch (...) | 
| 646       { | 655       { | 
| 647         // ignore window handles that are no longer valid | 656         // ignore window handles that are no longer valid | 
| 648         return true ; | 657         return true; | 
| 649       } | 658       } | 
| 650       if ( ! b ) | 659       if (! b) | 
| 651       { | 660       { | 
| 652         // Assert the process that created the window is not in our pidSet | 661         // Assert the process that created the window is not in our pidSet | 
| 653         return true ; | 662         return true; | 
| 654       } | 663       } | 
| 655       return f( window ) ; | 664       return f(window); | 
| 656     } | 665     } | 
| 657   } ; | 666   }; | 
| 658 | 667 | 
| 659 public: | 668 public: | 
| 660   template <size_t nFileNames> | 669   template <size_t nFileNames> | 
| 661   ProcessCloser(ProcessSnapshot & snapshot, const wchar_t * (&fileNameList)[nFil
     eNames]) | 670   ProcessCloser(ProcessSnapshot& snapshot, const wchar_t* (&fileNameList)[nFileN
     ames]) | 
| 662     : snapshot(snapshot), processNames(fileNameList), filter(processNames) | 671     : snapshot(snapshot), processNames(fileNameList), filter(processNames) | 
| 663   { | 672   { | 
| 664     update() ; | 673     update(); | 
| 665   } | 674   } | 
| 666 | 675 | 
| 667   /** | 676   /** | 
| 668    * Refresh our state to match the snapshot state. | 677    * Refresh our state to match the snapshot state. | 
| 669    */ | 678    */ | 
| 670   void Refresh() | 679   void Refresh() | 
| 671   { | 680   { | 
| 672     pidSet.clear() ; | 681     pidSet.clear(); | 
| 673     update() ; | 682     update(); | 
| 674   } | 683   } | 
| 675 | 684 | 
| 676   bool IsRunning() { return ! pidSet.empty() ; } ; | 685   bool IsRunning() | 
|  | 686   { | 
|  | 687     return ! pidSet.empty() ; | 
|  | 688   }; | 
| 677 | 689 | 
| 678   bool Contains( DWORD pid ) const { return pidSet.find( pid ) != pidSet.end() ;
      } ; | 690   bool Contains(DWORD pid) const | 
|  | 691   { | 
|  | 692     return pidSet.find(pid) != pidSet.end() ; | 
|  | 693   }; | 
| 679 | 694 | 
| 680   template< class F > | 695   template<class F> | 
| 681   bool IterateOurWindows( F f ) | 696   bool IterateOurWindows(F f) | 
| 682   { | 697   { | 
| 683     OnlyOurProcesses< F > g( * this, f ) ; | 698     OnlyOurProcesses<F> g(* this, f); | 
| 684     return EnumerateWindows( g ) ; | 699     return EnumerateWindows(g); | 
| 685   } | 700   } | 
| 686 | 701 | 
| 687   /* | 702   /* | 
| 688    * Shut down every process in the pidSet. | 703    * Shut down every process in the pidSet. | 
| 689    */ | 704    */ | 
| 690   bool ShutDown(ImmediateSession& session); | 705   bool ShutDown(ImmediateSession& session); | 
| 691 | 706 | 
| 692 } ; | 707 }; | 
| 693 | 708 | 
| 694 #endif | 709 #endif | 
| OLD | NEW | 
|---|