Index: installer/src/installer-lib/process.h |
=================================================================== |
--- a/installer/src/installer-lib/process.h |
+++ b/installer/src/installer-lib/process.h |
@@ -4,6 +4,8 @@ |
#ifndef PROCESS_H |
#define PROCESS_H |
+ |
+#include "handle.h" |
#include <vector> |
#include <set> |
@@ -13,71 +15,6 @@ |
#include <Windows.h> |
#include <TlHelp32.h> |
-//------------------------------------------------------- |
-// Windows_Handle |
-//------------------------------------------------------- |
-/** |
- * A handle to some Windows platform resource. |
- * |
- * Note, this is not the same as a Windows Installer handle (MSIHANDLE). |
- * The two handles have different underlying types and use different functions to close. |
- */ |
-class Windows_Handle |
-{ |
-public: |
- /** |
- * Ordinary constructor. |
- * |
- * Validates argument against INVALID_HANDLE_VALUE. No other checks performed. |
- */ |
- Windows_Handle( HANDLE h ) ; |
- |
- /** |
- * Destructor |
- */ |
- ~Windows_Handle() ; |
- |
- /** |
- * Conversion operator to underlying HANDLE. |
- */ |
- operator HANDLE() const { return handle ; } ; |
- |
- /** |
- * Raw handle assignment. |
- * |
- * This is equivalent to destroying the old object and constructing a new one in its place. |
- * In C++11 this would be handled by the move constructor on an rvalue reference. |
- */ |
- void operator=( HANDLE h ) ; |
- |
-private: |
- /** |
- * \invariant The handle is an open handle to some system resource. |
- */ |
- HANDLE handle ; |
- |
- /** |
- * Validation function for the handle. Invoked at both construction and assignment. |
- */ |
- void validate_handle() ; |
- |
- /** |
- * Copy constructor declared private and not defined. |
- * |
- * \par Implementation |
- * Add "= delete" for C++11. |
- */ |
- Windows_Handle( const Windows_Handle & ) ; |
- |
- /** |
- * Copy assignment declared private and not defined. |
- * |
- * \par Implementation |
- * Add "= delete" for C++11. |
- */ |
- Windows_Handle operator=( const Windows_Handle & ) ; |
- |
-}; |
//------------------------------------------------------- |
// exe_name_set: case-insensitive wide-string set |
@@ -361,12 +298,34 @@ |
template< class F > |
struct ew_data |
{ |
+ /** |
+ * Function to be applied to each enumerated window. |
+ */ |
F & f ; |
+ /** |
+ * Completion status of the enumeration. |
+ */ |
enumerate_windows_state status ; |
+ /** |
+ * An exception to be transported across the callback. |
+ * |
+ * The enumerator and the callback are not guaranteed to share a call stack, |
+ * nor need they even share compatible exception conventions, |
+ * and might not even be in the same thread. |
+ * Thus, if the applied function throws an exception, |
+ * we catch it in the callback and re-throw it in the enumerator. |
+ * This member holds such an exception. |
+ * |
+ * This member holds an exception only if 'status' has the value 'exception'. |
+ * Otherwise it's a null pointer. |
+ */ |
std::unique_ptr< std::exception > ee ; |
+ /** |
+ * Ordinary constructor. |
+ */ |
ew_data( F & f ) |
: f( f ), status( started ) |
{} |
@@ -374,12 +333,19 @@ |
/** |
* Callback function for EnumWindows. |
+ * |
+ * This function provides two standard behaviors. |
+ * It records early termination of the enumeration, should that happen by the applied function returning false. |
+ * It captures any exception thrown for transport back to the enumerator. |
*/ |
template< class F > |
BOOL CALLBACK enumeration_callback( HWND window, LPARAM x ) |
{ |
// LPARAM is always the same size as a pointer |
ew_data< F > * data = reinterpret_cast< ew_data< F > * >( x ) ; |
+ /* |
+ * Top-level try statement prevents exception from propagating back to system. |
+ */ |
try |
{ |
bool r = data -> f( window ) ; |
@@ -397,10 +363,10 @@ |
} |
catch ( ... ) |
{ |
+ data -> ee = std::unique_ptr< std::exception >() ; |
data -> status = exception ; |
return FALSE ; |
} |
- return TRUE ; |
} |
/** |