// This is a part of the Active Template Library. // Copyright (C) 1996-1998 Microsoft Corporation // All rights reserved. // // This source code is only intended as a supplement to the // Active Template Library Reference and related // electronic documentation provided with the library. // See these sources for detailed information regarding the // Active Template Library product. #ifndef __ATLDB_H #define __ATLDB_H // OLE DB Provider Support // Interface Impl Classes // // Data Source Object // // -Mandatory Interfaces: // IDBCreateSession // IDBInitialize // IDBProperties // IPersist // // Session Object // // -Mandatory Interfaces: // IGetDataSource // IOpenRowset // ISessionProperties // // -Optional Interfaces: // IDBCreateCommand // IDBSchemaRowset // // Rowset Object // // -Mandatory Interfaces: // IAccessor // IColumnsInfo // IConvertType // IRowset // IRowsetInfo // // -Optional Interfaces: // IRowsetIdentity // // Command Object // // -Mandatory Interfaces: // ICommand) // IAccessor) // ICommandProperties // ICommandText - derives from ICommand // IColumnsInfo // IConvertType #include #include #include #include #include //Forwards template class CUtlPropInfo; class CColumnIds; // Additional Property Flag needed internally const int DBPROPFLAGS_CHANGE = 0x40000000; // ------------- STRUCTURE DEFINITIONS -------------------------------- struct UPROPVAL { DBPROPOPTIONS dwOption; CColumnIds* pCColumnIds; DWORD dwFlags; VARIANT vValue; }; struct UPROPINFO { DBPROPID dwPropId; ULONG ulIDS; VARTYPE VarType; DBPROPFLAGS dwFlags; union { DWORD_PTR dwVal; LPOLESTR szVal; }; DBPROPOPTIONS dwOption; }; struct UPROP { ULONG cPropIds; UPROPINFO** rgpUPropInfo; UPROPVAL* pUPropVal; }; struct PROPCOLID { DBID dbidProperty; // The column id information DBPROPOPTIONS dwOption; VARIANT vValue; }; typedef PROPCOLID* PPROPCOLID; struct UPROPSET { const GUID* pPropSet; ULONG cUPropInfo; UPROPINFO* pUPropInfo; DWORD dwFlags; }; struct ATLBINDINGS { DBBINDING* pBindings; DWORD dwRef; DBCOUNTITEM cBindings; DBACCESSORFLAGS dwAccessorFlags; }; struct ATLCOLUMNINFO { LPOLESTR pwszName; ITypeInfo *pTypeInfo; DBORDINAL iOrdinal; DBCOLUMNFLAGS dwFlags; DBLENGTH ulColumnSize; DBTYPE wType; BYTE bPrecision; BYTE bScale; DBID columnid; DBBYTEOFFSET cbOffset; }; // // The following very large sections of defines are to implement auto determination // of Preoperty map constants based on a stringized prop name. There is one set for // Type (VT_), one for Init Value, and one for Property flags. // #define ABORTPRESERVE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define ACTIVESESSIONS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define APPENDONLY_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define ASYNCTXNABORT_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define ASYNCTXNCOMMIT_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define AUTH_CACHE_AUTHINFO_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define AUTH_ENCRYPT_PASSWORD_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define AUTH_INTEGRATED_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define AUTH_MASK_PASSWORD_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define AUTH_PASSWORD_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define AUTH_PERSIST_ENCRYPTED_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define AUTH_PERSIST_SENSITIVE_AUTHINFO_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define AUTH_USERID_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define BLOCKINGSTORAGEOBJECTS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define BOOKMARKS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define BOOKMARKSKIPPED_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define BOOKMARKTYPE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define BYREFACCESSORS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define CACHEDEFERRED_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define CANFETCHBACKWARDS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define CANHOLDROWS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define CANSCROLLBACKWARDS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define CATALOGLOCATION_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define CATALOGTERM_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define CATALOGUSAGE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define CHANGEINSERTEDROWS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_CHANGE ) #define COL_AUTOINCREMENT_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define COL_DEFAULT_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define COL_DESCRIPTION_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define COL_FIXEDLENGTH_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define COL_NULLABLE_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define COL_PRIMARYKEY_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define COL_UNIQUE_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define COLUMNDEFINITION_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define COLUMNRESTRICT_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define COMMANDTIMEOUT_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define COMMITPRESERVE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define CONCATNULLBEHAVIOR_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define CURRENTCATALOG_Flags ( DBPROPFLAGS_DATASOURCE | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define DATASOURCENAME_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define DATASOURCEREADONLY_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define DBMSNAME_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define DBMSVER_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define DEFERRED_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define DELAYSTORAGEOBJECTS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define DSOTHREADMODEL_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define GROUPBY_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define HETEROGENEOUSTABLES_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define IAccessor_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define IColumnsInfo_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define IColumnsRowset_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define IConnectionPointContainer_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define IConvertType_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define IRowset_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define IRowsetChange_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define IRowsetIdentity_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define IRowsetIndex_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define IRowsetInfo_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define IRowsetLocate_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define IRowsetResynch_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define IRowsetScroll_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define IRowsetUpdate_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define ISupportErrorInfo_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define ILockBytes_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define ISequentialStream_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define IStorage_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define IStream_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define IDENTIFIERCASE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define IMMOBILEROWS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INDEX_AUTOUPDATE_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INDEX_CLUSTERED_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INDEX_FILLFACTOR_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INDEX_INITIALSIZE_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INDEX_NULLCOLLATION_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INDEX_NULLS_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INDEX_PRIMARYKEY_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INDEX_SORTBOOKMARKS_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INDEX_TEMPINDEX_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INDEX_TYPE_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INDEX_UNIQUE_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INIT_DATASOURCE_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INIT_HWND_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INIT_IMPERSONATION_LEVEL_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INIT_LCID_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INIT_LOCATION_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INIT_MODE_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INIT_PROMPT_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INIT_PROTECTION_LEVEL_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INIT_PROVIDERSTRING_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define INIT_TIMEOUT_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define LITERALBOOKMARKS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define LITERALIDENTITY_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define MAXINDEXSIZE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define MAXOPENROWS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define MAXPENDINGROWS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define MAXROWS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define MAXROWSIZE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define MAXROWSIZEINCLUDESBLOB_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define MAXTABLESINSELECT_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define MAYWRITECOLUMN_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define MEMORYUSAGE_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define MULTIPLEPARAMSETS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define MULTIPLERESULTS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define MULTIPLESTORAGEOBJECTS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define MULTITABLEUPDATE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define NOTIFICATIONPHASES_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define NOTIFYCOLUMNSET_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define NOTIFYROWDELETE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define NOTIFYROWFIRSTCHANGE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define NOTIFYROWINSERT_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define NOTIFYROWRESYNCH_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define NOTIFYROWSETRELEASE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define NOTIFYROWSETFETCHPOSITIONCHANGE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define NOTIFYROWUNDOCHANGE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define NOTIFYROWUNDODELETE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define NOTIFYROWUNDOINSERT_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define NOTIFYROWUPDATE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define NULLCOLLATION_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define OLEOBJECTS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define ORDERBYCOLUMNSINSELECT_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define ORDEREDBOOKMARKS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define OTHERINSERT_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define OTHERUPDATEDELETE_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define OUTPUTPARAMETERAVAILABILITY_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define OWNINSERT_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define OWNUPDATEDELETE_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define PERSISTENTIDTYPE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define PREPAREABORTBEHAVIOR_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define PREPARECOMMITBEHAVIOR_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define PROCEDURETERM_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define PROVIDERNAME_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define PROVIDEROLEDBVER_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define PROVIDERVER_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define QUICKRESTART_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define QUOTEDIDENTIFIERCASE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define REENTRANTEVENTS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define REMOVEDELETED_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define REPORTMULTIPLECHANGES_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_CHANGE ) #define RETURNPENDINGINSERTS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define ROWRESTRICT_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define ROWSETCONVERSIONSONCOMMAND_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define ROWTHREADMODEL_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define SCHEMATERM_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define SCHEMAUSAGE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define SERVERCURSOR_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define SESS_AUTOCOMMITISOLEVELS_Flags ( DBPROPFLAGS_SESSION | DBPROPFLAGS_READ ) #define SQLSUPPORT_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define STRONGIDENTITY_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define STRUCTUREDSTORAGE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define SUBQUERIES_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define SUPPORTEDTXNDDL_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define SUPPORTEDTXNISOLEVELS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define SUPPORTEDTXNISORETAIN_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define TABLETERM_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define TBL_TEMPTABLE_Flags ( DBPROPFLAGS_TABLE | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define TRANSACTEDOBJECT_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ ) #define UPDATABILITY_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) #define USERNAME_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ ) #define ABORTPRESERVE_Type VT_BOOL #define ACTIVESESSIONS_Type VT_I4 #define APPENDONLY_Type VT_BOOL #define ASYNCTXNABORT_Type VT_BOOL #define ASYNCTXNCOMMIT_Type VT_BOOL #define AUTH_CACHE_AUTHINFO_Type VT_BOOL #define AUTH_ENCRYPT_PASSWORD_Type VT_BOOL #define AUTH_INTEGRATED_Type VT_BSTR #define AUTH_MASK_PASSWORD_Type VT_BOOL #define AUTH_PASSWORD_Type VT_BSTR #define AUTH_PERSIST_ENCRYPTED_Type VT_BOOL #define AUTH_PERSIST_SENSITIVE_AUTHINFO_Type VT_BOOL #define AUTH_USERID_Type VT_BSTR #define BLOCKINGSTORAGEOBJECTS_Type VT_BOOL #define BOOKMARKS_Type VT_BOOL #define BOOKMARKSKIPPED_Type VT_BOOL #define BOOKMARKTYPE_Type VT_I4 #define BYREFACCESSORS_Type VT_BOOL #define CACHEDEFERRED_Type VT_BOOL #define CANFETCHBACKWARDS_Type VT_BOOL #define CANHOLDROWS_Type VT_BOOL #define CANSCROLLBACKWARDS_Type VT_BOOL #define CATALOGLOCATION_Type VT_I4 #define CATALOGTERM_Type VT_BSTR #define CATALOGUSAGE_Type VT_I4 #define CHANGEINSERTEDROWS_Type VT_BOOL #define COL_AUTOINCREMENT_Type VT_BOOL #define COL_DEFAULT_Type VT_BSTR #define COL_DESCRIPTION_Type VT_BSTR #define COL_FIXEDLENGTH_Type VT_BOOL #define COL_NULLABLE_Type VT_BOOL #define COL_PRIMARYKEY_Type VT_BOOL #define COL_UNIQUE_Type VT_BOOL #define COLUMNDEFINITION_Type VT_I4 #define COLUMNRESTRICT_Type VT_BOOL #define COMMANDTIMEOUT_Type VT_I4 #define COMMITPRESERVE_Type VT_BOOL #define CONCATNULLBEHAVIOR_Type VT_I4 #define CURRENTCATALOG_Type VT_BSTR #define DATASOURCENAME_Type VT_BSTR #define DATASOURCEREADONLY_Type VT_BOOL #define DBMSNAME_Type VT_BSTR #define DBMSVER_Type VT_BSTR #define DEFERRED_Type VT_BOOL #define DELAYSTORAGEOBJECTS_Type VT_BOOL #define DSOTHREADMODEL_Type VT_I4 #define GROUPBY_Type VT_I4 #define HETEROGENEOUSTABLES_Type VT_I4 #define IAccessor_Type VT_BOOL #define IColumnsInfo_Type VT_BOOL #define IColumnsRowset_Type VT_BOOL #define IConnectionPointContainer_Type VT_BOOL #define IConvertType_Type VT_BOOL #define IRowset_Type VT_BOOL #define IRowsetChange_Type VT_BOOL #define IRowsetIdentity_Type VT_BOOL #define IRowsetIndex_Type VT_BOOL #define IRowsetInfo_Type VT_BOOL #define IRowsetLocate_Type VT_BOOL #define IRowsetResynch_Type VT_BOOL #define IRowsetScroll_Type VT_BOOL #define IRowsetUpdate_Type VT_BOOL #define ISupportErrorInfo_Type VT_BOOL #define ILockBytes_Type VT_BOOL #define ISequentialStream_Type VT_BOOL #define IStorage_Type VT_BOOL #define IStream_Type VT_BOOL #define IDENTIFIERCASE_Type VT_I4 #define IMMOBILEROWS_Type VT_BOOL #define INDEX_AUTOUPDATE_Type VT_BOOL #define INDEX_CLUSTERED_Type VT_BOOL #define INDEX_FILLFACTOR_Type VT_I4 #define INDEX_INITIALSIZE_Type VT_I4 #define INDEX_NULLCOLLATION_Type VT_I4 #define INDEX_NULLS_Type VT_I4 #define INDEX_PRIMARYKEY_Type VT_BOOL #define INDEX_SORTBOOKMARKS_Type VT_BOOL #define INDEX_TEMPINDEX_Type VT_BOOL #define INDEX_TYPE_Type VT_I4 #define INDEX_UNIQUE_Type VT_BOOL #define INIT_DATASOURCE_Type VT_BSTR #define INIT_HWND_Type VT_I4 #define INIT_IMPERSONATION_LEVEL_Type VT_I4 #define INIT_LCID_Type VT_I4 #define INIT_LOCATION_Type VT_BSTR #define INIT_MODE_Type VT_I4 #define INIT_PROMPT_Type VT_I2 #define INIT_PROTECTION_LEVEL_Type VT_I4 #define INIT_PROVIDERSTRING_Type VT_BSTR #define INIT_TIMEOUT_Type VT_I4 #define LITERALBOOKMARKS_Type VT_BOOL #define LITERALIDENTITY_Type VT_BOOL #define MAXINDEXSIZE_Type VT_I4 #define MAXOPENROWS_Type VT_I4 #define MAXPENDINGROWS_Type VT_I4 #define MAXROWS_Type VT_I4 #define MAXROWSIZE_Type VT_I4 #define MAXROWSIZEINCLUDESBLOB_Type VT_BOOL #define MAXTABLESINSELECT_Type VT_I4 #define MAYWRITECOLUMN_Type VT_BOOL #define MEMORYUSAGE_Type VT_I4 #define MULTIPLEPARAMSETS_Type VT_BOOL #define MULTIPLERESULTS_Type VT_I4 #define MULTIPLESTORAGEOBJECTS_Type VT_BOOL #define MULTITABLEUPDATE_Type VT_BOOL #define NOTIFICATIONPHASES_Type VT_I4 #define NOTIFYCOLUMNSET_Type VT_I4 #define NOTIFYROWDELETE_Type VT_I4 #define NOTIFYROWFIRSTCHANGE_Type VT_I4 #define NOTIFYROWINSERT_Type VT_I4 #define NOTIFYROWRESYNCH_Type VT_I4 #define NOTIFYROWSETRELEASE_Type VT_I4 #define NOTIFYROWSETFETCHPOSITIONCHANGE_Type VT_I4 #define NOTIFYROWUNDOCHANGE_Type VT_I4 #define NOTIFYROWUNDODELETE_Type VT_I4 #define NOTIFYROWUNDOINSERT_Type VT_I4 #define NOTIFYROWUPDATE_Type VT_I4 #define NULLCOLLATION_Type VT_I4 #define OLEOBJECTS_Type VT_I4 #define ORDERBYCOLUMNSINSELECT_Type VT_BOOL #define ORDEREDBOOKMARKS_Type VT_BOOL #define OTHERINSERT_Type VT_BOOL #define OTHERUPDATEDELETE_Type VT_BOOL #define OUTPUTPARAMETERAVAILABILITY_Type VT_I4 #define OWNINSERT_Type VT_BOOL #define OWNUPDATEDELETE_Type VT_BOOL #define PERSISTENTIDTYPE_Type VT_I4 #define PREPAREABORTBEHAVIOR_Type VT_I4 #define PREPARECOMMITBEHAVIOR_Type VT_I4 #define PROCEDURETERM_Type VT_BSTR #define PROVIDERNAME_Type VT_BSTR #define PROVIDEROLEDBVER_Type VT_BSTR #define PROVIDERVER_Type VT_BSTR #define QUICKRESTART_Type VT_BOOL #define QUOTEDIDENTIFIERCASE_Type VT_I4 #define REENTRANTEVENTS_Type VT_BOOL #define REMOVEDELETED_Type VT_BOOL #define REPORTMULTIPLECHANGES_Type VT_BOOL #define RETURNPENDINGINSERTS_Type VT_BOOL #define ROWRESTRICT_Type VT_BOOL #define ROWSETCONVERSIONSONCOMMAND_Type VT_BOOL #define ROWTHREADMODEL_Type VT_I4 #define SCHEMATERM_Type VT_BSTR #define SCHEMAUSAGE_Type VT_I4 #define SERVERCURSOR_Type VT_BOOL #define SESS_AUTOCOMMITISOLEVELS_Type VT_I4 #define SQLSUPPORT_Type VT_I4 #define STRONGIDENTITY_Type VT_BOOL #define STRUCTUREDSTORAGE_Type VT_I4 #define SUBQUERIES_Type VT_I4 #define SUPPORTEDTXNDDL_Type VT_I4 #define SUPPORTEDTXNISOLEVELS_Type VT_I4 #define SUPPORTEDTXNISORETAIN_Type VT_I4 #define TABLETERM_Type VT_BSTR #define TBL_TEMPTABLE_Type VT_BOOL #define TRANSACTEDOBJECT_Type VT_BOOL #define UPDATABILITY_Type VT_I4 #define USERNAME_Type VT_BSTR #define ABORTPRESERVE_Value VARIANT_FALSE #define ACTIVESESSIONS_Value 0 #define APPENDONLY_Value VARIANT_FALSE #define ASYNCTXNABORT_Value VARIANT_FALSE #define ASYNCTXNCOMMIT_Value VARIANT_FALSE #define AUTH_CACHE_AUTHINFO_Value VARIANT_FALSE #define AUTH_ENCRYPT_PASSWORD_Value VARIANT_FALSE #define AUTH_INTEGRATED_Value OLESTR("") #define AUTH_MASK_PASSWORD_Value VARIANT_FALSE #define AUTH_PASSWORD_Value OLESTR("") #define AUTH_PERSIST_ENCRYPTED_Value VARIANT_FALSE #define AUTH_PERSIST_SENSITIVE_AUTHINFO_Value VARIANT_FALSE #define AUTH_USERID_Value OLESTR("") #define BLOCKINGSTORAGEOBJECTS_Value VARIANT_FALSE #define BOOKMARKS_Value VARIANT_FALSE #define BOOKMARKSKIPPED_Value VARIANT_FALSE #define BOOKMARKTYPE_Value 0 #define BYREFACCESSORS_Value VARIANT_FALSE #define CACHEDEFERRED_Value VARIANT_FALSE #define CANFETCHBACKWARDS_Value VARIANT_TRUE #define CANHOLDROWS_Value VARIANT_TRUE #define CANSCROLLBACKWARDS_Value VARIANT_TRUE #define CATALOGLOCATION_Value 0 #define CATALOGTERM_Value OLESTR("") #define CATALOGUSAGE_Value 0 #define CHANGEINSERTEDROWS_Value VARIANT_FALSE #define COL_AUTOINCREMENT_Value VARIANT_FALSE #define COL_DEFAULT_Value OLESTR("") #define COL_DESCRIPTION_Value OLESTR("") #define COL_FIXEDLENGTH_Value VARIANT_FALSE #define COL_NULLABLE_Value VARIANT_FALSE #define COL_PRIMARYKEY_Value VARIANT_FALSE #define COL_UNIQUE_Value VARIANT_FALSE #define COLUMNDEFINITION_Value 0 #define COLUMNRESTRICT_Value VARIANT_FALSE #define COMMANDTIMEOUT_Value 0 #define COMMITPRESERVE_Value VARIANT_FALSE #define CONCATNULLBEHAVIOR_Value 0 #define CURRENTCATALOG_Value OLESTR("") #define DATASOURCENAME_Value OLESTR("") #define DATASOURCEREADONLY_Value VARIANT_TRUE #define DBMSNAME_Value OLESTR("") #define DBMSVER_Value OLESTR("") #define DEFERRED_Value VARIANT_FALSE #define DELAYSTORAGEOBJECTS_Value VARIANT_FALSE #define DSOTHREADMODEL_Value DBPROPVAL_RT_APTMTTHREAD #define GROUPBY_Value 0 #define HETEROGENEOUSTABLES_Value 0 #define IAccessor_Value VARIANT_TRUE #define IColumnsInfo_Value VARIANT_TRUE #define IColumnsRowset_Value VARIANT_FALSE #define IConnectionPointContainer_Value VARIANT_FALSE #define IConvertType_Value VARIANT_TRUE #define IRowset_Value VARIANT_TRUE #define IRowsetChange_Value VARIANT_FALSE #define IRowsetIdentity_Value VARIANT_TRUE #define IRowsetIndex_Value VARIANT_FALSE #define IRowsetInfo_Value VARIANT_TRUE #define IRowsetLocate_Value VARIANT_FALSE #define IRowsetResynch_Value VARIANT_FALSE #define IRowsetScroll_Value VARIANT_FALSE #define IRowsetUpdate_Value VARIANT_FALSE #define ISupportErrorInfo_Value VARIANT_FALSE #define ILockBytes_Value VARIANT_FALSE #define ISequentialStream_Value VARIANT_FALSE #define IStorage_Value VARIANT_FALSE #define IStream_Value VARIANT_FALSE #define IDENTIFIERCASE_Value 0 #define IMMOBILEROWS_Value VARIANT_FALSE #define INDEX_AUTOUPDATE_Value VARIANT_FALSE #define INDEX_CLUSTERED_Value VARIANT_FALSE #define INDEX_FILLFACTOR_Value 0 #define INDEX_INITIALSIZE_Value 0 #define INDEX_NULLCOLLATION_Value 0 #define INDEX_NULLS_Value 0 #define INDEX_PRIMARYKEY_Value VARIANT_FALSE #define INDEX_SORTBOOKMARKS_Value VARIANT_FALSE #define INDEX_TEMPINDEX_Value VARIANT_FALSE #define INDEX_TYPE_Value 0 #define INDEX_UNIQUE_Value VARIANT_FALSE #define INIT_DATASOURCE_Value OLESTR("") #define INIT_HWND_Value 0 #define INIT_IMPERSONATION_LEVEL_Value 0 #define INIT_LCID_Value 0 #define INIT_LOCATION_Value OLESTR("") #define INIT_MODE_Value 0 #define INIT_PROMPT_Value VT_I2 #define INIT_PROTECTION_LEVEL_Value 0 #define INIT_PROVIDERSTRING_Value OLESTR("") #define INIT_TIMEOUT_Value 0 #define LITERALBOOKMARKS_Value VARIANT_FALSE #define LITERALIDENTITY_Value VARIANT_FALSE #define MAXINDEXSIZE_Value 0 #define MAXOPENROWS_Value 0 #define MAXPENDINGROWS_Value 0 #define MAXROWS_Value 0 #define MAXROWSIZE_Value 0 #define MAXROWSIZEINCLUDESBLOB_Value VARIANT_FALSE #define MAXTABLESINSELECT_Value 0 #define MAYWRITECOLUMN_Value VARIANT_FALSE #define MEMORYUSAGE_Value 0 #define MULTIPLEPARAMSETS_Value VARIANT_FALSE #define MULTIPLERESULTS_Value 0 #define MULTIPLESTORAGEOBJECTS_Value VARIANT_FALSE #define MULTITABLEUPDATE_Value VARIANT_FALSE #define NOTIFICATIONPHASES_Value 0 #define NOTIFYCOLUMNSET_Value 0 #define NOTIFYROWDELETE_Value 0 #define NOTIFYROWFIRSTCHANGE_Value 0 #define NOTIFYROWINSERT_Value 0 #define NOTIFYROWRESYNCH_Value 0 #define NOTIFYROWSETRELEASE_Value 0 #define NOTIFYROWSETFETCHPOSITIONCHANGE_Value 0 #define NOTIFYROWUNDOCHANGE_Value 0 #define NOTIFYROWUNDODELETE_Value 0 #define NOTIFYROWUNDOINSERT_Value 0 #define NOTIFYROWUPDATE_Value 0 #define NULLCOLLATION_Value 0 #define OLEOBJECTS_Value 0 #define ORDERBYCOLUMNSINSELECT_Value VARIANT_FALSE #define ORDEREDBOOKMARKS_Value VARIANT_FALSE #define OTHERINSERT_Value VARIANT_FALSE #define OTHERUPDATEDELETE_Value VARIANT_FALSE #define OUTPUTPARAMETERAVAILABILITY_Value 0 #define OWNINSERT_Value VARIANT_FALSE #define OWNUPDATEDELETE_Value VARIANT_FALSE #define PERSISTENTIDTYPE_Value 0 #define PREPAREABORTBEHAVIOR_Value 0 #define PREPARECOMMITBEHAVIOR_Value 0 #define PROCEDURETERM_Value OLESTR("") #define PROVIDERNAME_Value OLESTR("") #define PROVIDEROLEDBVER_Value OLESTR("2.0") #define PROVIDERVER_Value OLESTR("") #define QUICKRESTART_Value VARIANT_FALSE #define QUOTEDIDENTIFIERCASE_Value 0 #define REENTRANTEVENTS_Value VARIANT_FALSE #define REMOVEDELETED_Value VARIANT_FALSE #define REPORTMULTIPLECHANGES_Value VARIANT_FALSE #define RETURNPENDINGINSERTS_Value VARIANT_FALSE #define ROWRESTRICT_Value VARIANT_FALSE #define ROWSETCONVERSIONSONCOMMAND_Value VARIANT_TRUE #define ROWTHREADMODEL_Value 0 #define SCHEMATERM_Value OLESTR("") #define SCHEMAUSAGE_Value 0 #define SERVERCURSOR_Value VARIANT_FALSE #define SESS_AUTOCOMMITISOLEVELS_Value 0 #define SQLSUPPORT_Value 0 #define STRONGIDENTITY_Value VARIANT_FALSE #define STRUCTUREDSTORAGE_Value 0 #define SUBQUERIES_Value 0 #define SUPPORTEDTXNDDL_Value 0 #define SUPPORTEDTXNISOLEVELS_Value 0 #define SUPPORTEDTXNISORETAIN_Value 0 #define TABLETERM_Value OLESTR("") #define TBL_TEMPTABLE_Value VARIANT_FALSE #define TRANSACTEDOBJECT_Value VARIANT_FALSE #define UPDATABILITY_Value 0 #define USERNAME_Value OLESTR("") #define OUT_OF_LINE virtual #define BEGIN_PROPSET_MAP(Class) \ static UPROPSET* _GetPropSet(ULONG* pNumPropSets, ULONG* pcElemPerSupported, UPROPSET* pSet = NULL, GUID* pguidSet = (GUID*)&(GUID_NULL)) \ { \ typedef Class _PropSetClass; \ ULONG& cElemsMax = *pcElemPerSupported; \ cElemsMax = 0; \ int nCurProp = 0; \ int cRemainder = 0; \ cRemainder; #define BEGIN_PROPERTY_SET_EX(guid, flags) \ if (pNumPropSets != NULL) \ { \ pSet[nCurProp].pPropSet = &guid; \ pSet[nCurProp].dwFlags = flags; \ } \ static const UPROPINFO aProperty##guid[] = \ { #define BEGIN_PROPERTY_SET(guid) BEGIN_PROPERTY_SET_EX(guid, 0) #define PROPERTY_INFO_ENTRY_EX(dwPropID, vt, dwFlags, value, options) DBPROP_##dwPropID, IDS_DBPROP_##dwPropID, vt, dwFlags, (DWORD_PTR)value, (DBPROPOPTIONS)options, #define PROPERTY_INFO_ENTRY_VALUE(dwPropID, value) PROPERTY_INFO_ENTRY_EX(dwPropID, dwPropID##_Type, ##dwPropID##_Flags, value, 0) #define PROPERTY_INFO_ENTRY(dwPropID) PROPERTY_INFO_ENTRY_VALUE(dwPropID, dwPropID##_Value) #define END_PROPERTY_SET(guid) \ }; \ if (pNumPropSets != NULL) \ { \ pSet[nCurProp].pUPropInfo = (UPROPINFO*)aProperty##guid; \ pSet[nCurProp].cUPropInfo = sizeof(aProperty##guid) / sizeof(UPROPINFO); \ cRemainder = (pSet[nCurProp].cUPropInfo % 32) ? 1 : 0; \ if (cElemsMax < (pSet[nCurProp].cUPropInfo / 32 + cRemainder)) \ { \ cElemsMax = (pSet[nCurProp].cUPropInfo / 32 + cRemainder); \ } \ } \ nCurProp++; #define CHAIN_PROPERTY_SET(ChainClass) \ ULONG cPropSets##ChainClass, cElsSupported##ChainClass; \ int cSets##ChainClass = (int)(DWORD_PTR)ChainClass::_GetPropSet(NULL, &cElsSupported##ChainClass); \ if (pNumPropSets != NULL) \ { \ UPROPSET* pSetA = (UPROPSET*)_alloca(sizeof(UPROPSET)*cSets##ChainClass); \ UPROPSET* pSetTemp = ChainClass::_GetPropSet(&cPropSets##ChainClass, &cElsSupported##ChainClass, pSetA); \ cElemsMax = (cElemsMax < cElsSupported##ChainClass) ? cElsSupported##ChainClass : cElemsMax; \ ATLASSERT(pSetTemp); \ for (ULONG iSet = nCurProp; iSet < nCurProp+cPropSets##ChainClass; iSet++) \ { \ pSet[iSet].pPropSet = pSetTemp[iSet-nCurProp].pPropSet; \ pSet[iSet].dwFlags = pSetTemp[iSet-nCurProp].dwFlags; \ pSet[iSet].pUPropInfo = pSetTemp[iSet-nCurProp].pUPropInfo; \ pSet[iSet].cUPropInfo = pSetTemp[iSet-nCurProp].cUPropInfo; \ } \ } \ nCurProp += cSets##ChainClass; #define END_PROPSET_MAP() \ if (pNumPropSets != NULL) \ { \ if (IsEqualGUID(*pguidSet, GUID_NULL)) \ { \ *pNumPropSets = nCurProp; \ return pSet; \ } \ else \ { \ *pNumPropSets = 1; \ UINT i = 0; \ for (; i < sizeof(pSet)/sizeof(UPROPSET) && IsEqualGUID(*(pSet[i].pPropSet), *pguidSet); i++); \ return (i == sizeof(pSet)/sizeof(UPROPSET)) ? &pSet[0] : &pSet[i]; \ } \ } \ return (UPROPSET*)(DWORD_PTR)nCurProp; \ } // For DataSource flags IDBInitialize::m_dwStatus enum DATASOURCE_FLAGS { DSF_MASK_INIT = 0xFFFFF00F, // Mask for stuff lasting over init/uninit. DSF_PERSIST_DIRTY = 0x00000001, // Set if init string changes. DSF_INITIALIZED = 0x00000010, // Have we been initialized. }; #define DBID_USE_GUID_OR_PGUID(e) \ ((1<<(e)) & \ ( 1<> 5) // dw / 32 = dw / (sizeof(DWORD)*8) #define ModDword(dw) (dw & (32-1)) // dw % 32 #define DwordSizeofBits(nBits) (nBits/32+1) // Use in array declarations #define CLEARBITARRAY( rgdwFlags ) memset( rgdwFlags, 0, sizeof(rgdwFlags) ) template BOOL InRange(T& val, T& valMin, T& valMax) { return ( valMin <= val && val <= valMax ); } // Implementation Class class CBitFieldOps { public: void SETBIT( DWORD rgdwFlags[], const DWORD dwBit ) { rgdwFlags[DivDword(dwBit)] |= 1 << ModDword(dwBit); } void CLEARBIT( DWORD rgdwFlags[], const DWORD dwBit ) { rgdwFlags[DivDword(dwBit)] &= ~( 1 << ModDword(dwBit) ); } DWORD TESTBIT( const DWORD rgdwFlags[], const DWORD dwBit ) { //old//Note: Not {0,1}, but from {0...2^32-1}. // Note: Now returns {0,1}. return ( rgdwFlags[DivDword(dwBit)] & ( 1 << ModDword(dwBit) ) ) != 0; } }; // Implementation Class class CDBIDOps { public: HRESULT CompareDBIDs(const DBID* pdbid1, const DBID* pdbid2) { // Array of valid eKind matches, in addition to matching exactly. static BYTE s_rgbKind[] = { DBKIND_PGUID_NAME, // DBKIND_GUID_NAME DBKIND_PGUID_PROPID, // DBKIND_GUID_PROPID DBKIND_NAME, // DBKIND_NAME DBKIND_GUID_NAME, // DBKIND_PGUID_NAME DBKIND_GUID_PROPID, // DBKIND_PGUID_PROPID DBKIND_PROPID, // DBKIND_PROPID DBKIND_GUID // DBKIND_GUID }; if( !pdbid1 || !pdbid2 ) return S_FALSE; // Assume a match, and discard early if we can. if (!InRange(pdbid2->eKind, (DWORD)0, (DWORD)(sizeof(s_rgbKind)/sizeof(*s_rgbKind)))) { ATLTRACE2(atlTraceDBProvider, 0, "Column ID out of Range\n"); return E_FAIL; } if (pdbid1->eKind != pdbid2->eKind && pdbid1->eKind != s_rgbKind[pdbid2->eKind]) return S_FALSE; if (DBID_USE_GUID_OR_PGUID(pdbid1->eKind)) { if (!DBID_USE_GUID_OR_PGUID(pdbid2->eKind)) return S_FALSE; // Compare GUIDs. // Note that _GUID_ is equivalent to _PGUID_. if (!InlineIsEqualGUID( DBID_USE_PGUID(pdbid1->eKind) ? *(pdbid1->uGuid.pguid) : pdbid1->uGuid.guid, DBID_USE_PGUID(pdbid2->eKind) ? *(pdbid2->uGuid.pguid) : pdbid2->uGuid.guid )) return S_FALSE; } if (DBID_USE_NAME(pdbid1->eKind)) { if (!DBID_USE_NAME(pdbid2->eKind)) return S_FALSE; // Compare names. // Need to check if 1 is null and the other is not. if ( ((pdbid1->uName.pwszName == NULL) && (pdbid2->uName.pwszName != NULL)) || ((pdbid1->uName.pwszName != NULL) && (pdbid2->uName.pwszName == NULL)) ) return S_FALSE; // Since the above check does not rule out both being null, which is // a valid comparison, and wcscmp will GPF if they were, we need // to check for valid pointers if( pdbid1->uName.pwszName && pdbid2->uName.pwszName ) { // Assume null-terminated. // Assume LCID match is OK (note diff with lstrcmp(), CompareString().) if (wcscmp(pdbid1->uName.pwszName, pdbid2->uName.pwszName) != 0) return S_FALSE; } } if (DBID_USE_PROPID(pdbid1->eKind)) { if (!DBID_USE_PROPID(pdbid2->eKind)) return S_FALSE; // Compare PROPID. if (pdbid1->uName.ulPropid != pdbid2->uName.ulPropid) return S_FALSE; } // No reason to discard, so must have matched each field successfully. return S_OK; } static HRESULT IsValidDBID(const DBID* pdbid1) { ATLASSERT( pdbid1 ); if( pdbid1 && ((pdbid1->eKind == DBKIND_GUID_NAME) || (pdbid1->eKind == DBKIND_GUID_PROPID) || (pdbid1->eKind == DBKIND_NAME) || (pdbid1->eKind == DBKIND_PGUID_NAME) || (pdbid1->eKind == DBKIND_PGUID_PROPID) || (pdbid1->eKind == DBKIND_PROPID) || (pdbid1->eKind == DBKIND_GUID)) ) return S_OK; else return S_FALSE; } HRESULT CopyDBIDs(DBID* pdbidDest, const DBID* pdbidSrc) { size_t cwchBuffer; ATLASSERT( pdbidDest || pdbidSrc ); if( !pdbidDest || !pdbidSrc ) return S_FALSE; // Save eKind pdbidDest->eKind = pdbidSrc->eKind; switch( pdbidSrc->eKind ) { case DBKIND_GUID_NAME: pdbidDest->uGuid.guid = pdbidSrc->uGuid.guid; cwchBuffer = ocslen(pdbidSrc->uName.pwszName); cwchBuffer++; pdbidDest->uName.pwszName = (PWSTR)CoTaskMemAlloc(cwchBuffer * sizeof(WCHAR)); if( pdbidDest->uName.pwszName ) memcpy(pdbidDest->uName.pwszName, pdbidSrc->uName.pwszName, cwchBuffer*sizeof(WCHAR)); else return E_OUTOFMEMORY; break; case DBKIND_GUID_PROPID: pdbidDest->uGuid.guid = pdbidSrc->uGuid.guid; pdbidDest->uName.ulPropid = pdbidSrc->uName.ulPropid; break; case DBKIND_NAME: cwchBuffer = ocslen(pdbidSrc->uName.pwszName); cwchBuffer++; pdbidDest->uName.pwszName = (PWSTR)CoTaskMemAlloc(cwchBuffer * sizeof(WCHAR)); if( pdbidDest->uName.pwszName ) memcpy(pdbidDest->uName.pwszName, pdbidSrc->uName.pwszName, cwchBuffer*sizeof(WCHAR)); else return E_OUTOFMEMORY; break; case DBKIND_PGUID_NAME: pdbidDest->uGuid.pguid = (GUID*)CoTaskMemAlloc(sizeof(GUID)); if( pdbidDest->uGuid.pguid ) { *(pdbidDest->uGuid.pguid) = *(pdbidSrc->uGuid.pguid); cwchBuffer = ocslen(pdbidSrc->uName.pwszName); cwchBuffer++; pdbidDest->uName.pwszName = (PWSTR)CoTaskMemAlloc(cwchBuffer * sizeof(WCHAR)); if( pdbidDest->uName.pwszName ) { memcpy(pdbidDest->uName.pwszName, pdbidSrc->uName.pwszName, cwchBuffer*sizeof(WCHAR)); break; } else { CoTaskMemFree(pdbidDest->uGuid.pguid); pdbidDest->uGuid.pguid = NULL; } } return E_OUTOFMEMORY; case DBKIND_PGUID_PROPID: pdbidDest->uGuid.pguid = (GUID*)CoTaskMemAlloc(sizeof(GUID)); if( pdbidDest->uGuid.pguid ) *(pdbidDest->uGuid.pguid) = *(pdbidSrc->uGuid.pguid); else return E_OUTOFMEMORY; pdbidDest->uName.ulPropid = pdbidSrc->uName.ulPropid; break; case DBKIND_PROPID: pdbidDest->uName.ulPropid = pdbidSrc->uName.ulPropid; break; case DBKIND_GUID: pdbidDest->uGuid.guid = pdbidSrc->uGuid.guid; break; default: ATLASSERT(L"Unhandled dbid1.ekind"); return S_FALSE; } return S_OK; } static GUID* GetDBIDpGuid(DBID& dbid) { GUID* pGuid; switch (dbid.eKind) { case DBKIND_PGUID_NAME: case DBKIND_PGUID_PROPID: pGuid = dbid.uGuid.pguid; break; case DBKIND_GUID_NAME: case DBKIND_GUID_PROPID: case DBKIND_GUID: pGuid = &(dbid.uGuid.guid); break; default: pGuid = NULL; } return pGuid; } static ULONG GetPropIDFromDBID(DBID& dbid) { switch (dbid.eKind) { case DBKIND_GUID_PROPID: case DBKIND_PGUID_PROPID: case DBKIND_PROPID: return dbid.uName.ulPropid; default: return 0; } } void FreeDBIDs(DBID* pdbidSrc) { switch( pdbidSrc->eKind ) { case DBKIND_GUID_NAME: CoTaskMemFree(pdbidSrc->uName.pwszName); break; case DBKIND_NAME: CoTaskMemFree(pdbidSrc->uName.pwszName); break; case DBKIND_PGUID_NAME: CoTaskMemFree(pdbidSrc->uGuid.pguid); CoTaskMemFree(pdbidSrc->uName.pwszName); break; case DBKIND_PGUID_PROPID: CoTaskMemFree(pdbidSrc->uGuid.pguid); break; case DBKIND_GUID_PROPID: case DBKIND_PROPID: case DBKIND_GUID: break; default: ATLASSERT(L"Unhandled dbid1.ekind"); break; } } }; extern "C" const CLSID CLSID_DataConvert; class CConvertHelper { public: CConvertHelper() {} HRESULT FinalConstruct() { HRESULT hr = ::CoCreateInstance(CLSID_DataConvert, NULL, CLSCTX_INPROC_SERVER, IID_IDataConvert, (void**)&m_spConvert); if (FAILED(hr)) return hr; // Check to see if the data conversion routine is 2.0 capable, if so. Initialize // the conversion routine to be 2.0. DCINFO rgInfo[] = {{DCINFOTYPE_VERSION, {VT_UI4, 0, 0, 0, 0x0}}}; CComPtr spIDCInfo; hr = m_spConvert->QueryInterface(&spIDCInfo); if (hr == S_OK) { V_UI4(&rgInfo->vData) = 0x200; // OLEDB Version 02.00 spIDCInfo->SetInfo(1, rgInfo); } return hr; } CComPtr m_spConvert; }; // IDBCreateSessionImpl template class ATL_NO_VTABLE IDBCreateSessionImpl : public IDBCreateSession { public: STDMETHOD(CreateSession)(IUnknown *pUnkOuter, REFIID riid, IUnknown **ppDBSession) { ATLTRACE2(atlTraceDBProvider, 0, "IDBCreateSessionImpl::CreateSession\n"); if (ppDBSession == NULL) return E_INVALIDARG; T* pT = (T*)this; if (!(pT->m_dwStatus & DSF_INITIALIZED)) { ATLTRACE2(atlTraceDBProvider, 0, "IDBCreateSessionImpl::CreateSession : Error not initialized\n"); *ppDBSession = NULL; return E_UNEXPECTED; } CComPolyObject *pSession; // You can't QI for an interface other than IUnknown when aggregating // and creating the object. You might ask for your own interface, // which would be bad. Note, we return DB_E_NOAGGREGATION instead of // CLASS_E_NOAGGREGATION due to OLE DB constraints. if (pUnkOuter != NULL && !InlineIsEqualUnknown(riid)) return DB_E_NOAGGREGATION; HRESULT hr = CComPolyObject::CreateInstance(pUnkOuter, &pSession); if (SUCCEEDED(hr)) { CComPtr spCreator; hr = pSession->QueryInterface(IID_IObjectWithSite, (void**)&spCreator); if (SUCCEEDED(hr)) { spCreator->SetSite(this); hr = pSession->QueryInterface(riid, (void**)ppDBSession); } else delete pSession; } return hr; } }; // IDBInitializeImpl template class ATL_NO_VTABLE IDBInitializeImpl : public IDBInitialize { public: IDBInitializeImpl() { m_dwStatus = 0; m_pCUtlPropInfo = NULL; m_cSessionsOpen = 0; } ~IDBInitializeImpl() { delete m_pCUtlPropInfo; } STDMETHOD(Uninitialize)(void) { ATLTRACE2(atlTraceDBProvider, 0, "IDBInitializeImpl::Uninitialize\n"); T* pT = (T*)this; pT->Lock(); if (pT->m_cSessionsOpen != 0) { ATLTRACE2(atlTraceDBProvider, 0, "Uninitialized called with Open Sessions\n"); return DB_E_OBJECTOPEN; } delete m_pCUtlPropInfo; m_pCUtlPropInfo = NULL; pT->m_dwStatus |= DSF_PERSIST_DIRTY; pT->m_dwStatus &= DSF_MASK_INIT; // Clear all non-init flags. pT->Unlock(); return S_OK; } LONG m_cSessionsOpen; DWORD m_dwStatus; CUtlPropInfo* m_pCUtlPropInfo; STDMETHOD(Initialize)(void) { ATLTRACE2(atlTraceDBProvider, 0, "IDBInitializeImpl::Initialize\n"); T *pT = (T*)(this); T::ObjectLock lock(pT); HRESULT hr; if (pT->m_dwStatus & DSF_INITIALIZED) { ATLTRACE2(atlTraceDBProvider, 0, "IDBInitializeImpl::Initialize Error : Already Initialized\n"); return DB_E_ALREADYINITIALIZED; } delete m_pCUtlPropInfo; m_pCUtlPropInfo = NULL; ATLTRY(m_pCUtlPropInfo = new CUtlPropInfo()) if (m_pCUtlPropInfo == NULL) { ATLTRACE2(atlTraceDBProvider, 0, "IDBInitializeImpl::Initialize Error : OOM\n"); return E_OUTOFMEMORY; } hr = m_pCUtlPropInfo->FInit(); if (hr == S_OK) { pT->m_dwStatus |= DSF_INITIALIZED; } else { delete m_pCUtlPropInfo; m_pCUtlPropInfo = NULL; } return hr; } }; // Implementation Class class CPropColID : public PROPCOLID, public CDBIDOps { public: CPropColID() { VariantInit(&vValue); } ~CPropColID() { FreeDBIDs(&dbidProperty); VariantClear(&vValue); } bool operator==(const CPropColID& colId) { return (CompareDBIDs(&dbidProperty, &(colId.dbidProperty)) == S_OK) ? true : false; } }; class CColumnIds : public CDBIDOps, public CSimpleArray { public: PPROPCOLID AddNode() { CPropColID colID; if (Add(colID)) return &(m_aT[GetSize()]); return NULL; } HRESULT RemoveColumnId(const DBID* pdbidProp) { for (int i = 0; i < GetSize(); i++) { if (CompareDBIDs(pdbidProp, &(m_aT[i].dbidProperty)) == S_OK) return (RemoveAt(i)) ? S_OK : E_FAIL; } return E_FAIL; } HRESULT AddColumnId(DBPROP* pProp) { CPropColID colID; HRESULT hr = CopyDBIDs(&(colID.dbidProperty),&(pProp->colid)); if(FAILED(hr)) return hr; colID.dwOption = pProp->dwOptions; hr = VariantCopy(&(colID.vValue),&(pProp->vValue)); if(FAILED(hr)) return hr; return (Add(colID)) ? S_OK : E_OUTOFMEMORY; } HRESULT AddColumnId(PPROPCOLID pPropNode) { CPropColID colID; HRESULT hr = CopyDBIDs(&(colID.dbidProperty),&(pPropNode->dbidProperty)); if(FAILED(hr)) return hr; colID.dwOption = pPropNode->dwOption; hr = VariantCopy(&(colID.vValue),&(pPropNode->vValue)); if(FAILED(hr)) return hr; return (Add(colID)) ? S_OK : E_OUTOFMEMORY; } ULONG GetCountOfPropColids(){ return (ULONG)GetSize();} PPROPCOLID FindColumnId(const DBID* pdbidProp) { for (int i = 0; i < GetSize(); i++) { if (CompareDBIDs(pdbidProp, &(m_aT[i].dbidProperty)) == S_OK) return &(m_aT[i]); } return NULL; } HRESULT GetValue(int iColId, DWORD* pdwOptions, DBID* pColid, VARIANT* pvValue) { HRESULT hr; ATLASSERT(pdwOptions && pColid && pvValue); ATLASSERT(iColId >= 0 && iColId < m_nSize); CPropColID& colId = m_aT[iColId]; *pdwOptions = colId.dwOption; CopyDBIDs( pColid, &(colId.dbidProperty) ); if(FAILED(hr = VariantCopy(pvValue, &(colId.vValue)))) return hr; return S_OK; } }; const ULONG cchDescBuffSize = 256; const DWORD DBINTERNFLAGS_CHANGED = 0x00000001; // Rules for GetPropertiesArgChk const DWORD ARGCHK_PROPERTIESINERROR = 0x00000001; // Implementation Class template class CUtlPropInfo : public CBitFieldOps, public CDBIDOps { public: enum EnumGetPropInfo { GETPROPINFO_ALLPROPIDS = 0x0001, GETPROPINFO_NOTSUPPORTED = 0x0002, GETPROPINFO_ERRORSOCCURRED = 0x0004, GETPROPINFO_VALIDPROP = 0x0008 }; CUtlPropInfo() { m_cUPropSet = 0; m_pUPropSet = NULL; m_cPropSetDex = 0; m_rgiPropSetDex = NULL; m_cElemPerSupported = 0; m_rgdwSupported = NULL; } ~CUtlPropInfo() { delete[] m_rgiPropSetDex; delete[] m_rgdwSupported; if (m_pUPropSet != NULL) CoTaskMemFree(m_pUPropSet); } //Determine the number of description buffers needed ULONG CalcDescripBuffers(ULONG cPropInfoSet, DBPROPINFOSET* pPropInfoSet) { ULONG cBuffers = 0; ATLASSERT(m_pUPropSet); ATLASSERT(cPropInfoSet && pPropInfoSet); for(ULONG ulSet=0; ulSetpwszDescription = pDescBuffer; // Load the string into temp buffer cch = LoadDescription(pUPropInfo[ulProp].ulIDS, wszBuff, (sizeof(wszBuff)/sizeof(*wszBuff))); if( cch ) { // Adjust for '\0' cch++; // Transfer to official buffer if room memcpy(pDescBuffer, wszBuff, cch * sizeof(WCHAR)); pDescBuffer += cch; } else { wcscpy(pDescBuffer, L"UNKNOWN"); pDescBuffer += (wcslen(L"UNKNOWN") + 1); } } pCurPropInfo->dwPropertyID = pUPropInfo[ulProp].dwPropId; pCurPropInfo->dwFlags = pUPropInfo[ulProp].dwFlags; pCurPropInfo->vtType = pUPropInfo[ulProp].VarType; pCurPropInfo->vValues.vt = VT_EMPTY; dwStatus |= GETPROPINFO_VALIDPROP; // Increment to next available buffer ulNext++; } } else { ATLASSERT( m_cPropSetDex == 1 ); for( ulProp = 0; ulProp < cPropInfos; ulProp++, ulNext++ ) { pCurPropInfo = &(pPropInfo[ulNext]); // Process Properties based on Restriction array. pCurPropInfo->dwPropertyID = rgPropertySets[ulSet].rgPropertyIDs[ulProp]; if( GetUPropInfoPtr(m_rgiPropSetDex[ul], pCurPropInfo->dwPropertyID, &pUPropInfo) == S_OK ) { // If the ppDescBuffer pointer was not NULL, then // we need supply description of the properties if( ppDescBuffer ) { // Set Buffer pointer pCurPropInfo->pwszDescription = pDescBuffer; // Load the string into temp buffer cch = LoadDescription(pUPropInfo->ulIDS, wszBuff, (sizeof(wszBuff)/sizeof(*wszBuff))); if( cch ) { // Adjust for '\0' cch++; // Transfer to official buffer if room memcpy(pDescBuffer, wszBuff, cch * sizeof(WCHAR)); pDescBuffer += cch; } else { wcscpy(pDescBuffer, L"UNKNOWN"); pDescBuffer += (wcslen(L"UNKNOWN") + 1); } } pCurPropInfo->dwPropertyID = pUPropInfo->dwPropId; pCurPropInfo->dwFlags = pUPropInfo->dwFlags; pCurPropInfo->vtType = pUPropInfo->VarType; dwStatus |= GETPROPINFO_VALIDPROP; } else { // Not Supported pCurPropInfo->dwFlags = DBPROPFLAGS_NOTSUPPORTED; dwStatus |= GETPROPINFO_ERRORSOCCURRED; } } } } } else { hr = E_OUTOFMEMORY; goto EXIT; } NEXT_SET: pPropInfoSet[ulSet].cPropertyInfos = ulNext; pPropInfoSet[ulSet].rgPropertyInfos = pPropInfo; } // Success, set return values *pcPropertyInfoSets = cSets; *prgPropertyInfoSets = pPropInfoSet; // At least one propid was marked as not S_OK if( dwStatus & GETPROPINFO_ERRORSOCCURRED ) { // If at least 1 property was set if( dwStatus & GETPROPINFO_VALIDPROP ) return DB_S_ERRORSOCCURRED; else { // Do not free any of the rgPropertyInfoSets, but // do free the ppDescBuffer if( pDescBuffer ) { ATLASSERT( ppDescBuffer ); CoTaskMemFree(pDescBuffer); *ppDescBuffer = NULL; } return DB_E_ERRORSOCCURRED; } } return S_OK; EXIT: // Check if failure and clean up any allocated memory if( FAILED(hr) && (hr != DB_E_ERRORSOCCURRED) ) { // Free Description Buffer if( pDescBuffer ) { ATLASSERT( ppDescBuffer ); CoTaskMemFree(pDescBuffer); *ppDescBuffer = NULL; } if( pPropInfoSet ) { // Loop through Property Sets for(ulSet=0; ulSetGetResourceInstance(), ids, pszBuf, cchBuff); wcscpy(pwszBuff, T2W(pszBuf)); return nTemp; } }; class ATL_NO_VTABLE CUtlPropsBase : public CBitFieldOps, public CDBIDOps { public: ULONG m_cUPropSet; //count of UPropSet items UPROPSET* m_pUPropSet; //Pointer to UPropset items UPROP* m_pUProp; ULONG m_cUPropSetHidden; //Count of Hidden items DWORD m_dwFlags; //Configuration flags ULONG m_cPropSetDex; //count of UPropSet Indexes ULONG* m_rgiPropSetDex; //pointer to Array of UPropSet Index values ULONG m_cElemPerSupported;//number of DWORDS per UPropSet to indicate supported UPropIds DWORD* m_rgdwSupported; //pointer to array of DWORDs indicating supported UPropIds DWORD* m_rgdwPropsInError;//pointer to array of DWORDs indicating if property is in error enum EnumUPropSetFlags { UPROPSET_HIDDEN = 0x00000001, UPROPSET_PASSTHROUGH = 0x00000002 }; enum EnumGetProp { GETPROP_ALLPROPIDS = 0x0001, GETPROP_NOTSUPPORTED = 0x0002, GETPROP_ERRORSOCCURRED = 0x0004, GETPROP_VALIDPROP = 0x0008, GETPROP_PROPSINERROR = 0x0010 }; enum EnumSetProp { SETPROP_BADOPTION = 0x0001, SETPROP_NOTSUPPORTED = 0x0002, SETPROP_VALIDPROP = 0x0004, SETPROP_ERRORS = 0x0008, SETPROP_COLUMN_LEVEL = 0x0010, SETPROP_WAS_REQUIRED = 0x0020 }; HRESULT SetPassThrough(const DBPROPSET* pPropSet) { ATLASSERT(pPropSet); DBPROP* pProp = pPropSet->rgProperties; //Default implementation just sets all properties as NOTSUPPORTED for( ULONG ul=0; ulcProperties; ul++, pProp++ ) pProp->dwStatus = DBPROPSTATUS_NOTSUPPORTED; return DB_E_ERRORSOCCURRED; } HRESULT GetIndexofPropIdinPropSet(ULONG iCurSet, DBPROPID dwPropertyId, ULONG* piCurPropId) { ATLASSERT(piCurPropId); UPROPINFO* pUPropInfo = m_pUPropSet[iCurSet].pUPropInfo; for(ULONG ul=0; ulvValue; if (var.vt == VT_BOOL) { if (var.boolVal != VARIANT_TRUE && var.boolVal != VARIANT_FALSE) return S_FALSE; } return S_OK; } virtual HRESULT OnPropertyChanged(ULONG /*iCurSet*/, DBPROP* /*pDBProp*/) = 0; HRESULT SetProperty(ULONG iCurSet, ULONG iCurProp, DBPROP* pDBProp) { HRESULT hr = S_OK; UPROP* pUProp; UPROPVAL* pUPropVal; UPROPINFO* pUPropInfo; ULONG iUProp; ATLASSERT( pDBProp ); // Set pointer to correct set pUProp = &(m_pUProp[iCurSet]); ATLASSERT( pUProp ); pUPropInfo = &(m_pUPropSet[iCurSet].pUPropInfo[iCurProp]); ATLASSERT( pUPropInfo ); // Determine the index within m_pUProp for(iUProp=0; iUPropcPropIds; iUProp++) { if( (pUProp->rgpUPropInfo[iUProp])->dwPropId == pDBProp->dwPropertyID ) break; } if( iUProp >= pUProp->cPropIds ) { ATLASSERT( !"Should have found index of property to set" ); hr = E_FAIL; pDBProp->dwStatus = DBPROPSTATUS_NOTSUPPORTED; goto EXIT; } //Get the UPROPVAL node pointer within that propset. pUPropVal = &(pUProp->pUPropVal[iUProp]); ATLASSERT( pUPropVal ); // Handle VT_EMPTY, which indicates to the provider to // reset this property to the providers default if( pDBProp->vValue.vt == VT_EMPTY ) { if( pUPropInfo->dwFlags & DBPROPFLAGS_COLUMNOK ) { // Remove any nodes, because the default applies to // all columns delete pUPropVal->pCColumnIds; pUPropVal->pCColumnIds = NULL; } // Should clear here, since previous values may already // have been cached and need to be replaced. VariantClear(&(pUPropVal->vValue)); pUPropVal->dwFlags &= ~DBINTERNFLAGS_CHANGED; hr = GetDefaultValue(iCurSet, pDBProp->dwPropertyID, &(pUPropVal->dwOption), &(pUPropVal->vValue)); goto EXIT; } // Column Level if( pUPropInfo->dwFlags & DBPROPFLAGS_COLUMNOK ) { // Check to see if it applies to all if( (CompareDBIDs(&(pDBProp->colid), &DB_NULLID) == S_OK) ) { // Remove the Columns Storage object delete pUPropVal->pCColumnIds; pUPropVal->pCColumnIds = NULL; pUPropVal->dwOption = pDBProp->dwOptions; if( FAILED(hr = VariantCopy(&(pUPropVal->vValue), &(pDBProp->vValue))) ) goto EXIT; pUPropVal->dwFlags |= DBINTERNFLAGS_CHANGED; } else // Does not apply to all columns { if( pUPropVal->pCColumnIds == NULL ) ATLTRY(pUPropVal->pCColumnIds = new CColumnIds) if( pUPropVal->pCColumnIds ) { if( FAILED(hr = (pUPropVal->pCColumnIds)->AddColumnId(pDBProp)) ) goto EXIT; pUPropVal->dwFlags |= DBINTERNFLAGS_CHANGED; } else { hr = E_OUTOFMEMORY; goto EXIT; } } } else { // Set for non-column level properties pUPropVal->dwOption = pDBProp->dwOptions; if( FAILED(hr = VariantCopy(&(pUPropVal->vValue), &(pDBProp->vValue))) ) goto EXIT; OnPropertyChanged(iCurSet, pDBProp); pUPropVal->dwFlags |= DBINTERNFLAGS_CHANGED; } EXIT: if( SUCCEEDED(hr) ) pDBProp->dwStatus = DBPROPSTATUS_OK; return hr; } HRESULT SetProperties(const DWORD /*dwStatus*/, const ULONG cPropertySets, const DBPROPSET rgPropertySets[], const ULONG cSelectProps = 1, const GUID** ppGuid = NULL, bool bIsCreating = false) { DWORD dwState = 0; ULONG ulCurSet, ulProp, ulCurProp = 0; DBPROP* rgDBProp; UPROPINFO* pUPropInfo; VARIANT vDefaultValue; DWORD dwOption; // ppGuid specifies the property sets that the consumer can set based // on the interface that called this function. ATLASSERT(ppGuid != NULL); if ((cPropertySets != 0) && (rgPropertySets == NULL)) return E_INVALIDARG; // Initialize Variant VariantInit(&vDefaultValue); // Process property sets for(ULONG ulSet=0; ulSetdwFlags & DBPROPFLAGS_WRITE) == 0 ) { rgDBProp[ulProp].dwStatus = DBPROPSTATUS_OK; VariantClear(&vDefaultValue); // VT_EMPTY against a read only property should be a no-op since // the VT_EMPTY means the default. if( V_VT(&rgDBProp[ulProp].vValue) == VT_EMPTY ) { dwState |= SETPROP_VALIDPROP; continue; } if( SUCCEEDED(GetDefaultValue(ulCurSet, rgDBProp[ulProp].dwPropertyID, &dwOption, &(vDefaultValue))) ) { if( V_VT(&rgDBProp[ulProp].vValue) == V_VT(&vDefaultValue) ) { switch( V_VT(&vDefaultValue) ) { case VT_BOOL: if( V_BOOL(&rgDBProp[ulProp].vValue) == V_BOOL(&vDefaultValue) ) { dwState |= SETPROP_VALIDPROP; continue; } break; case VT_I2: if( V_I2(&rgDBProp[ulProp].vValue) == V_I2(&vDefaultValue) ) { dwState |= SETPROP_VALIDPROP; continue; } break; case VT_I4: if( V_I4(&rgDBProp[ulProp].vValue) == V_I4(&vDefaultValue) ) { dwState |= SETPROP_VALIDPROP; continue; } break; case VT_BSTR: if( wcscmp(V_BSTR(&rgDBProp[ulProp].vValue), V_BSTR(&vDefaultValue)) == 0 ) { dwState |= SETPROP_VALIDPROP; continue; } break; } } } dwState |= SETPROP_ERRORS; dwState |= (rgDBProp[ulProp].dwOptions == DBPROPOPTIONS_REQUIRED) ? SETPROP_WAS_REQUIRED : 0; rgDBProp[ulProp].dwStatus = DBPROPSTATUS_NOTSETTABLE; continue; } // Check that the property is being set with the correct VARTYPE if( (rgDBProp[ulProp].vValue.vt != pUPropInfo->VarType) && (rgDBProp[ulProp].vValue.vt != VT_EMPTY) ) { dwState |= SETPROP_ERRORS; dwState |= (rgDBProp[ulProp].dwOptions == DBPROPOPTIONS_REQUIRED) ? SETPROP_WAS_REQUIRED : 0; rgDBProp[ulProp].dwStatus = DBPROPSTATUS_BADVALUE; continue; } // Check that the value is legal if( (rgDBProp[ulProp].vValue.vt != VT_EMPTY) && IsValidValue(ulCurSet, &(rgDBProp[ulProp])) == S_FALSE ) { dwState |= SETPROP_ERRORS; dwState |= (rgDBProp[ulProp].dwOptions == DBPROPOPTIONS_REQUIRED) ? SETPROP_WAS_REQUIRED : 0; rgDBProp[ulProp].dwStatus = DBPROPSTATUS_BADVALUE; continue; } // Check for a bad COLID, we only catch bad DBIDs if( pUPropInfo->dwFlags & DBPROPFLAGS_COLUMNOK ) { if( CDBIDOps::IsValidDBID(&(rgDBProp[ulProp].colid)) == S_FALSE ) { dwState |= SETPROP_ERRORS; dwState |= (rgDBProp[ulProp].dwOptions == DBPROPOPTIONS_REQUIRED) ? SETPROP_WAS_REQUIRED : 0; rgDBProp[ulProp].dwStatus = DBPROPSTATUS_BADCOLUMN; continue; } dwState |= SETPROP_COLUMN_LEVEL; } if( SUCCEEDED(SetProperty(ulCurSet, ulCurProp, /*pUPropInfo,*/ &(rgDBProp[ulProp]))) ) { dwState |= SETPROP_VALIDPROP; } } } VariantClear(&vDefaultValue); // At least one propid was marked as not S_OK if( dwState & SETPROP_ERRORS ) { if (!bIsCreating) { return (dwState & SETPROP_VALIDPROP) ? DB_S_ERRORSOCCURRED : DB_E_ERRORSOCCURRED; } else { return (dwState & SETPROP_WAS_REQUIRED) ? DB_E_ERRORSOCCURRED : DB_S_ERRORSOCCURRED; } } return S_OK; } OUT_OF_LINE HRESULT CopyUPropVal(ULONG iPropSet, UPROPVAL* rgUPropVal) { HRESULT hr = S_OK; UPROP* pUProp; UPROPVAL* pUPropVal; DBPROP dbProp; ATLASSERT(rgUPropVal); ATLASSERT(iPropSet < m_cUPropSet); VariantInit(&dbProp.vValue); pUProp = &(m_pUProp[iPropSet]); for(ULONG ul=0; ulcPropIds; ul++) { pUPropVal = &(pUProp->pUPropVal[ul]); // Transfer dwOptions rgUPropVal[ul].dwOption = pUPropVal->dwOption; // Transfer Flags rgUPropVal[ul].dwFlags = pUPropVal->dwFlags; // Transfer Column Properties if( pUPropVal->pCColumnIds ) { ATLTRY(rgUPropVal[ul].pCColumnIds = new CColumnIds) if( rgUPropVal[ul].pCColumnIds ) { CColumnIds* pColIds = pUPropVal->pCColumnIds; for (int i = 0; i < pColIds->GetSize(); i++) { hr = (pUPropVal->pCColumnIds)->GetValue(i, &(dbProp.dwOptions),&(dbProp.colid), &(dbProp.vValue)); if( FAILED(hr) ) goto EXIT; if( FAILED(hr = (rgUPropVal[ul].pCColumnIds)->AddColumnId(&dbProp)) ) goto EXIT; } } else { hr = E_OUTOFMEMORY; goto EXIT; } } else { rgUPropVal[ul].pCColumnIds = NULL; } // Transfer value VariantInit(&(rgUPropVal[ul].vValue)); if( FAILED(hr = VariantCopy(&(rgUPropVal[ul].vValue), &(pUPropVal->vValue))) ) goto EXIT; } EXIT: VariantClear(&(dbProp.vValue)); return hr; } void ClearPropertyInError() { ATLASSERT( m_rgdwPropsInError ); memset(m_rgdwPropsInError, 0, m_cUPropSet * m_cElemPerSupported * sizeof(DWORD)); } void CopyUPropSetsSupported(DWORD* rgdwSupported) { memcpy(rgdwSupported, m_rgdwSupported, m_cUPropSet * m_cElemPerSupported * sizeof(DWORD)); } virtual HRESULT InitUPropSetsSupported() = 0; virtual HRESULT GetIndexofPropSet(const GUID* pPropSet, ULONG* pulCurSet) = 0; ULONG GetCountofWritablePropsInPropSet(ULONG iPropSet) { ULONG cWritable = 0; UPROPINFO* pUPropInfo; ATLASSERT( m_pUPropSet ); ATLASSERT( iPropSet < m_cUPropSet ); pUPropInfo = m_pUPropSet[iPropSet].pUPropInfo; for(ULONG ul=0; ulvt = rInfo.VarType; *pdwOption = rInfo.dwOption; switch(rInfo.VarType) { case VT_BSTR: pVar->bstrVal = SysAllocString(rInfo.szVal); break; default: pVar->lVal = (DWORD)rInfo.dwVal; break; } CoTaskMemFree(pPropSet); return S_OK; } } CoTaskMemFree(pPropSet); return E_FAIL; } HRESULT InternalFInit(PGetPropSet pfnGetSet, CUtlPropsBase* pCopyMe = NULL) { HRESULT hr; ULONG ulPropId; ULONG cPropIds; ULONG iPropSet; ULONG iNewDex; UPROPINFO** rgpUPropInfo; UPROPVAL* rgUPropVal; UPROPINFO* pUPropInfo; // If a pointer is passed in, we should copy that property object if( pCopyMe ) { // Establish some base values m_cUPropSet = pCopyMe->m_cUPropSet; if (m_pUPropSet != NULL) CoTaskMemFree(m_pUPropSet); m_pUPropSet = (UPROPSET*)CoTaskMemAlloc(sizeof(UPROPSET) * m_cUPropSet); if (m_pUPropSet == NULL) return E_OUTOFMEMORY; memcpy(m_pUPropSet, pCopyMe->m_pUPropSet, sizeof(UPROPSET) * m_cUPropSet); m_cElemPerSupported = pCopyMe->m_cElemPerSupported; ATLASSERT( (m_cUPropSet != 0) && (m_cElemPerSupported != 0) ); // Retrieve Supported Bitmask ATLTRY(m_rgdwSupported = new DWORD[m_cUPropSet * m_cElemPerSupported]) ATLTRY(m_rgdwPropsInError = new DWORD[m_cUPropSet * m_cElemPerSupported]) if( m_rgdwSupported == NULL|| m_rgdwPropsInError == NULL) { delete[] m_rgdwSupported; delete[] m_rgdwPropsInError; return E_OUTOFMEMORY; } ClearPropertyInError(); pCopyMe->CopyUPropSetsSupported(m_rgdwSupported); } else { INT_PTR cSets = (INT_PTR)(*pfnGetSet)(NULL, &m_cElemPerSupported, NULL, (GUID*)&GUID_NULL); UPROPSET* pSet = (UPROPSET*)CoTaskMemAlloc(sizeof(UPROPSET) * cSets); if (pSet == NULL) return E_OUTOFMEMORY; pSet = (*pfnGetSet)(&m_cUPropSet, &m_cElemPerSupported, pSet, (GUID*)&GUID_NULL); if (m_pUPropSet != NULL) CoTaskMemFree(m_pUPropSet); m_pUPropSet = pSet; ATLASSERT( (m_cUPropSet != 0) && (m_cElemPerSupported != 0) ); if( !m_cUPropSet || !m_cElemPerSupported ) return E_FAIL; ATLTRY(m_rgdwSupported = new DWORD[m_cUPropSet * m_cElemPerSupported]) ATLTRY(m_rgdwPropsInError = new DWORD[m_cUPropSet * m_cElemPerSupported]) if( m_rgdwSupported == NULL || m_rgdwPropsInError == NULL) { delete[] m_rgdwSupported; delete[] m_rgdwPropsInError; return E_OUTOFMEMORY; } else ClearPropertyInError(); if( FAILED(hr = InitUPropSetsSupported()) ) { delete[] m_rgdwSupported; m_rgdwSupported = NULL; return hr; } } // Allocate UPROPS structures for the count of Property sets ATLTRY(m_pUProp = (UPROP*) new UPROP[m_cUPropSet]) if( m_pUProp) { memset(m_pUProp, 0, m_cUPropSet * sizeof(UPROP)); } else { m_cUPropSet = 0; return E_OUTOFMEMORY; } // With in the UPROPS Structure allocate and intialize the // Property IDs that belong to this property set. for(iPropSet=0; iPropSet 0 ) { ATLTRY(rgpUPropInfo = (UPROPINFO**) new UPROPINFO*[cPropIds]) ATLTRY(rgUPropVal = (UPROPVAL*) new UPROPVAL[cPropIds]) if( rgpUPropInfo != NULL && rgUPropVal != NULL) { if( pCopyMe ) { pCopyMe->CopyUPropInfo(iPropSet, rgpUPropInfo); if( FAILED(hr = pCopyMe->CopyUPropVal(iPropSet, rgUPropVal)) ) return hr; } else { // Clear Pointer Array memset(rgpUPropInfo, 0, cPropIds * sizeof(UPROPINFO*)); // Set Pointer to correct property ids with a property set pUPropInfo = m_pUPropSet[iPropSet].pUPropInfo; // Set up the writable property buffers iNewDex = 0; for(ulPropId=0; ulPropId