597 lines
19 KiB
C++
597 lines
19 KiB
C++
//-----------------------------------------------------------------------------
|
|
// Microsoft OLE DB TABLECOPY Sample
|
|
// Copyright (C) 1995-2000 Microsoft Corporation
|
|
//
|
|
// @doc
|
|
//
|
|
// @module DATASOURCE.CPP
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// Includes
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
#include "WinMain.h"
|
|
#include "Common.h"
|
|
#include "DataSource.h"
|
|
#include "msdaguid.h" //CLSID_OLEDB_ENUMERATOR
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDataSource::CDataSource
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
CDataSource::CDataSource()
|
|
{
|
|
//OLEDB Interfaces
|
|
m_pIDBInitialize = NULL; //DataSource
|
|
m_pIOpenRowset = NULL; //Session
|
|
m_pIDBSchemaRowset = NULL; //Session
|
|
m_pITableDefinition = NULL; //Session
|
|
m_pIIndexDefinition = NULL; //Session
|
|
m_pICommandText = NULL; //Command
|
|
|
|
//ProviderInfo
|
|
m_pwszProviderName = NULL; //Pointer into m_rgProviderInfo.wszName
|
|
m_pwszProviderParseName = NULL; //Pointer into m_rgProviderInfo.wszParseName
|
|
m_pwszProviderFileName = NULL; //DBPROP_PROVIDERNAME
|
|
m_pwszProviderVer = NULL; //DBPROP_PROVIDERVER
|
|
m_pwszProviderOLEDBVer = NULL; //DBPROP_PROVIDEROLEDBVER
|
|
|
|
//Enumerator ProvierInfo
|
|
m_cProviderInfo = 0;
|
|
m_rgProviderInfo = NULL;
|
|
m_pIParseDisplayName = NULL; //Enumerator
|
|
|
|
//Properties
|
|
m_fReadOnly = TRUE; //DBPROP_DATASOURCEREADONLY
|
|
m_fPrimaryKeysSupported = FALSE;//DBPROP_SQLSUPPORT
|
|
m_fMultipleParamSets = FALSE;//DBPROP_MULTIPLEPARAMSETS
|
|
m_fIRowsetChange = FALSE;//DBPROP_IRowsetChange
|
|
m_fIRowsetUpdate = FALSE;//DBPROP_IRowsetUpdate
|
|
m_dwStorageObjects = 0; //DBPROP_STRUCTUREDSTORAGE
|
|
|
|
m_pwszCatalog = NULL; //DBPROP_CURRENTCATALOG
|
|
m_pwszCatalogTerm = NULL; //DBPROP_CATALOGTERM
|
|
m_pwszCatalogLocation = NULL; //DBPROP_CATALOGLOCATION
|
|
m_pwszSchemaTerm = NULL; //DBPROP_SCHEMATERM
|
|
m_pwszTableTerm = NULL; //DBPROP_TABLETERM
|
|
|
|
//DataSource Info
|
|
m_ulActiveSessions = 0; //DBPROP_ACTIVESESSIONS
|
|
m_pwszDataSource = NULL; //DBPROP_DATASOURCENAME
|
|
m_pwszDBMS = NULL; //DBPROP_DBMSNAME
|
|
m_pwszDBMSVer = NULL; //DBPROP_DBMSVER
|
|
|
|
m_fConnected = FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// CDataSource::~CDataSource
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
CDataSource::~CDataSource()
|
|
{
|
|
Disconnect();
|
|
|
|
//Enumerator ProviderInfo
|
|
m_cProviderInfo = 0;
|
|
SAFE_FREE(m_rgProviderInfo);
|
|
SAFE_RELEASE(m_pIParseDisplayName);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// BOOL CDataSource::IsConnected
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
BOOL CDataSource::IsConnected()
|
|
{
|
|
return m_fConnected;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// BOOL CDataSource::IsSimilar
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
BOOL CDataSource::IsSimilar(CDataSource* pCDataSource)
|
|
{
|
|
ASSERT(pCDataSource);
|
|
|
|
//Must be Connected to compare
|
|
if(!IsConnected() || !pCDataSource->IsConnected())
|
|
return FALSE;
|
|
|
|
ASSERT(m_pwszDBMS && pCDataSource->m_pwszDBMS);
|
|
ASSERT(m_pwszDBMSVer && pCDataSource->m_pwszDBMSVer);
|
|
|
|
//Similiar: Must be the same DBMS and Version
|
|
if(wcscmp(m_pwszDBMS, pCDataSource->m_pwszDBMS)==0 &&
|
|
wcscmp(m_pwszDBMSVer, pCDataSource->m_pwszDBMSVer)==0)
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// BOOL CDataSource::IsEqual
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
BOOL CDataSource::IsEqual(CDataSource* pCDataSource)
|
|
{
|
|
ASSERT(pCDataSource);
|
|
|
|
//Must be Connected to compare
|
|
if(!IsConnected() || !pCDataSource->IsConnected())
|
|
return FALSE;
|
|
|
|
ASSERT(m_pwszCatalog && pCDataSource->m_pwszCatalog);
|
|
ASSERT(m_pwszDBMS && pCDataSource->m_pwszDBMS);
|
|
ASSERT(m_pwszDBMSVer && pCDataSource->m_pwszDBMSVer);
|
|
|
|
//Equal:
|
|
//Must have same Catalog, DBMS, Version
|
|
//Note, Don't have to have the same DataSource Name (an access
|
|
//database can have multiple names for the same file)
|
|
if(wcscmp(m_pwszCatalog, pCDataSource->m_pwszCatalog)==0 &&
|
|
wcscmp(m_pwszDBMS, pCDataSource->m_pwszDBMS)==0 &&
|
|
wcscmp(m_pwszDBMSVer, pCDataSource->m_pwszDBMSVer)==0)
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// BOOL CDataSource::Disconnect
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
BOOL CDataSource::Disconnect()
|
|
{
|
|
//Interfaces
|
|
SAFE_RELEASE(m_pIDBInitialize);
|
|
SAFE_RELEASE(m_pIOpenRowset);
|
|
SAFE_RELEASE(m_pIDBSchemaRowset);
|
|
SAFE_RELEASE(m_pITableDefinition);
|
|
SAFE_RELEASE(m_pIIndexDefinition);
|
|
SAFE_RELEASE(m_pICommandText);
|
|
|
|
//Properties
|
|
SAFE_FREE(m_pwszCatalog);
|
|
SAFE_FREE(m_pwszCatalogTerm);
|
|
SAFE_FREE(m_pwszCatalogLocation);
|
|
SAFE_FREE(m_pwszSchemaTerm);
|
|
SAFE_FREE(m_pwszTableTerm);
|
|
SAFE_FREE(m_pwszDataSource);
|
|
SAFE_FREE(m_pwszDBMS);
|
|
SAFE_FREE(m_pwszDBMSVer);
|
|
|
|
SAFE_FREE(m_pwszProviderFileName);
|
|
SAFE_FREE(m_pwszProviderVer);
|
|
SAFE_FREE(m_pwszProviderOLEDBVer);
|
|
|
|
m_fConnected = FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// BOOL CDataSource::Connect
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
HRESULT CDataSource::Connect(HWND hWnd, CDataSource* pCDataSource)
|
|
{
|
|
ASSERT(hWnd);
|
|
|
|
HRESULT hr;
|
|
ULONG cPropSets = 0;
|
|
DBPROPSET* rgPropSets = NULL;
|
|
|
|
IDBProperties* pIDBProperties = NULL;
|
|
IDBCreateSession* pIDBCreateSession = NULL;
|
|
|
|
//Local interface pointers, until we have a connection
|
|
IDBInitialize* pIDBInitialize = NULL;
|
|
IOpenRowset* pIOpenRowset = NULL;
|
|
IDBCreateCommand* pIDBCreateCommand = NULL;
|
|
ICommandText* pICommandText = NULL;
|
|
|
|
ULONG chEaten = 0;
|
|
IMoniker* pIMoniker = NULL;
|
|
|
|
|
|
//if there is no provider chosen pick something from the enumerator
|
|
if(pCDataSource == NULL)
|
|
{
|
|
//if there is an enumerator
|
|
if (m_pIParseDisplayName)
|
|
{
|
|
//Get the IDBInitalize interface
|
|
//Could just do a CoCreateInstance on the Provider CLSID, but since were using
|
|
//The enumerator, we can be a more general app by using IParseDisplayName
|
|
ASSERT(m_pwszProviderParseName);
|
|
XTESTC(hr = m_pIParseDisplayName->ParseDisplayName(NULL, m_pwszProviderParseName, &chEaten, &pIMoniker));
|
|
XTESTC(hr = BindMoniker(pIMoniker, 0, IID_IDBInitialize, (void**)&pIDBInitialize));
|
|
}
|
|
else
|
|
{
|
|
//if there is no ParseDisplay name there was no enumerator
|
|
//so let try whatever the user typed in if something was typed in
|
|
if (m_pwszProviderName)
|
|
{
|
|
CLSID clsid;
|
|
hr = CLSIDFromProgID(m_pwszProviderName, &clsid);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
XTESTC(hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IDBInitialize, (void**)&pIDBInitialize));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//get what was chosen
|
|
CLSID clsid;
|
|
XTESTC(hr = CLSIDFromProgID(m_pwszProviderName, &clsid));
|
|
if (S_OK == hr)
|
|
{
|
|
XTESTC(hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IDBInitialize, (void**)&pIDBInitialize));
|
|
}
|
|
else
|
|
{
|
|
goto CLEANUP;
|
|
}
|
|
}
|
|
|
|
//DBPROP_INIT_HWND
|
|
if(IsSettableProperty(pIDBInitialize, DBPROP_INIT_HWND, DBPROPSET_DBINIT))
|
|
{
|
|
#ifdef _WIN64
|
|
SetProperty(DBPROP_INIT_HWND, DBPROPSET_DBINIT, &cPropSets, &rgPropSets, DBTYPE_I8, (LONG_PTR)hWnd);
|
|
#else
|
|
SetProperty(DBPROP_INIT_HWND, DBPROPSET_DBINIT, &cPropSets, &rgPropSets, DBTYPE_I4, (LONG_PTR)hWnd);
|
|
#endif
|
|
}
|
|
|
|
//DBPROP_INIT_PROMPT
|
|
if(IsSettableProperty(pIDBInitialize, DBPROP_INIT_PROMPT, DBPROPSET_DBINIT))
|
|
SetProperty(DBPROP_INIT_PROMPT, DBPROPSET_DBINIT, &cPropSets, &rgPropSets, DBTYPE_I2, DBPROMPT_COMPLETE);
|
|
//DBPROP_INIT_MODE
|
|
if(IsSettableProperty(pIDBInitialize, DBPROP_INIT_MODE, DBPROPSET_DBINIT))
|
|
SetProperty(DBPROP_INIT_MODE, DBPROPSET_DBINIT, &cPropSets, &rgPropSets, DBTYPE_I4, DB_MODE_READWRITE | DB_MODE_SHARE_DENY_WRITE);
|
|
|
|
//Set the DataSource Properties
|
|
//IDBProperties is a MANDATORY interface, if error try and Initialize anyway
|
|
XTEST(hr = pIDBInitialize->QueryInterface(IID_IDBProperties, (void **)&pIDBProperties));
|
|
XTEST(hr = pIDBProperties->SetProperties(cPropSets, rgPropSets));
|
|
|
|
//Initailize
|
|
XTESTC(hr = pIDBInitialize->Initialize());
|
|
|
|
//Get the Session Object
|
|
XTESTC(hr = pIDBInitialize->QueryInterface(IID_IDBCreateSession, (void **)&pIDBCreateSession));
|
|
|
|
//Create the SessionObject
|
|
XTESTC(hr = pIDBCreateSession->CreateSession(NULL, IID_IOpenRowset, (IUnknown**)&pIOpenRowset));
|
|
|
|
//Get the CommandText object - If supported
|
|
if(SUCCEEDED(pIOpenRowset->QueryInterface(IID_IDBCreateCommand, (void**)&pIDBCreateCommand)))
|
|
XTESTC(hr = pIDBCreateCommand->CreateCommand(NULL, IID_ICommandText, (IUnknown**)&pICommandText));
|
|
|
|
//Do away with any previous connections
|
|
Disconnect();
|
|
|
|
//If we have made it this far, we are successfully connected,
|
|
m_fConnected = TRUE;
|
|
|
|
//Save the new connection interfaces
|
|
SAFE_ADDREF(pIDBInitialize);
|
|
m_pIDBInitialize = pIDBInitialize;
|
|
|
|
SAFE_ADDREF(pIOpenRowset);
|
|
m_pIOpenRowset = pIOpenRowset;
|
|
|
|
SAFE_ADDREF(pICommandText);
|
|
m_pICommandText = pICommandText;
|
|
|
|
//Obtain ITableDefinition/IIndexDefintion if supported
|
|
pIOpenRowset->QueryInterface(IID_ITableDefinition, (void**)&m_pITableDefinition);
|
|
pIOpenRowset->QueryInterface(IID_IIndexDefinition, (void**)&m_pIIndexDefinition);
|
|
pIOpenRowset->QueryInterface(IID_IDBSchemaRowset, (void**)&m_pIDBSchemaRowset);
|
|
|
|
//Now get the connection properties
|
|
QTESTC(hr = GetConnectionProps());
|
|
|
|
CLEANUP:
|
|
FreeProperties(cPropSets, rgPropSets);
|
|
|
|
//Release Interfaces
|
|
SAFE_RELEASE(pIDBInitialize);
|
|
SAFE_RELEASE(pIDBProperties);
|
|
SAFE_RELEASE(pIDBCreateSession);
|
|
SAFE_RELEASE(pIOpenRowset);
|
|
SAFE_RELEASE(pIDBCreateCommand);
|
|
SAFE_RELEASE(pICommandText);
|
|
SAFE_RELEASE(pIMoniker);
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// HRESULT CDataSource::GetConnectionProps
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CDataSource::GetConnectionProps()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwSqlSupport = 0;
|
|
|
|
//DBPROP_CURRENTCATALOG
|
|
hr = GetProperty(m_pIDBInitialize, DBPROP_CURRENTCATALOG,
|
|
DBPROPSET_DATASOURCE, &m_pwszCatalog);
|
|
|
|
//DBPROP_CATALOGTERM
|
|
hr = GetProperty(m_pIDBInitialize, DBPROP_CATALOGTERM,
|
|
DBPROPSET_DATASOURCEINFO, &m_pwszCatalogTerm);
|
|
if(!m_pwszCatalogTerm[0])
|
|
{
|
|
SAFE_FREE(m_pwszCatalogTerm);
|
|
m_pwszCatalogTerm = wcsDuplicate(L"Catalog");
|
|
}
|
|
|
|
|
|
//DBPROP_CATALOGLOCATION
|
|
hr = GetProperty(m_pIDBInitialize, DBPROP_CATALOGLOCATION,
|
|
DBPROPSET_DATASOURCEINFO, &m_pwszCatalogLocation);
|
|
|
|
//DBPROP_SCHEMATERM
|
|
hr = GetProperty(m_pIDBInitialize, DBPROP_SCHEMATERM,
|
|
DBPROPSET_DATASOURCEINFO, &m_pwszSchemaTerm);
|
|
if(!m_pwszSchemaTerm[0])
|
|
{
|
|
SAFE_FREE(m_pwszSchemaTerm);
|
|
m_pwszSchemaTerm = wcsDuplicate(L"Schema");
|
|
}
|
|
|
|
//DBPROP_TABLETERM
|
|
hr = GetProperty(m_pIDBInitialize, DBPROP_TABLETERM,
|
|
DBPROPSET_DATASOURCEINFO, &m_pwszTableTerm);
|
|
if(!m_pwszTableTerm[0])
|
|
{
|
|
SAFE_FREE(m_pwszTableTerm);
|
|
m_pwszTableTerm = wcsDuplicate(L"Table");
|
|
}
|
|
|
|
//DBPROP_ACTIVESESSIONS
|
|
hr = GetProperty(m_pIDBInitialize, DBPROP_ACTIVESESSIONS,
|
|
DBPROPSET_DATASOURCEINFO, &m_ulActiveSessions);
|
|
|
|
//DBPROP_DATASOURCENAME
|
|
hr = GetProperty(m_pIDBInitialize, DBPROP_DATASOURCENAME,
|
|
DBPROPSET_DATASOURCEINFO, &m_pwszDataSource);
|
|
|
|
//DBPROP_DBMSNAME
|
|
hr = GetProperty(m_pIDBInitialize, DBPROP_DBMSNAME,
|
|
DBPROPSET_DATASOURCEINFO, &m_pwszDBMS);
|
|
|
|
//DBPROP_DBMSVER
|
|
hr = GetProperty(m_pIDBInitialize, DBPROP_DBMSVER,
|
|
DBPROPSET_DATASOURCEINFO, &m_pwszDBMSVer);
|
|
|
|
//DBPROP_DATASOURCEREADONLY
|
|
hr = GetProperty(m_pIDBInitialize, DBPROP_DATASOURCEREADONLY,
|
|
DBPROPSET_DATASOURCEINFO, &m_fReadOnly);
|
|
|
|
//DBPROP_PROVIDERNAME
|
|
hr = GetProperty(m_pIDBInitialize, DBPROP_PROVIDERNAME,
|
|
DBPROPSET_DATASOURCEINFO, &m_pwszProviderFileName);
|
|
|
|
//DBPROP_PROVIDERVER
|
|
hr = GetProperty(m_pIDBInitialize, DBPROP_PROVIDERVER,
|
|
DBPROPSET_DATASOURCEINFO, &m_pwszProviderVer);
|
|
|
|
//DBPROP_PROVIDEROLEDBVER
|
|
hr = GetProperty(m_pIDBInitialize, DBPROP_PROVIDEROLEDBVER,
|
|
DBPROPSET_DATASOURCEINFO, &m_pwszProviderOLEDBVer);
|
|
|
|
//DBPROP_MULTIPLEPARAMSETS
|
|
hr = GetProperty(m_pIDBInitialize, DBPROP_MULTIPLEPARAMSETS,
|
|
DBPROPSET_DATASOURCEINFO, &m_fMultipleParamSets);
|
|
|
|
//DBPROP_STRUCTUREDSTORAGE
|
|
hr = GetProperty(m_pIDBInitialize, DBPROP_STRUCTUREDSTORAGE,
|
|
DBPROPSET_DATASOURCEINFO, &m_dwStorageObjects);
|
|
|
|
//DBPROP_SQLSUPPORT
|
|
hr = GetProperty(m_pIDBInitialize, DBPROP_SQLSUPPORT,
|
|
DBPROPSET_DATASOURCEINFO, &dwSqlSupport);
|
|
|
|
//Are PrimaryKeys supported
|
|
m_fPrimaryKeysSupported = dwSqlSupport & DBPROPVAL_SQL_ANSI89_IEF;
|
|
|
|
//DBPROP_IRowsetChange
|
|
m_fIRowsetChange = FALSE;
|
|
if(IsSupportedProperty(m_pIDBInitialize, DBPROP_IRowsetChange, DBPROPSET_ROWSET))
|
|
m_fIRowsetChange = TRUE;
|
|
|
|
//DBPROP_IRowsetUpdate
|
|
m_fIRowsetUpdate = FALSE;
|
|
if(IsSupportedProperty(m_pIDBInitialize, DBPROP_IRowsetUpdate, DBPROPSET_ROWSET))
|
|
m_fIRowsetUpdate = TRUE;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// HRESULT CDataSource::GetProviders
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CDataSource::GetProviders()
|
|
{
|
|
HRESULT hr;
|
|
|
|
HROW* rghRows = NULL;
|
|
DBCOUNTITEM cRowsObtained = 0;
|
|
IRowset* pIRowset = NULL;
|
|
|
|
IAccessor* pIAccessor = NULL;
|
|
HACCESSOR hAccessor = DB_NULL_HACCESSOR;
|
|
|
|
//Release Previous ProviderInfo
|
|
m_cProviderInfo = 0;
|
|
SAFE_FREE(m_rgProviderInfo);
|
|
ISourcesRowset* pISourcesRowset = NULL;
|
|
|
|
// Bind the user and table name for the list
|
|
const static ULONG cBindings = 4;
|
|
const static DBBINDING rgBindings[cBindings] =
|
|
{
|
|
1,
|
|
offsetof(PROVIDERINFO, wszName),
|
|
0,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
DBPART_VALUE,
|
|
DBMEMOWNER_CLIENTOWNED,
|
|
DBPARAMIO_NOTPARAM,
|
|
MAX_NAME_LEN,
|
|
0,
|
|
DBTYPE_WSTR,
|
|
0,
|
|
0,
|
|
|
|
2,
|
|
offsetof(PROVIDERINFO, wszParseName),
|
|
0,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
DBPART_VALUE,
|
|
DBMEMOWNER_CLIENTOWNED,
|
|
DBPARAMIO_NOTPARAM,
|
|
MAX_NAME_LEN,
|
|
0,
|
|
DBTYPE_WSTR,
|
|
0,
|
|
0,
|
|
|
|
3,
|
|
offsetof(PROVIDERINFO, wszDescription),
|
|
0,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
DBPART_VALUE,
|
|
DBMEMOWNER_CLIENTOWNED,
|
|
DBPARAMIO_NOTPARAM,
|
|
MAX_NAME_LEN,
|
|
0,
|
|
DBTYPE_WSTR,
|
|
0,
|
|
0,
|
|
|
|
4,
|
|
offsetof(PROVIDERINFO, wType),
|
|
0,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
DBPART_VALUE,
|
|
DBMEMOWNER_CLIENTOWNED,
|
|
DBPARAMIO_NOTPARAM,
|
|
sizeof(DBTYPE),
|
|
0,
|
|
DBTYPE_UI2,
|
|
0,
|
|
0,
|
|
};
|
|
|
|
|
|
//Initialize the OLE DB Enumerator and Obtain rowset
|
|
hr = CoCreateInstance(CLSID_OLEDB_ENUMERATOR, NULL, CLSCTX_INPROC_SERVER, IID_ISourcesRowset, (void**)&pISourcesRowset);
|
|
if (REGDB_E_CLASSNOTREG == hr)
|
|
{
|
|
//if there is no enumerator, horse'em
|
|
|
|
//Alloc room for ProviderInfo
|
|
m_cProviderInfo++;
|
|
SAFE_REALLOC(m_rgProviderInfo, PROVIDERINFO, m_cProviderInfo);
|
|
memset(&m_rgProviderInfo[0], 0, sizeof(PROVIDERINFO));
|
|
|
|
StringCchCopyW(m_rgProviderInfo[0].wszName,
|
|
sizeof(m_rgProviderInfo[0].wszName)/sizeof(WCHAR),
|
|
L"MSDASQL");
|
|
StringCchCopyW(m_rgProviderInfo[0].wszParseName,
|
|
sizeof(m_rgProviderInfo[0].wszParseName)/sizeof(WCHAR),
|
|
L"{c8b522cb-5cf3-11ce-ade5-00aa0044773d}");
|
|
StringCchCopyW(m_rgProviderInfo[0].wszDescription,
|
|
sizeof(m_rgProviderInfo[0].wszDescription)/sizeof(WCHAR),
|
|
L"Microsoft OLE DB Provider for ODBC Drivers");
|
|
m_rgProviderInfo[0].wType = DBSOURCETYPE_DATASOURCE;
|
|
|
|
return hr;
|
|
}
|
|
|
|
XTESTC(hr);
|
|
XTESTC(hr = pISourcesRowset->GetSourcesRowset(NULL, IID_IRowset, 0, NULL, (IUnknown**)&pIRowset));
|
|
|
|
//Create Accessor
|
|
XTESTC(hr = pIRowset->QueryInterface(IID_IAccessor, (void **)&pIAccessor));
|
|
XTESTC(hr = pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA, cBindings, rgBindings, 0, &hAccessor, NULL));
|
|
|
|
//Obtain IParseDisplayName interface
|
|
XTESTC(hr = pISourcesRowset->QueryInterface(IID_IParseDisplayName, (void**)&m_pIParseDisplayName));
|
|
|
|
//Loop through the entire returned rowet
|
|
while(TRUE)
|
|
{
|
|
XTESTC(hr = pIRowset->GetNextRows(NULL, 0, MAX_BLOCK_SIZE, &cRowsObtained, &rghRows));
|
|
|
|
//ENDOFROWSET
|
|
if(cRowsObtained==0)
|
|
break;
|
|
|
|
//Alloc room for ProviderInfo (in chunks)
|
|
SAFE_REALLOC(m_rgProviderInfo, PROVIDERINFO, m_cProviderInfo + cRowsObtained);
|
|
memset(&m_rgProviderInfo[m_cProviderInfo], 0, sizeof(PROVIDERINFO)*cRowsObtained);
|
|
|
|
//Loop over rows obtained and get ProviderInfo
|
|
for(ULONG i=0; i<cRowsObtained; i++)
|
|
{
|
|
//Get the Data
|
|
XTESTC(hr = pIRowset->GetData(rghRows[i], hAccessor, (void*)&m_rgProviderInfo[m_cProviderInfo]));
|
|
|
|
//Only interested in DATASOURCEs, not other ENUMERATORs
|
|
if(m_rgProviderInfo[m_cProviderInfo].wType == DBSOURCETYPE_DATASOURCE)
|
|
m_cProviderInfo++;
|
|
}
|
|
|
|
//Release all the rows
|
|
XTESTC(hr = pIRowset->ReleaseRows(cRowsObtained, rghRows, NULL, NULL, NULL));
|
|
SAFE_FREE(rghRows);
|
|
}
|
|
|
|
CLEANUP:
|
|
if(hAccessor && pIAccessor)
|
|
XTEST(pIAccessor->ReleaseAccessor(hAccessor,NULL));
|
|
|
|
SAFE_RELEASE(pISourcesRowset);
|
|
SAFE_RELEASE(pIRowset);
|
|
SAFE_RELEASE(pIAccessor);
|
|
SAFE_FREE(rghRows);
|
|
return hr;
|
|
}
|
|
|
|
|