When an error occurs in a provider, the provider can return an OLE DB error object to describe that error. To do this, it makes the following calls:
The following code shows an example of how a provider might create an OLE DB error object in response to being unable to open a table and transfer ownership of the object to the Automation DLL:
#include <oledb.h>
IClassFactory   *m_pErrorObjectFactory ;
IParseDisplayName *pppwow;
DWORD      errCantOpenTable;
IOpenRowset   *pSimpleProvider;
DBPROPSET    rgPropertySets[1];
IRowset     *pRowset;
DBID     TableID;
extern GUID    CLSID_THISISAM;
extern DISPID  DISPID_OpenRowset;
BSTR     bstrTableName;
int main() {
 ERRORINFO  ErrorInfo;
 HRESULT    hr, hrErr;
 IErrorInfo  *pErrorInfo;
 IErrorRecords *pErrorRecords;
 // Clear the current error object.
 SetErrorInfo(0, NULL);
 // Try to open the table or call another provider to do it.
 hrErr = pSimpleProvider->OpenRowset(NULL, &TableID, NULL, IID_IRowset, 1,
             rgPropertySets, (IUnknown**) &pRowset);
 if (!FAILED(hrErr))
  return hrErr;
 // An error or warning occurred while opening the table. 
 //Get the current error object. If one does not exist, create a new one.
 GetErrorInfo(0, &pErrorInfo);
 if (!pErrorInfo)
  hr = m_pErrorObjectFactory->CreateInstance(NULL, CLSID_EXTENDEDERRORINFO,
                 (void**) &pErrorInfo);
 // Get an IErrorRecords interface pointer on the error object.
 hr = pErrorInfo->QueryInterface(IID_IErrorRecords, (void**) &pErrorRecords);
 // Set up a parameter to pass to the object.
 VARIANTARG  varg;
 VariantInit (&varg);
 DISPPARAMS  dispparams = {&varg, NULL, 1, 0};
 varg.vt = VT_BSTR;
 varg.bstrVal = SysAllocString(bstrTableName);
 // Fill in the ERRORINFO structure and add the error record.
 ErrorInfo.hrError = hrErr;
 ErrorInfo.dwMinor = errCantOpenTable;
 ErrorInfo.clsid = CLSID_THISISAM;
 ErrorInfo.iid   = IID_IOpenRowset;
 ErrorInfo.dispid  = DISPID_OpenRowset;
 hr = pErrorRecords->AddErrorRecord(&ErrorInfo,ErrorInfo.dwMinor,&dispparams,NULL,0);
 VariantClear(&varg);
 // Call SetErrorInfo to pass the error object to the Automation DLL.
 hr = SetErrorInfo(0, pErrorInfo);
 // Release the interface pointers on the object to finish transferring ownership of
 // the object to the Automation DLL.
 pErrorRecords->Release();
 pErrorInfo->Release();
 return hr;
};
The following code example shows how a provider adds a record to an OLE DB error object that includes a pointer to a custom error object:
#include <oledb.h>
class CSQLStateObject:public ISQLErrorInfo {
 public:
  CSQLStateObject(OLECHAR );
  CSQLStateObject();
  HRESULT __stdcall QueryInterface(REFIID, void** );
  ULONG __stdcall AddRef(void);
  ULONG __stdcall Release(void);
  HRESULT __stdcall GetSQLInfo( 
   /* [out] */ BSTR __RPC_FAR *pbstrSQLState,
   /* [out] */ LONG __RPC_FAR *plNativeError);
};
IClassFactory *g_pErrorObjectFactory ;
extern DISPID  DISPID_GetData;
extern GUID  CLSID_THISISAM;
DWORD    errGeneralError;
int main() {
 ERRORINFO  ErrorInfo;
 HRESULT    hr, hrErr;
 IErrorInfo  *pErrorInfo;
 IErrorRecords *pErrorRecords;
 // Clear the current error object.
 SetErrorInfo(0, NULL);
 // Do something that causes an error to occur. (Not shown.)
 if (!FAILED(hrErr))
  return hrErr;
 // An error or warning occurred. Get the current error object. If one    //does not exist, create one.
 GetErrorInfo(0, &pErrorInfo);
 if (!pErrorInfo)
  hr = g_pErrorObjectFactory->CreateInstance(NULL, CLSID_EXTENDEDERRORINFO,
                 (void**) &pErrorInfo);
 // Get an IErrorRecords interface pointer on the error object.
 hr = pErrorInfo->QueryInterface(IID_IErrorRecords, (void**) &pErrorRecords);
 // Create a custom error object.
 CSQLStateObject* pMyErrObj = new CSQLStateObject(OLESTR("HY000"));
 // Fill in the ERRORINFO structure and add the error record.
 ErrorInfo.hrError = hrErr;
 ErrorInfo.dwMinor = errGeneralError;
 ErrorInfo.clsid = CLSID_THISISAM;
 ErrorInfo.iid   = IID_IRowset;
 ErrorInfo.dispid  = DISPID_GetData;
 hr = pErrorRecords->AddErrorRecord(&ErrorInfo, ErrorInfo.dwMinor, NULL,
              (void**) pMyErrObj, 0);
 // Release the interface pointer on the custom error object to finish transferring
 // ownership of it to the error object.
 pMyErrObj->Release();
 // Call SetErrorInfo to pass the error object to the Automation DLL.
 hr = SetErrorInfo(0, pErrorInfo);
 // Release the interface pointers on the object to finish transferring ownership of
 // the object to the Automation DLL.
 pErrorRecords->Release();
 pErrorInfo->Release();
 return hr;
};