////////////////////////////////////////////////////////////////////////////////////////////////// // // Microsoft WMIOLE DB Provider // (C) Copyright 1999 Microsoft Corporation. All Rights Reserved. // // CDBSession base object and contained interface definitions // ////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef _DBSESS_H_ #define _DBSESS_H_ ////////////////////////////////////////////////////////////////////////////////////////////////// class CImpIGetDataSource; class CImpIOpenRowset; class CImpISessionProperties; class CImpITableDefinition; class CImplIBindRsrc; class CImpIDBSchemaRowset; class CImplIIndexDefinition; class CImplIAlterTable; class CBinder; class CImpITransactionLocal; class CBaseRowObj; //99/04/12 typedef CImpIGetDataSource* PIMPIGETDATASOURCE; typedef CImpIOpenRowset* PIMPIOPENROWSET; typedef CImpISessionProperties* PIMPISESSIONPROPERTIES; typedef CImpITableDefinition* PIMPITABLEDEFINITION; //99/04/1288 typedef CImplIBindRsrc* PIMPIBINDSRC; typedef CImplIIndexDefinition* PIMPINDEXDEF; typedef CImplIAlterTable* PIMPIALTERTABLE; typedef CImpITransactionLocal * PIMPITRANSACTIONLOCAL; ////////////////////////////////////////////////////////////////////////////////////////////////// // // Containing class for all interfaces on the DBSession Object // ////////////////////////////////////////////////////////////////////////////////////////////////// class CDBSession : public CBaseObj { //=============================================================== // contained interfaces are friends //=============================================================== friend class CImpIGetDataSource; friend class CImpIOpenRowset; friend class CImpIDataSource; friend class CImpISessionProperties; friend class CImpITableDefinition; friend class CImplIBindRsrc; friend class CImpIDBCreateCommand; friend class CImplIIndexDefinition; friend class CBinder; friend class CImpITransactionLocal; protected: ULONG m_nOpenedRowset; // number of rows & rowsets opened PCUTILPROP m_pUtilProp; // Utility object to manage properties PIMPIOPENROWSET m_pIOpenRowset; // contained IOpenRowset PIMPIGETDATASOURCE m_pIGetDataSource; // contained IGetDataSource PIMPISESSIONPROPERTIES m_pISessionProperties; // contained ISessionProperties PIMPITABLEDEFINITION m_pITableDefinition; // contained ITableDefinition PIMPIBINDSRC m_pIBindResource; // Pointer to bindresource CImpIDBSchemaRowset * m_pISchemaRowset; CImpIDBCreateCommand * m_pIDBCreateCommand; // Contained IDBCreateCommand PIMPINDEXDEF m_pIIndexDefinition; // Contained IIndexDefinition PIMPIALTERTABLE m_pIAlterTable; // Contained IAlterTable PIMPISUPPORTERRORINFO m_pISupportErrorInfo; // contained ISupportErrorInfo PIMPITRANSACTIONLOCAL m_pITransLocal; // contained ITransactionLocal interface BOOL m_bTxnStarted; // flag to indicate if Txn has started or not ISOLEVEL m_TxnIsoLevel; XACTUOW m_TxnGuid; // unit of work identifying the transaction CFlexArray m_OpenedRowsets; HRESULT CreateCommand(IUnknown *pUnkOuter, REFGUID guidTemp,IUnknown ** ppUnk); HRESULT CreateRow(IUnknown *pUnkOuter, WCHAR *pstrURL,REFGUID guidTemp,IUnknown ** ppUnk); HRESULT CreateRowset(IUnknown *pUnkOuter, WCHAR *pstrURL, REFGUID guidTemp,IUnknown ** ppUnk); BOOL CheckIfValidDataSrc(); HRESULT AddInterfacesForISupportErrorInfo(); BOOL IsTransactionActive() { return m_bTxnStarted; } void SetTransactionActive(BOOL bActive) { m_bTxnStarted = bActive; } void SetIsolationLevel(ISOLEVEL isoLevel) { m_TxnIsoLevel = isoLevel; } ISOLEVEL GetIsolationLevel() { return m_TxnIsoLevel; } HRESULT GenerateNewUOW(GUID &guidTrans); XACTUOW GetCurrentUOW() { return m_TxnGuid; } void SetAllOpenRowsetToZoombieState(); public: CDBSession(LPUNKNOWN); ~CDBSession(void); LPUNKNOWN m_pISessionCache; //data cache session (synchronized with this session) PCDATASOURCE m_pCDataSource; // parent data source object HRESULT FInit( CDataSource *pCDataSource ); // Intitialization Routine inline void DecRowsetCount(void){if(this->m_nOpenedRowset) this->m_nOpenedRowset--;}; // inline to dec rowset count STDMETHODIMP QueryInterface(REFIID, LPVOID *); STDMETHODIMP_(ULONG) AddRef(void); STDMETHODIMP_(ULONG) Release(void); inline void RowsetDestroyed() { m_nOpenedRowset = 0; }; HRESULT GetDataSrcProperty(DBPROPID propId , VARIANT & varValue); void AddRowset(CBaseRowObj * pRowset); // add rowset to list of open rowset void RemoveRowset(CBaseRowObj * pRowset); // deletes the rowset from list of open rowset // 07/12/2000 // NTRaid : 142348 HRESULT ExecuteQuery(CQuery *pQuery) { return m_pCDataSource->m_pWbemWrap->ExecuteQuery(pQuery);} }; typedef CDBSession *PCDBSESSION; ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Contained IGetDataSource class // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// class CImpIGetDataSource : public IGetDataSource { private: DEBUGCODE(ULONG m_cRef); CDBSession *m_pObj; public: CImpIGetDataSource( CDBSession *pObj ) { DEBUGCODE(m_cRef = 0L); m_pObj = pObj; } ~CImpIGetDataSource() { } STDMETHODIMP_(ULONG) AddRef(void) { DEBUGCODE(InterlockedIncrement((long*)&m_cRef)); return m_pObj->GetOuterUnknown()->AddRef(); } STDMETHODIMP_(ULONG) Release(void) { DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef); if( lRef < 0 ){ ASSERT("Reference count on Object went below 0!") }) return m_pObj->GetOuterUnknown()->Release(); } STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv) { return m_pObj->GetOuterUnknown()->QueryInterface(riid, ppv); } STDMETHODIMP GetDataSource( REFIID, IUnknown** ); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // contained IOpenRowset class // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// class CImpIOpenRowset : public IOpenRowset { private: DEBUGCODE(ULONG m_cRef); CDBSession *m_pObj; BOOL GetIRowProp(ULONG cPropSet, DBPROPSET[]); public: CImpIOpenRowset( CDBSession *pObj ) { DEBUGCODE(m_cRef = 0L); m_pObj = pObj; } ~CImpIOpenRowset() { } STDMETHODIMP_(ULONG) AddRef(void) { DEBUGCODE(InterlockedIncrement((long*)&m_cRef)); return m_pObj->GetOuterUnknown()->AddRef(); } STDMETHODIMP_(ULONG) Release(void) { DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef); if( lRef < 0 ){ ASSERT("Reference count on Object went below 0!") }) return m_pObj->GetOuterUnknown()->Release(); } STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv) { return m_pObj->GetOuterUnknown()->QueryInterface(riid, ppv); } STDMETHODIMP OpenRowset( IUnknown*, DBID*, DBID*, REFIID, ULONG, DBPROPSET[], IUnknown** ); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Contained ISessionProperties class // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// class CImpISessionProperties : public ISessionProperties { friend class CBinder; private: DEBUGCODE(ULONG m_cRef); CDBSession *m_pObj; CDBSession * GetSessionPtr() { return m_pObj; } // This function is to give the session object pointer // to the binder object public: CImpISessionProperties( CDBSession *pObj ) { DEBUGCODE(m_cRef = 0L); m_pObj = pObj; } ~CImpISessionProperties() { } STDMETHODIMP_(ULONG) AddRef(void) { DEBUGCODE(InterlockedIncrement((long*)&m_cRef)); return m_pObj->GetOuterUnknown()->AddRef(); } STDMETHODIMP_(ULONG) Release(void) { DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef); if( lRef < 0 ){ ASSERT("Reference count on Object went below 0!") }) return m_pObj->GetOuterUnknown()->Release(); } STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv) { return m_pObj->GetOuterUnknown()->QueryInterface(riid, ppv); } STDMETHODIMP GetProperties ( ULONG cPropertySets, const DBPROPIDSET rgPropertySets[], ULONG* pcProperties, DBPROPSET** prgProperties ); STDMETHODIMP SetProperties ( ULONG cProperties, DBPROPSET rgProperties[] ); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Contained ITableDefinition class // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// class CImpITableDefinition : public ITableDefinition { private: DEBUGCODE(ULONG m_cRef); CDBSession *m_pObj; public: CImpITableDefinition( CDBSession *pObj ) { DEBUGCODE(m_cRef = 0L); m_pObj = pObj; } ~CImpITableDefinition() { } STDMETHODIMP_(ULONG) AddRef(void) { DEBUGCODE(InterlockedIncrement((long*)&m_cRef)); return m_pObj->GetOuterUnknown()->AddRef(); } STDMETHODIMP_(ULONG) Release(void) { DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef); if( lRef < 0 ){ ASSERT("Reference count on Object went below 0!") }) return m_pObj->GetOuterUnknown()->Release(); } STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv) { return m_pObj->GetOuterUnknown()->QueryInterface(riid, ppv); } STDMETHODIMP CreateTable( IUnknown __RPC_FAR *pUnkOuter, DBID __RPC_FAR *pTableID, DBORDINAL cColumnDescs, const DBCOLUMNDESC __RPC_FAR rgColumnDescs[ ], REFIID riid, ULONG cPropertySets, DBPROPSET __RPC_FAR rgPropertySets[ ], DBID __RPC_FAR *__RPC_FAR *ppTableID, IUnknown __RPC_FAR *__RPC_FAR *ppRowset); STDMETHODIMP DropTable( DBID __RPC_FAR *pTableID); STDMETHODIMP AddColumn( DBID __RPC_FAR *pTableID, DBCOLUMNDESC __RPC_FAR *pColumnDesc, DBID __RPC_FAR *__RPC_FAR *ppColumnID); STDMETHODIMP DropColumn( DBID __RPC_FAR *pTableID, DBID __RPC_FAR *pColumnID); }; class CImplIBindRsrc : public IBindResource { private: CDBSession *m_pObj; DEBUGCODE(ULONG m_cRef); BOOL CheckBindURLFlags(DBBINDURLFLAG dwBindURLFlags , REFGUID rguid); // Function to check if proper flags are // are set for the require object // To check if URL Matches the requested type of object BOOL CheckIfProperURL(BSTR & strUrl,REFGUID rguid,DBBINDURLSTATUS * pdwBindStatus); HRESULT BindURL(IUnknown * pUnkOuter, LPCOLESTR pwszURL, DBBINDURLFLAG dwBindURLFlags, REFGUID rguid, REFIID riid, DBIMPLICITSESSION * pImplSession, DBBINDURLSTATUS * pdwBindStatus, IUnknown ** ppUnk); public: CImplIBindRsrc( CDBSession *pObj ) { DEBUGCODE(m_cRef = 0L); m_pObj = pObj; } ~CImplIBindRsrc() { } STDMETHODIMP_(ULONG) AddRef(void) { DEBUGCODE(InterlockedIncrement((long*)&m_cRef)); return m_pObj->GetOuterUnknown()->AddRef(); } STDMETHODIMP_(ULONG) Release(void) { DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef); if( lRef < 0 ){ ASSERT("Reference count on Object went below 0!") }) return m_pObj->GetOuterUnknown()->Release(); } STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv) { return m_pObj->GetOuterUnknown()->QueryInterface(riid, ppv); } STDMETHODIMP Bind( IUnknown * pUnkOuter, LPCOLESTR pwszURL, DBBINDURLFLAG dwBindURLFlags, REFGUID rguid, REFIID riid, IAuthenticate * pAuthenticate, DBIMPLICITSESSION * pImplSession, DBBINDURLSTATUS * pdwBindStatus, IUnknown ** ppUnk); }; class CImplIIndexDefinition : public IIndexDefinition { private: DEBUGCODE(ULONG m_cRef); CDBSession *m_pObj; public: CImplIIndexDefinition( CDBSession *pObj ) { DEBUGCODE(m_cRef = 0L); m_pObj = pObj; } ~CImplIIndexDefinition() { } STDMETHODIMP_(ULONG) AddRef(void) { DEBUGCODE(InterlockedIncrement((long*)&m_cRef)); return m_pObj->GetOuterUnknown()->AddRef(); } STDMETHODIMP_(ULONG) Release(void) { DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef); if( lRef < 0 ){ ASSERT("Reference count on Object went below 0!") }) return m_pObj->GetOuterUnknown()->Release(); } STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv) { return m_pObj->GetOuterUnknown()->QueryInterface(riid, ppv); } STDMETHODIMP CreateIndex( DBID * pTableID, DBID * pIndexID, DBORDINAL cIndexColumnDescs, const DBINDEXCOLUMNDESC rgIndexColumnDescs[], ULONG cPropertySets, DBPROPSET rgPropertySets[], DBID ** ppIndexID); STDMETHODIMP DropIndex( DBID * pTableID, DBID * pIndexID); }; class CImplIAlterTable : public IAlterTable { private: DEBUGCODE(ULONG m_cRef); CDBSession *m_pObj; HRESULT CheckIfSupported(DBCOLUMNDESCFLAGS ColumnDescFlags); public: CImplIAlterTable( CDBSession *pObj ) { DEBUGCODE(m_cRef = 0L); m_pObj = pObj; } ~CImplIAlterTable() { } STDMETHODIMP_(ULONG) AddRef(void) { DEBUGCODE(InterlockedIncrement((long*)&m_cRef)); return m_pObj->GetOuterUnknown()->AddRef(); } STDMETHODIMP_(ULONG) Release(void) { DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef); if( lRef < 0 ){ ASSERT("Reference count on Object went below 0!") }) return m_pObj->GetOuterUnknown()->Release(); } STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv) { return m_pObj->GetOuterUnknown()->QueryInterface(riid, ppv); } STDMETHODIMP AlterColumn(DBID * pTableID, DBID * pColumnID, DBCOLUMNDESCFLAGS ColumnDescFlags, DBCOLUMNDESC * pColumnDesc); STDMETHODIMP AlterTable(DBID * pTableID, DBID * pNewTableID, ULONG cPropertySets, DBPROPSET rgPropertySet[]); }; ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Hashs a token and returns TRUE iff the token is a statement keywpord. // ////////////////////////////////////////////////////////////////////////////////////////////////////////////// class CImpIDBCreateCommand : public IDBCreateCommand { public: CImpIDBCreateCommand(PCDBSESSION pCDBSession) { m_pCDBSession = pCDBSession; DEBUGCODE(m_cRef = 0); } ~CImpIDBCreateCommand() {} STDMETHODIMP_(ULONG) AddRef(void) { DEBUGCODE(InterlockedIncrement((long*)&m_cRef)); return m_pCDBSession->GetOuterUnknown()->AddRef(); } STDMETHODIMP_(ULONG) Release(void) { DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef); if( lRef < 0 ){ ASSERT("Reference count on Object went below 0!") }) return m_pCDBSession->GetOuterUnknown()->Release(); } STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv) { return m_pCDBSession->GetOuterUnknown()->QueryInterface(riid, ppv); } STDMETHODIMP CreateCommand( IUnknown* punkOuter, REFIID riid, IUnknown **ppCommand ); private: CDBSession *m_pCDBSession; DEBUGCODE(ULONG m_cRef); }; typedef CImpIDBCreateCommand *PIMPIDBCREATECOMMAND; ////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Class declaration for implementing ITransactionLocal interface // ////////////////////////////////////////////////////////////////////////////////////////////////////////////// class CImpITransactionLocal : public ITransactionLocal { public: CImpITransactionLocal(PCDBSESSION pCDBSession) { m_pCDBSession = pCDBSession; DEBUGCODE(m_cRef = 0); } ~CImpITransactionLocal() {} STDMETHODIMP_(ULONG) AddRef(void) { DEBUGCODE(InterlockedIncrement((long*)&m_cRef)); return m_pCDBSession->GetOuterUnknown()->AddRef(); } STDMETHODIMP_(ULONG) Release(void) { DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef); if( lRef < 0 ){ ASSERT("Reference count on Object went below 0!") }) return m_pCDBSession->GetOuterUnknown()->Release(); } STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv) { return m_pCDBSession->GetOuterUnknown()->QueryInterface(riid, ppv); } STDMETHODIMP Commit (BOOL fRetaining, DWORD grfTC, DWORD grfRM); STDMETHODIMP Abort (BOID *pboidReason, BOOL fRetaining, BOOL fAsync); STDMETHODIMP GetTransactionInfo (XACTTRANSINFO *pinfo); STDMETHODIMP GetOptionsObject (ITransactionOptions ** ppOptions); STDMETHODIMP StartTransaction( ISOLEVEL isoLevel, ULONG isoFlags, ITransactionOptions *pOtherOptions, ULONG *pulTransactionLevel); private: CDBSession *m_pCDBSession; DEBUGCODE(ULONG m_cRef); HRESULT GetFlagsForIsolation(ISOLEVEL isoLevel,LONG &lFlag); }; typedef CImpITransactionLocal *PIMPITRANSACTIONLOCAL; #endif