2025-04-27 07:49:33 -04:00

284 lines
6.9 KiB
C++

// ErrorSupport.cpp: implementation of the CErrorSupport class.
#include "stdafx.h"
#include "ErrorSupport.h"
WORD IntCategoryFromMessageID(DWORD x) {return (WORD)(((x) & 0x0000F000) >> 12);}
// ---------------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------------
CErrorSupport::CErrorSupport(CLSID clsidMyCLSID, LPCTSTR szEventSource)
{
TCHAR *szTmp;
ProgIDFromCLSID(clsidMyCLSID, (unsigned short **) &szTmp);
m_bstrErrorSource = szTmp;
CoTaskMemFree(szTmp);
_tcscpy(m_szEventSource, szEventSource);
}
// ---------------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------------
CErrorSupport::CErrorSupport(LPCTSTR szErrorSource, LPCTSTR szEventSource)
{
m_bstrErrorSource = szErrorSource;
_tcscpy(m_szEventSource, szEventSource);
}
// ---------------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------------
void CErrorSupport::Log(HRESULT hr,
LPCTSTR szLineNum,
LPCTSTR szMethodName,
WORD wCategory,
WORD wMsgType,
DWORD dwMsgID,
LPCTSTR szFormat, ...)
{
va_list vl;
DWORD cStrings;
LPCTSTR *prgStrings;
CAtlArray<LPTSTR> rgStrings;
va_start(vl, szFormat);
// Build up the string list
//
if (szFormat != NULL)
{
InternalBuildStringList(hr, szLineNum, szMethodName, szFormat, &vl, &rgStrings);
cStrings = rgStrings.GetCount();
prgStrings = (LPCTSTR *)&rgStrings[0];
}
else
{
cStrings = 0;
prgStrings = NULL;
}
// Call the LogEvent function
//
InternalLogEvent(wCategory, dwMsgID, wMsgType, cStrings, prgStrings);
}
// ---------------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------------
HRESULT CErrorSupport::InternalLogEvent(WORD wCategory, DWORD dwMsgID, WORD wMsgType, DWORD cStrings, LPCTSTR *rgStrings)
{
BOOL nRetVal;
HRESULT hr;
HANDLE hEventSource = NULL;
// Register the event source
if ((hEventSource = RegisterEventSource(NULL, m_szEventSource)) == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto exit;
}
// Log the event
nRetVal = ReportEvent(hEventSource,
wMsgType,
wCategory,
dwMsgID,
NULL,
(WORD) cStrings,
0,
rgStrings,
NULL);
if (!nRetVal)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto exit;
}
hr = S_OK;
exit:
if (hEventSource != NULL)
DeregisterEventSource(hEventSource);
return hr;
}
// ---------------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------------
HRESULT CErrorSupport::InternalFormatOneString(TCHAR cFmt, va_list *pvl, BSTR *pbstr)
{
USES_CONVERSION;
DWORD dwMisc;
int iMisc;
LPTSTR pszMisc;
HRESULT hr;
VARIANT var;
TCHAR szSmallBuff[100];
LPVOID lpMsgBuf = NULL;
const DWORD MAX_ARG = 256;
__try
{
switch (cFmt)
{
case 'i':
iMisc = va_arg(*pvl, int);
_stprintf(szSmallBuff, _T("%d"), iMisc);
*pbstr = SysAllocString(T2W(szSmallBuff));
break;
case 'h':
case 'x':
iMisc = va_arg(*pvl, int);
_stprintf(szSmallBuff, _T("0x%x"), iMisc);
*pbstr = SysAllocString(T2W(szSmallBuff));
break;
case 'e':
iMisc = va_arg(*pvl, int);
dwMisc = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
(HRESULT_FACILITY(iMisc) == FACILITY_WIN32) ? HRESULT_CODE(iMisc) : iMisc,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
MAX_ARG,
NULL);
if (dwMisc)
{
LPTSTR psz;
if ((psz = (LPTSTR)alloca((dwMisc + 100) * sizeof(TCHAR))) == NULL)
{
hr = E_OUTOFMEMORY;
goto exit;
}
_stprintf(psz, _T("Error (0x%x): %s"), iMisc, lpMsgBuf);
*pbstr = SysAllocString(T2W(psz));
}
else
_stprintf(szSmallBuff, _T("Returned error: 0x%x"), iMisc);
break;
case 'c':
V_VT(&var) = VT_CY;
V_CY(&var) = va_arg(*pvl, CURRENCY);
hr = VariantChangeType(&var, &var, NULL, VT_BSTR);
if (FAILED(hr))
*pbstr = SysAllocString(_T("??.??"));
*pbstr = V_BSTR(&var);
break;
case 's':
pszMisc = va_arg(*pvl, TCHAR *);
*pbstr = SysAllocString(T2W(pszMisc));
break;
default:
_ASSERTE(FALSE);
*pbstr = SysAllocString(L"<Invalid format character>");
break;
}
hr = S_OK;
exit:;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
#if _DEBUG
OutputDebugString(_T("An exception occured in FormatOneString(). The arguments passed to LogEventMulti() or AddErrorEx() were incorrect.\n"));
_ASSERTE(FALSE);
*pbstr = SysAllocString(L"<ERROR>");
#endif // _DEBUG
}
if (lpMsgBuf != NULL)
LocalFree(lpMsgBuf);
return hr;
}
// ---------------------------------------------------------------------------------
//
//
// ---------------------------------------------------------------------------------
HRESULT CErrorSupport::InternalBuildStringList(HRESULT hrResult, LPCTSTR szLineNum, LPCTSTR szMethodName, LPCTSTR pszFmt, va_list *pvl, CAtlArray<LPTSTR> *prgStrings)
{
HRESULT hr;
BSTR bstr;
LPTSTR psz;
int i;
if (pszFmt != NULL)
{
for (i = 0; pszFmt[i] != NULL; i++)
{
hr = InternalFormatOneString(pszFmt[i], pvl, &bstr);
if (FAILED(hr))
goto exit;
psz = new TCHAR[SysStringLen(bstr)+1];
_tcscpy(psz, W2T(bstr));
prgStrings->Add(psz);
SysFreeString(bstr);
}
TCHAR szLastString[512];
_stprintf(szLastString, _T("\r\n\r\n\r\n%s, method/function:%s [%s] \r\n(HRESULT=0x%x)"), m_bstrErrorSource,
szMethodName, szLineNum, hrResult);
psz = new TCHAR[_tcslen(szLastString)];
_tcscpy(psz, szLastString);
prgStrings->Add(psz);
}
else
{
_ASSERTE(FALSE);
}
hr = S_OK;
exit:
#if _DEBUG
if (FAILED(hr))
{
TCHAR szMsg[200];
_stprintf(szMsg, _T("BuildStringList() was unable to process the va_list for LogEventMulti() or AddErrorEx(). Error 0x%x\n"), hr);
OutputDebugString(szMsg);
}
#endif _DEBUG
return hr;
}