//-------------------------------------------------------------------- // Microsoft OLE DB Test // // Copyright (C) 1995-2000 Microsoft Corporation // // @doc // // @module ExtraLib.h | This module contains header information for // ExtraLib.cpp general testing library // // @rev 01 | 02-22-96 | Microsoft | Created // @rev 02 | 12-01-96 | Microsoft | Updated // #ifndef _EXTRALIB_H_ #define _EXTRALIB_H_ #include "oledb.h" // MS (OLE DB) Header Files #include "oledberr.h" // MS (OLE DB) Errors #include // MS (OLE DB) Extra GUIDs (KAGPROP_QUERYBASEDUPDATES) #include // MS (OLE DB) IRowPosition #include "privlib.h" // Private Library #include // _beginthreadex #include //CONNECT_E_NOCONNECT //////////////////////////////////////////////////////////////////////////// // Globals // ///////////////////////////////////////////////////////////////////////////// extern CTable* g_pTable; // Global table extern CTable* g_pEmptyTable; // Empty table extern CTable* g_p1RowTable; // 1 Row Table extern DBCOUNTITEM g_ulNextRow; // NextRow extern IDBInitialize* g_pIDBInitialize; //Global DSO ptr extern IDBCreateSession* g_pIDBCreateSession; //Global DSO ptr extern IOpenRowset* g_pIOpenRowset; //Global Session ptr extern CRITICAL_SECTION GlobalMutex; //Global Mutex //////////////////////////////////////////////////////////////////////////// // Forwards // ///////////////////////////////////////////////////////////////////////////// class CStorage; class CImpIRowsetNotify; class CImpIDBAsynchNotify; class CImpIRowPositionChange; /////////////////////////////////////////////////////////////////////////// // Provider Specific // /////////////////////////////////////////////////////////////////////////// #define PROVIDER_CLSID GetModInfo()->GetThisTestModule()->m_ProviderClsid #define MSDASQL (CLSID_MSDASQL==PROVIDER_CLSID) /////////////////////////////////////////////////////////////////////////// // Strings // /////////////////////////////////////////////////////////////////////////// #define EQUAL_STR 0 #define ON TRUE #define OFF FALSE /////////////////////////////////////////////////////////////////////////// // Macros // /////////////////////////////////////////////////////////////////////////// #define SAFE_RELEASE_DSO(pv) { if(pv) ReleaseDataSource((IUnknown**)&(pv)); pv = NULL; } #define TCHECK(exp,hr) CHECK(exp, hr) #define TCOMPARE(x,y) COMPARE(x, y) #define TCOMPARE_(x) COMPARE(x, TRUE) #define TEST(exp) { if(!COMPARE(exp, TRUE)) TRETURN; } #define TEST_(exp,hr) { if(!CHECK(exp,hr)) TRETURN; } #define QTEST(exp) { if(!QCOMPARE(exp, TRUE)) TRETURN; } #define QTEST_(exp,hr) { if(!QCHECK((exp),hr)) TRETURN; } //COMP Macros #define COMP(exp1,exp2) { if(!COMPARE(exp1,exp2)) TRETURN; } #define COMPC(exp1,exp2) { if(!COMPARE(exp1,exp2)) goto CLEANUP; } //QCOMP Macros #define QCOMP(exp1,exp2) { if(!QCOMPARE(exp1,exp2)) TRETURN; } #define QCOMPC(exp1,exp2) { if(!QCOMPARE(exp1,exp2)) goto CLEANUP; } #define TEST_PROVIDER(exp) { TESTB = TEST_PASS; if(!(exp)) { TOUTPUT_LINE(L"NotSupported by Provider"); TESTB = TEST_SKIPPED; TRETURN; } } #define MODULENAME (LPWSTR)gwszModuleName #define SIZEOF_ONEROW (sizeof(void*)*m_cRowSize) #define SIZEOF_TABLE (5) #define MAX_NAME_LEN 256 #define MAX_QUERY_LEN 4096 #define NEGATIVE(ul) (-(LONG)(ul)) ////////////////////////////////////////////////////////////////////// // Enums // ////////////////////////////////////////////////////////////////////// //Const int names enum {ONE_ROW=1,TWO_ROWS,THREE_ROWS,FOUR_ROWS,FIVE_ROWS,SIX_ROWS,SEVEN_ROWS,EIGHT_ROWS,NINE_ROWS,TEN_ROWS,ELEVEN_ROWS,TWELVE_ROWS,THIRTEEN_ROWS,FOURTEEN_ROWS}; //Array index names enum {ROW_ONE=0,ROW_TWO,ROW_THREE,ROW_FOUR,ROW_FIVE,ROW_SIX,ROW_SEVEN,ROW_EIGHT,ROW_NINE,ROW_TEN,ROW_ELEVEN,ROW_TWELVE,ROW_THIRTEEN,ROW_FOURTEEN}; //Table index name enum {NO_ROWS=0,FIRST_ROW,SECOND_ROW,THIRD_ROW,FOURTH_ROW,FIFTH_ROW,SIXTH_ROW,SEVENTH_ROW,EIGHTH_ROW,NINTH_ROW,TENTH_ROW,TWELTH_ROW,THIRTEENTH_ROW,FOURTEENTH_ROW}; enum {COL_ONE=1}; // Prop status comparison enum VALUE_ENUM { NOT_USED=0, // Ignored VALID_VALUE, // Value is supported INVALID_VALUE, // Value is unsupported INDETERMINATE_VALUE // We don't know whether the value passed is supported }; // PropSets comparison enum PROPSETCOMPAREOPTIONS_ENUM { EXACT_MATCH=0, // properties in the properties' sets should exactly match IGNORE_OPTION_FOR_VTEMPTY // if both properties values are VT_EMPTY then ignore dwOptions mismatch }; #define DBPENDINGSTATUS_ALL ( DBPENDINGSTATUS_NEW |DBPENDINGSTATUS_CHANGED |DBPENDINGSTATUS_DELETED ) #define DBPART_ALL ( DBPART_VALUE | DBPART_LENGTH | DBPART_STATUS ) #define DBPROPVAL_NP_ALL ( DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER | DBPROPVAL_NP_FAILEDTODO | DBPROPVAL_NP_DIDEVENT ) #define DBPROPVAL_NP_CANCELABLE ( DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER ) #define DBPROPVAL_UP_ALL ( DBPROPVAL_UP_CHANGE | DBPROPVAL_UP_DELETE | DBPROPVAL_UP_INSERT ) #define DBPROPVAL_RT_ALL ( DBPROPVAL_RT_FREETHREAD | DBPROPVAL_RT_APTMTTHREAD | DBPROPVAL_RT_SINGLETHREAD ) #define DBPROPVAL_RT_BOTH ( DBPROPVAL_RT_FREETHREAD | DBPROPVAL_RT_APTMTTHREAD ) enum DBASYNCHREASONENUM { DBREASON_ONLOWRESOURCE = DBREASON_ROW_ASYNCHINSERT + 1, DBREASON_ONPROGRESS = DBREASON_ONLOWRESOURCE + 1, DBREASON_ONSTOP = DBREASON_ONPROGRESS + 1, }; typedef DWORD DBASYNCHREASON; #define DBREASON_ALL ( DBREASON_ONSTOP + 1 ) #define DBEVENTPHASE_ALL ( DBEVENTPHASE_DIDEVENT + 1 ) //////////////////////////////////////////////////////////////////////// // Multi-Threads // //////////////////////////////////////////////////////////////////////// enum {THREAD_ONE=0, THREAD_TWO, THREAD_THREE, THREAD_FOUR, THREAD_FIVE, THREAD_SIX}; enum {ONE_THREAD=1,TWO_THREADS,THREE_THREADS, FOUR_THREADS, FIVE_THREADS, SIX_THREADS, MAX_THREADS=10 }; enum {LISTENER_ONE=0, LISTENER_TWO, LISTENER_THREE, LISTENER_FOUR, LISTENER_FIVE}; enum {SOURCE_ONE=0, SOURCE_TWO, SOURCE_THREE, SOURCE_FOUR, SOURCE_FIVE}; //This simply the usage of threads down to 3 lines of code, CREATE/START/END inline BOOL CreateThreads(LPTHREAD_START_ROUTINE pFunc,void* pArgs,ULONG cThreads,HANDLE* rghThread,DWORD* rgThreadID) { ASSERT(pFunc && pArgs && rghThread && rgThreadID); for(ULONG i=0; ipFunc) #define THREAD_ARG1 ((ULONG_PTR)(((THREADARG*)pv)->pArg1)) #define THREAD_ARG2 ((ULONG_PTR)(((THREADARG*)pv)->pArg2)) #define THREAD_ARG4 ((ULONG_PTR)(((THREADARG*)pv)->pArg4)) #define THREAD_ARG3 ((ULONG_PTR)(((THREADARG*)pv)->pArg3)) #define THREAD_ARG5 ((ULONG_PTR)(((THREADARG*)pv)->pArg5)) struct THREADARG { LPVOID pFunc; LPVOID pArg1; LPVOID pArg2; LPVOID pArg3; LPVOID pArg4; LPVOID pArg5; }; inline THREADARG InitThreadArg(void* pFunc, void* pArg1 = NULL, void* pArg2 = NULL, void* pArg3 = NULL, void* pArg4 = NULL, void* pArg5 = NULL) { THREADARG ThreadArg = { pFunc, pArg1, pArg2, pArg3, pArg4, pArg5}; return ThreadArg; } WINOLEAPI CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit); #define THREAD_BEGIN CoInitializeEx(NULL, 0/*COINIT_MULTITHREADED*/ ); TBEGIN #define THREAD_BEGIN_(fFreeThreaded) CoInitializeEx(NULL, fFreeThreaded ? 0/*COINIT_MULTITHREADED*/ : 2/*COINIT_APARTMENTTHREADED*/); TBEGIN #define THREAD_END(hr) CoUninitialize(); _endthreadex(hr); return 0; #define THREAD_RETURN CoUninitialize(); TRETURN #define ThreadSwitch() Sleep(0) //////////////////////////////////////////////////////////////////////// // Extern // //////////////////////////////////////////////////////////////////////// extern GUID NULLGUID; extern DBID NULLDBID; extern DBID INVALID_DBID; extern DBID VALID_INDEXID; #define INVALID_TABLEID INVALID_DBID #define INVALID_INDEXID INVALID_DBID ////////////////////////////////////////////////////////////////////////////// // Memory Alloc/Free Routines // // A "safe" wrapper arround CoTaskMemAlloc to protect boundaries ////////////////////////////////////////////////////////////////////////////// #define HEAD_SIGN 0xedededed #define TAIL_SIGN 0xdededede #define ALLOC_SIGN 0xaa #define FREE_SIGN 0xbb void* BoundarySafeAlloc(ULONG cb); void BoundarySafeFree(void* pv); void BoundarySafeFree(ULONG cBuffers, void** ppv); #define PROVIDER_FREE2(cEle,ppv) { if(ppv) for(ULONG i=0; iPrepare(0),S_OK) CLEANUP: SAFE_RELEASE(pICommandPrepare); TRETURN } ////////////////////////////////////////////////////////////////////////////// // BitWise manipulations // ////////////////////////////////////////////////////////////////////////////// inline ULONG EnumToBitmask(ULONG eValue) { ULONG ulMask = 0x1; //Has to be less then the numer of "bits" in the return value ASSERT(eValue < (sizeof(ULONG)*8)); return ulMask << (eValue); } #define BITSET(val, mask) (((val) & (mask)) == (mask)) #define BITCLEAR(val, mask) (!((val) & (mask))) #define SETBIT(val, mask) ((val) |= (mask)) #define CLEARBIT(val, mask) ((val) &= ~(mask)) ///////////////////////////////////////////////////////////////////////////// // Enumerator Operations // ///////////////////////////////////////////////////////////////////////////// struct ENUMINFO { WCHAR wszName[MAX_NAME_LEN]; WCHAR wszParseName[MAX_NAME_LEN]; WCHAR wszDescription[MAX_NAME_LEN]; DBTYPE wType; VARIANT_BOOL fIsParent; }; HRESULT GetEnumInfo(IParseDisplayName* pIParseDisplayName, ULONG* pcEnumInfo, ENUMINFO** prgEnumInfo); HRESULT CreateFromDisplayName(IParseDisplayName* pIParseDisplayName, WCHAR* pwszDisplayName, REFIID riid, IUnknown** ppIUnknown); ////////////////////////////////////////////////////////////////////////// // Class CDataSource // // Basically a nice wrapper arround a DataSource object. ////////////////////////////////////////////////////////////////////////// class CDataSource : public CDataSourceObject { public: //Constructors CDataSource(WCHAR* pwszTestCaseName = INVALID(WCHAR*)); virtual ~CDataSource(); //members virtual BOOL Init(); virtual BOOL Terminate(); //cast operator virtual IDBInitialize* const pIDBInit(); virtual IUnknown* const pDataSource(); virtual IDBInitialize* const operator ()(); virtual HRESULT CreateInstance(); virtual HRESULT Initialize(IUnknown* pDataSource, EREINITIALIZE eReinitialize = REINITIALIZE_YES); virtual HRESULT Initialize(EREINITIALIZE eReinitialize = REINITIALIZE_YES); virtual HRESULT Uninitialize(); //GetProperties virtual HRESULT GetPropertyInfo(GUID guidPropertySet, ULONG* pcPropInfoSets = NULL, DBPROPINFOSET** prgPropInfoSets = NULL, WCHAR** ppwszStringBuffer = NULL); //SetProperties virtual BOOL SetProperty(DBPROPID dwPropertyID, GUID guidPropertySet = DBPROPSET_ROWSET, void* pValue = (void*)VARIANT_TRUE, DBTYPE wType = DBTYPE_BOOL, DBPROPOPTIONS dwOptions = DBPROPOPTIONS_REQUIRED, DBID colid = DB_NULLID); virtual BOOL SetSupportedProperty(DBPROPID dwPropertyID, GUID guidPropertySet = DBPROPSET_ROWSET, void* pValue = (void*)VARIANT_TRUE, DBTYPE wType = DBTYPE_BOOL, DBPROPOPTIONS dwOptions = DBPROPOPTIONS_REQUIRED, DBID colid = DB_NULLID); virtual BOOL SetSettableProperty(DBPROPID dwPropertyID, GUID guidPropertySet = DBPROPSET_ROWSET, void* pValue = (void*)VARIANT_TRUE, DBTYPE wType = DBTYPE_BOOL, DBPROPOPTIONS dwOptions = DBPROPOPTIONS_REQUIRED, DBID colid = DB_NULLID); virtual BOOL FreeProperties(); //Verification virtual BOOL VerifyDataSource(IUnknown* pDataSource, REFCLSID rclsid); virtual BOOL VerifyDataSource(IUnknown* pDataSource, DBPROPID dwPropertyID, GUID guidPropertySet, DBTYPE wType, void* pValue); //data ULONG m_cPropSets; DBPROPSET* m_rgPropSets; }; ////////////////////////////////////////////////////////////////// // Class COpenRowset // // Used to create multiple instantes of CTestCases even though our // privlib is really not designed for it, quite a useful hack... ////////////////////////////////////////////////////////////////// class COpenRowset : public CSessionObject { public: //Constructors COpenRowset(WCHAR* pwszTestCaseName = INVALID(WCHAR*)); virtual ~COpenRowset(); //methods virtual BOOL Init(); virtual BOOL Terminate(); //helper virtual HRESULT CreateOpenRowset(IID riid = IID_IRowset, IUnknown** ppIRowset = NULL, IUnknown* pIUnkOuter = NULL, EINTERFACE eInterface = ROWSET_INTERFACE); virtual HRESULT CreateOpenRowset(CTable* pCTable,IID riid = IID_IRowset, IUnknown** ppIRowset = NULL, IUnknown* pIUnkOuter = NULL, EINTERFACE eInterface = ROWSET_INTERFACE); virtual BOOL SetProperty(DBPROPID dwPropertyID, GUID guidPropertySet = DBPROPSET_ROWSET, void* pValue = (void*)VARIANT_TRUE, DBTYPE wType = DBTYPE_BOOL, DBPROPOPTIONS dwOptions = DBPROPOPTIONS_REQUIRED, DBID colid = DB_NULLID); virtual BOOL SetSupportedProperty(DBPROPID dwPropertyID, GUID guidPropertySet = DBPROPSET_ROWSET, void* pValue = (void*)VARIANT_TRUE, DBTYPE wType = DBTYPE_BOOL, DBPROPOPTIONS dwOptions = DBPROPOPTIONS_REQUIRED, DBID colid = DB_NULLID); virtual BOOL SetSettableProperty(DBPROPID dwPropertyID, GUID guidPropertySet = DBPROPSET_ROWSET, void* pValue = (void*)VARIANT_TRUE, DBTYPE wType = DBTYPE_BOOL, DBPROPOPTIONS dwOptions = DBPROPOPTIONS_REQUIRED, DBID colid = DB_NULLID); virtual BOOL FreeProperties(); //interface virtual IUnknown* const pISession(); virtual IOpenRowset* const operator()(); virtual IOpenRowset* const pIOpenRowset(); //protected: //data ULONG m_cPropSets; DBPROPSET* m_rgPropSets; protected: //data pointers }; ////////////////////////////////////////////////////////////////////////// // Class CCommand // // Basically a nice wrapper arround a command object. ////////////////////////////////////////////////////////////////////////// class CCommand : public CCommandObject { public: //Constructors CCommand(WCHAR* pwszTestCaseName = INVALID(WCHAR*)); virtual ~CCommand(); //members virtual BOOL Init(); virtual BOOL Terminate(); //Helpers virtual HRESULT CreateCommand(IUnknown* pIUnkOuter = NULL); virtual HRESULT SetCommandText(EQUERY eQuery, REFGUID rguidDialect = DBGUID_DEFAULT); virtual HRESULT SetProperties(); virtual HRESULT Execute(IUnknown* pUnkOuter, REFIID riid, IUnknown** ppRowset, DBROWCOUNT* pcRowsAffected = NULL, DBPARAMS* pParams = NULL); virtual BOOL SetProperty(DBPROPID dwPropertyID, GUID guidPropertySet = DBPROPSET_ROWSET, void* pValue = (void*)VARIANT_TRUE, DBTYPE wType = DBTYPE_BOOL, DBPROPOPTIONS dwOptions = DBPROPOPTIONS_REQUIRED, DBID colid = DB_NULLID); virtual BOOL FreeProperties(); //protected: ICommandText* m_pICommandText; ICommandProperties* m_pICommandProperties; ULONG m_cPropSets; DBPROPSET* m_rgPropSets; }; ////////////////////////////////////////////////////////////////////////// // Class CRowset // // Basically a nice wrapper arround a rowset object. This test will use // multiple rowsets, and its easier to have all the general functionality // together ////////////////////////////////////////////////////////////////////////// class CRowset : public CRowsetObject { public: //Constructors CRowset(WCHAR* pwszTestCaseName = INVALID(WCHAR*)); virtual ~CRowset(); //members virtual BOOL Init(); virtual BOOL Terminate(); virtual HRESULT CreateCommand(EQUERY eQuery = USE_SUPPORTED_SELECT_ALLFROMTBL); virtual HRESULT CreateAccessor(HACCESSOR* phAccessor, DBACCESSORFLAGS dwAccessorFlags, DBPART dwPart = DBPART_ALL, DBCOUNTITEM* pcBindings=NULL, DBBINDING** prgDBBINDING=NULL, DBLENGTH* pcRowSize=NULL, BLOBTYPE dwBlobType = NO_BLOB_COLS, DBBINDSTATUS** prgBindStauts = NULL, DWORD dwColsBound = UPDATEABLE_COLS_BOUND, ECOLS_BY_REF eColsByRef = NO_COLS_BY_REF, DBTYPE dwModifier = DBTYPE_EMPTY); virtual HRESULT CreateRowset(EQUERY eQuery = SELECT_ORDERBYNUMERIC, REFIID riid = IID_IRowset, CTable* pCTable = NULL, DBACCESSORFLAGS dwAccessorFlags = DBACCESSOR_ROWDATA, DBPART dwPart = DBPART_ALL, DWORD dwColsBound = UPDATEABLE_COLS_BOUND, ECOLUMNORDER eBindingOrder = FORWARD, ECOLS_BY_REF eColsByRef = NO_COLS_BY_REF, DBTYPE wTypeModifier = DBTYPE_EMPTY, BLOBTYPE dwBlobType = NO_BLOB_COLS); virtual HRESULT CreateRowset(DBPROPID dwProperty, EQUERY eQuery = SELECT_ORDERBYNUMERIC, REFIID riid = IID_IRowset, CTable* pCTable = NULL, DBACCESSORFLAGS dwAccessorFlags = DBACCESSOR_ROWDATA, DBPART dwPart = DBPART_ALL, DWORD dwColsBound = UPDATEABLE_COLS_BOUND, ECOLUMNORDER eBindingOrder = FORWARD, ECOLS_BY_REF eColsByRef = NO_COLS_BY_REF, DBTYPE wTypeModifier = DBTYPE_EMPTY, BLOBTYPE dwBlobType = NO_BLOB_COLS); virtual HRESULT CreateRowset(IUnknown* pIRowset, EQUERY eQuery = SELECT_ORDERBYNUMERIC, REFIID riid = IID_IRowset, CTable* pCTable = NULL, DBACCESSORFLAGS dwAccessorFlags = DBACCESSOR_ROWDATA, DBPART dwPart = DBPART_ALL, DWORD dwColsBound = UPDATEABLE_COLS_BOUND, ECOLUMNORDER eBindingOrder = FORWARD, ECOLS_BY_REF eColsByRef = NO_COLS_BY_REF, DBTYPE wTypeModifier = DBTYPE_EMPTY, BLOBTYPE dwBlobType = NO_BLOB_COLS); virtual HRESULT CreateRowsetFromTbl(DBCOUNTITEM cTableSize); virtual HRESULT DropRowset(); //helpers virtual BOOL SetProperty(DBPROPID dwPropertyID, GUID guidPropertySet = DBPROPSET_ROWSET, void* pValue = (void*)VARIANT_TRUE, DBTYPE wType = DBTYPE_BOOL, DBPROPOPTIONS dwOptions = DBPROPOPTIONS_REQUIRED, DBID colid = DB_NULLID); virtual BOOL SetSupportedProperty(DBPROPID dwPropertyID, GUID guidPropertySet = DBPROPSET_ROWSET, void* pValue = (void*)VARIANT_TRUE, DBTYPE wType = DBTYPE_BOOL, DBPROPOPTIONS dwOptions = DBPROPOPTIONS_REQUIRED, DBID colid = DB_NULLID); virtual BOOL SetSettableProperty(DBPROPID dwPropertyID, GUID guidPropertySet = DBPROPSET_ROWSET, void* pValue = (void*)VARIANT_TRUE, DBTYPE wType = DBTYPE_BOOL, DBPROPOPTIONS dwOptions = DBPROPOPTIONS_REQUIRED, DBID colid = DB_NULLID); virtual BOOL GetProperty(DBPROPID dwPropertyID, GUID guidPropertySet = DBPROPSET_ROWSET, VARIANT_BOOL bValue = VARIANT_TRUE); virtual BOOL GetProperty(DBPROPID dwPropertyID, GUID guidPropertySet, VARIANT_BOOL* pbValue); virtual BOOL GetProperty(DBPROPID dwPropertyID, GUID guidPropertySet, ULONG_PTR* pulValue); virtual BOOL GetProperty(DBPROPID dwPropertyID, GUID guidPropertySet, WCHAR** ppwszValue); virtual BOOL FreeProperties(); //Wrappers virtual HRESULT GetRow(DBCOUNTITEM iRow, HROW* phRow); virtual HRESULT GetRow(DBCOUNTITEM iRow, DBCOUNTITEM cRows, HROW* rghRow); virtual HRESULT GetRow(DBCOUNTITEM iRow, DBCOUNTITEM cRows, DBCOUNTITEM* pcRowsObtained, HROW* rghRow); virtual HRESULT GetNextRows(HROW* phRow); virtual HRESULT GetNextRows(DBROWCOUNT cRows, HROW* rghRow); virtual HRESULT GetNextRows(DBROWOFFSET lOffset, DBROWCOUNT cRows, HROW* rghRow); virtual HRESULT GetNextRows(DBROWOFFSET lOffset, DBROWCOUNT cRows, DBCOUNTITEM* pcRowsObtained, HROW* rghRow); virtual HRESULT GetNextRows(DBROWOFFSET lOffset, DBROWCOUNT cRows, DBCOUNTITEM* pcRowsObtained, HROW** rghRow); virtual HRESULT ReleaseRows(HROW hRow); virtual HRESULT ReleaseRows(DBCOUNTITEM cRows, HROW* rghRow, DBREFCOUNT* rgRefCounts, DBROWSTATUS* rgRowStatus = NULL); virtual HRESULT ReleaseRows(DBCOUNTITEM cRows, HROW* rghRow, DBREFCOUNT** prgRefCounts = NULL, DBROWSTATUS** prgRowStatus = NULL); virtual HRESULT ReleaseAccessor(HACCESSOR hAccessor, DBCOUNTITEM cBindings = 0, DBBINDING* rgBindings = NULL, void* pData = NULL); virtual HRESULT RestartPosition(HCHAPTER hChapter = DB_INVALID_HCHAPTER); virtual HRESULT GetRowData(HROW hRow, void** ppData); virtual HRESULT GetRowData(DBCOUNTITEM cRows, HROW* rghRow, void** ppData); virtual HRESULT GetData(HROW hRow, HACCESSOR hAccessor, void* pData); virtual DBCOUNTITEM GetTotalRows(); virtual DBORDINAL GetTotalColumns(BOOL fIncludeBookmark = FALSE); virtual HRESULT FindColInfo(DBCOLUMNFLAGS dwFlags, DBCOLUMNINFO* pColInfo); virtual HRESULT GetColInfo(DBORDINAL* pcColumns, DBCOLUMNINFO** prgInfo, WCHAR** ppStringsBuffer=NULL); virtual HRESULT GetBookmark(HROW hRow, DBBKMARK *pcbBookmark, BYTE **ppBookmark); virtual HRESULT ResynchRows(DBCOUNTITEM cRows,HROW* rghRow,DBCOUNTITEM* pcResynchedRows = NULL, HROW** prgResynchedRows = NULL, DBROWSTATUS** prgRowStatus = NULL); //IGetRow virtual HRESULT GetRowObject(DBCOUNTITEM iRow, CRowObject* pCRowObject, ULONG_PTR ulpOleObjects = 0, HROW hRowSpecified = NULL); virtual HRESULT GetRowObject(IUnknown* pIUnkOuter, DBCOUNTITEM iRow, REFIID riid, IUnknown** ppIUnknown, ULONG_PTR ulpOleObjects = 0, HROW hRowSpecified = NULL); virtual HRESULT GetRowFromHROW(IUnknown* pIUnkOuter, HROW hRow, REFIID riid, IUnknown** ppIUnknown); virtual HRESULT GetURLFromHROW(HROW hRow, WCHAR** ppwszURL); //helpers virtual BOOL CompareRowData(void* pOrgData, void* pData, HACCESSOR hAccessor = DB_NULL_HACCESSOR, BOOL fSetData = FALSE); virtual BOOL CompareRowData(HROW hRow, void* pData); virtual BOOL CompareRowData(DBCOUNTITEM cRows, HROW* rghRow, void** rgpData); virtual HRESULT GetStorageData(HROW hRow, HACCESSOR hAccessor, void* pBuffer = NULL, ULONG* pcBytes = NULL, REFIID riid = IID_IUnknown, IUnknown** ppIUnknown = NULL); virtual BOOL VerifyRowHandles(DBCOUNTITEM iRow, HROW hRow); virtual BOOL VerifyRowHandles(DBCOUNTITEM cRows, HROW* rghRows, DBCOUNTITEM iRowStart, ECOLUMNORDER eOrder = FORWARD); virtual BOOL CompareTableData(DBCOUNTITEM iTableRow, void* pData, DBCOUNTITEM cBindings = 0, DBBINDING* rgBindings = NULL); virtual BOOL VerifyAllRows(); virtual BOOL CompareRowset(IUnknown* pIRowset); virtual BOOL ValidRow(HROW hRow); virtual BOOL ValidRow(DBCOUNTITEM cRows, HROW* rghRow); virtual BOOL IsSameRow(HROW hRow1, HROW hRow2); //Create Data virtual BOOL MakeRowData(void** ppData, HACCESSOR hAccessor = DB_NULL_HACCESSOR, DBCOUNTITEM* piRow = NULL); virtual BOOL ReleaseRowData(void* pData, HACCESSOR hAccessor = DB_NULL_HACCESSOR, BOOL fFreeBuffer = TRUE); //cast operator virtual IUnknown* const pISession(); virtual IAccessor* const pIAccessor(); virtual ICommand* const pICommand(); virtual IUnknown* const pIUnknown(); virtual IRowset* const pIRowset(); virtual IRowset* const operator ()(); virtual CTable* const pTable(); virtual DBCOUNTITEM GetMaxOpenRows() { return m_ulMaxOpenRows; } virtual BOOL AllowOpenRows(DBCOUNTITEM cOpenRows) { return m_ulMaxOpenRows==0 || m_ulMaxOpenRows>=cOpenRows; } //data HACCESSOR m_hAccessor; DBLENGTH m_cRowSize; DBCOUNTITEM m_cBindings; DBBINDING* m_rgBinding; void* m_pData; DBCOUNTITEM m_ulTableRows; DBCOUNTITEM m_ulMaxOpenRows; BOOL m_bCanHoldRows; BOOL m_bCanFetchBackwards; BOOL m_bCanScrollBackwards; ULONG_PTR m_ulpOleObjects; protected: //data pointers IUnknown* m_pIUnknown; IRowset* m_pIRowset; }; //////////////////////////////////////////////////////////////////// // Class CRowsetChange // // Conatins all the functionality of IRowsetChange as well as all the // IRowset functionality //////////////////////////////////////////////////////////////////// class CRowsetChange : public CRowset { public: //contsructor CRowsetChange(WCHAR* pwszTestCaseName = INVALID(WCHAR*)); virtual ~CRowsetChange(); virtual BOOL Terminate(); // SetData methods virtual HRESULT ModifyRow(HROW hRow); virtual HRESULT ModifyRow(DBCOUNTITEM cRows, HROW* rghRow); virtual HRESULT SetData(HROW hRow, HACCESSOR hAccessor, void* pData); // Delete mothods virtual HRESULT DeleteRow(HROW hRow); virtual HRESULT DeleteRow(DBCOUNTITEM cRows, HROW* rghRow, DBROWSTATUS* rgRowStatus = NULL); // InsertRow methods virtual HRESULT InsertRow(HROW* phRow); virtual HRESULT InsertRow(DBCOUNTITEM cRows, HROW* rghRow); virtual HRESULT InsertRow(HACCESSOR hAccessor, void* pData, HROW* phRow); virtual HRESULT CreateRowset(EQUERY eQuery = SELECT_ORDERBYNUMERIC, REFIID riid = IID_IRowset, CTable* pCTable = NULL, DBACCESSORFLAGS dwAccessorFlags = DBACCESSOR_ROWDATA, DBPART dwPart = DBPART_ALL, DWORD dwColsBound = UPDATEABLE_COLS_BOUND, ECOLUMNORDER eBindingOrder = FORWARD, ECOLS_BY_REF eColsByRef = NO_COLS_BY_REF, DBTYPE wTypeModifier = DBTYPE_EMPTY, BLOBTYPE dwBlobType = NO_BLOB_COLS); virtual HRESULT CreateRowset(DBPROPID dwProperty, EQUERY eQuery = SELECT_ORDERBYNUMERIC, REFIID riid = IID_IRowset, CTable* pCTable = NULL, DBACCESSORFLAGS dwAccessorFlags = DBACCESSOR_ROWDATA, DBPART dwPart = DBPART_ALL, DWORD dwColsBound = UPDATEABLE_COLS_BOUND, ECOLUMNORDER eBindingOrder = FORWARD, ECOLS_BY_REF eColsByRef = NO_COLS_BY_REF, DBTYPE wTypeModifier = DBTYPE_EMPTY, BLOBTYPE dwBlobType = NO_BLOB_COLS); virtual HRESULT CreateRowset(IUnknown* pIRowset, EQUERY eQuery = SELECT_ORDERBYNUMERIC, REFIID riid = IID_IRowset, CTable* pCTable = NULL, DBACCESSORFLAGS dwAccessorFlags = DBACCESSOR_ROWDATA, DBPART dwPart = DBPART_ALL, DWORD dwColsBound = UPDATEABLE_COLS_BOUND, ECOLUMNORDER eBindingOrder = FORWARD, ECOLS_BY_REF eColsByRef = NO_COLS_BY_REF, DBTYPE wTypeModifier = DBTYPE_EMPTY, BLOBTYPE dwBlobType = NO_BLOB_COLS); //Interface to private members virtual IRowsetChange* const pIRowsetChange(); protected: //Data IRowsetChange* m_pIRowsetChange; }; ////////////////////////////////////////////////////////////////// // Class CRowsetUpdate // // Conatins all the functionality of IRowsetUpdate as well as the // ability of CRowsetChange ////////////////////////////////////////////////////////////////// class CRowsetUpdate : public CRowsetChange { public: //contsructor CRowsetUpdate(WCHAR* pwszTestCaseName = INVALID(WCHAR*)); virtual ~CRowsetUpdate(); virtual BOOL Terminate(); //Wrappers virtual HRESULT HardDeleteRow(HROW hRow); virtual HRESULT HardDeleteRow(DBCOUNTITEM cRows, HROW* rghRow); //IRowsetUpdate::Update virtual HRESULT UpdateRow(HROW hRow); virtual HRESULT UpdateRow(DBCOUNTITEM cRows, HROW* rghRow, DBCOUNTITEM* pcUpdatedRows = NULL, HROW** prgUpdatedRows = NULL, DBROWSTATUS** prgRowStatus = NULL); virtual HRESULT UpdateAll(); //IRowsetUpdate::Undo virtual HRESULT UndoRow(HROW hRow); virtual HRESULT UndoRow(DBCOUNTITEM cRows,HROW* rghRow,DBCOUNTITEM* pcRowsUndone = NULL, HROW** prgRowsUndone = NULL, DBROWSTATUS** prgRowStatus = NULL); virtual HRESULT UndoAll(); //IRowsetUpdate::GetPendingRows virtual HRESULT GetPendingRows(DBCOUNTITEM PendingRows); virtual HRESULT GetPendingRows(DBPENDINGSTATUS RowStatus, DBCOUNTITEM PendingRows); virtual HRESULT GetPendingRows(DBPENDINGSTATUS RowStatus, DBCOUNTITEM PendingRows, DBPENDINGSTATUS PendingStatus); //IRowsetUpdate::GetOriginalData virtual HRESULT GetOriginalData(HROW hRow, void** ppData); virtual HRESULT GetOriginalData(DBCOUNTITEM cRows, HROW* rghRow, void** ppData); //IRowsetUpdate::GetRowStatus virtual HRESULT GetRowStatus(HROW hRow, DBROWSTATUS RowStatus); virtual HRESULT GetRowStatus(DBCOUNTITEM cRows , HROW* rghRow, DBROWSTATUS RowStatus); //helpers virtual BOOL CompareOrgRowData(HROW hRow); virtual BOOL CompareOrgStorageData(HROW hRow, HACCESSOR hAccessor, void* pBuffer); virtual HRESULT GetOrgStorageData(HROW hRow, HACCESSOR hAccessor, void* pBuffer = NULL, ULONG* pcBytes = NULL, REFIID riid = IID_IUnknown, IUnknown** ppIUnknown = NULL); virtual BOOL CompareWithDefaults(void* pData); virtual HRESULT CreateRowset(EQUERY eQuery = SELECT_ORDERBYNUMERIC, REFIID riid = IID_IRowset, CTable* pCTable = NULL, DBACCESSORFLAGS dwAccessorFlags = DBACCESSOR_ROWDATA, DBPART dwPart = DBPART_ALL, DWORD dwColsBound = UPDATEABLE_COLS_BOUND, ECOLUMNORDER eBindingOrder = FORWARD, ECOLS_BY_REF eColsByRef = NO_COLS_BY_REF, DBTYPE wTypeModifier = DBTYPE_EMPTY, BLOBTYPE dwBlobType = NO_BLOB_COLS); virtual HRESULT CreateRowset(DBPROPID dwProperty, EQUERY eQuery = SELECT_ORDERBYNUMERIC, REFIID riid = IID_IRowset, CTable* pCTable = NULL, DBACCESSORFLAGS dwAccessorFlags = DBACCESSOR_ROWDATA, DBPART dwPart = DBPART_ALL, DWORD dwColsBound = UPDATEABLE_COLS_BOUND, ECOLUMNORDER eBindingOrder = FORWARD, ECOLS_BY_REF eColsByRef = NO_COLS_BY_REF, DBTYPE wTypeModifier = DBTYPE_EMPTY, BLOBTYPE dwBlobType = NO_BLOB_COLS); virtual HRESULT CreateRowset(IUnknown* pIRowset, EQUERY eQuery = SELECT_ORDERBYNUMERIC, REFIID riid = IID_IRowset, CTable* pCTable = NULL, DBACCESSORFLAGS dwAccessorFlags = DBACCESSOR_ROWDATA, DBPART dwPart = DBPART_ALL, DWORD dwColsBound = UPDATEABLE_COLS_BOUND, ECOLUMNORDER eBindingOrder = FORWARD, ECOLS_BY_REF eColsByRef = NO_COLS_BY_REF, DBTYPE wTypeModifier = DBTYPE_EMPTY, BLOBTYPE dwBlobType = NO_BLOB_COLS); //Interface to private methods, can't modify virtual IRowsetUpdate* const pIRowsetUpdate(); virtual DBCOUNTITEM GetMaxPendingRows() { return m_ulMaxPendingRows; } virtual BOOL AllowPendingRows(DBCOUNTITEM cPendingRows) { return m_ulMaxPendingRows==0 || m_ulMaxPendingRows>=cPendingRows; } protected: //Data IRowsetUpdate* m_pIRowsetUpdate; DBCOUNTITEM m_ulMaxPendingRows; }; /////////////////////////////////////////////////////////////////////////////// // Class CListener // // Listens on the connections for notifications, (ie: a sink) ////////////////////////////////////////////////////////////////////////////// class CListener : public CBase { public: CListener(REFIID riid = IID_IUnknown, IUnknown* pIUnknown = NULL); virtual ~CListener(); //IUnknown DEFINE_QI_ADDREF_RELEASE; //Helpers virtual HRESULT Advise(DWORD* pdwCookie, IUnknown* pIUnknown = NULL, REFIID riid = IID_IUnknown); virtual HRESULT Unadvise(DWORD dwCookie, IUnknown* pIUnknown = NULL, REFIID riid = IID_IUnknown); virtual BOOL SetNotifications(BOOL bValue = TRUE) { m_bFire = bValue; return TRUE; } virtual BOOL SetCancel(DBREASON eReason, DBEVENTPHASE ePhase) { m_eCancelReason = eReason; m_eCancelPhase = ePhase; return TRUE; } virtual BOOL SetError(HRESULT hr) { m_hrReturn = hr; return TRUE; } virtual BOOL SetType(REFIID riid = IID_IUnknown) { m_iid = riid; return TRUE; } virtual BOOL WantedEvent(DBREASON eReason, DBEVENTPHASE ePhase); virtual BOOL SetEvent(DBREASON eReason, DBEVENTPHASE ePhase, BOOL bValue = TRUE); virtual BOOL SetAdvise(DBREASON eReason, DBEVENTPHASE ePhase) { m_eAdviseReason = eReason; m_eAdvisePhase = ePhase; return TRUE; } virtual BOOL SetUnadvise(DBREASON eReason, DBEVENTPHASE ePhase) { m_eUnadviseReason = eReason; m_eUnadvisePhase = ePhase; return TRUE; } virtual BOOL Restart(); virtual BOOL ResetTimesNotified(DBREASON eReason = DBREASON_ALL, DBEVENTPHASE ePhase = DBEVENTPHASE_ALL); virtual ULONG GetTimesNotified(DBREASON eReason = DBREASON_ALL, DBEVENTPHASE ePhase = DBEVENTPHASE_ALL); virtual BOOL IsCancelable(DBREASON eReason, DBEVENTPHASE ePhase, IUnknown* pIUnknown = NULL); virtual HRESULT CauseNotification(DBREASON eReason, IUnknown* pIUnknown = NULL); virtual BOOL SetReEntrantcy(DBREASON eReason, DBEVENTPHASE ePhase, void* pReEntrantFunc, void* pReEntrantData); virtual BOOL GetReEntrantcy(DBREASON eReason, DBEVENTPHASE ePhase, void** ppReEntrantFunc, void** ppReEntrantData); //Helpers virtual HRESULT AcceptOrVeto( IUnknown* pIUnknown, DBREASON eReason, // @parm IN | Reason for notification DBEVENTPHASE ePhase, // @parm IN | Phase of event BOOL fCantDeny); protected: //Data //OPTIONAL CImpIRowsetNotify* m_pCImpIRowsetNotify; CImpIDBAsynchNotify* m_pCImpIDBAsynchNotify; CImpIRowPositionChange* m_pCImpIRowPositionChange; DBREASON m_eCancelReason; // Weither to Cancel/Veto the notifcation DBEVENTPHASE m_eCancelPhase; // Weither to Cancel/Veto the notifcation DBREASON m_eAdviseReason; //Reason to advise another listener on DBEVENTPHASE m_eAdvisePhase; //Phase to advise another listener on DBREASON m_eUnadviseReason; //Reason to Unadvise another listener on DBEVENTPHASE m_eUnadvisePhase; //Phase to Unadvise another listener on HRESULT m_hrReturn; // Which HRESULT to return BOOL m_bFire; // Indicates weither to fire notifcations at all //2D array, of numer of times REASON / PHASE was notified ULONG m_rgNotified[DBREASON_ALL][DBEVENTPHASE_ALL]; //2D array, of which REASON / PHASE to fire ULONG m_rgEvent[DBREASON_ALL][DBEVENTPHASE_ALL]; DWORD m_dwCookie; //Reentrant Data DBREASON m_eReEntrantReason; DBEVENTPHASE m_eReEntrantPhase; void* m_pReEntrantFunc; // func to call within the listener void* m_pReEntrantData; //Source information (optional) IID m_iid; IUnknown* m_pIUnknown; }; //REENTRANT_ROWSETFUNC - function to be called from within a listener... typedef HRESULT (*REENTRANT_ROWSETFUNC) (CRowset* pCRowset, IRowset* pIRowset, DBCOUNTITEM cRows, const HROW rghRows[], DBORDINAL cColumns, const DBORDINAL rgColumns[]); //////////////////////////////////////////////////////// // CImpIRowsetNotify // //////////////////////////////////////////////////////// class CImpIRowsetNotify : public IRowsetNotify //@base public | IRowsetNotify { private: //@access private DEFINE_IUNKNOWN_MEMBER_DATA(CImpIRowsetNotify, IRowsetNotify) public: //@access public DEFINE_IUNKNOWN_CTOR_DTOR(CImpIRowsetNotify, IRowsetNotify); DEFINE_DELEGATING_QI_ADDREF_RELEASE; //IRowsetNotify virtual HRESULT STDMETHODCALLTYPE OnFieldChange( /* [in] */ IRowset __RPC_FAR *pRowset, /* [in] */ HROW hRow, /* [in] */ DBORDINAL cColumns, /* [size_is][in] */ DBORDINAL __RPC_FAR rgColumns[ ], /* [in] */ DBREASON eReason, /* [in] */ DBEVENTPHASE ePhase, /* [in] */ BOOL fCantDeny); virtual HRESULT STDMETHODCALLTYPE OnRowChange( /* [in] */ IRowset __RPC_FAR *pRowset, /* [in] */ DBCOUNTITEM cRows, /* [size_is][in] */ const HROW __RPC_FAR rghRows[ ], /* [in] */ DBREASON eReason, /* [in] */ DBEVENTPHASE ePhase, /* [in] */ BOOL fCantDeny); virtual HRESULT STDMETHODCALLTYPE OnRowsetChange( /* [in] */ IRowset __RPC_FAR *pRowset, /* [in] */ DBREASON eReason, /* [in] */ DBEVENTPHASE ePhase, /* [in] */ BOOL fCantDeny); //Helpers virtual HRESULT AcceptOrVeto( IRowset* pIRowset, DBREASON eReason, // @parm IN | Reason for notification DBEVENTPHASE ePhase, // @parm IN | Phase of event BOOL fCantDeny, DBCOUNTITEM cRows = 0, const HROW rghRows[] = NULL, DBORDINAL cColumns = 0, const DBORDINAL rgColumns[] = NULL ); protected: //data }; //////////////////////////////////////////////////////// // CImpIDBAsynchNotify // //////////////////////////////////////////////////////// class CImpIDBAsynchNotify : public IDBAsynchNotify //@base public | IDBAsynchNotify { private: //@access private DEFINE_IUNKNOWN_MEMBER_DATA(CImpIDBAsynchNotify, IDBAsynchNotify) public: //@access public DEFINE_IUNKNOWN_CTOR_DTOR(CImpIDBAsynchNotify, IDBAsynchNotify); DEFINE_DELEGATING_QI_ADDREF_RELEASE; //IDBAsynchNotify STDMETHOD(OnLowResource)( /* [in] */ DB_DWRESERVE dwReserved) ; STDMETHOD(OnProgress)( /* [in] */ HCHAPTER hChapter, /* [in] */ DBASYNCHOP ulOperation, /* [in] */ DBCOUNTITEM ulProgress, /* [in] */ DBCOUNTITEM ulProgressMax, /* [in] */ DBASYNCHPHASE ulAsynchPhase, /* [in] */ LPOLESTR pwszStatusText); STDMETHOD(OnStop)( /* [in] */ HCHAPTER hChapter, /* [in] */ DBASYNCHOP ulOperation, /* [in] */ HRESULT hrStatus, /* [in] */ LPOLESTR pwszStatusText); //Helpers virtual HRESULT AcceptOrVeto( HCHAPTER hChapter, DBASYNCHREASON eReason, DBASYNCHOP ulOperation, DBCOUNTITEM ulProgress, DBCOUNTITEM ulProgressMax, DBASYNCHPHASE ePhase, LPOLESTR pwszStatusText); protected: //Data }; //////////////////////////////////////////////////////// // CImpIRowPositionChange // //////////////////////////////////////////////////////// class CImpIRowPositionChange : public IRowPositionChange //@base public | IRowPositionChange { private: //@access private DEFINE_IUNKNOWN_MEMBER_DATA(CImpIRowPositionChange, IRowPositionChange) public: //@access public DEFINE_IUNKNOWN_CTOR_DTOR(CImpIRowPositionChange, IRowPositionChange); DEFINE_DELEGATING_QI_ADDREF_RELEASE; //IRowPositionChange STDMETHOD(OnRowPositionChange) ( DBREASON eReason, DBEVENTPHASE ePhase, BOOL fCantDeny ); protected: //Data }; #endif // _EXTRALIB_H_