OLE DB Programmer's Reference |
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. ULONG cBindings = 5; DBBINDING rgBindings[cBindings] = { 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; ULONG cRowsObtained = 0; ULONG cEnumInfo = 0; ENUMINFO* rgEnumInfo; 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 (ULONG 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; }
1998-2001 Microsoft Corporation. All rights reserved.