//----------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1995. // // File: CRSEmbed.cxx // // Contents: IUnknown embedder for temptable. // // Functions: // // Notes: // // // History: 08/30/96 | RenatoB | Created //---------------------------------------------------------------------------- //----------------------------------------------------------------------------- // @class CRowsetInfo | embedding of Rowset, // to give our IrowsetInfo interface // // //----------------------------------------------------------------------------- // Includes #include "oleds.hxx" //+--------------------------------------------------------------------------- // // Function: CRowsetInfo::QueryInterface // // Synopsis: @mfunc QueryInterface. // IUknown implementation. // IID_IUnknown and IID_IRowsetInfo are not delegated // All other IID's are delegated to _pRowset // //-----------------------------------------------------------------------. HRESULT CRowsetInfo::QueryInterface( REFIID riid, LPVOID *ppv ) { HRESULT hr; if (ppv == NULL) RRETURN(E_INVALIDARG); *ppv = NULL; if (riid == IID_IUnknown) { *ppv = (IRowsetInfo FAR *) this; AddRef(); } if (riid == IID_IRowsetInfo) { *ppv = (IRowsetInfo FAR *) this; AddRef(); } //delegate all the rest to the TempTable Rowset if (_pRowset == NULL) RRETURN(E_UNEXPECTED); hr=((LPUNKNOWN)_pRowset)->QueryInterface(riid, ppv); RRETURN(hr); } //+--------------------------------------------------------------------------- // // Function: CRowsetInfo::CRowsetInfo // // Synopsis: @mfunc Ctor // // Arguments: // // // Returns: @rdesc NONE // // Modifies: // // History: 08/30/96 RenatoB Created // //---------------------------------------------------------------------------- CRowsetInfo::CRowsetInfo( IUnknown *pUnkOuter, // controlling unknown) IUnknown *pParentObject, // RowProvider CSessionObject *pCSession, // Session that created rowset CCommandObject *pCCommand // Command object that created rowset ) { _pUnkOuter= (pUnkOuter == NULL) ? this : pUnkOuter; _pRowset = NULL; _pParentObject = pParentObject; _pCSession= pCSession; _pCCommand = pCCommand; _pMalloc = NULL; _dwStatus = 0; _cPropertySets = 0; _pPropertySets = NULL; if (_pCCommand !=NULL) _pCCommand->IncrementOpenRowsets(); //this section is for IRowsetInfo and IUnknown methods. InitializeCriticalSection(&_csRowsetInfo); } //+--------------------------------------------------------------------------- // // Function: CRowsetInfo::~CRowsetInfo // // Synopsis: @mfunc Dtor // // Arguments: // // // Returns: @rdesc NONE // // Modifies: // // History: 08/30/96 RenatoB Created // //---------------------------------------------------------------------------- CRowsetInfo::~CRowsetInfo() { // release _pPropertySets FreePropertySets(_cPropertySets, _pPropertySets); if (_pMalloc!= NULL) _pMalloc->Release(); if (_pCCommand !=NULL) { _pCCommand->DecrementOpenRowsets(); _pCCommand->Release(); _pCCommand = NULL; } if (_pCSession != NULL) { _pCSession->Release(); _pCSession = NULL; } if (_pParentObject != NULL){ _pParentObject->Release(); _pParentObject=NULL; } if (_pRowset != NULL){ ((LPUNKNOWN)_pRowset)->Release(); _pRowset=NULL; } if ( _pCRowsetInfo!= NULL) { delete _pCRowsetInfo; _pCRowsetInfo = NULL; } DeleteCriticalSection(&_csRowsetInfo); } //+--------------------------------------------------------------------------- // // Function: CRowsetInfo::FInit // // Synopsis: @mfunc Initializer // // Called by: CreateTempTable // Called when: After calling pIServiceProvider->ProvideService // Synopsis: @mfunc Initializer // // Arguments: // // // Returns: @rdesc NONE // @flag S_OK | Interface is supported // @flag E_OUTOFMEMORY | Interface is not supported by the TempTable // @flag E_INVALIDARG | One or more arguments are invalid. // // Modifies: // // History: 08/30/96 RenatoB Created // //---------------------------------------------------------------------------- HRESULT CRowsetInfo::FInit( IUnknown *pRowset) // TmpTable interface { HRESULT hr; hr = S_OK; _pRowset = pRowset; RRETURN(hr); } //+--------------------------------------------------------------------------- // // Function: CRowsetInfo::GetReferencedRowset // // Synopsis: @mfunc Returns an interface pointer to the rowset to which a bookmark applies // // Called by: Client // Called when: Any time // // Arguments: // iOrdinal [in] Bookmark column for which to get related rowset. Must be 0 in this impl. // riid [in] IID of the interface pointer to return in *ppReferencedRowset. // ppReferencedRowset[out] pointer to Rowset object referenced by Bookmark // // // Returns: @rdesc NONE // S_OK | Interface is supported // E_INVALIDARG | ppReferencedRowset was a NULL pointer // E_FAIL | provider specific error // E_NOINTERFACE | Rowset does not support interface // DB_E_NOTAREFENCEDCOLUMN | iOrdinal was not 0 // //---------------------------------------------------------------------------- HRESULT CRowsetInfo::GetReferencedRowset( DBORDINAL iOrdinal, REFIID riid, IUnknown** ppReferencedRowset ) { CAutoBlock(&(_csRowsetInfo)); if (ppReferencedRowset == NULL) RRETURN(E_INVALIDARG); if (iOrdinal != 0) RRETURN(DB_E_BADORDINAL); RRETURN(QueryInterface( riid, (void**)ppReferencedRowset) ); }; //+--------------------------------------------------------------------------- // // Function: CRowsetInfo::GetSpecificaton // // Synopsis: @mfunc Returns an interface pointer to the command that created the rowset // // Called by: Client // Called when: Any time // // Arguments: // riid [in] IID of the interface pointer to return in *ppSpecification. // ppSpecification [out] pointer to command // // // Returns: @rdesc NONE // S_OK | Interface is supported // E_INVALIDARG | ppSpecification was a NULL pointer // E_FAIL | provider specific error // E_NOINTERFACE | Command does not support interface // S_FALSE | Rowset does not have command that created it //---------------------------------------------------------------------------- HRESULT CRowsetInfo::GetSpecification( REFIID riid, IUnknown** ppSpecification ) { CAutoBlock(&(_csRowsetInfo)); if (ppSpecification == NULL) RRETURN(E_INVALIDARG); if ( _pParentObject == NULL) RRETURN(S_FALSE); RRETURN(_pParentObject->QueryInterface(riid, (void**)ppSpecification)); }; //+--------------------------------------------------------------------------- // // Function: CRowsetInfo::GetProperties // // Synopsis: @mfunc GetProperties // Overloads the TempTable's IRowsetInfo::GetProperties. // The first time this function is called, it calls the // TmpTable IRowsetInfo::GetProperties with cPropertyIdSets == 0 // // Called by: Client. // Called when: Any time. // // Arguments: // cPropertyIDSets[in] The number of DBPROPIDSET structures in rgProperttySets // rgPropertyIDSets[in] Array of cPropertyIDSets of DBPROIDSET structs. // pcPropertySets[out] number of DBPROPSET returned in *prgPropertySets // prgPropertySets[out] pointer to array of DBPROPSET structures, having the // value and status of requested properties // // Returns: @rdesc HRESULT // S_OK Success // DB_S_ERRORSOCCURRED Values were not supported for some properties // E_FAIL A provider-specific error occurred // E_INVALIDARG cPropertyIDSets > 0 and rgPropertyIdSEts = NULL // pcPropertySets or prgPropertySets was NULL pointer // In al element of rgPropertyIDSets, cPropertyIDs was not zero // and rgPropertyIDs was a Null pointer // E_OUTOFMEMORY Provider could not allocate memory // DB_E_ERRORSOCCURRED Values were not returned for any properties //-----------------------------------------------------------------------. HRESULT CRowsetInfo::GetProperties( const ULONG cPropertyIDSets, const DBPROPIDSET rgPropertyIDSets[], ULONG* pcPropertySets, DBPROPSET** prgPropertySets ) { CAutoBlock(&(_csRowsetInfo)); // mplPropertyIDsets maps the position of a property set in rgPropertyIDSets[] // within _pPropertySets. It has (-1) if not mappable LONG mplPropertyIDSets[50]; // mplPropertySets maps the position of a property within its corresponding // rgProperties in _pPropertySets. It has (-1) if not mappable. LONG position; HRESULT hr = S_OK; ULONG i; ULONG j; ULONG ibPropertyIDsets; ULONG ibPropertySets; BOOL bPartialSuccess = FALSE; BOOL bErrorsOccurred = FALSE; //validate arguments if ( ((cPropertyIDSets > 0) && ( rgPropertyIDSets == NULL)) || (pcPropertySets == NULL) || (prgPropertySets == NULL) ) RRETURN(E_INVALIDARG); for (i = 0; i< cPropertyIDSets; i++) { if ((rgPropertyIDSets[i].cPropertyIDs > 0) && (rgPropertyIDSets[i].rgPropertyIDs ==NULL)) RRETURN(E_INVALIDARG); } //Initializate, if needed if (_dwStatus == 0) InitProperties(); if (_dwStatus & STAT_INITERROR) //initialization was unsuccessful RRETURN(E_FAIL); // If CPropertyIDSets == 0, just copy *pcPropertySets = 0; *prgPropertySets = NULL; //case when cPropertyIDSets == 0 if (cPropertyIDSets == 0) { //allocate memory for the property sets *prgPropertySets = (DBPROPSET*) _pMalloc->Alloc( _cPropertySets*sizeof(DBPROPSET) ); if (*prgPropertySets == NULL) { hr = E_OUTOFMEMORY; goto error; }; *pcPropertySets = _cPropertySets; // copy the array of property sets and make rgProperties equal to NULL memcpy( (void*) *prgPropertySets, (void*) _pPropertySets, _cPropertySets*sizeof(DBPROPSET) ); for (i = 0; i< _cPropertySets; i++) (*prgPropertySets)[i].rgProperties = NULL; // make copies of each of the rgProperties contained in _pPropertySets for (i = 0; i< _cPropertySets ; i++) { (*prgPropertySets)[i].rgProperties= (DBPROP*)_pMalloc->Alloc( _pPropertySets[i].cProperties*sizeof(DBPROP) ); if ((*prgPropertySets)[i].rgProperties == NULL) { hr = E_OUTOFMEMORY; goto error; }; memcpy( (void*)((*prgPropertySets)[i].rgProperties), (void*) (_pPropertySets[i].rgProperties), _pPropertySets[i].cProperties*sizeof(DBPROP) ); }; RRETURN(S_OK); }; // This is the case when cPropertyIDSets != 0 // First, allocate memory *prgPropertySets = (DBPROPSET*) _pMalloc->Alloc( cPropertyIDSets*sizeof(DBPROPSET) ); if (*prgPropertySets == NULL) { hr = E_OUTOFMEMORY; goto error; }; memset((void*)*prgPropertySets, 0, sizeof(DBPROPSET)*cPropertyIDSets ); *pcPropertySets= cPropertyIDSets; memset(mplPropertyIDSets, 0, sizeof(LONG)*cPropertyIDSets ); for (i=0; iAlloc( _pPropertySets[ibPropertyIDsets].cProperties*sizeof(DBPROP) ); if ((*prgPropertySets)[i].rgProperties == NULL) { hr = E_OUTOFMEMORY; goto error; }; (*prgPropertySets)[i].cProperties= _pPropertySets[ibPropertyIDsets].cProperties; memcpy( (void*) ((*prgPropertySets)[i].rgProperties), (void*) _pPropertySets[ibPropertyIDsets].rgProperties, _pPropertySets[ibPropertyIDsets].cProperties*sizeof(DBPROP) ); } else { //the client asks for some properties only. Alloc and clear memory (*prgPropertySets)[i].rgProperties= (DBPROP*)_pMalloc->Alloc(rgPropertyIDSets[i].cPropertyIDs *sizeof(DBPROP)); if ((*prgPropertySets)[i].rgProperties == NULL) { hr = E_OUTOFMEMORY; goto error; }; (*prgPropertySets)[i].cProperties = rgPropertyIDSets[i].cPropertyIDs; memset( ((*prgPropertySets)[i].rgProperties), 0, rgPropertyIDSets[i].cPropertyIDs*sizeof(DBPROP) ); //iterate and set values for (j=0; j 0) && (rgPropertySets == NULL)) { return; } if (cPropertySets == 0) return; if (_pMalloc == NULL) { return; } //Free the individual arrays of properties for (i=0; i< cPropertySets; i++) { if ((rgPropertySets[i].cProperties > 0) && (rgPropertySets[i].rgProperties != NULL)) _pMalloc->Free(rgPropertySets[i].rgProperties); }; //Free the array of propertysets _pMalloc->Free(rgPropertySets); } //+--------------------------------------------------------------------------- // // Function: CRowsetInfo::InitProperties // // Synopsis: @mfunc initilizes _cPropertySets and _pPropertySets from // _pRowset // //---------------------------------------------------------------------------- HRESULT CRowsetInfo::InitProperties(void) { HRESULT hr; IRowsetInfo* pRowsetInfo = NULL; hr = CoGetMalloc(MEMCTX_TASK, &_pMalloc); if (FAILED(hr)) { goto error; } if (_pRowset == NULL) { hr = E_FAIL; goto error; }; hr = _pRowset->QueryInterface(IID_IRowsetInfo, (void**) &pRowsetInfo); if (FAILED (hr)) { goto error; }; hr= pRowsetInfo->GetProperties(0, NULL, &_cPropertySets, &_pPropertySets); if (FAILED(hr)) { goto error; } _dwStatus =STAT_DIDINIT; pRowsetInfo->Release(); RRETURN(S_OK); error: _dwStatus = STAT_INITERROR; if (_pMalloc != NULL) { _pMalloc->Release(); _pMalloc = NULL; } if (pRowsetInfo != NULL) pRowsetInfo->Release(); ; RRETURN(hr); }; //+--------------------------------------------------------------------------- // // Function: CRowsetInfo::SearchGuid // // Synopsis: @mfunc // // Arguments: riid [in] GUID to be searched for // // Returns: // The position of the GUID withing _pPropertySets. Returns -1 // if not found // //---------------------------------------------------------------------------- LONG CRowsetInfo::SearchGuid(GUID riid) { ULONG i; for (i = 0; i < _cPropertySets; i++) { if (_pPropertySets[i].guidPropertySet == riid) return (i); }; return -1; }; //+--------------------------------------------------------------------------- // // Function: CRowsetInfo::SearchPropid // // Synopsis: @mfunc Searchs for a Propid within _PropertySets // // Arguments: // ibPropertySet [in] The index, within _pPropertySets, // of the DBPROPSET to be searched // dwPropertyID [in] The propid to be searched // Returns: // The position of the DBPROP with propid=dwPropertyID // within _pPropertySets[ibPropertySet]. Returns -1 // if not found // //---------------------------------------------------------------------------- LONG CRowsetInfo::SearchPropid( ULONG ibPropertySet, DWORD dwPropertyID) { ULONG i; for (i = 0; i < _pPropertySets[ibPropertySet].cProperties; i++) { if (_pPropertySets[ibPropertySet].rgProperties[i].dwPropertyID ==dwPropertyID ) return (i); }; return -1; };