Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: installer/src/installer-lib/process.h

Issue 29329159: Issue #1185 - Fix formatting in installer-lib and its tests (Closed)
Patch Set: Created Oct. 15, 2015, 7:03 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « installer/src/installer-lib/interaction.cpp ('k') | installer/src/installer-lib/process.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
OLDNEW
« no previous file with comments | « installer/src/installer-lib/interaction.cpp ('k') | installer/src/installer-lib/process.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld