Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Connection to an MDP requires using the root enumerator to create a rowset representing all OLE DB providers. This function returns a pointer to the IDBInitialize interface for an MDP data source object:
//
HRESULT MDPConnectUsingRootEnum(IDBInitialize** ppIDBInitialize)
{
HRESULT hr;
assert(*ppIDBInitialize == NULL);
// The ENUMINFO structure is used to bind data source
// rowset data for the provider list.
struct ENUMINFO
{
WCHAR wszName[MAX_NAME_LEN];
WCHAR wszParseName[MAX_NAME_LEN];
WCHAR wszDescription[MAX_NAME_LEN];
DBTYPE wType;
VARIANT_BOOL fIsParent;
};
// Initialize the OLE DB enumerator and obtain rowset.
ISourcesRowset* pISourcesRowset = NULL;
hr = CoCreateInstance(CLSID_OLEDB_ENUMERATOR, NULL,
CLSCTX_INPROC_SERVER, IID_ISourcesRowset,
(void**)&pISourcesRowset);
IRowset* pIRowset = NULL;
hr = pISourcesRowset->GetSourcesRowset(NULL,
IID_IRowset, 0, NULL, (IUnknown**)&pIRowset);
// Create accessor.
IAccessor* pIAccessor = NULL;
hr = pIRowset->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
// rgBindings array defines column data to be bound
// to the ENUMINFO data structure.
DBCOUNTITEM cBindings = 5;
DBBINDING rgBindings[5] =
{
1, offsetof(ENUMINFO, wszName), 0, 0, NULL, NULL, NULL,
DBPART_VALUE, DBMEMOWNER_CLIENTOWNED, DBPARAMIO_NOTPARAM,
MAX_NAME_LEN, 0, DBTYPE_WSTR, 0, 0,
2, offsetof(ENUMINFO, wszParseName), 0, 0, NULL, NULL, NULL,
DBPART_VALUE, DBMEMOWNER_CLIENTOWNED, DBPARAMIO_NOTPARAM,
MAX_NAME_LEN, 0, DBTYPE_WSTR, 0, 0,
3, offsetof(ENUMINFO, wszDescription), 0, 0, NULL, NULL, NULL,
DBPART_VALUE, DBMEMOWNER_CLIENTOWNED, DBPARAMIO_NOTPARAM,
MAX_NAME_LEN, 0, DBTYPE_WSTR, 0, 0,
4, offsetof(ENUMINFO, wType), 0, 0, NULL, NULL, NULL, DBPART_VALUE,
DBMEMOWNER_CLIENTOWNED, DBPARAMIO_NOTPARAM, sizeof(DBTYPE), 0,
DBTYPE_UI2, 0, 0,
5, offsetof(ENUMINFO, fIsParent), 0, 0, NULL, NULL, NULL,
DBPART_VALUE, DBMEMOWNER_CLIENTOWNED, DBPARAMIO_NOTPARAM,
sizeof(VARIANT_BOOL), 0, DBTYPE_BOOL, 0, 0,
};
HACCESSOR hAccessor = DB_NULL_HACCESSOR;
hr = pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA,
cBindings, rgBindings, 0, &hAccessor, NULL);
// Obtain IParseDisplayName interface.
IParseDisplayName* pIParseDisplayName = NULL;
hr = pISourcesRowset->QueryInterface(IID_IParseDisplayName,
(void**)&pIParseDisplayName);
// Loop through the entire returned rowset.
HROW* rghRows = NULL;
DBRCOUNTITEM cRowsObtained = 0;
ULONG cEnumInfo = 0;
ENUMINFO* rgEnumInfo = NULL;
while (SUCCEEDED(hr))
{
hr = pIRowset->GetNextRows(NULL, 0, 20, &cRowsObtained, &rghRows);
if (FAILED(hr)) break;
if (cRowsObtained == 0)
{
// ENDOFROWSET
break;
}
// Alloc room for ProviderInfo (in chunks).
rgEnumInfo =
(ENUMINFO*)CoTaskMemRealloc(rgEnumInfo,
(cEnumInfo+cRowsObtained) * sizeof(ENUMINFO));
memset(&rgEnumInfo[cEnumInfo], 0,
sizeof(ENUMINFO)*cRowsObtained);
// Loop over rows obtained and get ProviderInfo.
for (DBCOUNTITEM i=0; i<cRowsObtained; i++)
{
// Get the data.
hr = pIRowset->GetData(rghRows[i], hAccessor,
(void*)&rgEnumInfo[cEnumInfo]);
if (FAILED(hr)) break;
cEnumInfo++;
}
// Release all the rows.
hr = pIRowset->ReleaseRows(cRowsObtained, rghRows, NULL, NULL,
NULL);
CoTaskMemFree(rghRows);
rghRows = NULL;
}
// If successfully obtained a set of providers...
if (SUCCEEDED(hr) && cEnumInfo)
{
// rgEnumInfo[cEnumInfo] contains enumerated info
// for all providers.
for (ULONG i=0; i<cEnumInfo; i++)
{
// Find multidimensional provider and connect
// with IParseDisplayName.
if (rgEnumInfo[i].wType == DBSOURCETYPE_DATASOURCE_MDP)
{
// Connect to MDP provider using IMoniker.
// Create binding context; use default options.
IBindCtx* pIBindCtx = NULL;
hr = CreateBindCtx(0, &pIBindCtx);
if (SUCCEEDED(hr))
{
ULONG chEaten = 0;
IMoniker* pIMoniker = NULL;
hr = pIParseDisplayName->ParseDisplayName(pIBindCtx,
rgEnumInfo[i].wszParseName, &chEaten, &pIMoniker);
}
if (SUCCEEDED(hr))
{
hr = BindMoniker(pIMoniker, 0, IID_IUnknown,
(void**)&pIDBInitialize);
}
if (pIBindCtx) pIBindCtx->Release();
if (pIMoniker) pIMoniker->Release();
if (SUCCEEDED(hr))
{
// If ParseDisplayName() and BindMoniker() have
// succeeded, pIDBInitialize is a valid
// interface pointer to the MDP data source.
break;
}
}
}
}
// Free enum info and rowset handles.
CoTaskMemFree(rgEnumInfo);
CoTaskMemFree(rghRows);
hr = pIParseDisplayName->Release();
hr = pIAccessor->ReleaseAccessor(hAccessor,NULL);
hr = pIAccessor->Release();
hr = pIRowset->Release();
hr = pISourcesRowset->Release();
return hr;
}