Index: installer/src/installer-lib/installer-lib.h |
=================================================================== |
new file mode 100644 |
--- /dev/null |
+++ b/installer/src/installer-lib/installer-lib.h |
@@ -0,0 +1,114 @@ |
+/** |
+* \file handle.h The "install session" is the context for all custom installation behavior. |
+*/ |
+ |
+#ifndef INSTALLER_LIB_H |
+#define INSTALLER_LIB_H |
+ |
+#include <stdexcept> |
+#include <sstream> |
+ |
+/** |
+* Standard runtime error for failure of Windows API calls. |
+* |
+* The design purpose of this class is to consistently report the details of a failed API call, with an eye toward logging. |
+* All the arguments passed to the constructor appear in what(). |
+* In addition the return value of GetLastError() appears. |
+* |
+* All the types for the constructors are generic. |
+* Any type that works with the output operator '<<' of a stream will work. |
+* |
+* \par Example |
+* For a simple error, where there's not much to add over the API call and the error code itself, just omit the second argument. |
+* \code |
+* throw windows_api_error( "MsiDatabaseOpenView", "ERROR_BAD_QUERY_SYNTAX" ) |
+* \endcode |
+* |
+* \par |
+* Sometimes you don't have a symbolic error code. |
+* This example uses a numeric error and a clarifying message. |
+* \code |
+* throw windows_api_error( "MsiOpenDatabaseW", x, "MSI database is on file system" ) |
+* \endcode |
+*/ |
+class windows_api_error |
+ : public std::runtime_error |
+{ |
+ template< class T1, class T2, class T3 > |
+ static std::string make_message( T1 api_function, T2 error_code, T3 message ) |
+ { |
+ std::ostringstream r, t ; |
+ std::string s ; |
+ |
+ t << api_function ; |
+ s = t.str() ; |
+ if ( s.empty() ) |
+ { |
+ s = "<unspecified>" ; |
+ } |
+ r << s << " returned " ; |
+ |
+ t = std::ostringstream() ; |
+ t << error_code ; |
+ s = t.str() ; |
+ if ( s.empty() ) |
+ { |
+ s = "<unknown>" ; |
+ } |
+ r << s << " with last error code " << ::GetLastError() ; |
+ |
+ t = std::ostringstream() ; |
+ t << message ; |
+ s = t.str() ; |
+ if ( ! s.empty() ) |
+ { |
+ r << ": " << s ; |
+ } |
+ |
+ return r.str() ; |
+ } |
+ |
+public: |
+ /** |
+ * Constructor with additional message. |
+ * |
+ * \param api_function |
+ * The name of the API function that returned an error code or a null handle. |
+ * \param error_code |
+ * The error code that the function returned, either symbolic or numeric. |
+ * Will be zero when the function returned a null handle. |
+ * \param message |
+ * Extra message to clarify the error |
+ */ |
+ template< class T1, class T2, class T3 > |
+ windows_api_error( T1 api_function, T2 error_code, T3 message ) |
+ : std::runtime_error( make_message( api_function, error_code, message ) ) |
+ {} |
+ |
+ /** |
+ * Constructor without anything extra. |
+ * |
+ * \param api_function |
+ * The name of the API function that returned an error code or a null handle. |
+ * \param error_code |
+ * The error code that the function returned, either symbolic or numeric. |
+ * Will be zero when the function returned a null handle. |
+ */ |
+ template< class T1, class T2 > |
+ windows_api_error( T1 api_function, T2 error_code ) |
+ : std::runtime_error( make_message( api_function, error_code, "" ) ) |
+ {} |
+} ; |
+ |
+/** |
+*/ |
+class not_yet_supported |
+ : public std::runtime_error |
+{ |
+public: |
+ not_yet_supported( std::string message ) |
+ : std::runtime_error( "Not yet supported: " + message ) |
+ {} |
+} ; |
+ |
+#endif |