示例#1
0
// 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();
  }
}
示例#2
0
// 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);
}
示例#3
0
//
//
//   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());
}
示例#5
0
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);
}
示例#6
0
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);
    }
};
示例#7
0
////////////////////////////////////////////////////////////////////////
// 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;
}
示例#9
0
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();
		}
	}
}
示例#10
0
IErrorInfo *COMException::GetErrorInfo()
{
    LIMITED_METHOD_CONTRACT;

    IErrorInfo *pErrorInfo = m_pErrorInfo;
    if (pErrorInfo != NULL)
        pErrorInfo->AddRef();
    return pErrorInfo;
}
示例#11
0
/*----------------------------------------------------------------------------------------------
	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;
}
示例#12
0
// 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);
}
示例#13
0
   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();
            }
        }
    }
示例#16
0
////////////////////////////////////////////////////////////////////////
// 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;
}
示例#17
0
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"));
	}
}
示例#18
0
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;
}
示例#19
0
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;
}
示例#20
0
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();
}
示例#22
0
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;
}
示例#23
0
/* 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;
}
示例#25
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;
}
示例#26
0
//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;
}
示例#27
0
//***************************************************************************
// 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);
    }
}
示例#28
0
/*
 * 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;
    }
示例#30
0
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);
}