tinyphone/tinyphone-installer/actions/LogResult.cpp
2018-12-20 03:54:49 +05:30

132 lines
3.7 KiB
C++

#include "stdafx.h"
#include <stdlib.h>
#include <lmerr.h>
// WiX Header Files:
#include <wcautil.h>
#include <strutil.h>
//
// This code modified from MSDN article 256348
// "How to obtain error message descriptions using the FormatMessage API"
// Currently found at http://support.microsoft.com/kb/256348/en-us
#define ERRMSGBUFFERSIZE 256
/**
* Use FormatMessage() to look an error code and log the error text.
*
* @param dwErrorMsgId The error code to be investigated.
*/
void LogError( DWORD dwErrorMsgId )
{
HLOCAL pBuffer = NULL; // Buffer to hold the textual error description.
DWORD ret = 0; // Temp space to hold a return value.
HINSTANCE hInst = NULL; // Instance handle for DLL.
BOOL doLookup = TRUE;
DWORD dwMessageId = dwErrorMsgId;
LPCSTR pMessage = "Error %d";
DWORD flags= FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS;
if ( HRESULT_FACILITY(dwErrorMsgId) == FACILITY_MSMQ ) {
hInst = LoadLibrary( TEXT("MQUTIL.DLL") );
flags |= FORMAT_MESSAGE_FROM_HMODULE;
doLookup = ( NULL != hInst );
} else if ( dwErrorMsgId >= NERR_BASE && dwErrorMsgId <= MAX_NERR ) {
hInst = LoadLibrary( TEXT("NETMSG.DLL") );
flags |= FORMAT_MESSAGE_FROM_HMODULE;
doLookup = ( NULL != hInst );
} else if ( HRESULT_FACILITY(dwErrorMsgId) == FACILITY_WIN32 ) {
// A "GetLastError" error, drop the HRESULT_FACILITY
dwMessageId &= 0x0000FFFF;
flags |= FORMAT_MESSAGE_FROM_SYSTEM;
}
if ( doLookup ) {
ret = FormatMessageA(
flags,
hInst, // Handle to the DLL.
dwMessageId, // Message identifier.
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language.
(LPSTR)&pBuffer, // Buffer that will hold the text string.
ERRMSGBUFFERSIZE, // Allocate at least this many chars for pBuffer.
NULL // No insert values.
);
}
if ( 0 < ret && NULL != pBuffer ) {
pMessage = (LPSTR)pBuffer;
}
// Display the string.
if ( WcaIsInitialized() ) {
WcaLogError( dwErrorMsgId, pMessage, dwMessageId );
} else {
// Log to stdout/stderr
fprintf_s( stderr, pMessage, dwMessageId );
if ( '\n'!= pMessage[ strlen(pMessage) - 1 ] ) {
fprintf_s( stderr, "\n");
}
}
// Free the buffer.
LocalFree( pBuffer );
}
void LogResult(
__in HRESULT hr,
__in_z __format_string PCSTR fmt, ...
)
{
// This code taken from MSDN vsprintf example found currently at
// http://msdn.microsoft.com/en-us/library/28d5ce15(v=vs.71).aspx
// ...and then modified... because it doesn't seem to work!
va_list args;
int len;
char * buffer;
va_start( args, fmt );
#pragma warning( push )
#pragma warning( disable : 4995 )
#pragma warning( disable : 4996 )
len = _vsnprintf( NULL, 0, fmt, args ) + 1;
#pragma warning( pop )
buffer = (char*)malloc( len * sizeof(char) );
#ifdef _DEBUG
::ZeroMemory(buffer, len);
#endif // _DEBUG
_vsnprintf_s( buffer, len, len-1, fmt, args );
// (MSDN code complete)
// Now that the buffer holds the formatted string, send it to
// the appropriate output.
if ( WcaIsInitialized() )
{
if ( FAILED( hr ) )
{
WcaLogError( hr, buffer );
LogError( hr );
}
else
{
WcaLog( LOGMSG_STANDARD, buffer );
}
}
else // Log to stdout/stderr
{
if ( FAILED( hr ) )
{
fprintf_s( stderr, "%s\n", buffer );
LogError( hr );
}
else
{
fprintf_s( stdout, "%s\n", buffer );
}
}
free( buffer );
}