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