Windows2003-3790/inetsrv/query/h/propbase.hxx

807 lines
25 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1994 - 1999.
//
// File: propbase.hxx
//
// Contents: Headers for common property handling routines
//
// Classes: CUtlPropInfo,
// CUtlProps
//
// History: 10-28-97 danleg Created from monarch uprops.hpp
//
//----------------------------------------------------------------------------
#pragma once
//
// Constants and Static Struct
//
#define DEFAULT_MACHINE L"."
const ULONG DWORDSNEEDEDPERSET = 2;
const ULONG DWORDSNEEDEDTOTAL = DWORDSNEEDEDPERSET * 5;
//
// Macros
//
#define INRANGE(z,zmin,zmax) ( (zmin) <= (z) && (z) <= (zmax) )
//
// Utility functions
//
// Bit array routines.
// Two versions: one for a single DWORD, one for arrays.
// Note that you pass in not a bit mask, but the bit number.
// i.e. dwBit = 0,1,2,3,4...31 instead of 1,2,4,8,0x10,0x20...
inline void SETBIT( DWORD &dwFlags, DWORD dwBit )
{
dwFlags |= 1 << dwBit;
}
inline void CLEARBIT( DWORD &dwFlags, DWORD dwBit )
{
dwFlags &= ~ (1<<dwBit);
}
inline DWORD TESTBIT( DWORD &dwFlags, DWORD dwBit )
{
return (dwFlags & (1<<dwBit)) != 0;
}
// Routines based on array-of-DWORD.
// Use these like a bit array, from 0...n-1.
#define DivDword(dw) (dw >> 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
inline void SETBIT( DWORD rgdwFlags[], const DWORD dwBit )
{
rgdwFlags[DivDword(dwBit)] |= 1 << ModDword(dwBit);
}
inline void CLEARBIT( DWORD rgdwFlags[], const DWORD dwBit )
{
rgdwFlags[DivDword(dwBit)] &= ~( 1 << ModDword(dwBit) );
}
#define CLEARBITARRAY( rgdwFlags ) RtlZeroMemory( rgdwFlags, sizeof(rgdwFlags) )
inline 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;
}
#undef DivDWord
#undef ModDWord
//
// Forward Declarations
//
class CColumnIds;
//
// Constants and Static Struct
//
// leave plenty of space for localization.
const ULONG CCH_GETPROPERTYINFO_DESCRIP_BUFFER_SIZE = 256;
const DWORD GETPROPINFO_ALLPROPIDS = 0x0001;
const DWORD GETPROPINFO_NOTSUPPORTED = 0x0002;
const DWORD GETPROPINFO_ERRORSOCCURRED = 0x0004;
const DWORD GETPROPINFO_VALIDPROP = 0x0008;
const DWORD GETPROP_ALLPROPIDS = 0x0001;
const DWORD GETPROP_NOTSUPPORTED = 0x0002;
const DWORD GETPROP_ERRORSOCCURRED = 0x0004;
const DWORD GETPROP_VALIDPROP = 0x0008;
const DWORD GETPROP_PROPSINERROR = 0x0010;
const DWORD SETPROP_BADOPTION = 0x0001;
const DWORD SETPROP_NOTSUPPORTED = 0x0002;
const DWORD SETPROP_VALIDPROP = 0x0004;
const DWORD SETPROP_ERRORS = 0x0008;
const DWORD SETPROP_COLUMN_LEVEL = 0x0010;
const DWORD DBINTERNFLAGS_NOCHANGE = 0x00000000;
const DWORD DBINTERNFLAGS_CHANGED = 0x00000001;
const DWORD DBINTERNFLAGS_CHEAPTOREQ = 0x00000002;
const DWORD DBINTERNFLAGS_INERROR = 0x00000004;
const DWORD DBINTERNFLAGS_INERRORSAVED = 0x00000008;
const DWORD DBINTERNFLAGS_TOTRUE = 0x80000000;
// Additional Property Flags needed internally
const DWORD DBPROPFLAGS_CHANGE = 0x80000000;
// Flags for controlling UPROPSETS
const DWORD UPROPSET_HIDDEN = 0x00000001;
const DWORD UPROPSET_PASSTHROUGH = 0x00000002;
// Rules for GetPropertiesArgChk
const DWORD ARGCHK_PROPERTIESINERROR = 0x00000001;
//
// STRUCTURE DEFINITIONS
//
typedef struct tagPropColId* PPROPCOLID;
typedef struct tagUPROPVAL
{
DBPROPOPTIONS dwOption;
DWORD dwFlags;
VARIANT vValue;
} UPROPVAL;
typedef struct tagUPROPINFO
{
DBPROPID dwPropId;
LPCWSTR pwszDesc;
VARTYPE VarType;
DBPROPFLAGS dwFlags;
} UPROPINFO;
typedef struct tagUPROP
{
ULONG cPropIds;
UPROPINFO** rgpUPropInfo;
UPROPVAL* pUPropVal;
} UPROP;
typedef struct tagUPROPSET
{
const GUID* pPropSet;
ULONG cUPropInfo;
const UPROPINFO* pUPropInfo;
DWORD dwFlags;
} UPROPSET;
//+-------------------------------------------------------------------------
//
// Class: CUtlPropInfo
//
// Purpose: Base class for property storage
//
// History: 11-12-97 danleg Created from Monarch
//
//--------------------------------------------------------------------------
class CUtlPropInfo
{
public:
//
// Ctor / Dtor
//
CUtlPropInfo();
virtual ~CUtlPropInfo() { };
SCODE GetPropertyInfo ( ULONG cPropertySets,
const DBPROPIDSET rgPropertySets[],
ULONG * pcPropertyInfoSets,
DBPROPINFOSET ** prgPropertyInfoSets,
WCHAR ** ppDescBuffer );
//
// Get the count of propsets.
//
ULONG GetUPropSetCount() { return _cUPropSet; }
//
// Reset the count of propsets.
//
void SetUPropSetCount( ULONG c ) { _cUPropSet = c; }
//
// Pure Virtual
//
virtual SCODE InitAvailUPropSets(
ULONG * pcUPropSet,
UPROPSET ** ppUPropSet,
ULONG * pcElemPerSupported )=0;
virtual SCODE InitUPropSetsSupported(
DWORD * rgdwSupported )=0;
//
// Load a localized description
//
virtual ULONG LoadDescription ( LPCWSTR pwszDesc,
PWSTR pwszBuff,
ULONG cchBuff )=0;
protected:
//
// Initialization routine called called from constructors of derived
// classes.
//
void FInit();
private:
//
// Count of UPropSet items
//
ULONG _cUPropSet;
//
// Pointer to UPropset items
//
UPROPSET * _pUPropSet;
//
// Count of UPropSet Indexes
//
ULONG _cPropSetDex;
//
// Pointer to Array of UPropSet Index values
//
XArray<ULONG> _xaiPropSetDex;
//
// Number of DWORDS per UPropSet to indicate supported UPropIds
//
ULONG _cElemPerSupported;
//
// Pointer to array of DWORDs indicating supported UPropIds
//
XArray<DWORD> _xadwSupported;
//
// Member functions
//
// Retrieve the property id pointer
SCODE GetUPropInfoPtr ( ULONG iPropSetDex,
DBPROPID dwPropertyId,
UPROPINFO ** ppUPropInfo );
// Retrieve the property set indexes that match this property set.
SCODE GetPropertySetIndex( const GUID * pPropertySet );
// Determine the number of description buffers needed
ULONG CalcDescripBuffers( ULONG cPropInfoSet,
DBPROPINFOSET* pPropInfoSet );
};
//+-------------------------------------------------------------------------
//
// Class: CUtlProps
//
// Purpose: Base class for property storage
//
// History: 11-12-97 danleg Created from Monarch
//
//--------------------------------------------------------------------------
class CUtlProps
{
public:
//
// Ctor / Dtor
//
CUtlProps( DWORD dwFlags = 0 );
virtual ~CUtlProps();
//
// Fill default values again.
//
SCODE FillDefaultValues(ULONG ulPropSetTarget = ULONG_MAX);
//
// Check the arguments for Retrieve Properties
//
void GetPropertiesArgChk( const ULONG cPropertySets,
const DBPROPIDSET rgPropertySets[],
ULONG * pcProperties,
DBPROPSET ** prgProperties );
//
// Check the arguments for Set Properties
//
static void SetPropertiesArgChk( const ULONG cPropertySets,
const DBPROPSET rgPropertySets[] );
//
// Retrieve Properties
//
SCODE GetProperties ( const ULONG cPropertySets,
const DBPROPIDSET rgPropertySets[],
ULONG * pcProperties,
DBPROPSET ** prgProperties );
//
// Set Properties
//
SCODE SetProperties ( const ULONG cPropertySets,
const DBPROPSET rgPropertySets[] );
inline void SetPropertyInError(
const ULONG iPropSet,
const ULONG iPropId );
inline void ClearPropertyInError( ) ;
BOOL IsPropSet ( const GUID * pguidPropSet,
DBPROPID dwPropId );
SCODE GetPropValue ( const GUID * pguidPropSet,
DBPROPID dwPropId,
VARIANT * pvValue );
SCODE SetPropValue ( const GUID * pguidPropSet,
DBPROPID dwPropId,
VARIANT * pvValue );
SCODE CopyUPropVal ( ULONG iPropSet,
UPROPVAL * rgUPropVal );
//
// Virtuals functions
//
virtual SCODE GetIndexofPropSet( const GUID * pPropSet,
ULONG * pulCurSet );
virtual SCODE GetIndexofPropIdinPropSet(
ULONG iCurSet,
DBPROPID dwPropertyId,
ULONG * piCurPropId );
//
// Pure Virtuals
//
virtual SCODE InitAvailUPropSets( ULONG * pcUPropSet,
UPROPSET ** ppUPropSet,
ULONG * pcElemPerSupported )=0;
virtual SCODE GetDefaultValue ( ULONG iPropSet,
DBPROPID dwPropId,
DWORD * dwOption,
VARIANT * pVar )=0;
virtual SCODE IsValidValue ( ULONG iCurSet,
DBPROP * pDBProp )=0;
virtual SCODE InitUPropSetsSupported( DWORD * rgdwSupported) = 0;
//
// Inlined functions
//
inline ULONG GetUPropSetCount() { return _cUPropSet; }
inline void SetUPropSetCount( ULONG c ) { _cUPropSet = c; }
//
// NOTE: The following functions depend on all prior properties in the
// array being writable. This is because the UPROP array contains only
// writable elements, and the UPROPINFO array contains writable and
// read-only elements. If this is a problem, we would need to define
// which one it came from and add the appropriate asserts...
//
// Get DBPROPOPTIONS_xx
inline DWORD GetPropOption ( ULONG iPropSet,
ULONG iProp );
// Set DBPROPOPTIONS_xx
inline void SetPropOption ( ULONG iPropSet,
ULONG iProp,
DWORD dwOption );
//
// Determine if property is required and variant_true
//
inline BOOL IsRequiredTrue ( ULONG iPropSet,
ULONG iProp );
inline DWORD GetInternalFlags( ULONG iPropSet,
ULONG iProp );
inline void AddInternalFlags( ULONG iPropSet,
ULONG iProp,
DWORD dwFlag );
inline void RemoveInternalFlags (
ULONG iPropSet,
ULONG iProp,
DWORD dwFlag );
inline VARIANT * GetVariant ( ULONG iPropSet,
ULONG iProp );
inline SCODE SetVariant ( ULONG iPropSet,
ULONG iProp,
VARIANT * pv );
inline void SetValEmpty ( ULONG iPropSet,
ULONG iProp );
inline BOOL IsEmpty ( ULONG iPropSet,
ULONG iProp );
inline void SetValBool ( ULONG iPropSet,
ULONG iProp,
VARIANT_BOOL bVal );
inline VARIANT_BOOL GetValBool ( ULONG iPropSet,
ULONG iProp );
inline void SetValShort ( ULONG iPropSet,
ULONG iProp,
SHORT iVal );
inline SHORT GetValShort ( ULONG iPropSet,
ULONG iProp );
inline void SetValLong ( ULONG iPropSet,
ULONG iProp,
LONG lVal );
inline LONG GetValLong ( ULONG iPropSet,
ULONG iProp );
inline SCODE SetValString ( ULONG iPropSet,
ULONG iProp,
const WCHAR * pwsz );
inline const WCHAR * GetValString(
ULONG iPropSet,
ULONG iProp );
inline const GUID * GetGuid ( ULONG iPropSet);
inline DWORD GetPropID ( ULONG iPropSet,
ULONG iProp );
inline VARTYPE GetExpectedVarType( ULONG iPropSet,
ULONG iProp );
// Inline Methods
inline void CopyAvailUPropSets( ULONG * pcUPropSet,
UPROPSET ** ppUPropSet,
ULONG * pcElemPerSupported );
inline void CopyUPropSetsSupported(
XArray<DWORD> & xadwSupported );
inline void CopyUPropInfo ( ULONG iPropSet,
XArray<UPROPINFO*> & xapUPropInfo );
protected:
//
// Number of DWORDS per UPropSet to indicate supported UPropIds
//
ULONG _cElemPerSupported;
//
// Pointer to array of DWORDs indicating supported UPropIds
//
XArray<DWORD> _xadwSupported;
//
// Pointer to array of DWORDs indicating if property is in error
//
XArray<DWORD> _xadwPropsInError;
//
// Initialization Method
//
virtual void FInit ( CUtlProps * pCopyMe = NULL );
private:
//
// Count of UPropSet items
//
ULONG _cUPropSet;
//
//Pointer to UPropset items
//
UPROPSET * _pUPropSet;
XArray<UPROP> _xaUProp;
//
// Count of Hidden items
//
ULONG _cUPropSetHidden;
//
// Configuration flags
//
DWORD _dwFlags;
//
// Count of UPropSet Indexes
//
ULONG _cPropSetDex;
//
// Pointer to Array of UPropSet Index values
//
XArray<ULONG> _xaiPropSetDex;
void FreeMemory ( );
ULONG GetCountofWritablePropsInPropSet(
ULONG iPropSet );
ULONG GetUPropValIndex( ULONG iCurset,
DBPROPID dwPropId);
SCODE SetProperty ( ULONG iCurSet,
ULONG iCurProp,
DBPROP * pDBProp);
//
// Retrieve the property set indexes that
// match this property set.
//
SCODE GetPropertySetIndex( GUID * pPropertySet );
};
// --------------------------------------------------------------------------
// -------------------- I N L I N E F U N C T I O N S ----------------------
// --------------------------------------------------------------------------
inline void CUtlProps::CopyAvailUPropSets
(
ULONG* pcUPropSet,
UPROPSET** ppUPropSet,
ULONG* pcElemPerSupported
)
{
Win4Assert( pcUPropSet && ppUPropSet && pcElemPerSupported );
*pcUPropSet = _cUPropSet;
*ppUPropSet = _pUPropSet;
*pcElemPerSupported = _cElemPerSupported;
}
inline void CUtlProps::CopyUPropSetsSupported
(
XArray<DWORD> & xadwSupported
)
{
// if the passed in array already has elements, we will leak
Win4Assert( xadwSupported.IsNull() );
xadwSupported.Init( _xadwSupported );
//RtlCopyMemory( xadwSupported.GetPointer(),
// _xadwSupported.GetPointer(),
// _cUPropSet * _cElemPerSupported * sizeof(DWORD) );
}
inline void CUtlProps::CopyUPropInfo
(
ULONG iPropSet,
XArray<UPROPINFO*> & xapUPropInfo
)
{
Win4Assert( xapUPropInfo.IsNull() );
Win4Assert( iPropSet < _cUPropSet );
xapUPropInfo.Init( _xaUProp[iPropSet].cPropIds );
RtlCopyMemory( xapUPropInfo.GetPointer(),
_xaUProp[iPropSet].rgpUPropInfo,
xapUPropInfo.SizeOf() );
}
inline void CUtlProps::ClearPropertyInError()
{
Win4Assert( !_xadwPropsInError.IsNull() );
RtlZeroMemory( _xadwPropsInError.GetPointer(), _cUPropSet * _cElemPerSupported * sizeof(DWORD) );
};
// Save a few lines by defining a common set of asserts.
#define is_proper_range \
( (iPropSet < _cUPropSet) \
&& (iProp < _pUPropSet[iPropSet].cUPropInfo) \
&& (iProp < _xaUProp[iPropSet].cPropIds) )
// Set Property Ids that should be in Error
inline void CUtlProps::SetPropertyInError
(
const ULONG iPropSet,
const ULONG iProp
)
{
SETBIT(&(_xadwPropsInError[iPropSet * _cElemPerSupported]), iProp);
};
// determine if the property is Required and VARIANT_TRUE
inline BOOL CUtlProps::IsRequiredTrue(ULONG iPropSet, ULONG iProp)
{
Win4Assert( is_proper_range );
Win4Assert(_xaUProp[iPropSet].pUPropVal[iProp].vValue.vt == VT_BOOL);
Win4Assert(V_BOOL(&_xaUProp[iPropSet].pUPropVal[iProp].vValue) == VARIANT_TRUE
|| V_BOOL(&_xaUProp[iPropSet].pUPropVal[iProp].vValue) == VARIANT_FALSE);
return( !(_xaUProp[iPropSet].pUPropVal[iProp].dwFlags & DBINTERNFLAGS_INERROR) &&
(_xaUProp[iPropSet].pUPropVal[iProp].dwOption == DBPROPOPTIONS_REQUIRED) &&
(V_BOOL(&_xaUProp[iPropSet].pUPropVal[iProp].vValue) == VARIANT_TRUE) );
};
// Get DBPROPOPTIONS_xx
inline DWORD CUtlProps::GetPropOption(ULONG iPropSet, ULONG iProp)
{
Win4Assert( is_proper_range );
return _xaUProp[iPropSet].pUPropVal[iProp].dwOption;
}
inline void CUtlProps::SetPropOption(ULONG iPropSet, ULONG iProp, DWORD dwOption)
{
Win4Assert( is_proper_range );
_xaUProp[iPropSet].pUPropVal[iProp].dwOption = dwOption;
}
inline DWORD CUtlProps::GetInternalFlags(ULONG iPropSet, ULONG iProp)
{
Win4Assert( is_proper_range );
return _xaUProp[iPropSet].pUPropVal[iProp].dwFlags;
}
inline void CUtlProps::AddInternalFlags(ULONG iPropSet, ULONG iProp, DWORD dwFlags)
{
Win4Assert( is_proper_range );
_xaUProp[iPropSet].pUPropVal[iProp].dwFlags |= dwFlags;
}
inline void CUtlProps::RemoveInternalFlags(ULONG iPropSet, ULONG iProp, DWORD dwFlags)
{
Win4Assert( is_proper_range );
_xaUProp[iPropSet].pUPropVal[iProp].dwFlags &= ~dwFlags;
}
inline VARIANT * CUtlProps::GetVariant(ULONG iPropSet, ULONG iProp)
{
Win4Assert( is_proper_range );
return & _xaUProp[iPropSet].pUPropVal[iProp].vValue;
}
inline SCODE CUtlProps::SetVariant(ULONG iPropSet, ULONG iProp, VARIANT *pv )
{
Win4Assert( is_proper_range );
// Does VariantClear first.
return VariantCopy( &_xaUProp[iPropSet].pUPropVal[iProp].vValue, pv );
}
inline void CUtlProps::SetValEmpty(ULONG iPropSet, ULONG iProp)
{
Win4Assert( is_proper_range );
VariantClear( &_xaUProp[iPropSet].pUPropVal[iProp].vValue );
}
inline BOOL CUtlProps::IsEmpty(ULONG iPropSet, ULONG iProp)
{
Win4Assert( is_proper_range );
return ( _xaUProp[iPropSet].pUPropVal[iProp].vValue.vt == VT_EMPTY);
}
inline void CUtlProps::SetValBool(ULONG iPropSet, ULONG iProp, VARIANT_BOOL bVal )
{
Win4Assert( is_proper_range );
// Note that we accept any "true" value.
VariantClear(&_xaUProp[iPropSet].pUPropVal[iProp].vValue);
_xaUProp[iPropSet].pUPropVal[iProp].vValue.vt = VT_BOOL;
V_BOOL(&_xaUProp[iPropSet].pUPropVal[iProp].vValue)
= (bVal ? VARIANT_TRUE : VARIANT_FALSE);
}
inline VARIANT_BOOL CUtlProps::GetValBool(ULONG iPropSet, ULONG iProp)
{
Win4Assert( is_proper_range );
Win4Assert(_xaUProp[iPropSet].pUPropVal[iProp].vValue.vt == VT_BOOL);
return V_BOOL(&_xaUProp[iPropSet].pUPropVal[iProp].vValue);
}
inline void CUtlProps::SetValShort(ULONG iPropSet, ULONG iProp, SHORT iVal )
{
Win4Assert( is_proper_range );
VariantClear(&_xaUProp[iPropSet].pUPropVal[iProp].vValue);
_xaUProp[iPropSet].pUPropVal[iProp].vValue.vt = VT_I2;
_xaUProp[iPropSet].pUPropVal[iProp].vValue.iVal = iVal;
}
inline SHORT CUtlProps::GetValShort(ULONG iPropSet, ULONG iProp)
{
Win4Assert( is_proper_range );
Win4Assert(_xaUProp[iPropSet].pUPropVal[iProp].vValue.vt == VT_I2);
return _xaUProp[iPropSet].pUPropVal[iProp].vValue.iVal;
}
inline void CUtlProps::SetValLong(ULONG iPropSet, ULONG iProp, LONG lVal )
{
Win4Assert( is_proper_range );
VariantClear(&_xaUProp[iPropSet].pUPropVal[iProp].vValue);
_xaUProp[iPropSet].pUPropVal[iProp].vValue.vt = VT_I4;
_xaUProp[iPropSet].pUPropVal[iProp].vValue.lVal = lVal;
}
// Get value as long
inline LONG CUtlProps::GetValLong(ULONG iPropSet, ULONG iProp)
{
Win4Assert( is_proper_range );
Win4Assert(_xaUProp[iPropSet].pUPropVal[iProp].vValue.vt == VT_I4);
return _xaUProp[iPropSet].pUPropVal[iProp].vValue.lVal;
}
// Set value as string
inline SCODE CUtlProps::SetValString(ULONG iPropSet, ULONG iProp, const WCHAR *pwsz )
{
Win4Assert( is_proper_range );
VARIANT *pv = &_xaUProp[iPropSet].pUPropVal[iProp].vValue;
VariantClear(pv);
pv->bstrVal = SysAllocString(pwsz);
if ( pv->bstrVal )
pv->vt = VT_BSTR;
else
return E_FAIL;
// See if this was used for non-string type.
// Typically this is an easy way to pass integer as a string.
if ( GetExpectedVarType(iPropSet,iProp) == VT_BSTR )
return NOERROR;
if ( pwsz[0] != L'\0' )
return VariantChangeType( pv, pv, 0, GetExpectedVarType(iPropSet,iProp) );
// Set to "", which for non-string means empty.
SysFreeString(pv->bstrVal);
pv->vt = VT_EMPTY;
return NOERROR;
}
inline const WCHAR * CUtlProps::GetValString(ULONG iPropSet, ULONG iProp)
{
Win4Assert( is_proper_range );
Win4Assert(_xaUProp[iPropSet].pUPropVal[iProp].vValue.vt == VT_BSTR);
return _xaUProp[iPropSet].pUPropVal[iProp].vValue.bstrVal;
}
inline const GUID * CUtlProps::GetGuid(ULONG iPropSet)
{
Win4Assert(iPropSet < _cUPropSet);
return _pUPropSet[iPropSet].pPropSet;
}
inline DWORD CUtlProps::GetPropID(ULONG iPropSet, ULONG iProp)
{
Win4Assert( is_proper_range );
return _pUPropSet[iPropSet].pUPropInfo[iProp].dwPropId;
}
inline VARTYPE CUtlProps::GetExpectedVarType(ULONG iPropSet, ULONG iProp)
{
Win4Assert( is_proper_range );
return _pUPropSet[iPropSet].pUPropInfo[iProp].VarType;
}
#undef is_proper_range