HRESULT ceDispatchSetErrorInfoSub( IN HRESULT hrError, OPTIONAL IN WCHAR const *pwszIDispatchMethod, OPTIONAL IN WCHAR const *pwszDescription, OPTIONAL IN WCHAR const *pwszSource, OPTIONAL IN IID const *piid, OPTIONAL IN WCHAR const *pwszHelpFile, IN DWORD dwHelpFileContext) { HRESULT hr; WCHAR const *pwszError = NULL; ICreateErrorInfo *pCreateErrorInfo = NULL; IErrorInfo *pErrorInfo = NULL; if (NULL != pwszIDispatchMethod) { pwszError = ceGetErrorMessageText(hrError, TRUE); } hr = CreateErrorInfo(&pCreateErrorInfo); _JumpIfError(hr, error, "CreateErrorInfo"); if (NULL != piid) { hr = pCreateErrorInfo->SetGUID(*piid); _PrintIfError(hr, "SetGUID"); } if (NULL != pwszSource) { hr = pCreateErrorInfo->SetSource(const_cast<WCHAR *>(pwszSource)); _PrintIfError(hr, "SetSource"); } if (NULL != pwszDescription) { hr = pCreateErrorInfo->SetDescription( const_cast<WCHAR *>(pwszDescription)); _PrintIfError(hr, "SetDescription"); } if (NULL != pwszHelpFile) { hr = pCreateErrorInfo->SetHelpFile(const_cast<WCHAR *>(pwszHelpFile)); _PrintIfError(hr, "SetHelpFile"); hr = pCreateErrorInfo->SetHelpContext(dwHelpFileContext); _PrintIfError(hr, "SetHelpContext"); } hr = pCreateErrorInfo->QueryInterface( IID_IErrorInfo, (VOID **) &pErrorInfo); _JumpIfError(hr, error, "QueryInterface"); SetErrorInfo(0, pErrorInfo); hr = S_OK; error: if (NULL != pwszError) { LocalFree(const_cast<WCHAR *>(pwszError)); } if (NULL != pErrorInfo) { pErrorInfo->Release(); } if (NULL != pCreateErrorInfo) { pCreateErrorInfo->Release(); } return(hr); }
/* * Generic COM error reporting function. */ static void comReportError(bpContext *ctx, HRESULT hrErr) { IErrorInfo *pErrorInfo; BSTR pSource = NULL; BSTR pDescription = NULL; HRESULT hr; char *source, *description; /* * See if there is anything to report. */ hr = GetErrorInfo(0, &pErrorInfo); if (hr == S_FALSE) { return; } /* * Get the description of the COM error. */ hr = pErrorInfo->GetDescription(&pDescription); if (!SUCCEEDED (hr)) { pErrorInfo->Release(); return; } /* * Get the source of the COM error. */ hr = pErrorInfo->GetSource(&pSource); if (!SUCCEEDED (hr)) { SysFreeString(pDescription); pErrorInfo->Release(); return; } /* * Convert windows BSTR to normal strings. */ source = BSTR_2_str(pSource); description = BSTR_2_str(pDescription); if (source && description) { Jmsg(ctx, M_FATAL, "%s(x%X): %s\n", source, hrErr, description); Dmsg(ctx, dbglvl, "%s(x%X): %s\n", source, hrErr, description); } if (source) { free(source); } if (description) { free(description); } /* * Generic cleanup (free the description and source as those are returned in * dynamically allocated memory by the COM routines.) */ SysFreeString(pSource); SysFreeString(pDescription); pErrorInfo->Release(); }
// Info: Gets both unrestricted and restricted error info // Parameters: scriptContext - the script context // pexcepinfo - the exception info of the error (unrestricted) // proerrstr - the winrt specific error strings (restricted) // pperrinfo - the IErrorInfo object // Returns: Failed HRESULT - if GetErrorInfo or QI fail // Success - otherwise HRESULT JavascriptErrorDebug::GetExcepAndErrorInfo(ScriptContext* scriptContext, HRESULT hrReturned, EXCEPINFO *pexcepinfo, RestrictedErrorStrings * proerrstr, IErrorInfo ** pperrinfo) { HRESULT hr; HRESULT hrResult; bool errorInfoMatch = false; memset(pexcepinfo, 0, sizeof(*pexcepinfo)); memset(proerrstr, 0, sizeof(*proerrstr)); *pperrinfo = nullptr; // GetErrorInfo returns S_FALSE if there is no rich error info // and S_OK if there is. IErrorInfo * perrinfo; if(NOERROR != (hr = GetErrorInfo(0L, &perrinfo))) { return hr; } // Fill Exception info perrinfo->GetSource(&pexcepinfo->bstrSource); perrinfo->GetDescription(&pexcepinfo->bstrDescription); perrinfo->GetHelpFile(&pexcepinfo->bstrHelpFile); perrinfo->GetHelpContext(&pexcepinfo->dwHelpContext); // Initialize restricted strings proerrstr->restrictedErrStr = nullptr; proerrstr->referenceStr = nullptr; proerrstr->capabilitySid = nullptr; BSTR bstrErr = nullptr; BSTR bstrRestrictedErr = nullptr; BSTR bstrCapabilitySid = nullptr; BSTR bstrReference = nullptr; IRestrictedErrorInfo * pROErrorInfo = nullptr; _Exception * pCLRException = nullptr; hr = perrinfo->QueryInterface(__uuidof(IRestrictedErrorInfo), reinterpret_cast<void**>(&pROErrorInfo)); if (SUCCEEDED(hr)) { // Get restricted error strings from IRestrictedErrorInfo HRESULT hrErr = S_OK; hrResult = pROErrorInfo->GetErrorDetails(&bstrErr, &hrErr, &bstrRestrictedErr, &bstrCapabilitySid); if (SUCCEEDED(hrResult)) { errorInfoMatch = (hrErr == hrReturned); if (errorInfoMatch) { if (nullptr != bstrRestrictedErr) { proerrstr->restrictedErrStr = bstrRestrictedErr; bstrRestrictedErr = nullptr; } if (nullptr != bstrCapabilitySid) { proerrstr->capabilitySid = bstrCapabilitySid; bstrCapabilitySid = nullptr; } } } hrResult = pROErrorInfo->GetReference(&bstrReference); if (SUCCEEDED(hrResult) && errorInfoMatch) { if (nullptr != bstrReference) { proerrstr->referenceStr = bstrReference; bstrReference = nullptr; } } } else { hr = perrinfo->QueryInterface(__uuidof(_Exception), reinterpret_cast<void**>(&pCLRException)); if(FAILED(hr)) { perrinfo->Release(); return hr; } hrResult = pCLRException->get_Message(&bstrRestrictedErr); if (SUCCEEDED(hrResult)) { errorInfoMatch = true; if (nullptr != bstrRestrictedErr) { proerrstr->restrictedErrStr = bstrRestrictedErr; bstrRestrictedErr = nullptr; } } } if (nullptr != bstrErr) { SysFreeString(bstrErr); bstrErr = nullptr; } if (nullptr != bstrRestrictedErr) { SysFreeString(bstrRestrictedErr); bstrRestrictedErr = nullptr; } if (nullptr != bstrCapabilitySid) { SysFreeString(bstrCapabilitySid); bstrCapabilitySid = nullptr; } if (nullptr != bstrReference) { SysFreeString(bstrReference); bstrReference = nullptr; } if (!errorInfoMatch) { if (nullptr != pexcepinfo->bstrSource) { SysFreeString(pexcepinfo->bstrSource); pexcepinfo->bstrSource = nullptr; } if (nullptr != pexcepinfo->bstrDescription) { SysFreeString(pexcepinfo->bstrDescription); pexcepinfo->bstrDescription = nullptr; } if (nullptr != pexcepinfo->bstrHelpFile) { SysFreeString(pexcepinfo->bstrHelpFile); pexcepinfo->bstrHelpFile = nullptr; } perrinfo->Release(); perrinfo = nullptr; hr = S_FALSE; } if (nullptr != pROErrorInfo) { pROErrorInfo->Release(); } if (nullptr != pCLRException) { pCLRException->Release(); } *pperrinfo = perrinfo; return hr; }
//*************************************************************************** // Function: PrintError // Purpose: Formats and prints the error message //*************************************************************************** void PrintError(char *pszFailureReason, SCODE psc, DWORD dwMode) { VARIANT varString; SCODE sc; IWbemClassObject *pErrorObject = NULL; IErrorInfo* pEI = NULL; fprintf(stdout, "%s\n", pszFailureReason); fprintf(stdout, "FunctionReturn: %S(0x%08lx)\n", WbemErrorString(psc), psc); if (GetErrorInfo(0, &pEI) == S_OK) { pEI->QueryInterface(IID_IWbemClassObject, (void**)&pErrorObject); pEI->Release(); } if (pErrorObject != NULL) { VariantInit(&varString); if (dwMode == ERROR_MODE_PRINTFIELDS) { if (pErrorObject->InheritsFrom(L"__NotifyStatus") != WBEM_NO_ERROR) { fprintf(stdout, "Unrecognized Error Object type\n"); } else if (pErrorObject->InheritsFrom(L"__ExtendedStatus") == WBEM_NO_ERROR) { sc = pErrorObject->Get(L"Description", 0L, &varString, NULL, NULL); if (sc != S_OK) { fprintf(stdout, "Can't get Description: %d\n", sc); } else if (V_VT(&varString) == VT_BSTR) { FWPRINTF(stdout, L"Description: %wS\n", V_BSTR(&varString)); } VariantClear(&varString); pErrorObject->Get(L"Operation", 0L, &varString, NULL, NULL); if (sc != S_OK) { fprintf(stdout, "Can't get Operation: %d\n", sc); } else if (V_VT(&varString) == VT_BSTR) { FWPRINTF(stdout, L"Operation: %wS\n", V_BSTR(&varString)); } VariantClear(&varString); pErrorObject->Get(L"ParameterInfo", 0L, &varString, NULL, NULL); if (sc != S_OK) { fprintf(stdout, "Can't get ParameterInfo: %d\n", sc); } else if (V_VT(&varString) == VT_BSTR) { FWPRINTF(stdout, L"ParameterInfo: %wS\n", V_BSTR(&varString)); } VariantClear(&varString); pErrorObject->Get(L"ProviderName", 0L, &varString, NULL, NULL); if (sc != S_OK) { fprintf(stdout, "Can't get ProviderName: %d\n", sc); } else if (V_VT(&varString) == VT_BSTR) { FWPRINTF(stdout, L"ProviderName: %wS\n", V_BSTR(&varString)); } VariantClear(&varString); } } else { BSTR bstrObjectText = NULL; if (SUCCEEDED(pErrorObject->GetObjectText(0, &bstrObjectText))) { fprintf(stdout, "%wS", bstrObjectText); SysFreeString(bstrObjectText); } } RELEASE(pErrorObject); } }
//Changed from //ms-help://MS.SSC.v35/MS.SSC.v35.EN/ssctechref/html/a25fafe1-e90a-4545-8836-749dd44135c0.htm CString SqlCeHelper::GetErrorsMessage() { static CString sErrIErrorInfo = L"IErrorInfo interface"; static CString sErrIErrorRecords = L"IErrorRecords interface"; static CString sErrRecordCount = L"error record count"; static CString sErrInfo = L"ERRORINFO structure"; static CString sErrStandardInfo = L"standard error info"; static CString sErrDescription = L"standard error description"; static CString sErrNoSource = L"error source"; HRESULT hr = S_OK; IErrorInfo *pIErrorInfo = NULL; IErrorRecords *pIErrorRecords = NULL; ERRORINFO errorInfo = { 0 }; IErrorInfo *pIErrorInfoRecord = NULL; CString message = L""; char str[255]; try { // This interface supports returning error information. // Get the error object from the system for the current // thread. hr = GetErrorInfo(0, &pIErrorInfo); if ( hr == S_FALSE ) { message = "No error occured."; return message; } if(FAILED(hr) || NULL == pIErrorInfo) throw sErrIErrorInfo; // The error records are retrieved from the IIErrorRecords // interface, which can be obtained from the IErrorInfo // interface. hr = pIErrorInfo->QueryInterface(IID_IErrorRecords, (void **) &pIErrorRecords); if ( FAILED(hr) || NULL == pIErrorRecords ) throw sErrIErrorRecords; // The IErrorInfo interface is no longer required because // we have the IErrorRecords interface, relase it. pIErrorInfo->Release(); pIErrorInfo = NULL; ULONG ulNumErrorRecs = 0; // Determine the number of records in this error object hr = pIErrorRecords->GetRecordCount(&ulNumErrorRecs); if ( FAILED(hr) ) throw sErrRecordCount; // Loop over each error record in the error object to display // information about each error. Errors are returned. for (DWORD dwErrorIndex = 0; dwErrorIndex < ulNumErrorRecs; dwErrorIndex++) { // Retrieve basic error information for this error. hr = pIErrorRecords->GetBasicErrorInfo(dwErrorIndex, &errorInfo); if ( FAILED(hr) ) throw sErrInfo; TCHAR szCLSID[64] = { 0 }; TCHAR szIID[64] = { 0 }; TCHAR szDISPID[64] = { 0 }; StringFromGUID2(errorInfo.clsid, (LPOLESTR)szCLSID, sizeof(szCLSID)); StringFromGUID2(errorInfo.iid, (LPOLESTR)szIID, sizeof(szIID)); sprintf(str, "HRESULT = %lx\n", errorInfo.hrError); message += str; sprintf(str, "clsid = %S\n", szCLSID); message += str; sprintf(str, "iid = %S\n", szIID); message += str; sprintf(str, "dispid = %ld\n", errorInfo.dispid); message += str; sprintf(str, "Native Error Code = %lx\n", errorInfo.dwMinor); message += str; // Retrieve standard error information for this error. hr = pIErrorRecords->GetErrorInfo(dwErrorIndex, NULL, &pIErrorInfoRecord); if ( FAILED(hr) ) throw sErrStandardInfo; BSTR bstrDescriptionOfError; BSTR bstrSourceOfError; // Get the description of the error. hr = pIErrorInfoRecord->GetDescription( &bstrDescriptionOfError); if ( FAILED(hr) ) throw sErrDescription; sprintf(str, "Description = %S\n", bstrDescriptionOfError); message += str; // Get the source of the error. hr = pIErrorInfoRecord->GetSource(&bstrSourceOfError); if ( FAILED(hr) ) throw sErrNoSource; sprintf(str, "Description = %S\n", bstrSourceOfError); message += str; // This interface variable will be used the next time // though this loop. In the last error case this interface // is no longer needed so we must release it. if(NULL != pIErrorInfoRecord) pIErrorInfoRecord->Release(); pIErrorInfoRecord = NULL; } } catch( CString& szMsg ) { message = L"Failed to retrieve " + szMsg; } if( pIErrorInfoRecord ) pIErrorInfoRecord->Release(); if ( pIErrorInfo ) pIErrorInfo->Release(); if ( pIErrorRecords ) pIErrorRecords->Release(); return message; }
//////////////////////////////////////////////////////////////////////// // myHandleResult // // This function is called as part of the XCHECK_HR macro; it takes a // HRESULT, which is returned by the method called in the XCHECK_HR // macro, and the file and line number where the method call was made. // If the method call failed, this function attempts to get and display // the extended error information for the call from the IErrorInfo, // IErrorRecords, and ISQLErrorInfo interfaces. // //////////////////////////////////////////////////////////////////////// HRESULT myHandleResult ( HRESULT hrReturned, LPCWSTR pwszFile, ULONG ulLine ) { HRESULT hr; IErrorInfo * pIErrorInfo = NULL; IErrorRecords * pIErrorRecords = NULL; ULONG cRecords; ULONG iErr; // If the method called as part of the XCHECK_HR macro failed, // we will attempt to get extended error information for the call if( FAILED(hrReturned) ) { // Obtain the current Error object, if any, by using the // OLE Automation GetErrorInfo function, which will give // us back an IErrorInfo interface pointer if successful hr = GetErrorInfo(0, &pIErrorInfo); // We've got the IErrorInfo interface pointer on the Error object if( SUCCEEDED(hr) && pIErrorInfo ) { // OLE DB extends the OLE Automation error model by allowing // Error objects to support the IErrorRecords interface; this // interface can expose information on multiple errors. hr = pIErrorInfo->QueryInterface(IID_IErrorRecords, (void**)&pIErrorRecords); if( SUCCEEDED(hr) ) { // Get the count of error records from the object CHECK_HR(hr = pIErrorRecords->GetRecordCount(&cRecords)); // Loop through the set of error records and // display the error information for each one for( iErr = 0; iErr < cRecords; iErr++ ) { myDisplayErrorRecord(hrReturned, iErr, pIErrorRecords, pwszFile, ulLine); } } // The object didn't support IErrorRecords; display // the error information for this single error else { myDisplayErrorInfo(hrReturned, pIErrorInfo, pwszFile, ulLine); } } // There was no Error object, so just display the HRESULT to the user else { wprintf(L"\nNo Error Info posted; HResult: 0x%08x\n" L"File: %s, Line: %d\n", hrReturned, pwszFile, ulLine); } } CLEANUP: if( pIErrorInfo ) pIErrorInfo->Release(); if( pIErrorRecords ) pIErrorRecords->Release(); return hrReturned; }
//////////////////////////////////////////////////////////////////////// // myDisplayErrorRecord // // This function displays the error information for a single error // record, including information from ISQLErrorInfo, if supported // //////////////////////////////////////////////////////////////////////// HRESULT myDisplayErrorRecord ( HRESULT hrReturned, ULONG iRecord, IErrorRecords * pIErrorRecords, LPCWSTR pwszFile, ULONG ulLine ) { HRESULT hr; IErrorInfo * pIErrorInfo = NULL; BSTR bstrDescription = NULL; BSTR bstrSource = NULL; BSTR bstrSQLInfo = NULL; static LCID lcid = GetUserDefaultLCID(); LONG lNativeError = 0; ERRORINFO ErrorInfo; // Get the IErrorInfo interface pointer for this error record CHECK_HR(hr = pIErrorRecords->GetErrorInfo(iRecord, lcid, &pIErrorInfo)); // Get the description of this error CHECK_HR(hr = pIErrorInfo->GetDescription(&bstrDescription)); // Get the source of this error CHECK_HR(hr = pIErrorInfo->GetSource(&bstrSource)); // Get the basic error information for this record CHECK_HR(hr = pIErrorRecords->GetBasicErrorInfo(iRecord, &ErrorInfo)); // If the error object supports ISQLErrorInfo, get this information myGetSqlErrorInfo(iRecord, pIErrorRecords, &bstrSQLInfo, &lNativeError); // Display the error information to the user if( bstrSQLInfo ) { wprintf(L"\nErrorRecord: HResult: 0x%08x\nDescription: %s\n" L"SQLErrorInfo: %s\nSource: %s\nFile: %s, Line: %d\n", ErrorInfo.hrError, bstrDescription, bstrSQLInfo, bstrSource, pwszFile, ulLine); } else { wprintf(L"\nErrorRecord: HResult: 0x%08x\nDescription: %s\n" L"Source: %s\nFile: %s, Line: %d\n", ErrorInfo.hrError, bstrDescription, bstrSource, pwszFile, ulLine); } CLEANUP: if( pIErrorInfo ) pIErrorInfo->Release(); SysFreeString(bstrDescription); SysFreeString(bstrSource); SysFreeString(bstrSQLInfo); return hr; }
// Throws the given error code and the message corresponding to the code. If the code is // a standard code and no message is provided, then the message is extracted from the system. HRESULT CCOMError::DispatchError(HRESULT hError, REFCLSID clsid, LPCTSTR source, LPCTSTR description, DWORD helpContext, LPCTSTR helpFileName) { // This function uses ATL conversion macros // (Hence we must use this MACRO provided by ATL) USES_CONVERSION; // Convert the description to OLE string LPOLESTR wszError = NULL; if(description != NULL) { // Convert to wide char wszError = T2OLE(description); } else { // If the code is a Win32 error code if(HRESULT_FACILITY(hError) == FACILITY_WIN32) { // Get the error from the system LPTSTR szError = NULL; if(!::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, HRESULT_CODE(hError), MAKELANGID(LANG_USER_DEFAULT, SUBLANG_DEFAULT), (LPTSTR)&szError, 0, NULL)) return HRESULT_FROM_WIN32(GetLastError()); // Convert the Error multibyte string to OLE string if(szError != NULL) { // Convert to wide char wszError = T2OLE(szError); // Free the multibyte string LocalFree(szError); } } } // Convert the source string to OLE string LPOLESTR wszSource = NULL; if(source != NULL) wszSource = T2OLE(source); // Convert the help filename to OLE string LPOLESTR wszHelpFile = NULL; if(helpFileName != NULL) wszHelpFile = T2OLE(helpFileName); // Get the ICreateErrorInfo Interface ICreateErrorInfo *pCreateErrorInfo = NULL; HRESULT hSuccess = CreateErrorInfo(&pCreateErrorInfo); ATLASSERT(SUCCEEDED(hSuccess)); // Fill the error information into it pCreateErrorInfo->SetGUID(clsid); if(wszError != NULL) pCreateErrorInfo->SetDescription(wszError); if(wszSource != NULL) pCreateErrorInfo->SetSource(wszSource); if(wszHelpFile != NULL) pCreateErrorInfo->SetHelpFile(wszHelpFile); pCreateErrorInfo->SetHelpContext(helpContext); // Get the IErrorInfo interface IErrorInfo *pErrorInfo = NULL; hSuccess = pCreateErrorInfo->QueryInterface(IID_IErrorInfo, (LPVOID *)&pErrorInfo); if(FAILED(hSuccess)) { pCreateErrorInfo->Release(); return hSuccess; } // Set this error information in the current thread hSuccess = SetErrorInfo(0, pErrorInfo); // Finally release the interfaces pCreateErrorInfo->Release(); pErrorInfo->Release(); // Failed to set the error info! if(FAILED(hSuccess)) return hSuccess; // And, Return the error code that was asked // to be dispatched HRESULT result = MAKE_HRESULT(1, FACILITY_ITF, hError); return result; }