#pragma once #include #include #include #include #include #include #include using namespace std; #ifdef _UNICODE #define tstring wstring #define tstringstream wstringstream #else // #ifdef _UNICODE #define tstring string #define tstringstream stringstream #endif // #ifdef _UNICODE // // useful debug macros // // // pragma message macro // usage: // #pragma UDDIMSG(Fix this later) // outputs during compile: // C:\...\Foo.c(25) : Fix this later // #define UDDISTR2(x) #x #define UDDISTR(x) UDDISTR2(x) #define UDDIMSG(x) message(__FILE__ "(" UDDISTR(__LINE__) ") : " #x) // // Break macro - break in debugger // #ifdef _X86_ #define UDDIBREAK() _asm { int 3 } #endif // // Assertion macro - trace a message and break if assertion failes // #if defined( _DEBUG ) || defined( DBG ) // // Print the location and expression of the assertion and halt // #define UDDIASSERT(exp) \ if( !(exp) ) \ { \ char psz[256]; \ ::_snprintf(psz, 256, "%s(%d) : Assertion Failed! - %s\n", \ __FILE__, __LINE__, #exp); \ OutputDebugStringA(psz); \ UDDIBREAK(); \ } #else #define UDDIASSERT(exp) #endif // // Verify macro - like UDDIASSERT but remains in all builds // #define UDDIVERIFYST(exp, id, hinst) \ if( !(exp) ) \ { \ _TCHAR szLocalizedString[ 512 ]; \ ::LoadString( hinst, id, szLocalizedString, 512 ); \ OutputDebugString( szLocalizedString ); \ throw CUDDIException((HRESULT)E_FAIL, \ szLocalizedString, _T(__FILE__), \ __LINE__, _T(__TIMESTAMP__), _T(__FUNCTION__) ); \ } #define UDDIVERIFY(exp, str) \ if( !(exp) ) \ { \ OutputDebugString( str ); \ throw CUDDIException((HRESULT)E_FAIL, \ str, _T(__FILE__), \ __LINE__, _T(__TIMESTAMP__), _T(__FUNCTION__) ); \ } // // Verify an hresult - trace description of message if bad HRESULT // #define UDDIVERIFYHR(hr) \ if( !SUCCEEDED(hr) ) \ { \ LPWSTR lpMsg; \ int n = ::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | \ FORMAT_MESSAGE_FROM_SYSTEM | \ FORMAT_MESSAGE_IGNORE_INSERTS, \ NULL, (hr), 0, \ (LPWSTR)&lpMsg, 0, NULL); \ if( n != 0 ) { \ lpMsg[::wcslen(lpMsg) - 2] = 0; \ } else { \ lpMsg = L"Unknown"; \ } \ wstring strMsg(lpMsg); \ ::LocalFree(lpMsg); \ throw CUDDIException((HRESULT)(hr), strMsg, _T(__FILE__), \ __LINE__, _T(__TIMESTAMP__), _T(__FUNCTION__)); \ } // // Verify an API call - trace description of message if GetLastError fails // #define UDDIVERIFYAPI() \ if( ::GetLastError() != ERROR_SUCCESS ) \ { \ DWORD dwErr = ::GetLastError(); \ LPWSTR lpMsg; \ int n = ::FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | \ FORMAT_MESSAGE_FROM_SYSTEM | \ FORMAT_MESSAGE_IGNORE_INSERTS, \ NULL, dwErr, 0, \ (LPWSTR)&lpMsg, 0, NULL); \ if( n != 0 ) { \ lpMsg[ ::wcslen(lpMsg) - 2 ] = 0; \ } else { \ lpMsg = L"Unknown"; \ } \ wstring strMsg( lpMsg ); \ ::LocalFree(lpMsg); \ throw CUDDIException((dwErr), strMsg.c_str(), _T(__FILE__), \ __LINE__, _T(__TIMESTAMP__), _T(__FUNCTION__) ); \ } // // main tracing function // void UDDITRACE( const char* pszFile, int nLine, int nSev, int nCat, const wchar_t* pszContext, const wchar_t* pszFormat, ... ); // // Severity codes // use when calling UDDITRACE to pull in file/line number // #define UDDI_SEVERITY_ERR __FILE__, __LINE__, 0x01 // EVENTLOG_ERROR_TYPE These are in WINNT.H #define UDDI_SEVERITY_WARN __FILE__, __LINE__, 0x02 // EVENTLOG_WARNING_TYPE #define UDDI_SEVERITY_INFO __FILE__, __LINE__, 0x04 // EVENTLOG_INFORMATION_TYPE #define UDDI_SEVERITY_PASS __FILE__, __LINE__, 0x08 // EVENTLOG_AUDIT_SUCCESS #define UDDI_SEVERITY_FAIL __FILE__, __LINE__, 0x10 // EVENTLOG_AUDIT_FAILURE #define UDDI_SEVERITY_VERB __FILE__, __LINE__, 0x20 // most detailed output // // Category codes // #define UDDI_CATEGORY_NONE 0x00 #define UDDI_CATEGORY_UI 0x01 #define UDDI_CATEGORY_MMC 0x02 #define UDDI_CATEGORY_INSTALL 0x03 // // Class CUDDIException // General exception class used for exception handling throughout. // class CUDDIException { public: // // Default constructor for CUDDIException // Simply sets default parameters. // CUDDIException() : m_dwErr( -1 ) , m_hrErr( E_FAIL ) , m_sErr( _T( "Unknown error" ) ) , m_iLine( -1 ) {} // // Copy constructor for CUDDIException // Deep copy from _copy. // Params: // _copy - the source object from which to copy. // CUDDIException( const CUDDIException& _copy ) : m_dwErr( _copy.m_dwErr ) , m_hrErr( _copy.m_hrErr ) , m_sErr( _copy.m_sErr ) , m_sBuildTimestamp( _copy.m_sBuildTimestamp ) , m_sFile( _copy.m_sFile ) , m_iLine( _copy.m_iLine ) , m_sFunction( _copy.m_sFunction ) {} // // Constructor for CUDDIException // Generates error info from a DWORD, meaning that it assumes // the DWORD was generated from GetLastError() and uses the // system FormatMessage() function to get the error text. // Params: // _err - a value returned from GetLastError(). // _file - the source file name where the error occurred. // _line - the line number in the source where the error // occurred. // _timestamp - the build timestamp of the file where the // error occurred. // CUDDIException( DWORD _err, const tstring& _file = _T( "" ), int _line = -1, const tstring& _timestamp = _T( "" ), const tstring& _function = _T("") ) : m_dwErr( _err ) , m_hrErr( E_FAIL ) , m_sBuildTimestamp( _timestamp ) , m_sFile( _file ) , m_iLine( _line ) , m_sFunction( _function ) { LPVOID lpMsgBuf; FormatMessage( // Gets the error text from the OS FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, _err, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), ( LPTSTR )&lpMsgBuf, 0, NULL ); m_sErr = ( LPTSTR )lpMsgBuf; LocalFree( lpMsgBuf ); } // // Constructor for CUDDIException // Stores error info from a DWORD and passed-in string. // Params: // _err - a DWORD error value. // _str - error text. // _file - the source file name where the error occurred. // _line - the line number in the source where the error // occurred. // _timestamp - the build timestamp of the file where the // error occurred. // CUDDIException( DWORD _err, const tstring& _str, const tstring& _file = _T( "" ), int _line = -1, const tstring& _timestamp = _T( "" ), const tstring& _function = _T("") ) : m_dwErr( _err ) , m_sErr( _str ) , m_hrErr( E_FAIL ) , m_sBuildTimestamp( _timestamp ) , m_sFile( _file ) , m_iLine( _line ) , m_sFunction(_function) {} // // Constructor for CUDDIException // Stores error info from an HRESULT and an error string. // Params: // _hr - an HRESULT. // _str - an error string. // _file - the source file name where the error occurred. // _line - the line number in the source where the error // occurred. // _timestamp - the build timestamp of the file where the // error occurred. // CUDDIException( HRESULT _hr, const tstring& _str, const tstring& _file = _T( "" ), int _line = -1, const tstring& _timestamp = _T( "" ), const tstring& _function = _T("") ) : m_dwErr( -1 ) , m_sErr( _str ) , m_hrErr( _hr ) , m_sBuildTimestamp( _timestamp ) , m_sFile( _file ) , m_iLine( _line ) , m_sFunction( _function ) {} // // Constructor for CUDDIException // Stores error info from an error string. // Params: // _str - an error string. // _file - the source file name where the error occurred. // _line - the line number in the source where the error // occurred. // _timestamp - the build timestamp of the file where the // error occurred. // CUDDIException( const tstring& _str, const tstring& _file = _T( "" ), int _line = -1, const tstring& _timestamp = _T( "" ), const tstring& _function = _T("") ) : m_dwErr( -1 ) , m_sErr( _str ) , m_hrErr( E_FAIL ) , m_sBuildTimestamp( _timestamp ) , m_sFile( _file ) , m_iLine( _line ) , m_sFunction( _function ) {} // // Assignment operator for CUDDIException // Deep copy from _copy. // Params: // _copy - the source object from which to copy. // CUDDIException& operator=( const CUDDIException& _copy ) { m_dwErr = _copy.m_dwErr; m_hrErr = _copy.m_hrErr; m_sErr = _copy.m_sErr; m_sBuildTimestamp = _copy.m_sBuildTimestamp; m_sFile = _copy.m_sFile; m_iLine = _copy.m_iLine; m_sFunction = _copy.m_sFunction; } // // Cast operators // We use cast operators to return the various error values // that can be stored in the error object. Thus, the following // code is possible: // CUDDIException _err( GetLastError() ); // DWORD dwErr = _err; // this will be GetLastError() // HRESULT hrErr = _err; // this will be E_FAIL // Tstring strErr = _err; // this will be the text description // // of GetLastError // operator DWORD() const { return m_dwErr; } operator HRESULT() const { return m_hrErr; } operator const tstring&() const { return m_sErr; } operator LPCTSTR() const { return m_sErr.c_str(); } const tstring& GetTimeStamp() const { return m_sBuildTimestamp; } const tstring& GetFile() const { return m_sFile; } int GetLine() const { return m_iLine; } const tstring& GetFunction() const { return m_sFunction; } const tstring GetEntireError() const { tstringstream strm; strm << _T("Error: ") << m_sErr << _T("\nCode: 0x") << hex << m_hrErr; #if defined(_DEBUG) || defined(DBG) strm << _T("\nFile: ") << m_sFile << _T("\nFunction: ") << m_sFunction << _T("\nLine: ") << m_iLine; #endif return strm.str(); } private: DWORD m_dwErr; HRESULT m_hrErr; tstring m_sErr; tstring m_sBuildTimestamp; tstring m_sFile; tstring m_sFunction; int m_iLine; }; #define THROW_UDDIEXCEPTION_ST( _hr_, _id_, _hinst_ ) \ _TCHAR szLocalizedString[ 1024 ]; \ ::LoadString( _hinst_, _id_, szLocalizedString, 1024 ); \ throw CUDDIException((HRESULT)_hr_, \ szLocalizedString, _T(__FILE__), \ __LINE__, _T(__TIMESTAMP__), _T(__FUNCTION__) ); \ #define THROW_UDDIEXCEPTION( _hr_, _str_ ) \ throw CUDDIException( (HRESULT)(_hr_), _str_, _T( __FILE__ ), __LINE__, _T( __TIMESTAMP__ ), _T( __FUNCTION__) ); #define THROW_UDDIEXCEPTION_RC( _rc_, _str_ ) \ throw CUDDIException( (DWORD)(_rc_), _str_, _T( __FILE__ ), __LINE__, _T( __TIMESTAMP__ ), _T( __FUNCTION__) ); // // // typedef vector StringVector; class CUDDIRegistryKey { public: CUDDIRegistryKey( const tstring& szRoot, REGSAM access = KEY_ALL_ACCESS, const tstring& szComputer=_T("") ); CUDDIRegistryKey( HKEY hHive, const tstring& szRoot, REGSAM access = KEY_ALL_ACCESS, const tstring& szComputer=_T("") ); ~CUDDIRegistryKey(); void Close(); DWORD GetDWORD( const LPCTSTR szName, DWORD dwDefault ); DWORD GetDWORD( const LPCTSTR szName ); tstring GetString( const LPCTSTR szName, const LPCTSTR szDefault ); tstring GetString( const LPCTSTR szName ); void GetMultiString( const LPCTSTR szName, StringVector& strs ); void SetValue( const LPCTSTR szName, DWORD dwValue ); void SetValue( const LPCTSTR szName, LPCTSTR szValue ); void DeleteValue( const tstring& szValue ); static void Create( HKEY hHive, const tstring& szPath, const tstring& szComputer=_T("") ); static void DeleteKey( HKEY hHive, const tstring& szPath, const tstring& szComputer=_T("") ); static BOOL KeyExists( HKEY hHive, const tstring& szPath, const tstring& szComputer=_T("") ); // // implements the "get" property for the registry key handle // HKEY GetCurrentHandle() { return m_hkey; } private: HKEY m_hHive; HKEY m_hkey; tstring m_szRoot; }; void UDDIMsgBox( HWND hwndParent, int idMsg, int idTitle, UINT nType, LPCTSTR szDetail = NULL ); void UDDIMsgBox( HWND hwndParent, LPCTSTR szMsg, int idTitle, UINT nType, LPCTSTR szDetail = NULL ); wstring LocalizedDate( const wstring& str ); wstring LocalizedDateTime( const wstring& str );