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;
};