Пример #1
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);
}
Пример #2
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;
    }
Пример #4
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);
    }
}
Пример #5
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;
}
Пример #6
0
////////////////////////////////////////////////////////////////////////
// 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;
}
Пример #7
0
////////////////////////////////////////////////////////////////////////
// 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;
}
Пример #8
0
// 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;
}