You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
772 lines
20 KiB
772 lines
20 KiB
//+--------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1999
|
|
//
|
|
// File: error.cpp
|
|
//
|
|
// Contents: Cert Server error wrapper routines
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
#include <pch.cpp>
|
|
|
|
#pragma hdrstop
|
|
|
|
#include <assert.h>
|
|
#include <ntdsbmsg.h>
|
|
#include <delayimp.h>
|
|
#include <wininet.h>
|
|
#include "resource.h"
|
|
|
|
#define __dwFILE__ __dwFILE_CERTCLIB_ERROR_CPP__
|
|
|
|
#define DBG_CERTSRV_DEBUG_PRINT
|
|
|
|
|
|
#define CERTLIB_12BITERRORMASK 0x00000fff
|
|
#define CERTLIB_WIN32ERRORMASK 0x0000ffff
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
// Jet errors:
|
|
|
|
#define HRESULT_FROM_JETWARNING(jerr) \
|
|
(ERROR_SEVERITY_WARNING | (FACILITY_NTDSB << 16) | jerr)
|
|
|
|
#define HRESULT_FROM_JETERROR(jerr) \
|
|
(ERROR_SEVERITY_ERROR | (FACILITY_NTDSB << 16) | -jerr)
|
|
|
|
#define JETERROR_FROM_HRESULT(hr) \
|
|
(-(LONG) (CERTLIB_WIN32ERRORMASK & (hr)))
|
|
|
|
#define ISJETERROR(hr) \
|
|
((~CERTLIB_WIN32ERRORMASK & (hr)) == (HRESULT) ~CERTLIB_WIN32ERRORMASK)
|
|
|
|
#define ISJETHRESULT(hr) \
|
|
((~CERTLIB_WIN32ERRORMASK & (hr)) == (HRESULT) (ERROR_SEVERITY_ERROR | \
|
|
(FACILITY_NTDSB << 16)))
|
|
|
|
#define wszJETERRORPREFIX L"ESE"
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
// Setup API errors:
|
|
|
|
#define ISSETUPHRESULT(hr) \
|
|
((~CERTLIB_WIN32ERRORMASK & (hr)) == (HRESULT) (ERROR_SEVERITY_ERROR | \
|
|
APPLICATION_ERROR_MASK | \
|
|
(FACILITY_NULL << 16)))
|
|
|
|
#define wszSETUPERRORPREFIX L"INF"
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
// Win32 errors:
|
|
|
|
#define ISWIN32ERROR(hr) \
|
|
((~CERTLIB_WIN32ERRORMASK & (hr)) == 0)
|
|
|
|
#define ISWIN32HRESULT(hr) \
|
|
((~CERTLIB_WIN32ERRORMASK & (hr)) == (HRESULT) (ERROR_SEVERITY_WARNING | \
|
|
(FACILITY_WIN32 << 16)))
|
|
|
|
#define WIN32ERROR_FROM_HRESULT(hr) \
|
|
(CERTLIB_WIN32ERRORMASK & (hr))
|
|
|
|
#define wszWIN32ERRORPREFIX L"WIN32"
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
// Http errors:
|
|
|
|
#define ISHTTPERROR(hr) \
|
|
((HRESULT) HTTP_STATUS_FIRST <= (hr) && (HRESULT) HTTP_STATUS_LAST >= (hr))
|
|
|
|
#define ISHTTPHRESULT(hr) \
|
|
(ISWIN32HRESULT(hr) && ISHTTPERROR(WIN32ERROR_FROM_HRESULT(hr)))
|
|
|
|
#define wszHTTPERRORPREFIX L"HTTP"
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
// Delayload errors:
|
|
|
|
#define DELAYLOAD_FROM_WIN32(hr) VcppException(ERROR_SEVERITY_ERROR, (hr))
|
|
|
|
#define WIN32ERROR_FROM_DELAYLOAD(hr) (CERTLIB_WIN32ERRORMASK & (hr))
|
|
|
|
#define ISDELAYLOADHRESULTFACILITY(hr) \
|
|
((~CERTLIB_WIN32ERRORMASK & (hr)) == (HRESULT) (ERROR_SEVERITY_ERROR | \
|
|
(FACILITY_VISUALCPP << 16)))
|
|
|
|
// E_DELAYLOAD_MOD_NOT_FOUND 0xc06d007e
|
|
#define E_DELAYLOAD_MOD_NOT_FOUND DELAYLOAD_FROM_WIN32(ERROR_MOD_NOT_FOUND)
|
|
|
|
// E_DELAYLOAD_PROC_NOT_FOUND 0xc06d007f
|
|
#define E_DELAYLOAD_PROC_NOT_FOUND DELAYLOAD_FROM_WIN32(ERROR_PROC_NOT_FOUND)
|
|
|
|
#define ISDELAYLOADHRESULT(hr) \
|
|
((HRESULT) E_DELAYLOAD_MOD_NOT_FOUND == (hr) || \
|
|
(HRESULT) E_DELAYLOAD_PROC_NOT_FOUND == (hr) || \
|
|
HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND) == (hr) || \
|
|
HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND) == (hr))
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
// ASN encoding errors:
|
|
|
|
#define ISOSSERROR(hr) \
|
|
((~CERTLIB_12BITERRORMASK & (hr)) == CRYPT_E_OSS_ERROR)
|
|
|
|
#define OSSERROR_FROM_HRESULT(hr) \
|
|
(CERTLIB_12BITERRORMASK & (hr))
|
|
|
|
#define wszOSSERRORPREFIX L"ASN"
|
|
|
|
|
|
HRESULT
|
|
myJetHResult(
|
|
IN HRESULT hr)
|
|
{
|
|
#if DBG_CERTSRV
|
|
HRESULT hrIn = hr;
|
|
#endif
|
|
if (S_OK != hr)
|
|
{
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
#if 0
|
|
hr = HRESULT_FROM_JETWARNING(hr);
|
|
#else
|
|
if (S_FALSE != hr)
|
|
{
|
|
_PrintError(hr, "JetHResult: mapping to S_FALSE");
|
|
}
|
|
CSASSERT(S_FALSE == hr);
|
|
hr = S_FALSE;
|
|
#endif
|
|
}
|
|
else if (ISJETERROR(hr))
|
|
{
|
|
hr = HRESULT_FROM_JETERROR(hr);
|
|
}
|
|
}
|
|
#if DBG_CERTSRV
|
|
if (S_OK != hrIn || S_OK != hr)
|
|
{
|
|
DBGPRINT((
|
|
DBG_SS_CERTLIBI,
|
|
"myJetHResult(%x (%d)) --> %x (%d)\n",
|
|
hrIn,
|
|
hrIn,
|
|
hr,
|
|
hr));
|
|
}
|
|
#endif
|
|
CSASSERT(S_OK == hr || S_FALSE == hr || FAILED(hr));
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
myHExceptionCode(
|
|
IN EXCEPTION_POINTERS const *pep)
|
|
{
|
|
HRESULT hr = pep->ExceptionRecord->ExceptionCode;
|
|
|
|
#if (0 == i386)
|
|
if ((HRESULT) STATUS_DATATYPE_MISALIGNMENT == hr)
|
|
{
|
|
hr = CERTSRV_E_ALIGNMENT_FAULT;
|
|
}
|
|
#endif
|
|
return(myHError(hr));
|
|
}
|
|
|
|
|
|
#ifdef DBG_CERTSRV_DEBUG_PRINT
|
|
|
|
VOID
|
|
myCaptureStackBackTrace(
|
|
EXCEPTION_POINTERS const *pep,
|
|
ULONG cSkip,
|
|
ULONG cFrames,
|
|
ULONG *aeip)
|
|
{
|
|
ZeroMemory(aeip, cFrames * sizeof(aeip[0]));
|
|
|
|
#if i386 == 1
|
|
ULONG ieip, *pebp;
|
|
ULONG *pebpMax = (ULONG *) MAXLONG; // 2 * 1024 * 1024 * 1024; // 2 gig - 1
|
|
ULONG *pebpMin = (ULONG *) (64 * 1024); // 64k
|
|
|
|
if (pep == NULL)
|
|
{
|
|
ieip = 0;
|
|
cSkip++; // always skip current frame
|
|
pebp = ((ULONG *) &pep) - 2;
|
|
}
|
|
else
|
|
{
|
|
ieip = 1;
|
|
assert(cSkip == 0);
|
|
aeip[0] = pep->ContextRecord->Eip;
|
|
pebp = (ULONG *) pep->ContextRecord->Ebp;
|
|
}
|
|
if (pebp >= pebpMin && pebp < pebpMax)
|
|
{
|
|
__try
|
|
{
|
|
for ( ; ieip < cSkip + cFrames; ieip++)
|
|
{
|
|
if (ieip >= cSkip)
|
|
{
|
|
aeip[ieip - cSkip] = *(pebp + 1); // save an eip
|
|
}
|
|
|
|
ULONG *pebpNext = (ULONG *) *pebp;
|
|
if (pebpNext < pebp + 2 || pebpNext >= pebpMax - 1)
|
|
{
|
|
break;
|
|
}
|
|
pebp = pebpNext;
|
|
}
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
;
|
|
}
|
|
}
|
|
#endif // i386 == 1
|
|
}
|
|
|
|
#endif // ifdef DBG_CERTSRV_DEBUG_PRINT
|
|
|
|
|
|
FNLOGEXCEPTION *s_pfnLogException = NULL;
|
|
|
|
VOID
|
|
myLogExceptionInit(
|
|
OPTIONAL IN FNLOGEXCEPTION *pfnLogException)
|
|
{
|
|
s_pfnLogException = pfnLogException;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
myHExceptionCodePrint(
|
|
IN EXCEPTION_POINTERS const *pep,
|
|
OPTIONAL IN char const *pszFile,
|
|
IN DWORD dwFile,
|
|
IN DWORD dwLine)
|
|
{
|
|
HRESULT hr;
|
|
#ifdef DBG_CERTSRV_DEBUG_PRINT
|
|
|
|
if (DbgIsSSActive(DBG_SS_ERROR) &&
|
|
(!myIsDelayLoadHResult(pep->ExceptionRecord->ExceptionCode) ||
|
|
DbgIsSSActive(DBG_SS_MODLOAD)))
|
|
{
|
|
WCHAR awc[35 + 3 * cwcDWORDSPRINTF];
|
|
ULONG aeip[16];
|
|
|
|
wsprintf(
|
|
awc,
|
|
L"0x%x @ 0x%p",
|
|
pep->ExceptionRecord->ExceptionFlags,
|
|
pep->ExceptionRecord->ExceptionAddress);
|
|
|
|
if (NULL == pszFile)
|
|
{
|
|
CSPrintErrorLineFileData(
|
|
awc,
|
|
__MAKELINEFILE__(dwFile, dwLine),
|
|
pep->ExceptionRecord->ExceptionCode);
|
|
}
|
|
else
|
|
{
|
|
CSPrintError(
|
|
"Exception",
|
|
awc,
|
|
pszFile,
|
|
dwLine,
|
|
pep->ExceptionRecord->ExceptionCode,
|
|
S_OK);
|
|
}
|
|
myCaptureStackBackTrace(pep, 0, ARRAYSIZE(aeip), aeip);
|
|
|
|
for (int i = 0; i < ARRAYSIZE(aeip); i++)
|
|
{
|
|
if (0 == aeip[i])
|
|
{
|
|
break;
|
|
}
|
|
DbgPrintf(MAXDWORD, "ln %x;", aeip[i]);
|
|
}
|
|
if (0 < i)
|
|
{
|
|
DbgPrintf(MAXDWORD, "\n");
|
|
}
|
|
}
|
|
#endif // DBG_CERTSRV_DEBUG_PRINT
|
|
|
|
hr = myHExceptionCode(pep);
|
|
if (NULL != s_pfnLogException)
|
|
{
|
|
(*s_pfnLogException)(hr, pep, pszFile, dwFile, dwLine);
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
|
|
BOOL
|
|
myIsDelayLoadHResult(
|
|
IN HRESULT hr)
|
|
{
|
|
return(ISDELAYLOADHRESULT(hr));
|
|
}
|
|
|
|
|
|
#define wszCOLONSPACE L": "
|
|
|
|
WCHAR const *
|
|
myHResultToStringEx(
|
|
IN OUT WCHAR *awchr,
|
|
IN HRESULT hr,
|
|
IN BOOL fRaw)
|
|
{
|
|
HRESULT hrd;
|
|
WCHAR const *pwszType;
|
|
LONG cwc;
|
|
|
|
hrd = hr;
|
|
pwszType = L"";
|
|
if (ISJETERROR(hr))
|
|
{
|
|
pwszType = wszJETERRORPREFIX wszCOLONSPACE;
|
|
}
|
|
else if (ISJETHRESULT(hr))
|
|
{
|
|
hrd = JETERROR_FROM_HRESULT(hr);
|
|
pwszType = wszJETERRORPREFIX wszCOLONSPACE;
|
|
}
|
|
else if (ISOSSERROR(hr))
|
|
{
|
|
hrd = OSSERROR_FROM_HRESULT(hr);
|
|
pwszType = wszOSSERRORPREFIX wszCOLONSPACE;
|
|
}
|
|
else if (ISHTTPHRESULT(hr) || ISHTTPERROR(hr))
|
|
{
|
|
hrd = WIN32ERROR_FROM_HRESULT(hr);
|
|
pwszType = wszWIN32ERRORPREFIX L"/" wszHTTPERRORPREFIX wszCOLONSPACE;
|
|
}
|
|
else if (ISWIN32HRESULT(hr) || ISWIN32ERROR(hr))
|
|
{
|
|
hrd = WIN32ERROR_FROM_HRESULT(hr);
|
|
pwszType = wszWIN32ERRORPREFIX wszCOLONSPACE;
|
|
}
|
|
else if (ISDELAYLOADHRESULTFACILITY(hr))
|
|
{
|
|
hrd = WIN32ERROR_FROM_DELAYLOAD(hr);
|
|
pwszType = wszWIN32ERRORPREFIX wszCOLONSPACE;
|
|
}
|
|
else if (ISSETUPHRESULT(hr))
|
|
{
|
|
pwszType = wszSETUPERRORPREFIX wszCOLONSPACE;
|
|
}
|
|
if (fRaw)
|
|
{
|
|
pwszType = L"";
|
|
}
|
|
|
|
cwc = _snwprintf(
|
|
awchr,
|
|
cwcHRESULTSTRING,
|
|
L"0x%x (%ws%d)",
|
|
hr,
|
|
pwszType,
|
|
hrd);
|
|
if (0 > cwc || cwcHRESULTSTRING <= cwc)
|
|
{
|
|
awchr[cwcHRESULTSTRING - 1] = L'\0';
|
|
}
|
|
return(awchr);
|
|
}
|
|
|
|
|
|
WCHAR const *
|
|
myHResultToString(
|
|
IN OUT WCHAR *awchr,
|
|
IN HRESULT hr)
|
|
{
|
|
return(myHResultToStringEx(awchr, hr, FALSE));
|
|
}
|
|
|
|
|
|
WCHAR const *
|
|
myHResultToStringRaw(
|
|
IN OUT WCHAR *awchr,
|
|
IN HRESULT hr)
|
|
{
|
|
return(myHResultToStringEx(awchr, hr, TRUE));
|
|
}
|
|
|
|
|
|
typedef struct _ERRORMAP
|
|
{
|
|
HRESULT hr;
|
|
UINT idMessage;
|
|
} ERRORMAP;
|
|
|
|
ERRORMAP g_aSetup[] = {
|
|
{ ERROR_EXPECTED_SECTION_NAME, IDS_SETUP_ERROR_EXPECTED_SECTION_NAME, },
|
|
{ ERROR_BAD_SECTION_NAME_LINE, IDS_SETUP_ERROR_BAD_SECTION_NAME_LINE, },
|
|
{ ERROR_SECTION_NAME_TOO_LONG, IDS_SETUP_ERROR_SECTION_NAME_TOO_LONG, },
|
|
{ ERROR_GENERAL_SYNTAX, IDS_SETUP_ERROR_GENERAL_SYNTAX, },
|
|
{ ERROR_WRONG_INF_STYLE, IDS_SETUP_ERROR_WRONG_INF_STYLE, },
|
|
{ ERROR_SECTION_NOT_FOUND, IDS_SETUP_ERROR_SECTION_NOT_FOUND, },
|
|
{ ERROR_LINE_NOT_FOUND, IDS_SETUP_ERROR_LINE_NOT_FOUND, },
|
|
};
|
|
|
|
ERRORMAP s_aHttp[] =
|
|
{
|
|
{ HTTP_STATUS_CONTINUE, IDS_HTTP_STATUS_CONTINUE },
|
|
{ HTTP_STATUS_SWITCH_PROTOCOLS, IDS_HTTP_STATUS_SWITCH_PROTOCOLS },
|
|
{ HTTP_STATUS_OK, IDS_HTTP_STATUS_OK },
|
|
{ HTTP_STATUS_CREATED, IDS_HTTP_STATUS_CREATED },
|
|
{ HTTP_STATUS_ACCEPTED, IDS_HTTP_STATUS_ACCEPTED },
|
|
{ HTTP_STATUS_PARTIAL, IDS_HTTP_STATUS_PARTIAL },
|
|
{ HTTP_STATUS_NO_CONTENT, IDS_HTTP_STATUS_NO_CONTENT },
|
|
{ HTTP_STATUS_RESET_CONTENT, IDS_HTTP_STATUS_RESET_CONTENT },
|
|
{ HTTP_STATUS_PARTIAL_CONTENT, IDS_HTTP_STATUS_PARTIAL_CONTENT },
|
|
{ HTTP_STATUS_AMBIGUOUS, IDS_HTTP_STATUS_AMBIGUOUS },
|
|
{ HTTP_STATUS_MOVED, IDS_HTTP_STATUS_MOVED },
|
|
{ HTTP_STATUS_REDIRECT, IDS_HTTP_STATUS_REDIRECT },
|
|
{ HTTP_STATUS_REDIRECT_METHOD, IDS_HTTP_STATUS_REDIRECT_METHOD },
|
|
{ HTTP_STATUS_NOT_MODIFIED, IDS_HTTP_STATUS_NOT_MODIFIED },
|
|
{ HTTP_STATUS_USE_PROXY, IDS_HTTP_STATUS_USE_PROXY },
|
|
{ HTTP_STATUS_REDIRECT_KEEP_VERB, IDS_HTTP_STATUS_REDIRECT_KEEP_VERB },
|
|
{ HTTP_STATUS_BAD_REQUEST, IDS_HTTP_STATUS_BAD_REQUEST },
|
|
{ HTTP_STATUS_DENIED, IDS_HTTP_STATUS_DENIED },
|
|
{ HTTP_STATUS_PAYMENT_REQ, IDS_HTTP_STATUS_PAYMENT_REQ },
|
|
{ HTTP_STATUS_FORBIDDEN, IDS_HTTP_STATUS_FORBIDDEN },
|
|
{ HTTP_STATUS_NOT_FOUND, IDS_HTTP_STATUS_NOT_FOUND },
|
|
{ HTTP_STATUS_BAD_METHOD, IDS_HTTP_STATUS_BAD_METHOD },
|
|
{ HTTP_STATUS_NONE_ACCEPTABLE, IDS_HTTP_STATUS_NONE_ACCEPTABLE },
|
|
{ HTTP_STATUS_PROXY_AUTH_REQ, IDS_HTTP_STATUS_PROXY_AUTH_REQ },
|
|
{ HTTP_STATUS_REQUEST_TIMEOUT, IDS_HTTP_STATUS_REQUEST_TIMEOUT },
|
|
{ HTTP_STATUS_CONFLICT, IDS_HTTP_STATUS_CONFLICT },
|
|
{ HTTP_STATUS_GONE, IDS_HTTP_STATUS_GONE },
|
|
{ HTTP_STATUS_LENGTH_REQUIRED, IDS_HTTP_STATUS_LENGTH_REQUIRED },
|
|
{ HTTP_STATUS_PRECOND_FAILED, IDS_HTTP_STATUS_PRECOND_FAILED },
|
|
{ HTTP_STATUS_REQUEST_TOO_LARGE, IDS_HTTP_STATUS_REQUEST_TOO_LARGE },
|
|
{ HTTP_STATUS_URI_TOO_LONG, IDS_HTTP_STATUS_URI_TOO_LONG },
|
|
{ HTTP_STATUS_UNSUPPORTED_MEDIA, IDS_HTTP_STATUS_UNSUPPORTED_MEDIA },
|
|
{ HTTP_STATUS_RETRY_WITH, IDS_HTTP_STATUS_RETRY_WITH },
|
|
{ HTTP_STATUS_SERVER_ERROR, IDS_HTTP_STATUS_SERVER_ERROR },
|
|
{ HTTP_STATUS_NOT_SUPPORTED, IDS_HTTP_STATUS_NOT_SUPPORTED },
|
|
{ HTTP_STATUS_BAD_GATEWAY, IDS_HTTP_STATUS_BAD_GATEWAY },
|
|
{ HTTP_STATUS_SERVICE_UNAVAIL, IDS_HTTP_STATUS_SERVICE_UNAVAIL },
|
|
{ HTTP_STATUS_GATEWAY_TIMEOUT, IDS_HTTP_STATUS_GATEWAY_TIMEOUT },
|
|
{ HTTP_STATUS_VERSION_NOT_SUP, IDS_HTTP_STATUS_VERSION_NOT_SUP },
|
|
};
|
|
|
|
|
|
DWORD
|
|
errLoadStaticMessage(
|
|
IN HRESULT hr,
|
|
IN ERRORMAP const *pmap,
|
|
IN DWORD cmap,
|
|
OUT WCHAR const **ppwszOut)
|
|
{
|
|
DWORD cwc = 0;
|
|
ERRORMAP const *pmapEnd;
|
|
|
|
for (pmapEnd = &pmap[cmap]; pmap < pmapEnd; pmap++)
|
|
{
|
|
if (hr == pmap->hr)
|
|
{
|
|
*ppwszOut = myLoadResourceString(pmap->idMessage);
|
|
if (NULL != *ppwszOut)
|
|
{
|
|
cwc = wcslen(*ppwszOut);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
//error:
|
|
return(cwc);
|
|
}
|
|
|
|
|
|
DWORD
|
|
errFormatMessage(
|
|
IN HMODULE hMod,
|
|
IN HRESULT hr,
|
|
OUT WCHAR const **ppwszOut,
|
|
OPTIONAL IN WCHAR const * const *ppwszArgs)
|
|
{
|
|
DWORD dwFlags;
|
|
|
|
dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER;
|
|
if (NULL == hMod)
|
|
{
|
|
dwFlags |= FORMAT_MESSAGE_FROM_SYSTEM;
|
|
}
|
|
else
|
|
{
|
|
dwFlags |= FORMAT_MESSAGE_FROM_HMODULE;
|
|
}
|
|
if (NULL == ppwszArgs || NULL == ppwszArgs[0])
|
|
{
|
|
dwFlags |= FORMAT_MESSAGE_IGNORE_INSERTS;
|
|
}
|
|
else
|
|
{
|
|
dwFlags |= FORMAT_MESSAGE_ARGUMENT_ARRAY;
|
|
}
|
|
return(FormatMessage(
|
|
dwFlags,
|
|
hMod,
|
|
hr,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
(WCHAR *) ppwszOut,
|
|
1,
|
|
(va_list *) ppwszArgs));
|
|
}
|
|
|
|
|
|
// Alloc and return error message string
|
|
|
|
WCHAR const *
|
|
myGetErrorMessageText(
|
|
IN HRESULT hr,
|
|
IN BOOL fHResultString)
|
|
{
|
|
return(myGetErrorMessageTextEx(hr, fHResultString, NULL));
|
|
}
|
|
|
|
|
|
WCHAR const *
|
|
myGetErrorMessageText1(
|
|
IN HRESULT hr,
|
|
IN BOOL fHResultString,
|
|
IN OPTIONAL WCHAR const *pwszInsertionText)
|
|
{
|
|
WCHAR const *apwszInsertionText[2];
|
|
WCHAR const * const *papwsz = NULL;
|
|
|
|
if (NULL != pwszInsertionText)
|
|
{
|
|
apwszInsertionText[0] = pwszInsertionText;
|
|
apwszInsertionText[1] = NULL;
|
|
papwsz = apwszInsertionText;
|
|
}
|
|
return(myGetErrorMessageTextEx(hr, fHResultString, papwsz));
|
|
}
|
|
|
|
|
|
WCHAR const *
|
|
myGetErrorMessageTextEx(
|
|
IN HRESULT hr,
|
|
IN BOOL fHResultString,
|
|
IN OPTIONAL WCHAR const * const *papwszInsertionText)
|
|
{
|
|
static WCHAR s_wszUnknownDefault[] = L"Error";
|
|
WCHAR const *pwszRet = NULL;
|
|
WCHAR const *pwszRetStatic = NULL;
|
|
WCHAR *pwszMsgT;
|
|
WCHAR awchr[cwcHRESULTSTRING];
|
|
DWORD cwc;
|
|
DWORD cwcCopy;
|
|
DWORD cwcUnexpected;
|
|
WCHAR const *pwszUnexpected = NULL;
|
|
WCHAR wszEmpty[] = L"";
|
|
HMODULE hMod1 = NULL;
|
|
HMODULE hMod2 = NULL;
|
|
|
|
if (E_UNEXPECTED == hr)
|
|
{
|
|
pwszUnexpected = myLoadResourceString(IDS_E_UNEXPECTED); // L"Unexpected method call sequence."
|
|
}
|
|
#if (0 == i386)
|
|
else if (STATUS_DATATYPE_MISALIGNMENT == hr)
|
|
{
|
|
pwszUnexpected = myLoadResourceString(IDS_E_DATA_MISALIGNMENT); // L"Possible data alignment fault."
|
|
}
|
|
#endif
|
|
if (NULL == pwszUnexpected)
|
|
{
|
|
HRESULT hrHttp = hr;
|
|
|
|
if (ISWIN32HRESULT(hrHttp))
|
|
{
|
|
hrHttp = WIN32ERROR_FROM_HRESULT(hrHttp);
|
|
}
|
|
if (ISHTTPERROR(hrHttp))
|
|
{
|
|
cwc = errLoadStaticMessage(
|
|
hrHttp,
|
|
s_aHttp,
|
|
ARRAYSIZE(s_aHttp),
|
|
&pwszUnexpected);
|
|
}
|
|
}
|
|
if (NULL == pwszUnexpected)
|
|
{
|
|
pwszUnexpected = wszEmpty;
|
|
}
|
|
cwcUnexpected = wcslen(pwszUnexpected);
|
|
|
|
cwc = errFormatMessage(NULL, hr, &pwszRet, papwszInsertionText);
|
|
if (0 == cwc && ISDELAYLOADHRESULTFACILITY(hr))
|
|
{
|
|
cwc = errFormatMessage(
|
|
NULL,
|
|
WIN32ERROR_FROM_DELAYLOAD(hr),
|
|
&pwszRet,
|
|
papwszInsertionText);
|
|
}
|
|
if (0 == cwc && ISSETUPHRESULT(hr))
|
|
{
|
|
cwc = errLoadStaticMessage(
|
|
hr,
|
|
g_aSetup,
|
|
ARRAYSIZE(g_aSetup),
|
|
&pwszRetStatic);
|
|
pwszRet = pwszRetStatic;
|
|
}
|
|
if (0 == cwc)
|
|
{
|
|
hMod1 = LoadLibrary(L"ntdsbmsg.dll");
|
|
if (NULL != hMod1)
|
|
{
|
|
HRESULT hrEDB = hr;
|
|
HRESULT hrFormat;
|
|
BOOL fFirst = TRUE;
|
|
|
|
while (TRUE)
|
|
{
|
|
cwc = errFormatMessage(hMod1, hrEDB, &pwszRet, papwszInsertionText);
|
|
if (0 == cwc && FAILED(hrEDB) && fFirst)
|
|
{
|
|
hrFormat = myHLastError();
|
|
if (HRESULT_FROM_WIN32(ERROR_MR_MID_NOT_FOUND) == hrFormat)
|
|
{
|
|
hrEDB = myJetHResult(hrEDB);
|
|
if (hrEDB != hr)
|
|
{
|
|
fFirst = FALSE;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (0 == cwc)
|
|
{
|
|
HMODULE hModT = GetModuleHandle(L"wininet.dll");
|
|
if (NULL != hModT)
|
|
{
|
|
HRESULT hrHttp = hr;
|
|
HRESULT hrFormat;
|
|
BOOL fFirst = TRUE;
|
|
|
|
while (TRUE)
|
|
{
|
|
cwc = errFormatMessage(hModT, hrHttp, &pwszRet, papwszInsertionText);
|
|
if (0 == cwc && ISWIN32HRESULT(hrHttp) && fFirst)
|
|
{
|
|
hrFormat = myHLastError();
|
|
if (HRESULT_FROM_WIN32(ERROR_MR_MID_NOT_FOUND) == hrFormat)
|
|
{
|
|
hrHttp = WIN32ERROR_FROM_HRESULT(hrHttp);
|
|
if (hrHttp != hr)
|
|
{
|
|
fFirst = FALSE;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (0 == cwc)
|
|
{
|
|
hMod2 = LoadLibrary(L"cdosys.dll");
|
|
if (NULL != hMod2)
|
|
{
|
|
cwc = errFormatMessage(hMod2, hr, &pwszRet, papwszInsertionText);
|
|
}
|
|
}
|
|
|
|
if (0 == cwc) // couldn't find error, use default & error code
|
|
{
|
|
fHResultString = TRUE;
|
|
}
|
|
awchr[0] = L'\0';
|
|
if (fHResultString)
|
|
{
|
|
myHResultToString(awchr, hr);
|
|
}
|
|
|
|
if (0 == cwc)
|
|
{
|
|
pwszRetStatic = myLoadResourceString(IDS_UNKNOWN_ERROR_CODE); // L"Error"
|
|
if (NULL == pwszRetStatic)
|
|
{
|
|
pwszRetStatic = s_wszUnknownDefault;
|
|
}
|
|
pwszRet = pwszRetStatic;
|
|
}
|
|
|
|
// strip trailing \r\n
|
|
|
|
cwcCopy = wcslen(pwszRet);
|
|
if (2 <= cwcCopy &&
|
|
L'\r' == pwszRet[cwcCopy - 2] &&
|
|
L'\n' == pwszRet[cwcCopy - 1])
|
|
{
|
|
cwcCopy -= 2;
|
|
}
|
|
cwc = cwcCopy + 1 + cwcUnexpected + 1 + wcslen(awchr) + 1;
|
|
pwszMsgT = (WCHAR *) LocalAlloc(LMEM_FIXED, cwc * sizeof(WCHAR));
|
|
if (NULL == pwszMsgT)
|
|
{
|
|
_JumpError(E_OUTOFMEMORY, error, "LocalAlloc");
|
|
}
|
|
CopyMemory(pwszMsgT, pwszRet, cwcCopy * sizeof(WCHAR));
|
|
pwszMsgT[cwcCopy] = L'\0';
|
|
|
|
if (0 != cwcUnexpected)
|
|
{
|
|
wcscat(pwszMsgT, L" ");
|
|
wcscat(pwszMsgT, pwszUnexpected);
|
|
}
|
|
if (fHResultString)
|
|
{
|
|
wcscat(pwszMsgT, L" ");
|
|
wcscat(pwszMsgT, awchr);
|
|
}
|
|
CSASSERT(wcslen(pwszMsgT) < cwc);
|
|
if (NULL != pwszRet && pwszRetStatic != pwszRet)
|
|
{
|
|
LocalFree(const_cast<WCHAR *>(pwszRet));
|
|
}
|
|
pwszRet = pwszMsgT;
|
|
|
|
error:
|
|
if (NULL != hMod1)
|
|
{
|
|
FreeLibrary(hMod1);
|
|
}
|
|
if (NULL != hMod2)
|
|
{
|
|
FreeLibrary(hMod2);
|
|
}
|
|
return(pwszRet);
|
|
}
|