windows-nt/Source/XPSP1/NT/inetsrv/query/icommand/stdqspec.cxx

738 lines
21 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1998.
//
// File: StdQSpec.cxx
//
// Contents: IQuery for file-based queries
//
// Classes: CQuerySpec
//
// History: 30 Jun 1995 AlanW Created
//
//----------------------------------------------------------------------------
#include <pch.cxx>
#pragma hdrstop
extern long gulcInstances;
#include <cidbprop.hxx>
#include <cmdprutl.hxx>
#include <dbprputl.hxx>
#include <datasrc.hxx>
#include <session.hxx>
#include <dsocf.hxx>
#include <lgplist.hxx>
#include <propglob.hxx>
#include "stdqspec.hxx"
//+-------------------------------------------------------------------------
//
// Member: CQuerySpec::QueryInternalQuery, protected
//
// Synopsis: Instantiates internal query, using current parameters.
//
// Returns: Pointer to internal query object.
//
// History: 03-Mar-1997 KyleP Created
// 14-May-1997 mohamedn hidden core/fs property sets
//
//--------------------------------------------------------------------------
PIInternalQuery * CQuerySpec::QueryInternalQuery()
{
//
// get a pointer to the PIInternalQuery interface
//
XInterface<CDbProperties> xIDbProps(new CDbProperties);
if ( xIDbProps.IsNull() )
THROW( CException( E_OUTOFMEMORY ) );
CGetCmdProps getCmdProps( (ICommand *)this);
SCODE sc;
PIInternalQuery * pQuery;
ULONG cardinality = getCmdProps.GetCardinality();
if ( cardinality <= 1 )
{
getCmdProps.PopulateDbProps( xIDbProps.GetPointer() );
sc = EvalQuery( &pQuery,
xIDbProps.GetReference(),
_xDocStore.GetPointer());
}
else
{
Win4Assert( !_xDocStore.GetPointer() );
sc = EvalDistributedQuery( &pQuery, getCmdProps );
}
if ( FAILED( sc ) )
QUIETTHROW( CException( sc ) );
Win4Assert( 0 != pQuery );
return pQuery;
} //QueryInternalQuery
//+-------------------------------------------------------------------------
//
// Member: CQuerySpec::CQuerySpec, public
//
// Synopsis: Constructor of a CQuerySpec
//
// Arguments: [pOuterUnk] - Outer unknown
// [ppMyUnk] - OUT: filled in with pointer to non-delegated
// IUnknown on return
// [pDocStore] - Known DocStore
//
// History: 22-Apr-97 KrishnaN Created
//
//--------------------------------------------------------------------------
CQuerySpec::CQuerySpec ( IUnknown * pOuterUnk, IUnknown ** ppMyUnk, ICiCDocStore * pDocStore )
: CRootQuerySpec(pOuterUnk, ppMyUnk)
{
//
// Squirrel away DocStore.
//
pDocStore->AddRef();
_xDocStore.Set(pDocStore);
InitScopePropertySets();
} //CQuerySpec
//+-------------------------------------------------------------------------
//
// Member: CQuerySpec::InitScopePropertySets, private
//
// Synopsis: Initializes internal data structs
//
// Arguments: none
//
// History: 06-04-97 mohamedn Created
//
//--------------------------------------------------------------------------
void CQuerySpec::InitScopePropertySets()
{
RtlZeroMemory( _aPropSet, sizeof (_aPropSet) );
_aCoreProps.Init ( INITIAL_PROPERTIES_COUNT );
_aFsClientProps.Init( INITIAL_PROPERTIES_COUNT );
_aPropSet[0].guidPropertySet = DBPROPSET_CIFRMWRKCOREEXT;
_aPropSet[0].rgProperties = _aCoreProps.GetPointer();
_aPropSet[1].guidPropertySet = DBPROPSET_FSCIFRMWRKEXT;
_aPropSet[1].rgProperties = _aFsClientProps.GetPointer();
} //InitScopePropertySets
//+---------------------------------------------------------------------------
//
// Method: CQuerySpec::SetProperties, public
//
// Synopsis: Set rowset scope properties
//
// Arguments: [cPropertySets] - number of property sets
// [rgPropertySets] - array of property sets
//
// Returns: SCODE - result code indicating error return status. One of
// S_OK, DB_S_ERRORSOCCURRED or DB_E_ERRORSOCCURRED. Any
// other errors are thrown.
//
// History: 01-Mar-97 KyleP Created
// 14-May-97 mohamedn hidden core/fs property set details
// 12-Dec-97 danleg ReleaseInternalQuery if setting scope props
//
//----------------------------------------------------------------------------
SCODE STDMETHODCALLTYPE CQuerySpec::SetProperties( ULONG cPropertySets,
DBPROPSET rgPropertySets[] )
{
_DBErrorObj.ClearErrorInfo();
//
// First, get parent properties.
//
SCODE scParent = CRootQuerySpec::SetProperties( cPropertySets, rgPropertySets );
//
// Any non-understood error is a bail. Return the error/successes from the parent.
//
if ( scParent != DB_S_ERRORSOCCURRED && scParent != DB_E_ERRORSOCCURRED )
return scParent;
BOOL fFoundErrors = FALSE;
SCODE sc = S_OK;
//
// Set properties not handled by parent
//
TRANSLATE_EXCEPTIONS;
TRY
{
DBPROPSET *pDbPropset = rgPropertySets;
BOOL fScopeProps = FALSE;
for ( unsigned i = 0; i < cPropertySets; i++, pDbPropset++ )
{
if ( DBPROPSET_FSCIFRMWRKEXT == pDbPropset->guidPropertySet ||
DBPROPSET_CIFRMWRKCOREEXT == pDbPropset->guidPropertySet )
{
SetPropertyset( pDbPropset );
fScopeProps = TRUE;
}
else
{
//
// keep track of any errors occured in base class.
//
DBPROP * pProp = pDbPropset->rgProperties;
ULONG cProps = pDbPropset->cProperties;
for ( unsigned j = 0; j < cProps; j++ )
{
if ( DBPROPSTATUS_OK != pProp[j].dwStatus )
fFoundErrors = TRUE;
}
}
}
//
// If we found any scope properties, release the
// internal query object.
//
if ( fScopeProps )
{
ReleaseInternalQuery();
}
}
CATCH( CException, e )
{
scParent = GetOleError( e );
fFoundErrors = TRUE;
}
END_CATCH;
UNTRANSLATE_EXCEPTIONS;
if ( fFoundErrors )
{
if ( S_OK != scParent )
{
_DBErrorObj.PostHResult( scParent, IID_ICommandProperties );
return scParent;
}
else
{
_DBErrorObj.PostHResult( DB_S_ERRORSOCCURRED, IID_ICommandProperties );
return DB_S_ERRORSOCCURRED;
}
}
else
return S_OK;
} //SetProperties
//+---------------------------------------------------------------------------
//
// Method: CQuerySpec::SetPropertyset, private
//
// Synopsis: Sets non-rowset properties
//
// Arguments: [pPropertyset] - pointer to property set (to be set).
//
// Returns: none - THROWS upon failure.
//
// History: 05-14-97 mohamedn created
//
//----------------------------------------------------------------------------
void CQuerySpec::SetPropertyset( DBPROPSET *pPropertySet )
{
DBPROP * pProp = pPropertySet->rgProperties;
ULONG cProps= pPropertySet->cProperties;
//
// un-error property dwStatus set by parent
//
for ( unsigned j = 0; j < cProps; j++ )
{
switch ( pProp[j].dwStatus )
{
case DBPROPSTATUS_NOTSUPPORTED:
pProp[j].dwStatus = DBPROPSTATUS_OK;
break;
case DBPROPSTATUS_OK:
break;
default:
vqDebugOut(( DEB_ERROR, "Unexpected pProp[j].dwStatus: j=%x, dwStatus=%x \n",j,pProp[j].dwStatus ));
}
}
//
// identify destination propset
//
for ( unsigned k = 0; k < SCOPE_PROPSET_COUNT; k++ )
{
if ( _aPropSet[k].guidPropertySet == pPropertySet->guidPropertySet )
break;
}
if ( k == SCOPE_PROPSET_COUNT )
{
Win4Assert( !"Should never be hit" );
THROW( CException(DB_E_ERRORSOCCURRED));
}
//
// update property set
//
UpdatePropertySet( _aPropSet[k], *pPropertySet );
} //SetPropertyset
//+---------------------------------------------------------------------------
//
// Method: CQuerySpec::UpdatePropertySet, private
//
// Synopsis: Sets non-rowset properties
//
// Arguments: [destPropSet] - destination property set
// [srcPropSet] - source property set
//
// Returns: none - THROWS upon failure.
//
// History: 06-04-97 mohamedn created
//
//----------------------------------------------------------------------------
void CQuerySpec::UpdatePropertySet(DBPROPSET &destPropSet, DBPROPSET &srcPropSet )
{
CDbProp * pDestProp = (CDbProp *)destPropSet.rgProperties;
CDbProp * pSrcProp = (CDbProp *)srcPropSet.rgProperties;
ULONG cErrors = 0;
for ( unsigned i = 0; i < srcPropSet.cProperties; i++ )
{
for ( unsigned j = 0; j < destPropSet.cProperties; j++ )
{
if ( pDestProp[j].dwPropertyID == pSrcProp[i].dwPropertyID )
{
if ( !pDestProp[j].Copy(pSrcProp[i]) )
THROW( CException(E_OUTOFMEMORY) );
break;
}
}
if ( j == destPropSet.cProperties )
{
//
// new PropID
//
if ( destPropSet.guidPropertySet == DBPROPSET_CIFRMWRKCOREEXT &&
j >= _aCoreProps.Count() )
{
_aCoreProps.GrowToSize( srcPropSet.cProperties );
_aPropSet[0].rgProperties = _aCoreProps.GetPointer();
pDestProp = (CDbProp *)destPropSet.rgProperties;
}
else if ( destPropSet.guidPropertySet == DBPROPSET_FSCIFRMWRKEXT &&
j >= _aFsClientProps.Count() )
{
_aFsClientProps.GrowToSize( srcPropSet.cProperties );
_aPropSet[1].rgProperties = _aFsClientProps.GetPointer();
pDestProp = (CDbProp *)destPropSet.rgProperties;
}
Win4Assert( pDestProp[j].dwPropertyID == 0 );
Win4Assert( pDestProp[j].dwStatus == 0 );
if ( !pDestProp[j].Copy(pSrcProp[i]) )
THROW( CException(E_OUTOFMEMORY) );
destPropSet.cProperties++;
}
}
if ( cErrors == srcPropSet.cProperties )
THROW (CException( DB_E_ERRORSOCCURRED ) );
if ( cErrors > 0 )
THROW (CException( DB_S_ERRORSOCCURRED ) );
} //UpdatePropertySet
//+---------------------------------------------------------------------------
//
// Method: CQuerySpec::GetProperties, public
//
// Synopsis: Get rowset properties
//
// Arguments: [cPropertySetIDs] - number of desired property set IDs or 0
// [rgPropertySetIDs] - array of desired property set IDs or NULL
// [pcPropertySets] - number of property sets returned
// [prgPropertySets] - array of returned property sets
//
// Returns: SCODE - result code indicating error return status. One of
// S_OK, DB_S_ERRORSOCCURRED or DB_E_ERRORSOCCURRED. Any
// other errors are thrown.
//
// History: 01-Mar-97 KyleP Created
// 14-May-97 mohamedn hidden core/fs property set details
//
//----------------------------------------------------------------------------
SCODE STDMETHODCALLTYPE CQuerySpec::GetProperties(
ULONG const cPropertySetIDs,
DBPROPIDSET const rgPropertySetIDs[],
ULONG * pcPropertySets,
DBPROPSET ** prgPropertySets)
{
_DBErrorObj.ClearErrorInfo();
BOOL fAddScopeProperties = FALSE;
ULONG cPropSetIDs = cPropertySetIDs;
XArray<CDbPropIDSet> aPropIDSets;
CDbPropIDSet * pPropIDSet = (CDbPropIDSet *)rgPropertySetIDs;
ULONG cAllocPropSets = cPropertySetIDs;
//
// Don't give back the scope properties for "all properties". If the
// magic number 3141592653 is given in, all properties including the
// scope properties are returned.
//
if ( 3141592653 == cPropertySetIDs )
{
fAddScopeProperties = TRUE;
cPropSetIDs = 0;
//
// We want all properties, including scope properties. The base
// implementation doesn't know about scope properties
//
SCODE sc = S_OK;
TRY
{
aPropIDSets.Init( 5 );
}
CATCH( CException, e )
{
sc = e.GetErrorCode();
}
END_CATCH;
if ( FAILED( sc ) )
return sc;
aPropIDSets[0].guidPropertySet = DBPROPSET_ROWSET;
aPropIDSets[0].cPropertyIDs = 0;
aPropIDSets[1].guidPropertySet = DBPROPSET_MSIDXS_ROWSET_EXT;
aPropIDSets[1].cPropertyIDs = 0;
aPropIDSets[2].guidPropertySet = DBPROPSET_QUERY_EXT;
aPropIDSets[2].cPropertyIDs = 0;
aPropIDSets[3].guidPropertySet = DBPROPSET_CIFRMWRKCOREEXT;
aPropIDSets[3].cPropertyIDs = 0;
aPropIDSets[4].guidPropertySet = DBPROPSET_FSCIFRMWRKEXT;
aPropIDSets[4].cPropertyIDs = 0;
cAllocPropSets = aPropIDSets.Count();
pPropIDSet = aPropIDSets.GetPointer();
}
SCODE scParent = CRootQuerySpec::GetProperties( cAllocPropSets,
pPropIDSet,
pcPropertySets,
prgPropertySets );
//
// Any non-understood error is a bail. S_OK here means all properties were
// handled by parent. Just return unless *all* props were requested.
//
if ( scParent != DB_S_ERRORSOCCURRED && scParent != DB_E_ERRORSOCCURRED )
{
if ( scParent != S_OK || 0 != cPropSetIDs )
return scParent;
}
SCODE sc = S_OK;
BOOL fFoundErrors = FALSE;
TRANSLATE_EXCEPTIONS;
TRY
{
//
// Find query properties.
//
if ( 0 == cPropSetIDs && fAddScopeProperties )
{
//
// Case 1: All properties were requested. Append scope onto
// appropriate property set.
//
for ( unsigned i = 0; i < SCOPE_PROPSET_COUNT; i++ )
{
DBPROPIDSET dbPropIdSet;
ZeroMemory((void *) &dbPropIdSet, sizeof DBPROPIDSET );
dbPropIdSet.guidPropertySet = _aPropSet[i].guidPropertySet;
//
// scan dest array of propsets (set by base) for matching guid.
//
for ( unsigned j = 0; j < *pcPropertySets; j++ )
{
if ( dbPropIdSet.guidPropertySet ==
(*prgPropertySets)[j].guidPropertySet )
{
GetPropValues( dbPropIdSet,
(*prgPropertySets)[j],
fFoundErrors );
break;
}
}
//
// PropSet not found
//
if ( j == *pcPropertySets )
{
fFoundErrors = TRUE;
Win4Assert( !"CRowsetProperties doesn't support requested propset." );
Win4Assert( !"base & derived classes are out of sync!");
}
}
}
else
{
//
// Case 2: Specific properties were requested.
//
for ( unsigned i = 0; i < cPropSetIDs; i++ )
{
//
// scan dest array of propsets (set by base) for matching guid.
//
for ( unsigned j = 0; j < *pcPropertySets; j++ )
{
if ( (*prgPropertySets)[j].guidPropertySet ==
rgPropertySetIDs[i].guidPropertySet )
{
GetPropValues( rgPropertySetIDs[i],
(*prgPropertySets)[j],
fFoundErrors );
break;
}
}
//
// PropSet not found
//
if ( j == *pcPropertySets )
{
fFoundErrors = TRUE;
Win4Assert( !"Unexpected PropertySet requested" );
}
}
}
}
CATCH( CException, e )
{
sc = e.GetErrorCode();
}
END_CATCH
UNTRANSLATE_EXCEPTIONS;
if ( FAILED(sc) && sc != DB_E_ERRORSOCCURRED )
{
for ( unsigned i = 0; i < *pcPropertySets; i++ )
{
DBPROP * rgProperties = (*prgPropertySets)[i].rgProperties;
unsigned cProperties = (*prgPropertySets)[i].cProperties;
for ( unsigned j = 0; j < cProperties; j++ )
VariantClear( &(rgProperties[j].vValue) );
CoTaskMemFree( rgProperties );
}
CoTaskMemFree( *prgPropertySets );
*prgPropertySets = 0;
}
if ( fFoundErrors )
{
if ( scParent != S_OK )
{
_DBErrorObj.PostHResult( scParent, IID_ICommandProperties );
return scParent;
}
else
{
_DBErrorObj.PostHResult( DB_S_ERRORSOCCURRED, IID_ICommandProperties );
return DB_S_ERRORSOCCURRED;
}
}
return sc;
} //GetProperties
//+-------------------------------------------------------------------------
//
// Member: CQuerySpec::GetPropValues, private
//
// Synopsis: Gets values of properties in a property set.
//
// Arguments: [rgPropertySetIDs] [in] - array of propIDs to get
// [rgPropertySet] [out] - reference to property set to fill
// [fFoundErrors] [out] - TRUE if any errors are found, but not thrown.
//
// Returns: Throws in case of failure
//
// History: 04-15-97 mohamedn created
//
//--------------------------------------------------------------------------
void CQuerySpec::GetPropValues( DBPROPIDSET const & rgPropertySetIDs,
DBPROPSET & rgPropertySet,
BOOL & fFoundErrors)
{
Win4Assert( rgPropertySet.guidPropertySet == rgPropertySetIDs.guidPropertySet );
//
// Locate private property set source
//
for ( unsigned i = 0; i < SCOPE_PROPSET_COUNT; i++ )
{
if ( rgPropertySet.guidPropertySet == _aPropSet[i].guidPropertySet )
{
break; // found source property set
}
}
//
// If not one of the scope propsets, return
//
if ( SCOPE_PROPSET_COUNT == i )
{
fFoundErrors = TRUE;
return;
}
DBPROPSET & srcPropSet = _aPropSet[i];
DBPROP * psrcDbProp = srcPropSet.rgProperties;
ULONG cPropsFound= 0;
ULONG cDbProps = rgPropertySetIDs.cPropertyIDs ?
rgPropertySetIDs.cPropertyIDs :
srcPropSet.cProperties;
XArrayOLEInPlace<CDbProp> aDbProps( cDbProps );
//
// scan private property set for reqeusted propId values
//
if ( 0 == rgPropertySetIDs.cPropertyIDs )
{
//
// return all properties
//
for ( i = 0; i < srcPropSet.cProperties; i++ )
{
if ( !aDbProps[i].Copy( psrcDbProp[i] ) )
THROW( CException(E_OUTOFMEMORY) );
Win4Assert( aDbProps[i].dwStatus == DBPROPSTATUS_OK );
}
cPropsFound = i;
}
else
{
//
// specific properties within this prop set are requested
//
for ( unsigned iPropsRequested = 0; iPropsRequested < rgPropertySetIDs.cPropertyIDs; iPropsRequested++ )
{
for ( unsigned iPropSrc = 0; iPropSrc < srcPropSet.cProperties; iPropSrc++ )
{
if ( rgPropertySetIDs.rgPropertyIDs[iPropsRequested] == psrcDbProp[iPropSrc].dwPropertyID )
{
if ( !aDbProps[iPropsRequested].Copy( psrcDbProp[iPropSrc] ) )
THROW( CException(E_OUTOFMEMORY) );
Win4Assert( aDbProps[iPropsRequested].dwStatus == DBPROPSTATUS_OK );
break;
}
}
//
// if requested propID not found
//
if ( iPropSrc == srcPropSet.cProperties )
{
//
// Property ID not set
//
aDbProps[iPropsRequested].dwPropertyID = rgPropertySetIDs.rgPropertyIDs[iPropsRequested];
aDbProps[iPropsRequested].dwStatus = DBPROPSTATUS_NOTSET;
fFoundErrors = TRUE;
}
}
cPropsFound = iPropsRequested;
}
//
// free rgProperties allocated by base class, assign new one.
//
CoTaskMemFree( rgPropertySet.rgProperties );
rgPropertySet.rgProperties = aDbProps.Acquire();
rgPropertySet.cProperties = cPropsFound;
} //GetPropValues