|
|
///////////////////////////////////////////////////////////////////////////////////
//
// Microsoft WMIOLE DB Provider
// (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
//
// CBinder object implementation
//
//
///////////////////////////////////////////////////////////////////////////////////
#include "headers.h"
#include "WmiOleDBMap.h"
///////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////
CBinder::CBinder(LPUNKNOWN pUnkOuter) : CBaseObj(BOT_BINDER,pUnkOuter) { m_cRef = 0;
m_pICreateRow = NULL; m_pIBinderProperties = NULL; m_pIBindResource = NULL; m_pISupportErrorInfo = NULL;
m_pDataSrc = NULL; m_pSession = NULL;
m_pUrlParser = NULL;
m_fDSOInitialized = FALSE;
//===============================================================
// Increment global object count.
//===============================================================
InterlockedIncrement(&g_cObj); }
///////////////////////////////////////////////////////////////////////////////////
// Destructor
///////////////////////////////////////////////////////////////////////////////////
CBinder::~CBinder() { HRESULT hr = S_OK; IDBInitialize *pInitialize = NULL; SAFE_RELEASE_PTR(m_pSession);
SAFE_RELEASE_PTR(m_pDataSrc); SAFE_DELETE_PTR(m_pICreateRow); SAFE_DELETE_PTR(m_pIBinderProperties); SAFE_DELETE_PTR(m_pIBindResource); SAFE_DELETE_PTR(m_pISupportErrorInfo);
SAFE_DELETE_PTR(m_pUrlParser); SAFE_DELETE_PTR(m_pUtilProp);
//===============================================================
// Decrement global object count.
//===============================================================
InterlockedDecrement(&g_cObj); }
/////////////////////////////////////////////////////////////////////////////////////////////////
// Function to navigate between the different interfaces
/////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CBinder::QueryInterface ( REFIID riid, LPVOID * ppv) { HRESULT hr = S_OK;
//======================================================
// Check parameters, if not valid return
//======================================================
if (NULL == ppv){ hr = E_INVALIDARG ; } else { //======================================================
// Place NULL in *ppv in case of failure
//======================================================
*ppv = NULL;
//======================================================
// This is the non-delegating IUnknown implementation
//======================================================
if (riid == IID_IUnknown) { *ppv = (LPVOID) this; } else if (riid == IID_IBindResource) { *ppv = (LPVOID) m_pIBindResource; } else if (riid == IID_IDBBinderProperties || riid == IID_IDBProperties) { *ppv = (LPVOID) m_pIBinderProperties; } else if (riid == IID_ICreateRow) { *ppv = (LPVOID) m_pICreateRow; } else if(riid == IID_ISupportErrorInfo) { *ppv = (LPVOID)m_pISupportErrorInfo; }
//======================================================
// If we're going to return an interface, AddRef first
//======================================================
if (*ppv){ ((LPUNKNOWN) *ppv)->AddRef(); hr = S_OK ; } else{ hr = E_NOINTERFACE; } } return hr; }
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Increments a persistence count for the object
//
// Current reference count
//
/////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_( ULONG ) CBinder::AddRef( void ) { return InterlockedIncrement((long*)&m_cRef); }
/////////////////////////////////////////////////////////////////////////////////////////////////
//
// Decrements a persistence count for the object and if persistence count is 0, the object
// destroys itself.
//
/////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_( ULONG ) CBinder::Release( void ) { InterlockedDecrement((long*)&m_cRef); if (!m_cRef){ g_pIDataConvert->Release(); delete this; return 0; }
return m_cRef; }
/////////////////////////////////////////////////////////////////////////////////////////////////
// Function to initialize the binder object
/////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CBinder::InitBinder() { HRESULT hr = S_OK; BOOL bRet = TRUE;
//================================================
// Instantiate the data conversion service object
//================================================
if( !g_pIDataConvert ){
hr = CoCreateInstance(CLSID_OLEDB_CONVERSIONLIBRARY, NULL, CLSCTX_INPROC_SERVER, IID_IDataConvert, (void **)&g_pIDataConvert); } else { //============================================
// Already instantiated, increment reference
// count
//============================================
g_pIDataConvert->AddRef(); }
if(SUCCEEDED(hr)) { IDCInfo *pDcInfo = NULL; DCINFO dcInfo[1];
dcInfo[0].eInfoType = DCINFOTYPE_VERSION; V_VT(&dcInfo[0].vData) = VT_UI4; V_UI4(&dcInfo[0].vData) = 0x200;
hr = g_pIDataConvert->QueryInterface(IID_IDCInfo,(void **)&pDcInfo); hr = pDcInfo->SetInfo(1,dcInfo);
//================================================
// Allocate properties management object
//================================================
m_pUtilProp = new CUtilProp; if(m_pUtilProp == NULL) { hr = E_OUTOFMEMORY; } else // NTRaid: 136443
// 07/05/00
if(SUCCEEDED(hr = m_pUtilProp->FInit(BINDERPROP))) { //================================================
// Allocate the URLParser class
//================================================
m_pUrlParser = new CURLParser;
//================================================
// Allocate contained interface objects
//================================================
m_pIBindResource = new CImplIBindResource( this ); m_pICreateRow = new CImplICreateRow( this ); m_pIBinderProperties = new CImplIDBBinderProperties( this ); m_pISupportErrorInfo = new CImpISupportErrorInfo(this);
if(!((BOOL)(m_pUtilProp && m_pUrlParser && m_pIBindResource && m_pICreateRow && m_pIBinderProperties && m_pISupportErrorInfo))) { hr = E_OUTOFMEMORY; } } }
if(SUCCEEDED(hr)) { hr = AddInterfacesForISupportErrorInfo(); }
return hr; }
/////////////////////////////////////////////////////////////////////////////////////////////////////
// Function to add interfaces to ISupportErrorInfo interface
/////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CBinder::AddInterfacesForISupportErrorInfo() { HRESULT hr = S_OK;
if(SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IBindResource))) if(SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IDBBinderProperties))) if(SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IDBProperties))) { hr = m_pISupportErrorInfo->AddInterfaceID(IID_ICreateRow); }
return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////
// Function to Create a Datasource object. The init flat parameter is the flags obtained
// from the binder flags passed to the IBinderResource::Bind function
// If the caller needs a pointer to a particular interface , then the id of the interface
// required will be passed in riid parmeter , otherwise this parameter will be GUID_NULL
/////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CBinder::CreateDSO(IUnknown *pUnkOuter,LONG lInitFlag, REFGUID riid,IUnknown ** ppUnk) { HRESULT hr = E_FAIL; IDBInitialize * pInitialize = NULL; IDBProperties * pDBProperties = NULL;
DBPROPSET rgPropertySets[1]; DBPROPIDSET rgPropIDSet[1];
DBPROP rgprop[1]; VARIANT varValue; ULONG cPropSets = 1; DBPROPSET* prgPropertySets; DBPROPID rgPropId[1];
if(m_pDataSrc != NULL) { hr = S_OK; if( riid != GUID_NULL) { //=============================================
// Get the required interface pointer
//=============================================
hr = m_pDataSrc->QueryInterface(riid , (void **)ppUnk); } } else { memset(&rgprop[0],0,sizeof(DBPROP)); memset(&rgPropertySets[0],0,sizeof(DBPROPSET));
VariantInit(&varValue); CDataSource *pDatasource = NULL; try { //=============================================
// Allocate a new datasource object
//=============================================
pDatasource = new CDataSource( pUnkOuter ); } catch(...) { SAFE_DELETE_PTR(pDatasource); throw; } if(pDatasource == NULL) { hr = E_OUTOFMEMORY; } else if(SUCCEEDED(hr = pDatasource->FInit())) { //==================================================================
// QI for IUnknown and save pointer in the member variable
//==================================================================
if(SUCCEEDED(hr =pDatasource->QueryInterface(IID_IUnknown , (void **)&m_pDataSrc))) if(SUCCEEDED(hr = m_pDataSrc->QueryInterface(IID_IDBProperties ,(void **)&pDBProperties))) { rgPropIDSet[0].cPropertyIDs = 0; rgPropIDSet[0].guidPropertySet = DBPROPSET_DBINIT;
//==================================================================
// Get the properties set thru IDBBinderProperties
//==================================================================
hr = m_pUtilProp->GetProperties(PROPSET_INIT,0,rgPropIDSet, &cPropSets,&prgPropertySets);
if(SUCCEEDED(hr = pDBProperties->SetProperties(cPropSets,prgPropertySets))) {
//==========================================================================
// Free memory we allocated to by GetProperties
//==========================================================================
m_pUtilProp->m_PropMemMgr.FreeDBPROPSET( cPropSets, prgPropertySets);
rgPropId[0] = DBPROP_INIT_DATASOURCE;
rgPropIDSet[0].guidPropertySet = DBPROPSET_DBINIT; rgPropIDSet[0].rgPropertyIDs = rgPropId; rgPropIDSet[0].cPropertyIDs = 1;
hr = m_pUtilProp->GetProperties( PROPSET_INIT,1, rgPropIDSet,&cPropSets,&prgPropertySets ); if(SUCCEEDED(hr)) { // if the property set is not empty then get the property DBPROP_INIT_DATASOURCE
// else extract it from URL
if(prgPropertySets[0].rgProperties[0].vValue.vt == VT_BSTR && prgPropertySets[0].rgProperties[0].vValue.bstrVal != NULL && SysStringLen(prgPropertySets[0].rgProperties[0].vValue.bstrVal) > 0) { rgprop[0].vValue.bstrVal = Wmioledb_SysAllocString(prgPropertySets[0].rgProperties[0].vValue.bstrVal); } else { m_pUrlParser->GetNameSpace(rgprop[0].vValue.bstrVal); } //==========================================================================
// Free memory we allocated to by GetProperties
//==========================================================================
m_pUtilProp->m_PropMemMgr.FreeDBPROPSET( cPropSets, prgPropertySets);
//==================================================================
// Get the namespace from the Parser and then set
// the DBPROP_INIT_DATASOURCE property
//==================================================================
rgprop[0].dwPropertyID = DBPROP_INIT_DATASOURCE; rgprop[0].vValue.vt = VT_BSTR; // m_pUrlParser->GetNameSpace(rgprop[0].vValue.bstrVal);
rgPropertySets[0].rgProperties = &rgprop[0]; rgPropertySets[0].cProperties = 1; rgPropertySets[0].guidPropertySet = DBPROPSET_DBINIT;
if(SUCCEEDED(hr = pDBProperties->SetProperties(1,rgPropertySets))) { // set the properties on the current property handler
hr = m_pUtilProp->SetProperties(PROPSET_INIT,1,rgPropertySets); }
SAFE_FREE_SYSSTRING(rgprop[0].vValue.bstrVal); }
if(SUCCEEDED(hr)) { VariantClear(&(rgprop[0].vValue)); //========================================
// Setting the DBPROP_DBINIT property
//========================================
rgprop[0].dwPropertyID = DBPROP_INIT_MODE; rgprop[0].vValue.vt =VT_I4; rgprop[0].vValue.lVal = lInitFlag;
rgPropertySets[0].rgProperties = &rgprop[0]; rgPropertySets[0].cProperties = 1; rgPropertySets[0].guidPropertySet = DBPROPSET_DBINIT;
if(SUCCEEDED(hr = pDBProperties->SetProperties(1,rgPropertySets)) && SUCCEEDED(hr = m_pUtilProp->SetProperties(PROPSET_INIT,1,rgPropertySets))) { //===============================================
// Get the pointer to IDBInitialize interface
//===============================================
hr = m_pDataSrc->QueryInterface(IID_IDBInitialize, (void **)&pInitialize);
//===============================================================
// Initialize the Datasource object if
// the flag does not indicate waiting for the initialization
//===============================================================
if(!(lInitFlag & DBBINDURLFLAG_WAITFORINIT)) { if(S_OK == (hr = pInitialize->Initialize())) m_fDSOInitialized = TRUE; }
if(S_OK == hr) {
if( riid != GUID_NULL) { //========================================
// Get the required interface pointer
//========================================
hr = m_pDataSrc->QueryInterface(riid , (void **)ppUnk); } } pInitialize->Release(); pDBProperties->Release(); } // If(Succeeded(call to SetProperties)) of DBPROP_INIT_MODE property
} // If(Succeeded(call to SetProperties)) of DBPROP_INIT_DATASOURCE property
} // If(Succeeded(call to SetProperties))
} // If Succeeded() for QI
} // if(Succeeded(pDatasource->FInit()))
else { hr = E_FAIL; } } // Else for if(m_pDataSrc != NULL)
return hr; }
/////////////////////////////////////////////////////////////////////////////////////////////////
// Function to create a session object
/////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CBinder::CreateSession(IUnknown *pUnkOuter, REFGUID riid,IUnknown ** ppUnk) { HRESULT hr = S_OK;
IDBCreateSession * pDBCreateSession = NULL; IDBInitialize * pInitialize = NULL;
assert(m_pDataSrc != NULL);
//====================================================================
// If the datasource is not yet initialized , then initialize it
//====================================================================
if(m_fDSOInitialized == FALSE) { //================================================
// Get the pointer to IDBInitialize interface
//================================================
hr = m_pDataSrc->QueryInterface(IID_IDBInitialize, (void **)&pInitialize);
if(S_OK == (hr = pInitialize->Initialize())) { m_fDSOInitialized = TRUE; } pInitialize->Release(); } if(SUCCEEDED(hr)) if(S_OK ==(hr = m_pDataSrc->QueryInterface(IID_IDBCreateSession,(void **)&pDBCreateSession))) { //======================
// Create session
//======================
if(S_OK ==(hr = pDBCreateSession->CreateSession(pUnkOuter,IID_IUnknown,(IUnknown**)&m_pSession))) { if(riid != GUID_NULL) { hr = m_pSession->QueryInterface(riid,(void **)ppUnk); } } }
if(pDBCreateSession) { pDBCreateSession->Release(); }
return hr; }
/////////////////////////////////////////////////////////////////////////////////////////////////
// Function to create a Command object
/////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CBinder::CreateCommand(IUnknown *pUnkOuter, REFGUID guidTemp,IUnknown ** ppUnk) {
return m_pSession->CreateCommand(pUnkOuter, guidTemp,ppUnk);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// Function to create a required row object
// NTRaid:136539 , 136540
// 07/05/00
/////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CBinder::CreateRow(IUnknown *pUnkOuter, REFGUID riid,IUnknown ** ppUnk ,ROWCREATEBINDFLAG rowCreateFlag) { HRESULT hr = E_FAIL; IUnknown * pUnkRow = NULL; BSTR strTable = NULL; BSTR strPath = NULL; CDBSession * pDBSess = NULL; ISessionProperties *pSessProp = NULL; CRow * pNewRow = NULL; DBPROPSET * pPropSet = NULL;
if( S_OK == (hr = m_pSession->QueryInterface(IID_ISessionProperties , (void **)&pSessProp))) {
pDBSess = ((CImpISessionProperties *)pSessProp)->GetSessionPtr(); pSessProp->Release();
// Get the path of the object
hr = m_pUrlParser->GetPathWithEmbededInstInfo(strPath);
// Get the class name
// m_pUrlParser->GetClassName(strTable);
// NTRaid : 134967
// 07/12/00
if(SUCCEEDED(hr) && SUCCEEDED(hr = m_pUtilProp->GetConnectionInitProperties(&pPropSet))) { hr = GetClassName(m_pUrlParser,pPropSet,strTable,m_pDataSrc->m_pWbemWrap); } //==========================================================================
// Free memory we allocated to get the namespace property above
//==========================================================================
CPropertyMemoryMgr::FreeDBPROPSET( 1, pPropSet);
if(SUCCEEDED(hr)) { try { // currently hardcoded to NO_QUALIFIERS
pNewRow = new CRow(pUnkOuter,pDBSess); } catch(...) { SAFE_DELETE_PTR(pNewRow); throw; }
if( pNewRow == NULL) { hr = E_OUTOFMEMORY; } else { if(S_OK ==(hr = pNewRow->InitRow(strPath,strTable,-1,rowCreateFlag))) { hr = pNewRow->QueryInterface(riid,(void **)ppUnk); }
if(hr == S_OK && rowCreateFlag != ROWOPEN) { hr = pNewRow->UpdateKeysForNewInstance(); } } //========================================================
// Free the strings allocated by the URLParser class
//========================================================
SysFreeString(strTable); SysFreeString(strPath); } if(FAILED(hr)) { SAFE_DELETE_PTR(pNewRow); *ppUnk = NULL; } }
return hr; }
/////////////////////////////////////////////////////////////////////////////////////////////////
// Function to create a Rowset object
/////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CBinder::CreateRowset(IUnknown *pUnkOuter, REFGUID riid,IUnknown ** ppUnk) { HRESULT hr = E_FAIL; IOpenRowset * pOpenRowset = NULL; DBPROPSET * pPropSet = NULL; ULONG cPropSets = 1;
DBPROPSET* prgPropertySets = NULL; BSTR strTableName = NULL;
assert(m_pSession != NULL);
//=========================================
// Get pointer to IOpenRowset interface
//=========================================
if(S_OK == (hr = m_pSession->QueryInterface(IID_IOpenRowset , (void **)&pOpenRowset))) { DBPROPIDSET rgPropIDSet[1]; rgPropIDSet[0].cPropertyIDs = 0; rgPropIDSet[0].guidPropertySet = DBPROPSET_ROWSET;
//=========================================
// Get the properties
//=========================================
hr = m_pUtilProp->GetProperties(PROPSET_ROWSET,0,rgPropIDSet, &cPropSets,&prgPropertySets);
//=========================================
// Get the class name and initialize the tableID
//=========================================
// NTRaid : 134967
// 07/12/00
if(SUCCEEDED(hr)) { if (SUCCEEDED(hr = m_pUtilProp->GetConnectionInitProperties(&pPropSet))) { hr = GetClassName(m_pUrlParser,pPropSet,strTableName,m_pDataSrc->m_pWbemWrap);
if (SUCCEEDED(hr)) { DBID tableID; memset(&tableID , 0 , sizeof(DBID)); tableID.eKind = DBKIND_NAME; tableID.uName.pwszName = strTableName;
//=========================================
// Open the rowset
//=========================================
hr = pOpenRowset->OpenRowset(pUnkOuter,&tableID,NULL,riid,cPropSets,prgPropertySets,ppUnk);
SAFE_FREE_SYSSTRING(strTableName); }
//==========================================================================
// Free memory we allocated to get the namespace property above
//==========================================================================
CPropertyMemoryMgr::FreeDBPROPSET( 1, pPropSet);
}
//==========================================================================
// Free memory we allocated to by GetProperties
//==========================================================================
m_pUtilProp->m_PropMemMgr.FreeDBPROPSET( cPropSets, prgPropertySets); } }
SAFE_RELEASE_PTR(pOpenRowset);
return hr; }
/*
///////////////////////////////////////////////////////////////////////////////////////////////////
// Get Binding flags and put it in a variable as INIT_MODE flags
///////////////////////////////////////////////////////////////////////////////////////////////////
void CBinder::GetInitAndBindFlagsFromBindFlags(DBBINDURLFLAG dwBindURLFlags,LONG & lInitMode ,LONG & lInitBindFlags) {
lInitMode = 0; lInitBindFlags = 0;
// DBPROP_INIT_MODE
if(DBBINDURLFLAG_READ & dwBindURLFlags) { lInitMode = lInitMode | DB_MODE_READ; }
if(DBBINDURLFLAG_WRITE & dwBindURLFlags) { lInitMode = lInitMode | DB_MODE_WRITE; }
if(DBBINDURLFLAG_SHARE_DENY_READ & dwBindURLFlags) { lInitMode = lInitMode | DB_MODE_SHARE_DENY_READ; }
if(DBBINDURLFLAG_SHARE_DENY_WRITE & dwBindURLFlags) { lInitMode = lInitMode | DB_MODE_SHARE_DENY_WRITE; }
if(DBBINDURLFLAG_SHARE_EXCLUSIVE & dwBindURLFlags) { lInitMode = lInitMode | DB_MODE_SHARE_EXCLUSIVE; }
if(DBBINDURLFLAG_SHARE_DENY_NONE & dwBindURLFlags) { lInitMode = lInitMode | DB_MODE_SHARE_DENY_NONE; }
// DBPROP_INIT_BINDFLAGS
if(DBBINDURLFLAG_RECURSIVE & dwBindURLFlags) { lInitBindFlags = lInitBindFlags | DB_BINDFLAGS_RECURSIVE; }
if(DBBINDURLFLAG_OUTPUT & dwBindURLFlags) { lInitBindFlags = lInitBindFlags | DB_BINDFLAGS_OUTPUT; }
if(DBBINDURLFLAG_DELAYFETCHCOLUMNS & dwBindURLFlags) { lInitBindFlags = lInitBindFlags | DB_BINDFLAGS_DELAYFETCHCOLUMNS; }
if(DBBINDURLFLAG_DELAYFETCHSTREAM & dwBindURLFlags) { lInitBindFlags = lInitBindFlags | DB_BINDFLAGS_DELAYFETCHSTREAM; }
} */ ////////////////////////////////////////////////////////////
// Function to release all the bound objects
////////////////////////////////////////////////////////////
HRESULT CBinder::ReleaseAllObjects() { SAFE_RELEASE_PTR(m_pDataSrc); SAFE_RELEASE_PTR(m_pSession); return S_OK;
}
|