// The CreateComErrorInfo function uses CreateErrorInfo to create error // object, which is then filled with the error information and passed to // the acceptor by a call to SetErrorInfo. void CreateComErrorInfo(const char* description, const char* source, const char* helpFile, UInt32 helpContext) { ICreateErrorInfo* createErrInfo; IErrorInfo* errInfo; std::basic_string<wchar_t> buf; if (CreateErrorInfo(&createErrInfo) == S_OK) { createErrInfo->SetGUID(IID_IErrorInfo); if (description != NULL) { buf = WideStringFromMultiByteString(description); createErrInfo->SetDescription(const_cast<wchar_t*>(buf.c_str())); } if (source != NULL) { buf = WideStringFromMultiByteString(source); createErrInfo->SetSource(const_cast<wchar_t*>(buf.c_str())); } if (helpFile != NULL) { buf = WideStringFromMultiByteString(helpFile); createErrInfo->SetHelpFile(const_cast<wchar_t*>(buf.c_str())); } createErrInfo->SetHelpContext(helpContext); if (createErrInfo->QueryInterface(IID_IErrorInfo, (void**)(&errInfo)) == S_OK) { SetErrorInfo(0, errInfo); errInfo->Release(); } createErrInfo->Release(); } }
// Given an EXCEPINFO, register the error information with the // IErrorInfo interface. BOOL PyCom_SetCOMErrorFromExcepInfo(const EXCEPINFO *pexcepinfo, REFIID riid) { ICreateErrorInfo *pICEI; HRESULT hr = CreateErrorInfo(&pICEI); if ( SUCCEEDED(hr) ) { pICEI->SetGUID(riid); pICEI->SetHelpContext(pexcepinfo->dwHelpContext); if ( pexcepinfo->bstrDescription ) pICEI->SetDescription(pexcepinfo->bstrDescription); if ( pexcepinfo->bstrHelpFile ) pICEI->SetHelpFile(pexcepinfo->bstrHelpFile); if ( pexcepinfo->bstrSource ) pICEI->SetSource(pexcepinfo->bstrSource); IErrorInfo *pIEI; Py_BEGIN_ALLOW_THREADS hr = pICEI->QueryInterface(IID_IErrorInfo, (LPVOID*) &pIEI); Py_END_ALLOW_THREADS if ( SUCCEEDED(hr) ) { SetErrorInfo(0, pIEI); pIEI->Release(); } pICEI->Release(); } return SUCCEEDED(hr); }
// // // makes an HRESULT with a code based on the DOM error code // HRESULT MakeHRESULT(DOMException& ex) { ICreateErrorInfo* pCErr = NULL; HRESULT sc = CreateErrorInfo(&pCErr); if(SUCCEEDED(sc)) { const XMLCh* msg = ex.msg; if(msg == NULL) { if(ex.code >= DOMException::INDEX_SIZE_ERR && ex.code <= DOMException::VALIDATION_ERR) { sc = pCErr->SetDescription(Msgs[ex.code]); } else { sc = pCErr->SetDescription(Msgs[0]); } } else { sc = pCErr->SetDescription(SysAllocString(ex.msg)); } IErrorInfo* pErr = NULL; sc = pCErr->QueryInterface(IID_IErrorInfo,(void**) &pErr); if(SUCCEEDED(sc)) { sc = SetErrorInfo(0,pErr); pErr->Release(); } pCErr->Release(); } return 0x80040600 + ex.code; }
// static void XPCThrower::ThrowCOMError(JSContext* cx, unsigned long COMErrorCode, nsresult rv, const EXCEPINFO * exception) { nsCAutoString msg; IErrorInfo * pError; const char * format; if(!nsXPCException::NameAndFormatForNSResult(rv, nsnull, &format)) format = ""; msg = format; #ifndef WINCE if(exception) { msg += static_cast<const char *> (_bstr_t(exception->bstrSource, false)); msg += " : "; msg.AppendInt(static_cast<PRUint32>(COMErrorCode)); msg += " - "; msg += static_cast<const char *> (_bstr_t(exception->bstrDescription, false)); } else { // Get the current COM error object unsigned long result = GetErrorInfo(0, &pError); if(SUCCEEDED(result) && pError) { // Build an error message from the COM error object BSTR bstrSource = NULL; if(SUCCEEDED(pError->GetSource(&bstrSource)) && bstrSource) { _bstr_t src(bstrSource, false); msg += static_cast<const char *>(src); msg += " : "; } msg.AppendInt(static_cast<PRUint32>(COMErrorCode), 16); BSTR bstrDesc = NULL; if(SUCCEEDED(pError->GetDescription(&bstrDesc)) && bstrDesc) { msg += " - "; _bstr_t desc(bstrDesc, false); msg += static_cast<const char *>(desc); } } else { // No error object, so just report the result msg += "COM Error Result = "; msg.AppendInt(static_cast<PRUint32>(COMErrorCode), 16); } } #else // No error object, so just report the result msg += "COM Error Result = "; msg.AppendInt(static_cast<PRUint32>(COMErrorCode), 16); #endif XPCThrower::BuildAndThrowException(cx, rv, msg.get()); }
HRESULT COMError::GenerateError(HM::String sDescription) { if (sDescription == _T("")) { sDescription = "The operation failed. Please check the hMailServer log for details."; } // Get the ICreateErrorInfo Interface ICreateErrorInfo *pCreateErrorInfo = NULL; HRESULT hSuccess = CreateErrorInfo(&pCreateErrorInfo); ATLASSERT(SUCCEEDED(hSuccess)); // pCreateErrorInfo->SetGUID(CLSID_BaseApp); pCreateErrorInfo->SetDescription(sDescription.AllocSysString()); HM::String sSource = "hMailServer COM library"; pCreateErrorInfo->SetSource(sSource.AllocSysString()); IErrorInfo *pErrInfo; if (SUCCEEDED(pCreateErrorInfo->QueryInterface(IID_IErrorInfo, reinterpret_cast<void**>(&pErrInfo)))) { SetErrorInfo(0, pErrInfo); pErrInfo->Release(); } pCreateErrorInfo->Release(); return MAKE_HRESULT(1, FACILITY_ITF, 1001); }
void VLCSupportErrorInfo::setErrorInfo(LPCOLESTR progid, REFIID riid, const char *description) { BSTR bstrDescription = BSTRFromCStr(CP_UTF8, description); if( NULL != bstrDescription ) { ICreateErrorInfo* pcerrinfo; HRESULT hr = CreateErrorInfo(&pcerrinfo); if( SUCCEEDED(hr) ) { IErrorInfo* perrinfo; pcerrinfo->SetSource((LPOLESTR)progid); pcerrinfo->SetGUID(riid); pcerrinfo->SetDescription((LPOLESTR)bstrDescription); hr = pcerrinfo->QueryInterface(IID_IErrorInfo, (LPVOID*) &perrinfo); if( SUCCEEDED(hr) ) { ::SetErrorInfo(0, perrinfo); perrinfo->Release(); } pcerrinfo->Release(); } SysFreeString(bstrDescription); } };
//////////////////////////////////////////////////////////////////////// // HRESULT GetErrorRecords // // Get the error message generated by an OLE DB object ///////////////////////////////////////////////////////////////////////////// HRESULT GetErrorRecords(ULONG* pcRecords, IErrorRecords** ppIErrorRecords) { ASSERT(pcRecords && ppIErrorRecords); HRESULT hr; //NULL output params *pcRecords = 0; *ppIErrorRecords = NULL; ISupportErrorInfo* pISupportErrorInfo = NULL; IErrorInfo* pIErrorInfo = NULL; //See if this interface supports ErrorInfo //If not there is no reason to display any error if((hr = GetErrorInfo(0, &pIErrorInfo))==S_OK && pIErrorInfo) { //IErrorRecords may not be supported on the existing error object. //Some other things could have posted an error object (VB) for example... QTESTC(hr = pIErrorInfo->QueryInterface(IID_IErrorRecords, (void**)ppIErrorRecords)); XTESTC(hr = (*ppIErrorRecords)->GetRecordCount(pcRecords)); } CLEANUP: SAFE_RELEASE(pISupportErrorInfo); SAFE_RELEASE(pIErrorInfo); return hr; }
STDMETHODIMP nsXPCDispTestMethods::CreateError() { CComBSTR someText(L"CreateError Test"); ICreateErrorInfo * pCreateError; IErrorInfo * pError; HRESULT result = CreateErrorInfo(&pCreateError); if (FAILED(result)) return E_NOTIMPL; result = pCreateError->QueryInterface(&pError); if (FAILED(result)) return E_NOTIMPL; result = pCreateError->SetDescription(someText); if (FAILED(result)) return E_NOTIMPL; result = pCreateError->SetGUID(IID_nsIXPCDispTestMethods); if (FAILED(result)) return E_NOTIMPL; CComBSTR source(L"XPCIDispatchTest.nsXPCDispTestMethods.1"); result = pCreateError->SetSource(source); if (FAILED(result)) return E_NOTIMPL; result = SetErrorInfo(0, pError); if (FAILED(result)) return E_NOTIMPL; pError->Release(); pCreateError->Release(); return E_FAIL; }
COMError::COMError(HRESULT hr) { _com_error e(hr); IErrorInfo *pIErrorInfo = NULL; GetErrorInfo(0, &pIErrorInfo); if (pIErrorInfo == NULL) { e = _com_error(hr); message = e.ErrorMessage(); } else { e = _com_error(hr, pIErrorInfo); message = e.ErrorMessage(); IErrorInfo *ptrIErrorInfo = e.ErrorInfo(); if (ptrIErrorInfo != NULL) { // IErrorInfo Interface located description = (WCHAR *)e.Description(); source = (WCHAR *)e.Source(); GUID tmpGuid = e.GUID(); RPC_WSTR guidStr = NULL; // must link in Rpcrt4.lib for UuidToString UuidToString(&tmpGuid, &guidStr); uuid = (WCHAR*)guidStr; RpcStringFree(&guidStr); ptrIErrorInfo->Release(); } } }
IErrorInfo *COMException::GetErrorInfo() { LIMITED_METHOD_CONTRACT; IErrorInfo *pErrorInfo = m_pErrorInfo; if (pErrorInfo != NULL) pErrorInfo->AddRef(); return pErrorInfo; }
/*---------------------------------------------------------------------------------------------- Static method to find a class factory (from the given CLSID) from all the class factories that are in the linked list. If the requested class factory is not found, *ppv is set to NULL and CLASS_E_CLASSNOTAVAILABLE is returned. ----------------------------------------------------------------------------------------------*/ HRESULT ModuleEntry::ModuleGetClassObject(REFCLSID clsid, REFIID iid, void ** ppv) { AssertPtrN(ppv); if (!ppv) return WarnHr(E_POINTER); *ppv = NULL; // This block of code is largely copied from the AssertNoErrorInfo method in throwable.h. // Here, however, we don't assert, but just dump a warning to the output window and // discard the spurious error info. This prevents asserts if Windows.Forms calls // a class factory (as it has been known to do) with spurious error info registered. #ifdef DEBUG IErrorInfo * pIErrorInfo = NULL; HRESULT hr = GetErrorInfo(0, &pIErrorInfo); Assert(SUCCEEDED(hr)); if(pIErrorInfo != NULL) { BSTR bstr; hr = pIErrorInfo->GetDescription(&bstr); Assert(SUCCEEDED(hr)); ::OutputDebugString(bstr); ::SysFreeString(bstr); hr = pIErrorInfo->GetSource(&bstr); Assert(SUCCEEDED(hr)); ::OutputDebugString(bstr); ::SysFreeString(bstr); pIErrorInfo->Release(); } #endif ModuleEntry * pme; try { for (pme = s_pmeFirst; pme; pme = pme->m_pobjNext) { AssertPtr(pme); pme->GetClassFactory(clsid, iid, ppv); if (*ppv) return S_OK; } } catch (const Throwable & thr) { return thr.Error(); } catch (...) { return WarnHr(E_FAIL); } return CLASS_E_CLASSNOTAVAILABLE; }
// The CreateExternalException function uses GetErrorInfo function to get // COM error information and then creates Exception with the error description. ExternalException* CreateExternalException() { IErrorInfo* errInfo; BSTR descriptionBStr; std::string descriptionStr; if (GetErrorInfo(0, &errInfo) == S_OK) { errInfo->GetDescription(&descriptionBStr); descriptionStr = MultiByteStringFromWideString(descriptionBStr); ::SysFreeString(descriptionBStr); } return new ExternalException(descriptionStr); }
int ErrorManager::GetNativeErrorCode(IErrorInfo *pIErrorInfo) { int iRetValue = 0; HRESULT hr = S_OK; IErrorRecords *pIErrorRecords = NULL; ERRORINFO errorInfo = { 0 }; IErrorInfo *pIErrorInfoRecord = NULL; try { hr = pIErrorInfo->QueryInterface(IID_IErrorRecords, (void **) &pIErrorRecords); if ( FAILED(hr) || NULL == pIErrorRecords ) return -1; pIErrorInfo->Release(); pIErrorInfo = NULL; ULONG ulNumErrorRecs = 0; hr = pIErrorRecords->GetRecordCount(&ulNumErrorRecs); if ( FAILED(hr) ) return -1; for (DWORD dwErrorIndex = 0; dwErrorIndex < ulNumErrorRecs; dwErrorIndex++) { hr = pIErrorRecords->GetBasicErrorInfo(dwErrorIndex, &errorInfo); if ( FAILED(hr) ) return -1; iRetValue = errorInfo.dwMinor; } } catch( ... ) { iRetValue = errorInfo.dwMinor; } if( pIErrorInfoRecord ) pIErrorInfoRecord->Release(); if ( pIErrorInfo ) pIErrorInfo->Release(); if ( pIErrorRecords ) pIErrorRecords->Release(); return iRetValue; }
//--------------------------------------------------------------------------- // RaiseException // // Raises an exception using the given source and description //--------------------------------------------------------------------------- void CAdRotator::RaiseException ( LPOLESTR strDescr ) { HRESULT hr; ICreateErrorInfo *pICreateErr; IErrorInfo *pIErr; LANGID langID = LANG_NEUTRAL; /* * Thread-safe exception handling means that we call * CreateErrorInfo which gives us an ICreateErrorInfo pointer * that we then use to set the error information (basically * to set the fields of an EXCEPINFO structure. We then * call SetErrorInfo to attach this error to the current * thread. ITypeInfo::Invoke will look for this when it * returns from whatever function was invokes by calling * GetErrorInfo. */ WCHAR strSource[MAX_RESSTRINGSIZE]; if ( ::LoadStringW( _Module.GetResourceInstance(), IDS_ERROR_SOURCE, strSource, MAX_RESSTRINGSIZE ) > 0 ) { //Not much we can do if this fails. if (!FAILED(CreateErrorInfo(&pICreateErr))) { pICreateErr->SetGUID(CLSID_AdRotator); pICreateErr->SetHelpFile(L""); pICreateErr->SetHelpContext(0L); pICreateErr->SetSource(strSource); pICreateErr->SetDescription(strDescr); hr = pICreateErr->QueryInterface(IID_IErrorInfo, (void**)&pIErr); if (SUCCEEDED(hr)) { if(SUCCEEDED(SetErrorInfo(0L, pIErr))) { pIErr->Release(); } } } pICreateErr->Release(); } }
void JavascriptErrorDebug::ClearErrorInfo(ScriptContext* scriptContext) { HRESULT hr = scriptContext->GetThreadContext()->GetWinRTErrorLibrary()->RoClearError(); // If we fail to create the delay-load library or fail to find RoClearError in it, fallback to Win8 behavior. if (FAILED(hr)) { IErrorInfo * perrinfo; if(NOERROR == (hr = GetErrorInfo(0L, &perrinfo))) { perrinfo->Release(); } } }
//////////////////////////////////////////////////////////////////////// // HRESULT DisplayErrorRecords // ///////////////////////////////////////////////////////////////////////////// HRESULT DisplayErrorRecords(HWND hWnd, ULONG cRecords, IErrorRecords* pIErrorRecords, WCHAR* pwszFile, ULONG ulLine) { HRESULT hr = S_OK; IErrorInfo* pIErrorInfo = NULL; BSTR bstrErrorInfo = NULL; BSTR bstrSQLInfo = NULL; LCID lcid = GetSystemDefaultLCID(); //Get the Error Records if(cRecords && pIErrorRecords) { LONG lNativeError = 0; ERRORINFO ErrorInfo; //Loop through the records for(ULONG i=0; i<cRecords; i++) { //GetErrorInfo XTESTC(hr = pIErrorRecords->GetErrorInfo(i,lcid,&pIErrorInfo)); //Get the Description XTESTC(hr = pIErrorInfo->GetDescription(&bstrErrorInfo)); //Get the Basic ErrorInfo XTESTC(hr = pIErrorRecords->GetBasicErrorInfo(i,&ErrorInfo)); //Get the SQL Info GetSqlErrorInfo(i, pIErrorRecords, &bstrSQLInfo); //Display the Error if(bstrSQLInfo) wMessageBox(hWnd, (hWnd ? MB_APPLMODAL : MB_TASKMODAL) | MB_ICONEXCLAMATION | MB_OK, wsz_ERRORINFO, L"Interface: %s\nResult: %x = %s\n\nIErrorInfo: [%s] %s\n\nFile: %s\nLine: %d", GetInterfaceName(ErrorInfo.iid), ErrorInfo.hrError, GetErrorName(ErrorInfo.hrError), bstrSQLInfo, bstrErrorInfo, pwszFile, ulLine); else wMessageBox(hWnd, (hWnd ? MB_APPLMODAL : MB_TASKMODAL) | MB_ICONEXCLAMATION | MB_OK, wsz_ERRORINFO, L"Interface: %s\nResult: %x = %s\n\nIErrorInfo: %s\n\nFile: %s\nLine: %d", GetInterfaceName(ErrorInfo.iid), ErrorInfo.hrError, GetErrorName(ErrorInfo.hrError), bstrErrorInfo, pwszFile, ulLine); SAFE_RELEASE(pIErrorInfo); SAFE_SYSFREE(bstrErrorInfo); SAFE_SYSFREE(bstrSQLInfo); } } CLEANUP: SAFE_RELEASE(pIErrorInfo); SAFE_SYSFREE(bstrErrorInfo); SAFE_SYSFREE(bstrSQLInfo); return hr; }
void OutErrorInfo(IUnknown *pUnk) { IErrorInfo *pErr; HRESULT hr = pUnk->QueryInterface(IID_IErrorInfo, (void **)&pErr); if(SUCCEEDED(hr)) { BSTR desc; pErr->GetDescription(&desc); OutputDebugString(desc); OutputDebugString(_T("\n")); SysFreeString(desc); } else { OutputDebugString(_T("Error is Unknown...\n")); } }
template <class T> HRESULT SepaControlDispatch<T>::SetErrorInfo(const wchar_t *pMessage) const { ICreateErrorInfo *pCreateErrorInfo; IErrorInfo *pErrorInfo; if (SUCCEEDED(CreateErrorInfo(&pCreateErrorInfo))) { pCreateErrorInfo->SetDescription(_bstr_t(pMessage).Detach()); pCreateErrorInfo->SetGUID(__uuidof(this)); pCreateErrorInfo->SetSource(_bstr_t(TEXT("Separatista")).Detach()); if (SUCCEEDED(pCreateErrorInfo->QueryInterface(IID_IErrorInfo, (LPVOID*)&pErrorInfo))) { ::SetErrorInfo(0, pErrorInfo); pErrorInfo->Release(); } pCreateErrorInfo->Release(); } return DISP_E_EXCEPTION; }
tscrypto::tsCryptoString COMMessage(HRESULT hr) { tscrypto::tsCryptoString sHr; switch (hr) { case S_OK: sHr = "OK"; break; case S_FALSE: sHr = "FALSE"; break; case E_NOTIMPL: sHr = "Not Implemented"; break; case E_UNEXPECTED: sHr = "Unexpected operation"; break; case E_OUTOFMEMORY: sHr = "Out Of Memory"; break; case E_INVALIDARG: sHr = "Invalid Argument"; break; case E_NOINTERFACE: sHr = "No Interface"; break; case E_POINTER: sHr = "Invalid Pointer"; break; case E_HANDLE: sHr = "Invalid Handle"; break; case E_ABORT: sHr = "Aborted"; break; case E_FAIL: sHr = "General Failure"; break; case E_ACCESSDENIED: sHr = "Access Denied"; break; case E_PENDING: sHr = ""; break; default: sHr.Format("0x%08X", hr); break; } #ifndef NO_IDISPATCH if (FAILED(hr)) { IErrorInfo* pErrInfo = nullptr; if (::GetErrorInfo(0, &pErrInfo) == S_OK) { BSTR tmp = nullptr; if (SUCCEEDED(pErrInfo->GetDescription(&tmp))) sHr << " - " << CryptoUtf16(tmp).toUtf8(); SysFreeString(tmp); pErrInfo->Release(); } } #endif // NO_IDISPATCH return sHr; }
int die (char const * szError, HRESULT hr) { fprintf (stderr, "\nDIE: %s\n", szError); fflush (stderr); if (hr != S_OK) { IErrorInfo * pIErr = NULL; BSTR bstrDesc = NULL; fprintf (stderr, "HRESULT = 0x%08x\n", hr); if (GetErrorInfo (0, &pIErr) == S_OK && pIErr->GetDescription (&bstrDesc) == S_OK) { fprintf (stderr, "%ls", bstrDesc); fflush (stderr); SysFreeString (bstrDesc); } if (pIErr) pIErr->Release(); } CoUninitialize(); exit (hr); }
void CMarshalErrorInfo::GenerateErrorInfo(REFGUID rGUID, _bstr_t source, _bstr_t message) { ICreateErrorInfo* pCreateInfo = NULL; IErrorInfo* pErrorInfo = NULL; // 创建ICreateErrorInfo对象 CreateErrorInfo(&pCreateInfo); // 设置属性值 pCreateInfo->SetGUID(rGUID); pCreateInfo->SetSource(source); pCreateInfo->SetDescription(message); // 获得pCreateInfo的IErrorInfo接口引用 pCreateInfo->QueryInterface(IID_IErrorInfo, (void**)&pErrorInfo); // 设置IErrorInfo SetErrorInfo(0,pErrorInfo); // 释放对象 pErrorInfo->Release(); pCreateInfo->Release(); }
HRESULT DualHandleException(REFIID riidSource, const CException* pAnyException) { USES_CONVERSION; ASSERT_VALID(pAnyException); TRACE0("DualHandleException called\n"); // Set ErrInfo object so that VTLB binding container // applications can get rich error information. ICreateErrorInfo* pcerrinfo; HRESULT hr = CreateErrorInfo(&pcerrinfo); if (SUCCEEDED(hr)) { TCHAR szDescription[256]; LPCTSTR pszDescription = szDescription; GUID guid = GUID_NULL; DWORD dwHelpContext = 0; BSTR bstrHelpFile = NULL; BSTR bstrSource = NULL; if (pAnyException->IsKindOf(RUNTIME_CLASS(COleDispatchException))) { // specific IDispatch style exception COleDispatchException* e = (COleDispatchException*)pAnyException; guid = riidSource; hr = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, (e->m_wCode + 0x200)); pszDescription = e->m_strDescription; dwHelpContext = e->m_dwHelpContext; // propagate source and help file if present // call ::SysAllocString directly so no further exceptions are thrown if (!e->m_strHelpFile.IsEmpty()) bstrHelpFile = ::SysAllocString(T2COLE(e->m_strHelpFile)); if (!e->m_strSource.IsEmpty()) bstrSource = ::SysAllocString(T2COLE(e->m_strSource)); } else if (pAnyException->IsKindOf(RUNTIME_CLASS(CMemoryException))) { // failed memory allocation AfxLoadString(AFX_IDP_FAILED_MEMORY_ALLOC, szDescription); hr = E_OUTOFMEMORY; } else { // other unknown/uncommon error AfxLoadString(AFX_IDP_INTERNAL_FAILURE, szDescription); hr = E_UNEXPECTED; } if (bstrHelpFile == NULL && dwHelpContext != 0) bstrHelpFile = ::SysAllocString(T2COLE(AfxGetApp()->m_pszHelpFilePath)); if (bstrSource == NULL) bstrSource = ::SysAllocString(T2COLE(AfxGetAppName())); // Set up ErrInfo object pcerrinfo->SetGUID(guid); pcerrinfo->SetDescription(::SysAllocString(T2COLE(pszDescription))); pcerrinfo->SetHelpContext(dwHelpContext); pcerrinfo->SetHelpFile(bstrHelpFile); pcerrinfo->SetSource(bstrSource); TRACE(_T("\tSource = %ws\n"), bstrSource); TRACE(_T("\tDescription = %s\n"), pszDescription); TRACE(_T("\tHelpContext = %lx\n"), dwHelpContext); TRACE(_T("\tHelpFile = %ws\n"), bstrHelpFile); // Set the ErrInfo object for the current thread IErrorInfo* perrinfo; if (SUCCEEDED(pcerrinfo->QueryInterface(IID_IErrorInfo, (LPVOID*)&perrinfo))) { SetErrorInfo(0, perrinfo); perrinfo->Release(); } pcerrinfo->Release(); } TRACE(_T("DualHandleException returning HRESULT %lx\n"), hr); return hr; }
/* Determines whether we can use the error information from the source object and if so, throws that as an error. If serr is non-NULL, then the error is not thrown in R but a COMSErrorInfo object is returned with the information in it. */ HRESULT checkErrorInfo(IUnknown *obj, HRESULT status, SEXP *serr) { HRESULT hr; ISupportErrorInfo *info; fprintf(stderr, "<checkErrorInfo> %X \n", (unsigned int) status); if(serr) *serr = NULL; hr = obj->QueryInterface(IID_ISupportErrorInfo, (void **)&info); if(hr != S_OK) { fprintf(stderr, "No support for ISupportErrorInfo\n");fflush(stderr); return(hr); } info->AddRef(); hr = info->InterfaceSupportsErrorInfo(IID_IDispatch); info->Release(); if(hr != S_OK) { fprintf(stderr, "No support for InterfaceSupportsErrorInfo\n");fflush(stderr); return(hr); } IErrorInfo *errorInfo; hr = GetErrorInfo(0L, &errorInfo); if(hr != S_OK) { /* fprintf(stderr, "GetErrorInfo failed\n");fflush(stderr); */ COMError(status); return(hr); } /* So there is some information for us. Use it. */ SEXP klass, ans, tmp; BSTR ostr; char *str; errorInfo->AddRef(); if(serr) { PROTECT(klass = MAKE_CLASS("SCOMErrorInfo")); PROTECT(ans = NEW(klass)); PROTECT(tmp = NEW_CHARACTER(1)); errorInfo->GetSource(&ostr); SET_STRING_ELT(tmp, 0, COPY_TO_USER_STRING(FromBstr(ostr))); SET_SLOT(ans, Rf_install("source"), tmp); UNPROTECT(1); PROTECT(tmp = NEW_CHARACTER(1)); errorInfo->GetDescription(&ostr); SET_STRING_ELT(tmp, 0, COPY_TO_USER_STRING(str = FromBstr(ostr))); SET_SLOT(ans, Rf_install("description"), tmp); UNPROTECT(1); PROTECT(tmp = NEW_NUMERIC(1)); NUMERIC_DATA(tmp)[0] = status; SET_SLOT(ans, Rf_install("status"), tmp); *serr = ans; UNPROTECT(3); errorInfo->Release(); PROBLEM "%s", str WARN; } else { errorInfo->GetDescription(&ostr); str = FromBstr(ostr); errorInfo->GetSource(&ostr); errorInfo->Release(); PROBLEM "%s (%s)", str, FromBstr(ostr) ERROR; } return(hr); }
int _tmain(int argc, _TCHAR* argv[]) { HRESULT hr; // COM 戻り値用変数 IClassTest* pClassTest; // COMインターフェイスポインタ // COMの初期化 ◆◆追加 hr = ::CoInitialize(NULL); if(FAILED(hr)){ printf("CoInitialize 失敗\n"); return 0; } // ---------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------- // <以下のコードは、アーリーバインディング方式での呼び出し> // インスタンスの作成(CLSID:[CLSID_ClassTest]とIID:[IID_IClassTest]を指定して、ポインタを取得) hr = ::CoCreateInstance((REFCLSID) CLSID_ClassTest, 0, CLSCTX_INPROC_SERVER, (REFIID) IID_IClassTest, (LPVOID*)&pClassTest); if(FAILED(hr)){ printf("CoCreateInstance 失敗\n"); return 0; } // BSTRを処理する場合は、_bstr_tが楽(解放など) // http://mzs184.blogspot.com/2008/04/bstrbstrt.html // _bstr_t Class // http://msdn.microsoft.com/ja-jp/library/zthfhkd6.aspx // _bstr_t::operator = // http://msdn.microsoft.com/ja-jp/library/7bh2f8sk.aspx _bstr_t bstrText = L"だいすけ"; _bstr_t bstrCaption = L"にしの"; _bstr_t bstrRetVal; // メソッド呼び出し // _bstr_t::wchar_t*, _bstr_t::char* // BSTRはOLECHAR(= WCHAR)のポインタなので適用可能。 // http://msdn.microsoft.com/ja-jp/library/btdzb8eb.aspx // _bstr_t::GetAddress // http://msdn.microsoft.com/ja-jp/library/t2x13207.aspx hr = pClassTest->MethodTest(bstrText, bstrCaption, bstrRetVal.GetAddress()); if(FAILED(hr)){ printf("MethodTest 失敗\n"); return 0; } MessageBox(NULL, bstrRetVal, L"戻り値", MB_OK); // bstrRetValをクリア(DetachしてSysFreeString) // _bstr_t::Detach // http://msdn.microsoft.com/en-us/library/3c73x1sf.aspx // SysFreeString // http://msdn.microsoft.com/ja-jp/site/ms221481 BSTR bstr = bstrRetVal.Detach(); if(bstr != NULL) { SysFreeString(bstr); } // bstrCaptionの再設定 bstrCaption = L""; // メソッド呼び出し(同上) hr = pClassTest->MethodTest(bstrText, bstrCaption, bstrRetVal.GetAddress()); // Dr.GUI Online // Dr.GUI と COM オートメーション、 // 第 3 部:続 COM のすばらしきデータ型 // http://msdn.microsoft.com/ja-jp/library/cc482694.aspx // ISupportErrorInfo、IErrorInfoでエラー情報を取得 if(FAILED(hr)) { // IID_ISupportErrorInfoインターフェイスを取得 ISupportErrorInfo *pSupport; hr = pClassTest->QueryInterface(IID_ISupportErrorInfo, (void**)&pSupport); if (SUCCEEDED(hr)) { hr = pSupport->InterfaceSupportsErrorInfo(IID_IClassTest); if (hr == S_OK) { // can't use SUCCEEDED here! S_FALSE succeeds! IErrorInfo *pErrorInfo; hr = GetErrorInfo(0, &pErrorInfo); if (SUCCEEDED(hr)) { // FINALLY can call methods on pErrorInfo! ...and handle the error! _bstr_t bstrErrorDescription; pErrorInfo->GetDescription(bstrErrorDescription.GetAddress()); // エラー情報 MessageBox(NULL, bstrErrorDescription, L"ErrorDescription", MB_OK); // don't forget to release! pErrorInfo->Release(); } } // don't forget to release! pSupport->Release(); } } // don't forget to release! pClassTest->Release(); // ---------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------- // <以下のコードは、レイトバインディング方式での呼び出し> // CLSID の取得 CLSID clsid; hr = CLSIDFromProgID(L"VC_COM.ClassTest", &clsid); if(FAILED(hr)){ printf("CLSIDFromProgID 失敗\n"); return 0; } // インスタンスの作成(CLSIDとIID:[IID_IDispatch]を指定して、ポインタを取得) IDispatch* pDisp = NULL; hr = ::CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_IDispatch, (void**)&pDisp); if(FAILED(hr)){ printf("CoCreateInstance 失敗\n"); return 0; } // COMディスパッチ識別子の取得 DISPID dispID; OLECHAR* wszName = L"MethodTest"; hr = pDisp->GetIDsOfNames(IID_NULL, &wszName, 1, LOCALE_USER_DEFAULT, &dispID); if(FAILED(hr)){ printf("GetIDsOfNames 失敗\n"); exit(1); } // CComVariant クラス(CComVariant は VARIANT 型から派生) // http://msdn.microsoft.com/ja-jp/library/ac97df2h.aspx // 引数を VARIANT 配列に設定 CComVariant pvArgs[2]; pvArgs[0] = L"だいすけ"; pvArgs[1] = L"にしの"; // 戻り値を VARIANT変数 CComVariant pvResult; // DISPPARAMS の設定 DISPPARAMS dispParams; dispParams.rgvarg = pvArgs; dispParams.rgdispidNamedArgs = NULL; dispParams.cArgs = 2; dispParams.cNamedArgs = 0; // メソッドにレイトバインド(Invoke) hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispParams, &pvResult, NULL, NULL); if(FAILED(hr)){ printf("MethodTest 失敗\n"); return 0; } // BSTRで格納されている時、tagVARIANTのメンバ、bstrValで取得可能。 // BSTRはOLECHAR(= WCHAR)のポインタなのでLPWSTRにキャスト可能。 MessageBox(NULL, (LPWSTR)pvResult.bstrVal, L"戻り値", MB_OK); // don't forget to release! pDisp->Release(); // ---------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------- // COMの終了処理 ◆◆追加 ::CoUninitialize(); return 0; }
/******************************************************************** SqlGetErrorInfo - gets error information from the last SQL function call NOTE: pbstrErrorSource and pbstrErrorDescription are optional ********************************************************************/ extern "C" HRESULT DAPI SqlGetErrorInfo( __in IUnknown* pObjectWithError, __in REFIID IID_InterfaceWithError, __in DWORD dwLocaleId, __out_opt BSTR* pbstrErrorSource, __out_opt BSTR* pbstrErrorDescription ) { HRESULT hr = S_OK; Assert(pObjectWithError); // interfaces needed to extract error information out ISupportErrorInfo* pISupportErrorInfo = NULL; IErrorInfo* pIErrorInfoAll = NULL; IErrorRecords* pIErrorRecords = NULL; IErrorInfo* pIErrorInfoRecord = NULL; // only ask for error information if the interface supports it. hr = pObjectWithError->QueryInterface(IID_ISupportErrorInfo,(void**)&pISupportErrorInfo); ExitOnFailure(hr, "No error information was found for object."); hr = pISupportErrorInfo->InterfaceSupportsErrorInfo(IID_InterfaceWithError); ExitOnFailure(hr, "InterfaceWithError is not supported for object with error"); // ignore the return of GetErrorInfo it can succeed and return a NULL pointer in pIErrorInfoAll anyway hr = ::GetErrorInfo(0, &pIErrorInfoAll); ExitOnFailure(hr, "failed to get error info"); if (S_OK == hr && pIErrorInfoAll) { // see if it's a valid OLE DB IErrorInfo interface that exposes a list of records hr = pIErrorInfoAll->QueryInterface(IID_IErrorRecords, (void**)&pIErrorRecords); if (SUCCEEDED(hr)) { ULONG cErrors = 0; pIErrorRecords->GetRecordCount(&cErrors); // get the error information for each record for (ULONG i = 0; i < cErrors; ++i) { hr = pIErrorRecords->GetErrorInfo(i, dwLocaleId, &pIErrorInfoRecord); if (SUCCEEDED(hr)) { if (pbstrErrorSource) { pIErrorInfoRecord->GetSource(pbstrErrorSource); } if (pbstrErrorDescription) { pIErrorInfoRecord->GetDescription(pbstrErrorDescription); } ReleaseNullObject(pIErrorInfoRecord); break; // TODO: return more than one error in the future! } } ReleaseNullObject(pIErrorRecords); } else // we have a simple error record { if (pbstrErrorSource) { pIErrorInfoAll->GetSource(pbstrErrorSource); } if (pbstrErrorDescription) { pIErrorInfoAll->GetDescription(pbstrErrorDescription); } } } else { hr = E_NOMOREITEMS; } LExit: ReleaseObject(pIErrorInfoRecord); ReleaseObject(pIErrorRecords); ReleaseObject(pIErrorInfoAll); ReleaseObject(pISupportErrorInfo); return hr; }
//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; }
//*************************************************************************** // 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); } }
/* * 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; }
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); }