1850 lines
42 KiB
C++
1850 lines
42 KiB
C++
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Copyright (c) 1998-2000 Microsoft Corporation
|
||
|
//
|
||
|
// Module Name:
|
||
|
// PropertyValue.cpp
|
||
|
//
|
||
|
// Description:
|
||
|
// Implementation of the cluster property value classes for the MSCLUS
|
||
|
// automation classes.
|
||
|
//
|
||
|
// Author:
|
||
|
// Galen Barbee (GalenB) 16-Dec-1998
|
||
|
//
|
||
|
// Revision History:
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
#include "stdafx.h"
|
||
|
#include "Property.h"
|
||
|
#include "PropertyValue.h"
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// Global variables
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
static const IID * iidCClusPropertyValue[] =
|
||
|
{
|
||
|
&IID_ISClusPropertyValue
|
||
|
};
|
||
|
|
||
|
static const IID * iidCClusPropertyValues[] =
|
||
|
{
|
||
|
&IID_ISClusPropertyValues
|
||
|
};
|
||
|
|
||
|
static const IID * iidCClusPropertyValueData[] =
|
||
|
{
|
||
|
&IID_ISClusPropertyValueData
|
||
|
};
|
||
|
|
||
|
|
||
|
//*************************************************************************//
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CClusPropertyValue class
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValue::CClusPropertyValue
|
||
|
//
|
||
|
// Description:
|
||
|
// Constructor.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
CClusPropertyValue::CClusPropertyValue( void )
|
||
|
{
|
||
|
m_dwFlags = 0;
|
||
|
m_pcpvdData = NULL;
|
||
|
|
||
|
#if CLUSAPI_VERSION >= 0x0500
|
||
|
m_cptType = CLUSPROP_TYPE_UNKNOWN;
|
||
|
#else
|
||
|
m_cptType = (CLUSTER_PROPERTY_TYPE) -1;
|
||
|
#endif // CLUSAPI_VERSION >= 0x0500
|
||
|
|
||
|
m_cpfFormat = CLUSPROP_FORMAT_UNKNOWN;
|
||
|
m_cbLength = 0;
|
||
|
|
||
|
m_piids = (const IID *) iidCClusPropertyValue;
|
||
|
m_piidsSize = ARRAYSIZE( iidCClusPropertyValue );
|
||
|
|
||
|
} //*** CClusPropertyValue::CClusPropertyValue()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValue::~CClusPropertyValue
|
||
|
//
|
||
|
// Description:
|
||
|
// Destructor.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
CClusPropertyValue::~CClusPropertyValue( void )
|
||
|
{
|
||
|
if ( m_pcpvdData != NULL )
|
||
|
{
|
||
|
m_pcpvdData->Release();
|
||
|
} // if: data vector has been allocated
|
||
|
|
||
|
} //*** CClusPropertyValue::~CClusPropertyValue()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValue::Create
|
||
|
//
|
||
|
// Description:
|
||
|
// Finish the heavy weight construction for a single value.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// varValue [IN] - The value.
|
||
|
// cptType [IN] - The cluster property type of the value.
|
||
|
// cpfFormat [IN] - The cluster property format of the value.
|
||
|
// cbLength [IN] - The length of the value.
|
||
|
// bReadOnly [IN] - Is this a read only property?
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or other HRESULT error.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CClusPropertyValue::Create(
|
||
|
IN VARIANT varValue,
|
||
|
IN CLUSTER_PROPERTY_TYPE cptType,
|
||
|
IN CLUSTER_PROPERTY_FORMAT cpfFormat,
|
||
|
IN size_t cbLength,
|
||
|
IN BOOL bReadOnly
|
||
|
)
|
||
|
{
|
||
|
HRESULT _hr = S_FALSE;
|
||
|
|
||
|
m_cptType = cptType;
|
||
|
m_cpfFormat = cpfFormat;
|
||
|
m_cbLength = cbLength;
|
||
|
|
||
|
if ( bReadOnly )
|
||
|
{
|
||
|
m_dwFlags |= READONLY;
|
||
|
} // if: set the read only flag
|
||
|
else
|
||
|
{
|
||
|
m_dwFlags &= ~READONLY;
|
||
|
} // else: clear the read only flag
|
||
|
|
||
|
_hr = CComObject< CClusPropertyValueData >::CreateInstance( &m_pcpvdData );
|
||
|
if ( SUCCEEDED( _hr ) )
|
||
|
{
|
||
|
CSmartPtr< CComObject < CClusPropertyValueData > > _ptrData( m_pcpvdData );
|
||
|
|
||
|
_hr = _ptrData->Create( varValue, cpfFormat, bReadOnly );
|
||
|
if ( SUCCEEDED( _hr ) )
|
||
|
{
|
||
|
_ptrData->AddRef();
|
||
|
} // if:
|
||
|
} // if: Can create an instance of CClusPropertyValueData
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValue::Create()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValue::Create
|
||
|
//
|
||
|
// Description:
|
||
|
// Finish the heavy weight construction for a value list.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// cbhValue [IN] - The value list buffer helper.
|
||
|
// bReadOnly [IN] - Is this a read only property?
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or other HRESULT error.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CClusPropertyValue::Create(
|
||
|
IN CLUSPROP_BUFFER_HELPER cbhValue,
|
||
|
IN BOOL bReadOnly
|
||
|
)
|
||
|
{
|
||
|
HRESULT _hr = S_FALSE;
|
||
|
|
||
|
m_cptType = (CLUSTER_PROPERTY_TYPE) cbhValue.pValue->Syntax.wType;
|
||
|
m_cpfFormat = (CLUSTER_PROPERTY_FORMAT) cbhValue.pValue->Syntax.wFormat;
|
||
|
m_cbLength = cbhValue.pValue->cbLength;
|
||
|
|
||
|
if ( bReadOnly )
|
||
|
{
|
||
|
m_dwFlags |= READONLY;
|
||
|
} // if: set the read only flag
|
||
|
else
|
||
|
{
|
||
|
m_dwFlags &= ~READONLY;
|
||
|
} // else: clear the read only flag
|
||
|
|
||
|
_hr = CComObject< CClusPropertyValueData >::CreateInstance( &m_pcpvdData );
|
||
|
if ( SUCCEEDED( _hr ) )
|
||
|
{
|
||
|
CSmartPtr< CComObject < CClusPropertyValueData > > _ptrData( m_pcpvdData );
|
||
|
|
||
|
_hr = _ptrData->Create( cbhValue, bReadOnly );
|
||
|
if ( SUCCEEDED( _hr ) )
|
||
|
{
|
||
|
_ptrData->AddRef();
|
||
|
} // if:
|
||
|
} // if: Can create an instance of CClusPropertyValueData
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValue::Create
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValue::get_Value
|
||
|
//
|
||
|
// Description:
|
||
|
// Return the default value data for this value.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pvarValue [IN] - Catches the data value.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or E_POINTER if not.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CClusPropertyValue::get_Value( IN VARIANT * pvarValue )
|
||
|
{
|
||
|
//ASSERT( pvarValue != NULL );
|
||
|
|
||
|
HRESULT _hr = E_POINTER;
|
||
|
|
||
|
if ( pvarValue != NULL )
|
||
|
{
|
||
|
_hr = VariantCopyInd( pvarValue, &(*m_pcpvdData)[ 0 ] );
|
||
|
}
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValue::get_Value()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValue::put_Value
|
||
|
//
|
||
|
// Description:
|
||
|
// Change the default data value.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// varValue [IN] - The new data value.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or S_FALSE if read only.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CClusPropertyValue::put_Value( IN VARIANT varValue )
|
||
|
{
|
||
|
HRESULT _hr = S_FALSE;
|
||
|
|
||
|
if ( ( m_dwFlags & READONLY ) == 0 )
|
||
|
{
|
||
|
CComVariant _varNew( varValue );
|
||
|
CComVariant _varOld( (*m_pcpvdData)[ 0 ] );
|
||
|
|
||
|
_hr = S_OK;
|
||
|
|
||
|
if ( _varOld != _varNew )
|
||
|
{
|
||
|
(*m_pcpvdData)[ 0 ] = _varNew;
|
||
|
m_dwFlags |= MODIFIED;
|
||
|
} // if: value changed
|
||
|
} // if:
|
||
|
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValue::put_Value()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValue::get_Type
|
||
|
//
|
||
|
// Description:
|
||
|
// Get this value's cluster property type.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pcptType [OUT] - Catches the value type.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or E_POINTER if not.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CClusPropertyValue::get_Type(
|
||
|
OUT CLUSTER_PROPERTY_TYPE * pcptType
|
||
|
)
|
||
|
{
|
||
|
//ASSERT( pcptType != NULL );
|
||
|
|
||
|
HRESULT _hr = E_POINTER;
|
||
|
|
||
|
if ( pcptType != NULL )
|
||
|
{
|
||
|
*pcptType = m_cptType;
|
||
|
_hr = S_OK;
|
||
|
} // if: property type pointer specified
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValue::get_Type()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValue::put_Type
|
||
|
//
|
||
|
// Description:
|
||
|
// Set this value's cluster property type.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// cptType [IN] - The new type.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or S_FALSE if read only.
|
||
|
//
|
||
|
// Note:
|
||
|
// It is possible that this should be removed. You cannot ever change
|
||
|
// a value's type.
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CClusPropertyValue::put_Type( IN CLUSTER_PROPERTY_TYPE cptType )
|
||
|
{
|
||
|
HRESULT _hr = S_FALSE;
|
||
|
|
||
|
if ( ( m_dwFlags & READONLY ) == 0 )
|
||
|
{
|
||
|
m_cptType = cptType;
|
||
|
_hr = S_OK;
|
||
|
} // if:
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValue::put_Type()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValue::get_Format
|
||
|
//
|
||
|
// Description:
|
||
|
// Get the value's cluster property format.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pcpfFormat [OUT] - Catches the format.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or E_POINTER if not.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CClusPropertyValue::get_Format(
|
||
|
OUT CLUSTER_PROPERTY_FORMAT * pcpfFormat
|
||
|
)
|
||
|
{
|
||
|
//ASSERT( pcpfFormat != NULL );
|
||
|
|
||
|
HRESULT _hr = E_POINTER;
|
||
|
|
||
|
if ( pcpfFormat != NULL )
|
||
|
{
|
||
|
*pcpfFormat = m_cpfFormat;
|
||
|
_hr = S_OK;
|
||
|
} // if: property format pointer specified
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValue::get_Format()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValue::put_Format
|
||
|
//
|
||
|
// Description:
|
||
|
// Set the value's cluster property format.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// cpfFormat [IN] - The new format for the value.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or S_FALSE if read only.
|
||
|
//
|
||
|
// Note:
|
||
|
// It is possible that this should be removed. You cannot ever change
|
||
|
// a value's format.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CClusPropertyValue::put_Format(
|
||
|
IN CLUSTER_PROPERTY_FORMAT cpfFormat
|
||
|
)
|
||
|
{
|
||
|
HRESULT _hr = S_FALSE;
|
||
|
|
||
|
if ( ( m_dwFlags & READONLY ) == 0 )
|
||
|
{
|
||
|
m_cpfFormat = cpfFormat;
|
||
|
_hr = S_OK;
|
||
|
} // if:
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValue::put_Format()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValue::get_Length
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns the length of this value.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// plLength [OUT] - Catches the length of this value.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or E_POINTER if not.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CClusPropertyValue::get_Length( OUT long * plLength )
|
||
|
{
|
||
|
//ASSERT( plLength != NULL );
|
||
|
|
||
|
HRESULT _hr = E_POINTER;
|
||
|
|
||
|
if ( plLength != NULL )
|
||
|
{
|
||
|
*plLength = (long) m_cbLength;
|
||
|
_hr = S_OK;
|
||
|
} // if: length pointer specified
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValue::get_Length()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValue::get_DataCount
|
||
|
//
|
||
|
// Description:
|
||
|
// Return the count of VARIANTS in the ClusProperyValueData object.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// plCount [OUT] - Catches the count.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or other HRESULT error.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CClusPropertyValue::get_DataCount( OUT long * plCount )
|
||
|
{
|
||
|
return m_pcpvdData->get_Count( plCount );
|
||
|
|
||
|
} //*** CClusPropertyValue::get_DataCount()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValue::get_Data
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns the data collection.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// ppClusterPropertyValueData [OUT] - Catches the data collection.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, E_POINTER, or other HRESULT error.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CClusPropertyValue::get_Data(
|
||
|
OUT ISClusPropertyValueData ** ppClusterPropertyValueData
|
||
|
)
|
||
|
{
|
||
|
//ASSERT( ppClusterPropertyValueData );
|
||
|
|
||
|
HRESULT _hr = E_POINTER;
|
||
|
|
||
|
if ( ppClusterPropertyValueData != NULL )
|
||
|
{
|
||
|
_hr = m_pcpvdData->QueryInterface( IID_ISClusPropertyValueData, (void **) ppClusterPropertyValueData );
|
||
|
}
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValue::get_Data()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValue::Modified
|
||
|
//
|
||
|
// Description:
|
||
|
// Sets this value to modified and returns the old modified state.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// bModified [IN] - New modified state.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// The old modified state.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL CClusPropertyValue::Modified( IN BOOL bModified )
|
||
|
{
|
||
|
BOOL _bTemp = ( m_dwFlags & MODIFIED );
|
||
|
|
||
|
if ( bModified )
|
||
|
{
|
||
|
m_dwFlags |= MODIFIED;
|
||
|
} // if: set the modified flag
|
||
|
else
|
||
|
{
|
||
|
m_dwFlags &= ~MODIFIED;
|
||
|
} // else: clear the modified flag
|
||
|
|
||
|
return _bTemp;
|
||
|
|
||
|
} //*** CClusPropertyValue::Modified()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValue::Value
|
||
|
//
|
||
|
// Description:
|
||
|
// Set a new value into this property value.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// rvarValue [IN] - the new value
|
||
|
//
|
||
|
// Return Value:
|
||
|
// The old value.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
CComVariant CClusPropertyValue::Value( const CComVariant & rvarValue )
|
||
|
{
|
||
|
CComVariant _varNew( rvarValue );
|
||
|
CComVariant _varOld( (*m_pcpvdData)[ 0 ] );
|
||
|
|
||
|
if ( _varOld != _varNew )
|
||
|
{
|
||
|
(*m_pcpvdData)[ 0 ] = _varNew;
|
||
|
m_dwFlags |= MODIFIED;
|
||
|
} // if: data changed
|
||
|
|
||
|
return _varOld;
|
||
|
|
||
|
} //*** CClusPropertyValue::Value()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValue::HrBinaryValue
|
||
|
//
|
||
|
// Description:
|
||
|
// Set the binary value of property value.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// psa [IN] - The SAFEARRY to save.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or other HRESULT error.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CClusPropertyValue::HrBinaryValue( IN SAFEARRAY * psa )
|
||
|
{
|
||
|
return m_pcpvdData->HrBinaryValue( psa );
|
||
|
|
||
|
} //*** CClusPropertyValue::HrBinaryValue()
|
||
|
|
||
|
|
||
|
//*************************************************************************//
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CClusPropertyValues class
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValues::CClusPropertyValues
|
||
|
//
|
||
|
// Description:
|
||
|
// Constructor.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
CClusPropertyValues::CClusPropertyValues( void )
|
||
|
{
|
||
|
m_piids = (const IID *) iidCClusPropertyValues;
|
||
|
m_piidsSize = ARRAYSIZE( iidCClusPropertyValues );
|
||
|
|
||
|
} //*** CClusPropertyValues::CClusPropertyValues()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValues::~CClusPropertyValues
|
||
|
//
|
||
|
// Description:
|
||
|
// Destructor.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
CClusPropertyValues::~CClusPropertyValues( void )
|
||
|
{
|
||
|
Clear();
|
||
|
|
||
|
} //*** CClusPropertyValues::~CClusPropertyValues()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValues::Clear
|
||
|
//
|
||
|
// Description:
|
||
|
// Releases the values in the collection.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusPropertyValues::Clear( void )
|
||
|
{
|
||
|
::ReleaseAndEmptyCollection< CClusPropertyValueVector, CComObject< CClusPropertyValue > >( m_cpvvValues );
|
||
|
|
||
|
} //*** CClusPropertyValues::Clear()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValues::HrGetVariantLength
|
||
|
//
|
||
|
// Description:
|
||
|
// Compute the length of the data from its variant type.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// rvarValue [IN] - The new value to compute the length of.
|
||
|
// pcbLength [OUT] - Catches the length.
|
||
|
// cpfFormat [IN] - The cluster property format.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or E_INVALIDARG if the type is bogus.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CClusPropertyValues::HrGetVariantLength(
|
||
|
IN const VARIANT rvarValue,
|
||
|
OUT PDWORD pcbLength,
|
||
|
IN CLUSTER_PROPERTY_FORMAT cpfFormat
|
||
|
)
|
||
|
{
|
||
|
HRESULT _hr = E_INVALIDARG;
|
||
|
VARTYPE _varType = rvarValue.vt;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
if ( ( _varType & VT_ARRAY ) && ( _varType & VT_UI1 ) )
|
||
|
{
|
||
|
SAFEARRAY * _psa = rvarValue.parray;
|
||
|
|
||
|
//
|
||
|
// only accept single dimensional arrays!
|
||
|
//
|
||
|
if ( ( _psa != NULL ) && ( ::SafeArrayGetDim( _psa ) == 1 ) )
|
||
|
{
|
||
|
size_t _cbElem = ::SafeArrayGetElemsize( _psa );
|
||
|
|
||
|
*pcbLength = _cbElem * _psa->cbElements;
|
||
|
_hr = S_OK;
|
||
|
} // if:
|
||
|
|
||
|
break;
|
||
|
} // if:
|
||
|
|
||
|
if ( _varType & VT_VECTOR )
|
||
|
{
|
||
|
break;
|
||
|
} // if: Don't know what to do with a vector...
|
||
|
|
||
|
_varType &= ~VT_BYREF; // mask off the by ref bit if it was set...
|
||
|
|
||
|
if ( ( _varType == VT_I2 ) || ( _varType == VT_I4 ) || ( _varType == VT_BOOL ) || ( _varType == VT_R4 ) )
|
||
|
{
|
||
|
*pcbLength = sizeof( DWORD );
|
||
|
_hr = S_OK;
|
||
|
break;
|
||
|
} // if:
|
||
|
else if ( _varType == VT_BSTR )
|
||
|
{
|
||
|
CComBSTR _bstr;
|
||
|
|
||
|
_bstr.Attach( rvarValue.bstrVal );
|
||
|
*pcbLength = _bstr.Length();
|
||
|
_bstr.Detach();
|
||
|
_hr = S_OK;
|
||
|
break;
|
||
|
} // else if:
|
||
|
else if ( ( _varType == VT_I8 ) || ( _varType == VT_R8 ) )
|
||
|
{
|
||
|
*pcbLength = sizeof( ULONGLONG );
|
||
|
_hr = S_OK;
|
||
|
break;
|
||
|
} // else if:
|
||
|
else if ( _varType == VT_VARIANT )
|
||
|
{
|
||
|
_hr = HrGetVariantLength( *rvarValue.pvarVal, pcbLength, cpfFormat );
|
||
|
break;
|
||
|
} // else if:
|
||
|
}
|
||
|
while( TRUE ); // do-while: want to avoid using a goto ;-)
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValues::HrGetVariantLength()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValues::get_Count
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns the count of elements (values) in the collection.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// plCount [OUT] - Catches the count.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or E_POINTER if not.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CClusPropertyValues::get_Count( OUT long * plCount )
|
||
|
{
|
||
|
//ASSERT( plCount != NULL );
|
||
|
|
||
|
HRESULT _hr = E_POINTER;
|
||
|
|
||
|
if ( plCount != NULL )
|
||
|
{
|
||
|
*plCount = m_cpvvValues.size();
|
||
|
_hr = S_OK;
|
||
|
}
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValues::get_Count()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValues::GetIndex
|
||
|
//
|
||
|
// Description:
|
||
|
// Get the index from the passed in variant.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// varIndex [IN] - Hold the index. This is a one based number.
|
||
|
// pnIndex [OUT] - Catches the zero based index in the collection.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, E_POINTER, or E_INVALIDARG if the index is out
|
||
|
// of range.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CClusPropertyValues::GetIndex(
|
||
|
IN VARIANT varIndex,
|
||
|
OUT UINT * pnIndex
|
||
|
)
|
||
|
{
|
||
|
//ASSERT( pnIndex != NULL );
|
||
|
|
||
|
HRESULT _hr = E_POINTER;
|
||
|
|
||
|
if ( pnIndex != NULL )
|
||
|
{
|
||
|
CComVariant _v;
|
||
|
UINT _nIndex = 0;
|
||
|
|
||
|
*pnIndex = 0;
|
||
|
|
||
|
_v.Copy( &varIndex );
|
||
|
|
||
|
// Check to see if the index is a number.
|
||
|
_hr = _v.ChangeType( VT_I4 );
|
||
|
if ( SUCCEEDED( _hr ) )
|
||
|
{
|
||
|
_nIndex = _v.lVal;
|
||
|
_nIndex--; // Adjust index to be 0 relative instead of 1 relative
|
||
|
}
|
||
|
|
||
|
// We found an index, now check the range.
|
||
|
if ( SUCCEEDED( _hr ) )
|
||
|
{
|
||
|
if ( _nIndex < m_cpvvValues.size() )
|
||
|
{
|
||
|
*pnIndex = _nIndex;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_hr = E_INVALIDARG;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValues::GetIndex()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValues::get_Item
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns the object (value) at the passed in index.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// varIndex [IN] - Hold the index. This is a one based number.
|
||
|
// ppPropertyValue [OUT] - Catches the property value.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, E_POINTER, or E_INVALIDARG if the index is out
|
||
|
// of range, or other HRESULT error.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CClusPropertyValues::get_Item(
|
||
|
IN VARIANT varIndex,
|
||
|
OUT ISClusPropertyValue ** ppPropertyValue
|
||
|
)
|
||
|
{
|
||
|
//ASSERT( ppPropertyValue != NULL );
|
||
|
|
||
|
HRESULT _hr = E_POINTER;
|
||
|
|
||
|
if ( ppPropertyValue != NULL )
|
||
|
{
|
||
|
CComObject< CClusPropertyValue > * _pPropertyValue = NULL;
|
||
|
UINT _nIndex = 0;
|
||
|
|
||
|
//
|
||
|
// Zero the out param
|
||
|
//
|
||
|
*ppPropertyValue = 0;
|
||
|
|
||
|
_hr = GetIndex( varIndex, &_nIndex );
|
||
|
if ( SUCCEEDED( _hr ) )
|
||
|
{
|
||
|
_pPropertyValue = m_cpvvValues[ _nIndex ];
|
||
|
_hr = _pPropertyValue->QueryInterface( IID_ISClusPropertyValue, (void **) ppPropertyValue );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValues::get_Item()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValues::get__NewEnum
|
||
|
//
|
||
|
// Description:
|
||
|
// Create and return a new enumeration for this collection.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// ppunk [OUT] - Catches the new enumeration.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, E_POINTER, or other HRESULT error.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CClusPropertyValues::get__NewEnum( IUnknown ** ppunk )
|
||
|
{
|
||
|
return ::HrNewIDispatchEnum< CClusPropertyValueVector, CComObject< CClusPropertyValue > >( ppunk, m_cpvvValues );
|
||
|
|
||
|
} //*** CClusPropertyValues::get__NewEnum()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValues::Create
|
||
|
//
|
||
|
// Description:
|
||
|
// Finish the heavy weight construction.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// varValue [IN] - The value.
|
||
|
// cptType [IN] - The cluster property type.
|
||
|
// cpfFormat [IN] - The cluster format type.
|
||
|
// bReadOnly [IN] - Is this a read only value/property?
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or other HRESULT error if not.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CClusPropertyValues::Create(
|
||
|
IN VARIANT varValue,
|
||
|
IN CLUSTER_PROPERTY_TYPE cptType,
|
||
|
IN CLUSTER_PROPERTY_FORMAT cpfFormat,
|
||
|
IN BOOL bReadOnly
|
||
|
)
|
||
|
{
|
||
|
HRESULT _hr = S_FALSE;
|
||
|
CComObject< CClusPropertyValue > * _pValue = NULL;
|
||
|
|
||
|
_hr = CComObject< CClusPropertyValue >::CreateInstance( &_pValue );
|
||
|
if ( SUCCEEDED( _hr ) )
|
||
|
{
|
||
|
CSmartPtr< CComObject < CClusPropertyValue > > _ptrValue( _pValue );
|
||
|
DWORD _cbLength = 0;
|
||
|
|
||
|
_hr = HrGetVariantLength( varValue, &_cbLength, cpfFormat );
|
||
|
if ( SUCCEEDED( _hr ) )
|
||
|
{
|
||
|
_hr = _ptrValue->Create( varValue, cptType, cpfFormat, _cbLength, bReadOnly );
|
||
|
if ( SUCCEEDED( _hr ) )
|
||
|
{
|
||
|
m_cpvvValues.insert( m_cpvvValues.end(), _ptrValue );
|
||
|
_ptrValue->AddRef();
|
||
|
} // if:
|
||
|
} // if:
|
||
|
} // if: Can create an instance of CClusPropertyValueData
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValues::Create()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValues::Create
|
||
|
//
|
||
|
// Description:
|
||
|
// Finish the heavy weight construction.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// rpvlValue [IN] - The value list.
|
||
|
// bReadOnly [IN] - Is this a read only value/property?
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or other HRESULT error if not.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CClusPropertyValues::Create(
|
||
|
IN const CClusPropValueList & rpvlValue,
|
||
|
IN BOOL bReadOnly
|
||
|
)
|
||
|
{
|
||
|
return HrFillPropertyValuesVector( const_cast< CClusPropValueList & >( rpvlValue ), bReadOnly );
|
||
|
|
||
|
} //*** CClusPropertyValues::Create()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValues::CreateItem
|
||
|
//
|
||
|
// Description:
|
||
|
// Create a new property value object and add it to the collection.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// bstrName [IN] - property name.
|
||
|
// varValue [IN] - the value to add.
|
||
|
// ppPropertyValue [OUT] - catches the newly created object.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, E_POINTER, or other HRESULT error.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CClusPropertyValues::CreateItem(
|
||
|
IN BSTR bstrName,
|
||
|
IN VARIANT varValue,
|
||
|
OUT ISClusPropertyValue ** ppPropertyValue
|
||
|
)
|
||
|
{
|
||
|
//ASSERT( ppPropertyValue != NULL );
|
||
|
|
||
|
HRESULT _hr = E_POINTER;
|
||
|
|
||
|
//
|
||
|
// TODO: GalenB 17 Jan 2000
|
||
|
//
|
||
|
// If are going to allow Multi-valued property creation we need to implement this method?
|
||
|
//
|
||
|
if ( ppPropertyValue != NULL )
|
||
|
{
|
||
|
_hr = E_NOTIMPL;
|
||
|
} // if: property value interface pointer not specified
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValues::CreateItem()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValues::RemoveItem
|
||
|
//
|
||
|
// Description:
|
||
|
// Remove the property value at the passed in index from the collection.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// varIndex [IN] - contains the index to remove.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, S_FALSE if read only, or other HRESULT error.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CClusPropertyValues::RemoveItem( VARIANT varIndex )
|
||
|
{
|
||
|
//
|
||
|
// TODO: GalenB 17 Jan 2000
|
||
|
//
|
||
|
// If are going to allow Multi-valued property creation we need to implement this method?
|
||
|
//
|
||
|
return E_NOTIMPL;
|
||
|
|
||
|
} //*** CClusPropertyValues::RemoveItem()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValues::HrFillPropertyValuesVector
|
||
|
//
|
||
|
// Description:
|
||
|
// Fill the collection from the passes in value list.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// cplPropValueList [IN] - The value list to parse.
|
||
|
// bReadOnly [IN] - Is this part of a read only property?
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or Win32 error as HRESULT.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CClusPropertyValues::HrFillPropertyValuesVector(
|
||
|
IN CClusPropValueList & cplPropValueList,
|
||
|
IN BOOL bReadOnly
|
||
|
)
|
||
|
{
|
||
|
HRESULT _hr = S_OK;
|
||
|
DWORD _sc;
|
||
|
CComVariant _var;
|
||
|
CComObject< CClusPropertyValue > * _pPropVal = NULL;
|
||
|
CLUSPROP_BUFFER_HELPER _cbhValue = { NULL };
|
||
|
|
||
|
_sc = cplPropValueList.ScMoveToFirstValue();
|
||
|
if ( _sc != ERROR_SUCCESS )
|
||
|
{
|
||
|
_hr = HRESULT_FROM_WIN32( _sc );
|
||
|
} // if: error moving to the first value
|
||
|
else
|
||
|
{
|
||
|
do
|
||
|
{
|
||
|
_cbhValue = cplPropValueList;
|
||
|
|
||
|
_hr = CComObject< CClusPropertyValue >::CreateInstance( &_pPropVal );
|
||
|
if ( SUCCEEDED( _hr ) )
|
||
|
{
|
||
|
CSmartPtr< CComObject < CClusPropertyValue > > _ptrProp( _pPropVal );
|
||
|
|
||
|
_hr = _ptrProp->Create( _cbhValue, bReadOnly );
|
||
|
if ( SUCCEEDED( _hr ) )
|
||
|
{
|
||
|
_ptrProp->AddRef();
|
||
|
m_cpvvValues.insert( m_cpvvValues.end(), _ptrProp );
|
||
|
} // if: create property ok
|
||
|
} // if: create property instance ok
|
||
|
|
||
|
//
|
||
|
// Move to the next value.
|
||
|
//
|
||
|
_sc = cplPropValueList.ScMoveToNextValue();
|
||
|
|
||
|
} while ( _sc == ERROR_SUCCESS ); // do-while: there are value in the list
|
||
|
|
||
|
if ( _sc != ERROR_NO_MORE_ITEMS )
|
||
|
{
|
||
|
_hr = HRESULT_FROM_WIN32( _sc );
|
||
|
} // if: error occurred moving to the next value
|
||
|
} // else: moved to the first value successfully
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValues::HrFillPropertyValuesVector()
|
||
|
|
||
|
|
||
|
//*************************************************************************//
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CClusPropertyValueData class
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValueData::CClusPropertyValueData
|
||
|
//
|
||
|
// Description:
|
||
|
// Constructor.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
CClusPropertyValueData::CClusPropertyValueData( void )
|
||
|
{
|
||
|
m_cpfFormat = CLUSPROP_FORMAT_UNKNOWN;
|
||
|
m_dwFlags = 0;
|
||
|
m_piids = (const IID *) iidCClusPropertyValueData;
|
||
|
m_piidsSize = ARRAYSIZE( iidCClusPropertyValueData );
|
||
|
|
||
|
} //*** CClusPropertyValueData::CClusPropertyValueData()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValueData::~CClusPropertyValueData
|
||
|
//
|
||
|
// Description:
|
||
|
// Destructor.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
CClusPropertyValueData::~CClusPropertyValueData( void )
|
||
|
{
|
||
|
Clear();
|
||
|
|
||
|
} //*** CClusPropertyValueData::~CClusPropertyValueData()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValueData::Clear
|
||
|
//
|
||
|
// Description:
|
||
|
// Erase the data collection.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CClusPropertyValueData::Clear( void )
|
||
|
{
|
||
|
if ( ! m_cpvdvData.empty() )
|
||
|
{
|
||
|
m_cpvdvData.erase( m_cpvdvData.begin(), m_cpvdvData.end() );
|
||
|
} // if:
|
||
|
|
||
|
} //*** CClusPropertyValueData::Clear()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValueData::get_Count
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns the count of elements (data) in the collection.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// plCount [OUT] - Catches the count.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or E_POINTER if not.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CClusPropertyValueData::get_Count( OUT long * plCount )
|
||
|
{
|
||
|
//ASSERT( plCount != NULL );
|
||
|
|
||
|
HRESULT _hr = E_POINTER;
|
||
|
|
||
|
if ( plCount != NULL )
|
||
|
{
|
||
|
*plCount = m_cpvdvData.size();
|
||
|
_hr = S_OK;
|
||
|
}
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValueData::get_Count()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValueData::GetIndex
|
||
|
//
|
||
|
// Description:
|
||
|
// Get the index from the passed in variant.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// varIndex [IN] - Hold the index. This is a one based number.
|
||
|
// pnIndex [OUT] - Catches the zero based index in the collection.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, E_POINTER, or E_INVALIDARG if the index is out
|
||
|
// of range.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CClusPropertyValueData::GetIndex(
|
||
|
IN VARIANT varIndex,
|
||
|
OUT UINT * pnIndex
|
||
|
)
|
||
|
{
|
||
|
//ASSERT( pnIndex != NULL );
|
||
|
|
||
|
HRESULT _hr = E_POINTER;
|
||
|
|
||
|
if ( pnIndex != NULL )
|
||
|
{
|
||
|
CComVariant _v;
|
||
|
UINT _nIndex = 0;
|
||
|
|
||
|
*pnIndex = 0;
|
||
|
|
||
|
_v.Copy( &varIndex );
|
||
|
|
||
|
// Check to see if the index is a number.
|
||
|
_hr = _v.ChangeType( VT_I4 );
|
||
|
if ( SUCCEEDED( _hr ) )
|
||
|
{
|
||
|
_nIndex = _v.lVal;
|
||
|
_nIndex--; // Adjust index to be 0 relative instead of 1 relative
|
||
|
}
|
||
|
|
||
|
// We found an index, now check the range.
|
||
|
if ( SUCCEEDED( _hr ) )
|
||
|
{
|
||
|
if ( _nIndex < m_cpvdvData.size() )
|
||
|
{
|
||
|
*pnIndex = _nIndex;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_hr = E_INVALIDARG;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValueData::GetIndex()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValueData::get_Item
|
||
|
//
|
||
|
// Description:
|
||
|
// Returns the object (data) at the passed in index.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// varIndex [IN] - Hold the index. This is a one based number.
|
||
|
// pvarData [OUT] - Catches the property value.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, E_POINTER, or E_INVALIDARG if the index is out
|
||
|
// of range, or other HRESULT error.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CClusPropertyValueData::get_Item(
|
||
|
IN VARIANT varIndex,
|
||
|
OUT VARIANT * pvarData
|
||
|
)
|
||
|
{
|
||
|
//ASSERT( pvarData != NULL );
|
||
|
|
||
|
HRESULT _hr = E_POINTER;
|
||
|
|
||
|
if ( pvarData != NULL )
|
||
|
{
|
||
|
UINT _nIndex = 0;
|
||
|
|
||
|
_hr = GetIndex( varIndex, &_nIndex );
|
||
|
if ( SUCCEEDED( _hr ) )
|
||
|
{
|
||
|
_hr = VariantCopyInd( pvarData, &m_cpvdvData[ _nIndex ] );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValueData::get_Item()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValueData::get__NewEnum
|
||
|
//
|
||
|
// Description:
|
||
|
// Create and return a new enumeration for this collection.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// ppunk [OUT] - Catches the new enumeration.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, E_POINTER, or other HRESULT error.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CClusPropertyValueData::get__NewEnum( IUnknown ** ppunk )
|
||
|
{
|
||
|
return ::HrNewVariantEnum< CClusPropertyValueDataVector >( ppunk, m_cpvdvData );
|
||
|
|
||
|
} //*** CClusPropertyValueData::get__NewEnum()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValueData::Create
|
||
|
//
|
||
|
// Description:
|
||
|
// Finish the heavy weight construction.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// varValue [IN] - The data value.
|
||
|
// cpfFormat [IN] - The cluster property format.
|
||
|
// bReadOnly [IN] - Is this data for a read only property?
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK -- Always!!!
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CClusPropertyValueData::Create(
|
||
|
IN VARIANT varValue,
|
||
|
IN CLUSTER_PROPERTY_FORMAT cpfFormat,
|
||
|
IN BOOL bReadOnly
|
||
|
)
|
||
|
{
|
||
|
if ( bReadOnly )
|
||
|
{
|
||
|
m_dwFlags |= READONLY;
|
||
|
} // if: set the read only flag
|
||
|
else
|
||
|
{
|
||
|
m_dwFlags &= ~READONLY;
|
||
|
} // else: clear the read only flag
|
||
|
|
||
|
m_cpfFormat = cpfFormat;
|
||
|
|
||
|
if ( ( varValue.vt & VT_BYREF ) && ( varValue.vt & VT_VARIANT ) )
|
||
|
{
|
||
|
m_cpvdvData.insert( m_cpvdvData.end(), *varValue.pvarVal );
|
||
|
} // if: the variant is a reference to another variant...
|
||
|
else
|
||
|
{
|
||
|
m_cpvdvData.insert( m_cpvdvData.end(), varValue );
|
||
|
} // else: the variant is the data...
|
||
|
|
||
|
return S_OK;
|
||
|
|
||
|
} //*** CClusPropertyValueData::Create()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValueData::Create
|
||
|
//
|
||
|
// Description:
|
||
|
// Finish the heavy weight construction.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// cbhValue [IN] - The value buffer helper.
|
||
|
// bReadOnly [IN] - Is this data for a read only property?
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or other HRESULT error if not.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CClusPropertyValueData::Create(
|
||
|
IN CLUSPROP_BUFFER_HELPER cbhValue,
|
||
|
IN BOOL bReadOnly
|
||
|
)
|
||
|
{
|
||
|
HRESULT _hr = S_OK;
|
||
|
|
||
|
if ( bReadOnly )
|
||
|
{
|
||
|
m_dwFlags |= READONLY;
|
||
|
} // if: set the read only flag
|
||
|
else
|
||
|
{
|
||
|
m_dwFlags &= ~READONLY;
|
||
|
} // else: clear the read only flag
|
||
|
|
||
|
m_cpfFormat = (CLUSTER_PROPERTY_FORMAT) cbhValue.pValue->Syntax.wFormat;
|
||
|
|
||
|
switch( m_cpfFormat )
|
||
|
{
|
||
|
#if CLUSAPI_VERSION >= 0x0500
|
||
|
case CLUSPROP_FORMAT_EXPANDED_SZ:
|
||
|
#endif // CLUSAPI_VERSION >= 0x0500
|
||
|
case CLUSPROP_FORMAT_SZ:
|
||
|
case CLUSPROP_FORMAT_EXPAND_SZ:
|
||
|
{
|
||
|
m_cpvdvData.insert( m_cpvdvData.end(), cbhValue.pStringValue->sz );
|
||
|
break;
|
||
|
} // case:
|
||
|
|
||
|
#if CLUSAPI_VERSION >= 0x0500
|
||
|
case CLUSPROP_FORMAT_LONG:
|
||
|
#endif // CLUSAPI_VERSION >= 0x0500
|
||
|
case CLUSPROP_FORMAT_DWORD:
|
||
|
{
|
||
|
#if CLUSAPI_VERSION >= 0x0500
|
||
|
m_cpvdvData.insert( m_cpvdvData.end(), cbhValue.pLongValue->l );
|
||
|
#else
|
||
|
m_cpvdvData.insert( m_cpvdvData.end(), (long) cbhValue.pDwordValue->dw );
|
||
|
#endif // CLUSAPI_VERSION >= 0x0500
|
||
|
break;
|
||
|
} // case:
|
||
|
|
||
|
case CLUSPROP_FORMAT_MULTI_SZ:
|
||
|
{
|
||
|
_hr = HrCreateMultiSz( cbhValue );
|
||
|
break;
|
||
|
} // case:
|
||
|
|
||
|
case CLUSPROP_FORMAT_BINARY:
|
||
|
{
|
||
|
_hr = HrCreateBinary( cbhValue );
|
||
|
break;
|
||
|
} // case:
|
||
|
|
||
|
default:
|
||
|
{
|
||
|
break;
|
||
|
} // default:
|
||
|
} // switch:
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValueData::Create()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValueData::CreateItem
|
||
|
//
|
||
|
// Description:
|
||
|
// Create a new object and add it to the collection.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// varValue [IN] - value to add.
|
||
|
// pvarData [OUT] - catches the new created object.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, S_FALSE if read only, or other HRESULT error.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CClusPropertyValueData::CreateItem(
|
||
|
IN VARIANT varValue,
|
||
|
OUT VARIANT * pvarData
|
||
|
)
|
||
|
{
|
||
|
//ASSERT( pvarData != NULL );
|
||
|
|
||
|
HRESULT _hr = E_POINTER;
|
||
|
|
||
|
if ( pvarData != NULL )
|
||
|
{
|
||
|
if ( ( m_dwFlags & READONLY ) == 0 )
|
||
|
{
|
||
|
if ( ( m_cpfFormat == CLUSPROP_FORMAT_MULTI_SZ ) && ( varValue.vt == VT_BSTR ) )
|
||
|
{
|
||
|
m_cpvdvData.insert( m_cpvdvData.end(), varValue );
|
||
|
*pvarData = varValue; // kinda acquard, but that's automation for ya'
|
||
|
_hr = S_OK;
|
||
|
} // if:
|
||
|
else
|
||
|
{
|
||
|
_hr = E_INVALIDARG;
|
||
|
} // else:
|
||
|
} // if:
|
||
|
else
|
||
|
{
|
||
|
_hr = S_FALSE;
|
||
|
} // else:
|
||
|
} // if:
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValueData::CreateItem()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValueData::RemoveItem
|
||
|
//
|
||
|
// Description:
|
||
|
// Remove the data at the passed in index.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// varIndex [IN] - variant that contains the index to remove.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, S_FALSE if read only, or other HRESULT error.
|
||
|
//
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
STDMETHODIMP CClusPropertyValueData::RemoveItem( IN VARIANT varIndex )
|
||
|
{
|
||
|
HRESULT _hr = S_FALSE;
|
||
|
|
||
|
if ( ( m_dwFlags & READONLY ) == 0 )
|
||
|
{
|
||
|
UINT _iDelete = 0;
|
||
|
|
||
|
_hr = GetIndex( varIndex, &_iDelete );
|
||
|
if ( SUCCEEDED( _hr ) )
|
||
|
{
|
||
|
CClusPropertyValueDataVector::iterator _itDelete = m_cpvdvData.begin();
|
||
|
CClusPropertyValueDataVector::const_iterator _itLast = m_cpvdvData.end();
|
||
|
UINT _nCount;
|
||
|
|
||
|
for ( _nCount = 0; ( ( _iDelete < _nCount ) && ( _itDelete != _itLast ) ); _itDelete++, _nCount++ )
|
||
|
{
|
||
|
} // for:
|
||
|
|
||
|
m_cpvdvData.erase( _itDelete );
|
||
|
|
||
|
_hr = S_OK;
|
||
|
}
|
||
|
} // if:
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValueData::RemoveItem()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValueData::operator=
|
||
|
//
|
||
|
// Description:
|
||
|
// Saves the passed in data into the collection at the default
|
||
|
// position.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// varvalue [IN] - The data to save.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// The old data.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
const CComVariant & CClusPropertyValueData::operator=(
|
||
|
IN const CComVariant & varData
|
||
|
)
|
||
|
{
|
||
|
m_cpvdvData[ 0 ] = varData;
|
||
|
|
||
|
return m_cpvdvData[ 0 ];
|
||
|
|
||
|
} //*** CClusPropertyValueData::operator=()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValueData::HrCreateMultiSz
|
||
|
//
|
||
|
// Description:
|
||
|
// Parse the passed in multi string into a collection of strings.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// cbhValue [IN] - The property value buffer helper.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK -- Always!
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CClusPropertyValueData::HrCreateMultiSz(
|
||
|
IN CLUSPROP_BUFFER_HELPER cbhValue
|
||
|
)
|
||
|
{
|
||
|
HRESULT _hr = S_OK;
|
||
|
LPWSTR _psz = cbhValue.pMultiSzValue->sz;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
m_cpvdvData.insert( m_cpvdvData.end(), _psz );
|
||
|
_psz += lstrlenW( _psz ) + 1;
|
||
|
}
|
||
|
while( *_psz != L'\0' ); // do-while not at end of string...
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValueData::HrCreateMultiSz()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValueData::HrFillMultiSzBuffer
|
||
|
//
|
||
|
// Description:
|
||
|
// Create a multi string from the collection of strings.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// ppsz [OUT] - Catches the mutli string.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or Win32 error as HRESULT if not.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CClusPropertyValueData::HrFillMultiSzBuffer( OUT LPWSTR * ppsz ) const
|
||
|
{
|
||
|
//ASSERT( ppsz != NULL );
|
||
|
|
||
|
HRESULT _hr = E_POINTER;
|
||
|
DWORD _cbLength = 0;
|
||
|
CClusPropertyValueDataVector::const_iterator _itFirst = m_cpvdvData.begin();
|
||
|
CClusPropertyValueDataVector::const_iterator _itLast = m_cpvdvData.end();
|
||
|
|
||
|
if ( ppsz != NULL )
|
||
|
{
|
||
|
_hr = S_OK;
|
||
|
for ( ; _itFirst != _itLast; _itFirst++ )
|
||
|
{
|
||
|
if ( (*_itFirst).vt == VT_BSTR )
|
||
|
{
|
||
|
_cbLength += ( ::lstrlenW( (*_itFirst).bstrVal ) + 1 ); // don't forget the NULL!
|
||
|
} // if:
|
||
|
else
|
||
|
{
|
||
|
_hr = E_INVALIDARG;
|
||
|
break;
|
||
|
} // else:
|
||
|
} // for:
|
||
|
|
||
|
if ( SUCCEEDED( _hr ) )
|
||
|
{
|
||
|
LPWSTR _psz = NULL;
|
||
|
|
||
|
*ppsz = (LPWSTR) ::LocalAlloc( LMEM_ZEROINIT, _cbLength + 2 ); // ends in NULL NULL
|
||
|
if ( *ppsz != NULL )
|
||
|
{
|
||
|
_psz = *ppsz;
|
||
|
|
||
|
for ( _itFirst = m_cpvdvData.begin(); _itFirst != _itLast; _itFirst++ )
|
||
|
{
|
||
|
_cbLength = lstrlenW( (*_itFirst).bstrVal );
|
||
|
::lstrcpyW( _psz, (*_itFirst).bstrVal );
|
||
|
_psz += ( _cbLength + 1 );
|
||
|
} // for:
|
||
|
|
||
|
} // if:
|
||
|
else
|
||
|
{
|
||
|
DWORD _sc = ::GetLastError();
|
||
|
|
||
|
_hr = HRESULT_FROM_WIN32( _sc );
|
||
|
} // else:
|
||
|
} // if:
|
||
|
} // if:
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValueData::HrFillMultiSzBuffer()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValueData::HrCreateBinary
|
||
|
//
|
||
|
// Description:
|
||
|
// Create a safeArray from the passed in binary property value.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// cbhValue [IN] - The binary property value.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or other HRESULT error if not.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CClusPropertyValueData::HrCreateBinary(
|
||
|
IN CLUSPROP_BUFFER_HELPER cbhValue
|
||
|
)
|
||
|
{
|
||
|
HRESULT _hr = E_OUTOFMEMORY;
|
||
|
SAFEARRAY * _psa = NULL;
|
||
|
SAFEARRAYBOUND _sab[ 1 ];
|
||
|
|
||
|
_sab[ 0 ].lLbound = 0;
|
||
|
_sab[ 0 ].cElements = cbhValue.pValue->cbLength;
|
||
|
|
||
|
//
|
||
|
// allocate a one dimensional SafeArray of BYTES
|
||
|
//
|
||
|
_psa = ::SafeArrayCreate( VT_UI1, 1, _sab );
|
||
|
if ( _psa != NULL )
|
||
|
{
|
||
|
PBYTE _pb = NULL;
|
||
|
|
||
|
//
|
||
|
// get a pointer to the SafeArray
|
||
|
//
|
||
|
_hr = ::SafeArrayAccessData( _psa, (PVOID *) &_pb );
|
||
|
if ( SUCCEEDED( _hr ) )
|
||
|
{
|
||
|
CComVariant _var;
|
||
|
|
||
|
::CopyMemory( _pb, cbhValue.pBinaryValue->rgb, cbhValue.pValue->cbLength );
|
||
|
|
||
|
//
|
||
|
// tell the variant what it is holding onto
|
||
|
//
|
||
|
_var.parray = _psa;
|
||
|
_var.vt = VT_ARRAY | VT_UI1;
|
||
|
|
||
|
m_cpvdvData.insert( m_cpvdvData.end(), _var );
|
||
|
|
||
|
//
|
||
|
// release the pointer into the SafeArray
|
||
|
//
|
||
|
_hr = ::SafeArrayUnaccessData( _psa );
|
||
|
} // if:
|
||
|
} // if:
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValueData::HrCreateBinary()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CClusPropertyValueData::HrBinaryValue
|
||
|
//
|
||
|
// Description:
|
||
|
// Set the binary value of this property value data.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// psa [IN] - The SAFEARRY to save.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK if successful, or other HRESULT error.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CClusPropertyValueData::HrBinaryValue( IN SAFEARRAY * psa )
|
||
|
{
|
||
|
ASSERT( psa != NULL );
|
||
|
|
||
|
HRESULT _hr = E_POINTER;
|
||
|
|
||
|
if ( psa != NULL )
|
||
|
{
|
||
|
CComVariant _var;
|
||
|
|
||
|
if ( ! m_cpvdvData.empty() )
|
||
|
{
|
||
|
m_cpvdvData.erase( m_cpvdvData.begin() );
|
||
|
} // if:
|
||
|
|
||
|
//
|
||
|
// tell the variant what it is holding onto
|
||
|
//
|
||
|
_var.parray = psa;
|
||
|
_var.vt = VT_ARRAY | VT_UI1;
|
||
|
|
||
|
m_cpvdvData.insert( m_cpvdvData.begin(), _var );
|
||
|
_hr = S_OK;
|
||
|
} // if:
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CClusPropertyValueData::HrBinaryValue()
|