Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2896 lines
89 KiB

/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1997-2002 Microsoft Corporation
//
// Module Name:
// PropListSrc.cpp
//
// Header File:
// PropList.h
//
// Description:
// Implementation of the CClusPropList class.
//
// Maintained By:
// Galen Barbee (GalenB) 31-MAY-2000
//
/////////////////////////////////////////////////////////////////////////////
#include <StrSafe.h>
#include <PropList.h>
#include "clstrcmp.h"
/////////////////////////////////////////////////////////////////////////////
// Constant Definitions
/////////////////////////////////////////////////////////////////////////////
const int BUFFER_GROWTH_FACTOR = 256;
/////////////////////////////////////////////////////////////////////////////
//++
//
// CchMultiSz
//
// Description:
// Length of all of the substrings of a multisz string minus the final NULL.
//
// (i.e., includes the nulls of the substrings, excludes the final null)
// multiszlen( "abcd\0efgh\0\0" => 5 + 5 = 10
//
// Arguments:
// psz [IN] The string to get the length of.
//
// Return Value:
// Count of characters in the multisz or 0 if empty.
//
//--
/////////////////////////////////////////////////////////////////////////////
static size_t CchMultiSz(
IN LPCWSTR psz
)
{
Assert( psz != NULL );
size_t _cchTotal = 0;
size_t _cchChars;
while ( *psz != L'\0' )
{
_cchChars = wcslen( psz ) + 1;
_cchTotal += _cchChars;
psz += _cchChars;
} // while: pointer not stopped on EOS
return _cchTotal;
} //*** CchMultiSz
/////////////////////////////////////////////////////////////////////////////
//++
//
// NCompareMultiSz
//
// Description:
// Compare two MULTI_SZ buffers.
//
// Arguments:
// pszSource [IN] The source string.
// pszTarget [IN] The target string.
//
// Return Value:
// If the string pointed to by pszSource is less than the string pointed
// to by pszTarget, the return value is negative. If the string pointed
// to by pszSource is greater than the string pointed to by pszTarget,
// the return value is positive. If the strings are equal, the return value
// is zero.
//
//--
/////////////////////////////////////////////////////////////////////////////
static int NCompareMultiSz(
IN LPCWSTR pszSource,
IN LPCWSTR pszTarget
)
{
Assert( pszSource != NULL );
Assert( pszTarget != NULL );
while ( ( *pszSource != L'\0' ) && ( *pszTarget != L'\0') )
{
//
// Move to end of strings.
//
while ( ( *pszSource != L'\0' ) && ( *pszTarget != L'\0') && ( *pszSource == *pszTarget ) )
{
++pszSource;
++pszTarget;
} // while: pointer not stopped on EOS
//
// If strings are the same, skip past terminating NUL.
// Otherwise exit the loop.
if ( ( *pszSource == L'\0' ) && ( *pszTarget == L'\0') )
{
++pszSource;
++pszTarget;
} // if: both stopped on EOS
else
{
break;
} // else: stopped because something is not equal -- wr are done.
} // while: pointer not stopped on EOS
return *pszSource - *pszTarget;
} //*** NCompareMultiSz
//*************************************************************************//
/////////////////////////////////////////////////////////////////////////////
// CClusPropValueList class
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropValueList::ScMoveToFirstValue
//
// Description:
// Move the cursor to the first value in the value list.
//
// Arguments:
// None.
//
// Return Value:
// ERROR_SUCCESS Position moved to the first value successfully.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropValueList::ScMoveToFirstValue( void )
{
Assert( m_cbhValueList.pb != NULL );
DWORD _sc;
m_cbhCurrentValue = m_cbhValueList;
m_cbDataLeft = m_cbDataSize;
m_fAtEnd = FALSE;
if ( m_cbhCurrentValue.pSyntax->dw == CLUSPROP_SYNTAX_ENDMARK )
{
_sc = ERROR_NO_MORE_ITEMS;
} // if: no items in the value list
else
{
_sc = ERROR_SUCCESS;
} // else: items exist in the value list
return _sc;
} //*** CClusPropValueList::ScMoveToFirstValue
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropValueList::ScMoveToNextValue
//
// Description:
// Move the cursor to the next value in the list.
//
// Arguments:
// None.
//
// Return Value:
// ERROR_SUCCESS Position moved to the next value successfully.
// ERROR_NO_MORE_ITEMS Already at the end of the list.
// ERROR_INVALID_DATA Not enough data in the buffer.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropValueList::ScMoveToNextValue( void )
{
Assert( m_cbhCurrentValue.pb != NULL );
DWORD _sc = ERROR_NO_MORE_ITEMS;
size_t _cbDataSize;
CLUSPROP_BUFFER_HELPER _cbhCurrentValue;
_cbhCurrentValue = m_cbhCurrentValue;
//
// Don't try to move if we're already at the end.
//
if ( m_fAtEnd )
{
goto Cleanup;
} // if: already at the end of the list
//
// Make sure the buffer is big enough for the value header.
//
if ( m_cbDataLeft < sizeof( *_cbhCurrentValue.pValue ) )
{
_sc = TW32( ERROR_INVALID_DATA );
goto Cleanup;
} // if: not enough data left
//
// Calculate how much to advance buffer pointer.
//
_cbDataSize = sizeof( *_cbhCurrentValue.pValue )
+ ALIGN_CLUSPROP( _cbhCurrentValue.pValue->cbLength );
//
// Make sure the buffer is big enough for the value header,
// the data itself, and the endmark.
//
if ( m_cbDataLeft < _cbDataSize + sizeof( CLUSPROP_SYNTAX ) )
{
_sc = TW32( ERROR_INVALID_DATA );
goto Cleanup;
} // if: not enough data left
//
// Move past the current value to the next value's syntax.
//
_cbhCurrentValue.pb += _cbDataSize;
//
// This test will ensure that the value is always valid since we won't
// advance if the next thing is the endmark.
//
if ( _cbhCurrentValue.pSyntax->dw != CLUSPROP_SYNTAX_ENDMARK )
{
m_cbhCurrentValue = _cbhCurrentValue;
m_cbDataLeft -= _cbDataSize;
_sc = ERROR_SUCCESS;
} // if: next value's syntax is not the endmark
else
{
m_fAtEnd = TRUE;
} // else: next value's syntax is the endmark
Cleanup:
return _sc;
} //*** CClusPropValueList::ScMoveToNextValue
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropValueList::ScCheckIfAtLastValue
//
// Description:
// Indicate whether we are on the last value in the list or not.
//
// Arguments:
// None.
//
// Return Value:
// ERROR_SUCCESS Not currently at the last value in the list.
// ERROR_NO_MORE_ITEMS Currently at the last value in the list.
// ERROR_INVALID_DATA Not enough data in the buffer.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropValueList::ScCheckIfAtLastValue( void )
{
Assert( m_cbhCurrentValue.pb != NULL );
DWORD _sc = ERROR_SUCCESS;
CLUSPROP_BUFFER_HELPER _cbhCurrentValue;
size_t _cbDataSize;
_cbhCurrentValue = m_cbhCurrentValue;
//
// Don't try to recalculate if we already know
// we're at the end of the list.
//
if ( m_fAtEnd )
{
goto Cleanup;
} // if: already at the end of the list
//
// Make sure the buffer is big enough for the value header.
//
if ( m_cbDataLeft < sizeof( *_cbhCurrentValue.pValue ) )
{
_sc = TW32( ERROR_INVALID_DATA );
goto Cleanup;
} // if: not enough data left
//
// Calculate how much to advance buffer pointer.
//
_cbDataSize = sizeof( *_cbhCurrentValue.pValue )
+ ALIGN_CLUSPROP( _cbhCurrentValue.pValue->cbLength );
//
// Make sure the buffer is big enough for the value header,
// the data itself, and the endmark.
//
if ( m_cbDataLeft < _cbDataSize + sizeof( CLUSPROP_SYNTAX ) )
{
_sc = TW32( ERROR_INVALID_DATA );
goto Cleanup;
} // if: not enough data left
//
// Move past the current value to the next value's syntax.
//
_cbhCurrentValue.pb += _cbDataSize;
//
// We are on the last value if the next thing after this value
// is an endmark.
//
if ( _cbhCurrentValue.pSyntax->dw == CLUSPROP_SYNTAX_ENDMARK )
{
_sc = ERROR_NO_MORE_ITEMS;
} // if: next value's syntax is the endmark
Cleanup:
return _sc;
} //*** CClusPropValueList::ScCheckIfAtLastValue
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropValueList::ScAllocValueList
//
// Description:
// Allocate a value list buffer that's big enough to hold the next
// value.
//
// Arguments:
// cbMinimum [IN] Minimum size of the value list.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropValueList::ScAllocValueList( IN size_t cbMinimum )
{
Assert( cbMinimum > 0 );
DWORD _sc = ERROR_SUCCESS;
size_t _cbTotal = 0;
//
// Add the size of the item count and final endmark.
//
cbMinimum += sizeof( CLUSPROP_VALUE );
_cbTotal = m_cbDataSize + cbMinimum;
if ( m_cbBufferSize < _cbTotal )
{
PBYTE _pbNewValuelist = NULL;
cbMinimum = max( BUFFER_GROWTH_FACTOR, cbMinimum );
_cbTotal = m_cbDataSize + cbMinimum;
//
// Allocate and zero a new buffer.
//
_pbNewValuelist = new BYTE[ _cbTotal ];
if ( _pbNewValuelist != NULL )
{
ZeroMemory( _pbNewValuelist, _cbTotal );
//
// If there was a previous buffer, copy it and the delete it.
//
if ( m_cbhValueList.pb != NULL )
{
if ( m_cbDataSize != 0 )
{
CopyMemory( _pbNewValuelist, m_cbhValueList.pb, m_cbDataSize );
} // if: data already exists in buffer
delete [] m_cbhValueList.pb;
m_cbhCurrentValue.pb = _pbNewValuelist + (m_cbhCurrentValue.pb - m_cbhValueList.pb);
} // if: there was a previous buffer
else
{
m_cbhCurrentValue.pb = _pbNewValuelist + sizeof( DWORD ); // move past prop count
} // else: no previous buffer
//
// Save the new buffer.
//
m_cbhValueList.pb = _pbNewValuelist;
m_cbBufferSize = _cbTotal;
} // if: allocation succeeded
else
{
_sc = TW32( ERROR_NOT_ENOUGH_MEMORY );
} // else: allocation failed
} // if: buffer isn't big enough
return _sc;
} //*** CClusPropValueList::ScAllocValueList
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropValueList::ScGetResourceValueList
//
// Description:
// Get value list of a resource.
//
// Arguments:
// hResource [IN] Handle for the resource to get properties from.
// dwControlCode [IN] Control code for the request.
// hHostNode [IN] Handle for the node to direct this request to.
// Defaults to NULL.
// lpInBuffer [IN] Input buffer for the request. Defaults to NULL.
// cbInBufferSize [IN] Size of the input buffer. Defaults to 0.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropValueList::ScGetResourceValueList(
IN HRESOURCE hResource,
IN DWORD dwControlCode,
IN HNODE hHostNode,
IN LPVOID lpInBuffer,
IN size_t cbInBufferSize
)
{
Assert( hResource != NULL );
Assert( (dwControlCode & (CLUSCTL_OBJECT_MASK << CLUSCTL_OBJECT_SHIFT))
== (CLUS_OBJECT_RESOURCE << CLUSCTL_OBJECT_SHIFT) );
DWORD _sc = ERROR_SUCCESS;
DWORD _cb = 512;
//
// Overwrite anything that may be in the buffer.
// Allows this class instance to be reused.
//
m_cbDataSize = 0;
//
// Get values.
//
_sc = ScAllocValueList( _cb );
if ( _sc == ERROR_SUCCESS )
{
_sc = TW32E( ClusterResourceControl(
hResource,
hHostNode,
dwControlCode,
lpInBuffer,
static_cast< DWORD >( cbInBufferSize ),
m_cbhValueList.pb,
static_cast< DWORD >( m_cbBufferSize ),
&_cb
), ERROR_MORE_DATA );
if ( _sc == ERROR_MORE_DATA )
{
_sc = TW32( ScAllocValueList( _cb ) );
if ( _sc == ERROR_SUCCESS )
{
_sc = TW32( ClusterResourceControl(
hResource,
hHostNode,
dwControlCode,
lpInBuffer,
static_cast< DWORD >( cbInBufferSize ),
m_cbhValueList.pb,
static_cast< DWORD >( m_cbBufferSize ),
&_cb
) );
} // if: ScAllocValueList succeeded
} // if: buffer too small
} // if: ScAllocValueList succeeded
if ( _sc != ERROR_SUCCESS )
{
DeleteValueList();
} // if: error getting properties.
else
{
m_cbDataSize = static_cast< size_t >( _cb );
m_cbDataLeft = static_cast< size_t >( _cb );
} // else: no errors
return _sc;
} //*** CClusPropValueList::ScGetResourceValueList
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropValueList::ScGetResourceTypeValueList
//
// Description:
// Get value list of a resource type.
//
// Arguments:
// hCluster [IN] Handle for the cluster in which the resource
// type resides.
// pwszResTypeName [IN] Name of the resource type.
// dwControlCode [IN] Control code for the request.
// hHostNode [IN] Handle for the node to direct this request to.
// Defaults to NULL.
// lpInBuffer [IN] Input buffer for the request. Defaults to NULL.
// cbInBufferSize [IN] Size of the input buffer. Defaults to 0.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropValueList::ScGetResourceTypeValueList(
IN HCLUSTER hCluster,
IN LPCWSTR pwszResTypeName,
IN DWORD dwControlCode,
IN HNODE hHostNode,
IN LPVOID lpInBuffer,
IN size_t cbInBufferSize
)
{
Assert( hCluster != NULL );
Assert( pwszResTypeName != NULL );
Assert( *pwszResTypeName != L'\0' );
Assert( (dwControlCode & (CLUSCTL_OBJECT_MASK << CLUSCTL_OBJECT_SHIFT))
== (CLUS_OBJECT_RESOURCE_TYPE << CLUSCTL_OBJECT_SHIFT) );
DWORD _sc = ERROR_SUCCESS;
DWORD _cb = 512;
//
// Overwrite anything that may be in the buffer.
// Allows this class instance to be reused.
//
m_cbDataSize = 0;
//
// Get values.
//
_sc = ScAllocValueList( _cb );
if ( _sc == ERROR_SUCCESS )
{
_sc = TW32E( ClusterResourceTypeControl(
hCluster,
pwszResTypeName,
hHostNode,
dwControlCode,
lpInBuffer,
static_cast< DWORD >( cbInBufferSize ),
m_cbhValueList.pb,
static_cast< DWORD >( m_cbBufferSize ),
&_cb
), ERROR_MORE_DATA );
if ( _sc == ERROR_MORE_DATA )
{
_sc = TW32( ScAllocValueList( _cb ) );
if ( _sc == ERROR_SUCCESS )
{
_sc = TW32( ClusterResourceTypeControl(
hCluster,
pwszResTypeName,
hHostNode,
dwControlCode,
lpInBuffer,
static_cast< DWORD >( cbInBufferSize ),
m_cbhValueList.pb,
static_cast< DWORD >( m_cbBufferSize ),
&_cb
) );
} // if: ScAllocValueList succeeded
} // if: buffer too small
} // if: ScAllocValueList succeeded
if ( _sc != ERROR_SUCCESS )
{
DeleteValueList();
} // if: error getting properties.
else
{
m_cbDataSize = static_cast< size_t >( _cb );
m_cbDataLeft = static_cast< size_t >( _cb );
} // else: no errors
return _sc;
} //*** CClusPropValueList::ScGetResourceTypeValueList
//*************************************************************************//
/////////////////////////////////////////////////////////////////////////////
// CClusPropList class
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScCopy
//
// Description:
// Copy a property list. This function is equivalent to an assignment
// operator. Since this operation can fail, no assignment operator is
// provided.
//
// Arguments:
// pcplPropList [IN] The proplist to copy into this instance.
// cbListSize [IN] The total size of the prop list.
//
// Return Value:
// Win32 status code.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScCopy(
IN const PCLUSPROP_LIST pcplPropList,
IN size_t cbListSize
)
{
Assert( pcplPropList != NULL );
DWORD _sc = ERROR_SUCCESS;
//
// Clean up any vestiges of a previous prop list.
//
if ( m_cbhPropList.pb != NULL )
{
DeletePropList();
} // if: the current list is not empty
//
// Allocate the new property list buffer. If successful,
// copy the source list.
//
m_cbhPropList.pb = new BYTE[ cbListSize ];
if ( m_cbhPropList.pb != NULL )
{
CopyMemory( m_cbhPropList.pList, pcplPropList, cbListSize );
m_cbBufferSize = cbListSize;
m_cbDataSize = cbListSize;
m_cbDataLeft = cbListSize;
_sc = ScMoveToFirstProperty();
} // if: new succeeded
else
{
_sc = TW32( ERROR_NOT_ENOUGH_MEMORY );
} // else:
return _sc;
} //*** CClusPropList::ScCopy
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScAppend
//
// Description:
// Append to a property list.
//
// Arguments:
// rclPropList [IN] The proplist to append onto this instance.
//
// Return Value:
// Win32 status code.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScAppend( IN const CClusPropList & rclPropList )
{
DWORD _sc = ERROR_SUCCESS;
size_t _cbPropertyCountOffset;
size_t _cbIncrement;
size_t _cbDataLeft;
PBYTE _pbsrc = NULL;
PBYTE _pbdest = NULL;
//
// Compute the number of bytes to get past the count of properties that
// is at the head of the list. This is typically sizeof DWORD.
//
_cbPropertyCountOffset = sizeof( m_cbhPropList.pList->nPropertyCount );
//
// Compute the allocation increment. This is used when growing our buffer
// and is the amount of data to copy from the passed in list. This includes
// the trailing endmark. m_cbDataSize does not include the leading property
// count DWORD.
//
_cbIncrement = rclPropList.m_cbDataSize;
//
// How much space remains in our current buffer?
//
_cbDataLeft = m_cbBufferSize - m_cbDataSize;
//
// If the size of the list to append is larger than what we have remaining
// then we need to grow the list.
//
if ( _cbIncrement > _cbDataLeft )
{
_sc = TW32( ScAllocPropList( m_cbDataSize + _cbIncrement ) );
if ( _sc != ERROR_SUCCESS )
{
goto Cleanup;
} // if:
} // if:
_pbdest = (PBYTE) &m_cbhPropList.pb[ _cbPropertyCountOffset + m_cbDataSize ];
_pbsrc = (PBYTE) &rclPropList.m_cbhPropList.pList->PropertyName;
CopyMemory( _pbdest, _pbsrc, _cbIncrement );
//
// Grow our data size to match our new size.
//
m_cbDataSize += _cbIncrement;
//
// Increment our property count to include the count of properties appended to the end
// of our buffer.
//
m_cbhPropList.pList->nPropertyCount += rclPropList.m_cbhPropList.pList->nPropertyCount;
Cleanup:
return _sc;
} //*** CClusPropList::ScAppend
////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScMoveToFirstProperty
//
// Description:
// Move the cursor to the first propery in the list.
//
// Arguments:
// None.
//
// Return Value:
// ERROR_SUCCESS Position moved to the first property successfully.
// ERROR_NO_MORE_ITEMS There are no properties in the list.
// ERROR_INVALID_DATA Not enough data in the buffer.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScMoveToFirstProperty( void )
{
Assert( m_cbhPropList.pb != NULL );
Assert( m_cbDataSize >= sizeof( m_cbhPropList.pList->nPropertyCount ) );
DWORD _sc;
size_t _cbDataLeft;
size_t _cbDataSize;
CLUSPROP_BUFFER_HELPER _cbhCurrentValue;
//
// Make sure the buffer is big enough for the list header.
//
if ( m_cbDataSize < sizeof( m_cbhPropList.pList->nPropertyCount ) )
{
_sc = TW32( ERROR_INVALID_DATA );
goto Cleanup;
} // if: not enough data
//
// Set the property counter to the number of properties in the list.
//
m_nPropsRemaining = m_cbhPropList.pList->nPropertyCount;
//
// Point the name pointer to the first name in the list.
//
m_cbhCurrentPropName.pName = &m_cbhPropList.pList->PropertyName;
m_cbDataLeft = m_cbDataSize - sizeof( m_cbhPropList.pList->nPropertyCount );
//
// Check to see if there are any properties in the list.
//
if ( m_nPropsRemaining == 0 )
{
_sc = ERROR_NO_MORE_ITEMS;
goto Cleanup;
} // if: no properties in the list
//
// Make sure the buffer is big enough for the first property name.
//
if ( m_cbDataLeft < sizeof( *m_cbhCurrentPropName.pName ) )
{
_sc = TW32( ERROR_INVALID_DATA );
goto Cleanup;
} // if: not enough data left
//
// Calculate how much to advance the buffer pointer.
//
_cbDataSize = sizeof( *m_cbhCurrentPropName.pName )
+ ALIGN_CLUSPROP( m_cbhCurrentPropName.pName->cbLength );
//
// Make sure the buffer is big enough for the name header
// and the data itself.
//
if ( m_cbDataLeft < _cbDataSize )
{
_sc = TW32( ERROR_INVALID_DATA );
goto Cleanup;
} // if: not enough data left
//
// Point the value buffer to the first value in the list.
//
_cbhCurrentValue.pb = m_cbhCurrentPropName.pb + _cbDataSize;
_cbDataLeft = m_cbDataLeft - _cbDataSize;
m_pvlValues.Init( _cbhCurrentValue, _cbDataLeft );
//
// Indicate we are successful.
//
_sc = ERROR_SUCCESS;
Cleanup:
return _sc;
} //*** CClusPropList::ScMoveToFirstProperty
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScMoveToNextProperty
//
// Description:
// Move the cursor to the next property in the list.
//
// Arguments:
// None.
//
// Return Value:
// ERROR_SUCCESS Position moved to the next property successfully.
// ERROR_NO_MORE_ITEMS Already at the end of the list.
// ERROR_INVALID_DATA Not enough data in the buffer.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScMoveToNextProperty( void )
{
Assert( m_cbhPropList.pb != NULL );
Assert( m_pvlValues.CbhValueList().pb != NULL );
DWORD _sc;
size_t _cbNameSize;
size_t _cbDataLeft;
size_t _cbDataSize;
CLUSPROP_BUFFER_HELPER _cbhCurrentValue;
CLUSPROP_BUFFER_HELPER _cbhPropName;
_cbhCurrentValue = m_pvlValues;
_cbDataLeft = m_pvlValues.CbDataLeft();
//
// If we aren't already at the last property, attempt to move to the next one.
//
_sc = TW32( ScCheckIfAtLastProperty() );
if ( _sc != ERROR_SUCCESS )
{
goto Cleanup;
} // if: already at the last property (probably)
//
// Make sure the buffer is big enough for the value header.
//
if ( _cbDataLeft < sizeof( *_cbhCurrentValue.pValue ) )
{
_sc = TW32( ERROR_INVALID_DATA );
goto Cleanup;
} // if: not enough data left
//
// Careful! Add offset only to cbhCurrentValue.pb. Otherwise
// pointer arithmetic will give undesirable results.
//
while ( _cbhCurrentValue.pSyntax->dw != CLUSPROP_SYNTAX_ENDMARK )
{
//
// Make sure the buffer is big enough for the value
// and an endmark.
//
_cbDataSize = sizeof( *_cbhCurrentValue.pValue )
+ ALIGN_CLUSPROP( _cbhCurrentValue.pValue->cbLength );
if ( _cbDataLeft < _cbDataSize + sizeof( *_cbhCurrentValue.pSyntax ) )
{
_sc = TW32( ERROR_INVALID_DATA );
goto Cleanup;
} // if: not enough data left
//
// Advance past the value.
//
_cbhCurrentValue.pb += _cbDataSize;
_cbDataLeft -= _cbDataSize;
} // while: not at endmark
if ( _sc != ERROR_SUCCESS )
{
goto Cleanup;
} // if: error occurred in loop
//
// Advanced past the endmark.
// Size check already performed in above loop.
//
_cbDataSize = sizeof( *_cbhCurrentValue.pSyntax );
_cbhCurrentValue.pb += _cbDataSize;
_cbDataLeft -= _cbDataSize;
//
// Point the name pointer to the next name in the list.
//
_cbhPropName = _cbhCurrentValue;
Assert( _cbDataLeft == m_cbDataSize - (_cbhPropName.pb - m_cbhPropList.pb) );
//
// Calculate the size of the name with header.
// Make sure the buffer is big enough for the name and an endmark.
//
if ( _cbDataLeft < sizeof( *_cbhPropName.pName ) )
{
_sc = TW32( ERROR_INVALID_DATA );
goto Cleanup;
} // if: not enough data
_cbNameSize = sizeof( *_cbhPropName.pName )
+ ALIGN_CLUSPROP( _cbhPropName.pName->cbLength );
if ( _cbDataLeft < _cbNameSize + sizeof( CLUSPROP_SYNTAX ) )
{
_sc = TW32( ERROR_INVALID_DATA );
goto Cleanup;
} // if: not enough data
//
// Point the value buffer to the first value in the list.
//
_cbhCurrentValue.pb = _cbhPropName.pb + _cbNameSize;
m_cbhCurrentPropName = _cbhPropName;
m_cbDataLeft = _cbDataLeft - _cbNameSize;
m_pvlValues.Init( _cbhCurrentValue, m_cbDataLeft );
//
// We've successfully advanced to the next property,
// so there is now one fewer property remaining.
//
--m_nPropsRemaining;
Assert( m_nPropsRemaining >= 1 );
_sc = ERROR_SUCCESS;
Cleanup:
return _sc;
} //*** CClusPropList::ScMoveToNextProperty
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScMoveToPropertyByName
//
// Description:
// Find the passed in property name in the proplist. Note that the
// cursor is reset to the beginning at the beginning of the routine and
// the current state of the cursor is lost.
//
// Arguments:
// pwszPropName [IN] Name of the property
//
// Return Value:
// ERROR_SUCCESS if the property was found, other Win32 code if not.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScMoveToPropertyByName( IN LPCWSTR pwszPropName )
{
Assert( m_cbhPropList.pb != NULL );
DWORD _sc;
_sc = ScMoveToFirstProperty();
if ( _sc == ERROR_SUCCESS )
{
do
{
//
// See if this is the specified property. If so, we're done.
//
if ( ClRtlStrICmp( m_cbhCurrentPropName.pName->sz, pwszPropName ) == 0 )
{
break;
} // if: property found
//
// Advance to the next property.
//
_sc = ScMoveToNextProperty(); // No TW32 because we expect an error when at the end
} while ( _sc == ERROR_SUCCESS ); // do-while: not end of list
} // if: successfully moved to the first property
return _sc;
} //*** ClusPropList::ScMoveToPropertyByName( LPCWSTR )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScAllocPropList
//
// Description:
// Allocate a property list buffer that's big enough to hold the next
// property.
//
// Arguments:
// cbMinimum [IN] Minimum size of the property list.
//
// Return Value:
// ERROR_SUCCESS
// ERROR_NOT_ENOUGH_MEMORY
// Other Win32 error codes
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScAllocPropList( IN size_t cbMinimum )
{
Assert( cbMinimum > 0 );
DWORD _sc = ERROR_SUCCESS;
size_t _cbTotal = 0;
//
// Add the size of the item count and final endmark.
//
cbMinimum += sizeof( CLUSPROP_VALUE );
_cbTotal = m_cbDataSize + cbMinimum;
if ( m_cbBufferSize < _cbTotal )
{
PBYTE _pbNewProplist = NULL;
cbMinimum = max( BUFFER_GROWTH_FACTOR, cbMinimum );
_cbTotal = m_cbDataSize + cbMinimum;
//
// Allocate and zero a new buffer.
//
_pbNewProplist = new BYTE[ _cbTotal ];
if ( _pbNewProplist != NULL )
{
ZeroMemory( _pbNewProplist, _cbTotal );
//
// If there was a previous buffer, copy it and the delete it.
//
if ( m_cbhPropList.pb != NULL )
{
if ( m_cbDataSize != 0 )
{
CopyMemory( _pbNewProplist, m_cbhPropList.pb, m_cbDataSize );
} // if: data already exists in buffer
delete [] m_cbhPropList.pb;
m_cbhCurrentProp.pb = _pbNewProplist + (m_cbhCurrentProp.pb - m_cbhPropList.pb);
} // if: there was a previous buffer
else
{
m_cbhCurrentProp.pb = _pbNewProplist + sizeof( DWORD ); // move past prop count
} // else: no previous buffer
//
// Save the new buffer.
//
m_cbhPropList.pb = _pbNewProplist;
m_cbBufferSize = _cbTotal;
} // if: allocation succeeded
else
{
_sc = TW32( ERROR_NOT_ENOUGH_MEMORY );
} // else: allocation failed
} // if: buffer isn't big enough
return _sc;
} //*** CClusPropList::ScAllocPropList
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScAddProp
//
// Description:
// Add a string property to a property list if it has changed.
//
// Arguments:
// pwszName [IN] Name of the property.
// pwszValue [IN] Value of the property to set in the list.
// pwszPrevValue [IN] Previous value of the property.
//
// Return Value:
// ERROR_SUCCESS or other Win32 error code.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScAddProp(
IN LPCWSTR pwszName,
IN LPCWSTR pwszValue,
IN LPCWSTR pwszPrevValue
)
{
Assert( pwszName != NULL );
DWORD _sc = ERROR_SUCCESS;
BOOL _fValuesDifferent = TRUE;
PCLUSPROP_PROPERTY_NAME _pName;
PCLUSPROP_SZ _pValue;
if (( pwszPrevValue != NULL ) && ( wcscmp( pwszValue, pwszPrevValue ) == 0 ))
{
_fValuesDifferent = FALSE;
} // if: we have a prev value and the values are the same
//
// If we should always add, or if the new value and the previous value
// are not equal, add the property to the property list.
//
if ( m_fAlwaysAddProp || _fValuesDifferent )
{
size_t _cbNameSize;
size_t _cbDataSize;
size_t _cbValueSize;
//
// Calculate sizes and make sure we have a property list.
//
_cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
+ ALIGN_CLUSPROP( (wcslen( pwszName ) + 1) * sizeof( *pwszName ) );
_cbDataSize = (wcslen( pwszValue ) + 1) * sizeof( *pwszValue );
_cbValueSize = sizeof( CLUSPROP_SZ )
+ ALIGN_CLUSPROP( _cbDataSize )
+ sizeof( CLUSPROP_SYNTAX ); // value list endmark
_sc = TW32( ScAllocPropList( _cbNameSize + _cbValueSize ) );
if ( _sc == ERROR_SUCCESS )
{
//
// Set the property name.
//
_pName = m_cbhCurrentProp.pName;
CopyProp( _pName, CLUSPROP_TYPE_NAME, pwszName );
m_cbhCurrentProp.pb += _cbNameSize;
//
// Set the property value.
//
_pValue = m_cbhCurrentProp.pStringValue;
CopyProp( _pValue, CLUSPROP_TYPE_LIST_VALUE, pwszValue, _cbDataSize );
m_cbhCurrentProp.pb += _cbValueSize;
//
// Increment the property count and buffer size.
//
m_cbhPropList.pList->nPropertyCount++;
m_cbDataSize += _cbNameSize + _cbValueSize;
} // if: ScAllocPropList successfully grew the proplist
} // if: the value has changed
return _sc;
} //*** CClusPropList::ScAddProp( LPCWSTR )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScAddMultiSzProp
//
// Description:
// Add a string property to a property list if it has changed.
//
// Arguments:
// pwszName [IN] Name of the property.
// pwszValue [IN] Value of the property to set in the list.
// pwszPrevValue [IN] Previous value of the property.
//
// Return Value:
// ERROR_SUCCESS or other Win32 error code.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScAddMultiSzProp(
IN LPCWSTR pwszName,
IN LPCWSTR pwszValue,
IN LPCWSTR pwszPrevValue
)
{
Assert( pwszName != NULL );
DWORD _sc = ERROR_SUCCESS;
BOOL _fValuesDifferent = TRUE;
PCLUSPROP_PROPERTY_NAME _pName;
PCLUSPROP_MULTI_SZ _pValue;
if ( ( pwszPrevValue != NULL ) && ( NCompareMultiSz( pwszValue, pwszPrevValue ) == 0 ) )
{
_fValuesDifferent = FALSE;
} // if: we have a prev value and the values are the same
//
// If we should always add, or if the new value and the previous value
// are not equal, add the property to the property list.
//
if ( m_fAlwaysAddProp || _fValuesDifferent )
{
size_t _cbNameSize;
size_t _cbDataSize;
size_t _cbValueSize;
//
// Calculate sizes and make sure we have a property list.
//
_cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
+ ALIGN_CLUSPROP( (wcslen( pwszName ) + 1) * sizeof( *pwszName ) );
_cbDataSize = static_cast< DWORD >( (CchMultiSz( pwszValue ) + 1) * sizeof( *pwszValue ) );
_cbValueSize = sizeof( CLUSPROP_SZ )
+ ALIGN_CLUSPROP( _cbDataSize )
+ sizeof( CLUSPROP_SYNTAX ); // value list endmark
_sc = TW32( ScAllocPropList( _cbNameSize + _cbValueSize ) );
if ( _sc == ERROR_SUCCESS )
{
//
// Set the property name.
//
_pName = m_cbhCurrentProp.pName;
CopyProp( _pName, CLUSPROP_TYPE_NAME, pwszName );
m_cbhCurrentProp.pb += _cbNameSize;
//
// Set the property value.
//
_pValue = m_cbhCurrentProp.pMultiSzValue;
CopyMultiSzProp( _pValue, CLUSPROP_TYPE_LIST_VALUE, pwszValue, _cbDataSize );
m_cbhCurrentProp.pb += _cbValueSize;
//
// Increment the property count and buffer size.
//
m_cbhPropList.pList->nPropertyCount++;
m_cbDataSize += _cbNameSize + _cbValueSize;
} // if: ScAllocPropList successfully grew the proplist
} // if: the value has changed
return _sc;
} //*** CClusPropList::ScAddMultiSzProp( LPCWSTR )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScAddExpandSzProp
//
// Description:
// Add an EXPAND_SZ string property to a property list if it has changed.
//
// Arguments:
// pwszName [IN] Name of the property.
// pwszValue [IN] Value of the property to set in the list.
// pwszPrevValue [IN] Previous value of the property.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScAddExpandSzProp(
IN LPCWSTR pwszName,
IN LPCWSTR pwszValue,
IN LPCWSTR pwszPrevValue
)
{
Assert( pwszName != NULL );
DWORD _sc = ERROR_SUCCESS;
BOOL _fValuesDifferent = TRUE;
PCLUSPROP_PROPERTY_NAME _pName;
PCLUSPROP_SZ _pValue;
if ( ( pwszPrevValue != NULL ) && ( wcscmp( pwszValue, pwszPrevValue ) == 0 ) )
{
_fValuesDifferent = FALSE;
} // if: we have a prev value and the values are the same
//
// If we should always add, or if the new value and the previous value
// are not equal, add the property to the property list.
//
if ( m_fAlwaysAddProp || _fValuesDifferent )
{
size_t _cbNameSize;
size_t _cbDataSize;
size_t _cbValueSize;
//
// Calculate sizes and make sure we have a property list.
//
_cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
+ ALIGN_CLUSPROP( (wcslen( pwszName ) + 1) * sizeof( *pwszName ) );
_cbDataSize = (wcslen( pwszValue ) + 1) * sizeof( *pwszValue );
_cbValueSize = sizeof( CLUSPROP_SZ )
+ ALIGN_CLUSPROP( _cbDataSize )
+ sizeof( CLUSPROP_SYNTAX ); // value list endmark
_sc = TW32( ScAllocPropList( _cbNameSize + _cbValueSize ) );
if ( _sc == ERROR_SUCCESS )
{
//
// Set the property name.
//
_pName = m_cbhCurrentProp.pName;
CopyProp( _pName, CLUSPROP_TYPE_NAME, pwszName );
m_cbhCurrentProp.pb += _cbNameSize;
//
// Set the property value.
//
_pValue = m_cbhCurrentProp.pStringValue;
CopyExpandSzProp( _pValue, CLUSPROP_TYPE_LIST_VALUE, pwszValue, _cbDataSize );
m_cbhCurrentProp.pb += _cbValueSize;
//
// Increment the property count and buffer size.
//
m_cbhPropList.pList->nPropertyCount++;
m_cbDataSize += _cbNameSize + _cbValueSize;
} // if: ScAllocPropList successfully grew the proplist
} // if: the value has changed
return _sc;
} //*** CClusPropList::ScAddExpandSzProp( LPCWSTR )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScAddProp
//
// Description:
// Add a DWORD property to a property list if it has changed.
//
// Arguments:
// pwszName [IN] Name of the property.
// nValue [IN] Value of the property to set in the list.
// nPrevValue [IN] Previous value of the property.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScAddProp(
IN LPCWSTR pwszName,
IN DWORD nValue,
IN DWORD nPrevValue
)
{
Assert( pwszName != NULL );
DWORD _sc = ERROR_SUCCESS;
PCLUSPROP_PROPERTY_NAME _pName;
PCLUSPROP_DWORD _pValue;
if ( m_fAlwaysAddProp || ( nValue != nPrevValue ) )
{
size_t _cbNameSize;
size_t _cbValueSize;
//
// Calculate sizes and make sure we have a property list.
//
_cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
+ ALIGN_CLUSPROP( (wcslen( pwszName ) + 1) * sizeof( *pwszName ) );
_cbValueSize = sizeof( CLUSPROP_DWORD )
+ sizeof( CLUSPROP_SYNTAX ); // value list endmark
_sc = TW32( ScAllocPropList( _cbNameSize + _cbValueSize ) );
if ( _sc == ERROR_SUCCESS )
{
//
// Set the property name.
//
_pName = m_cbhCurrentProp.pName;
CopyProp( _pName, CLUSPROP_TYPE_NAME, pwszName );
m_cbhCurrentProp.pb += _cbNameSize;
//
// Set the property value.
//
_pValue = m_cbhCurrentProp.pDwordValue;
CopyProp( _pValue, CLUSPROP_TYPE_LIST_VALUE, nValue );
m_cbhCurrentProp.pb += _cbValueSize;
//
// Increment the property count and buffer size.
//
m_cbhPropList.pList->nPropertyCount++;
m_cbDataSize += _cbNameSize + _cbValueSize;
} // if: ScAllocPropList successfully grew the proplist
} // if: the value has changed
return _sc;
} //*** CClusPropList::ScAddProp( DWORD )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScAddProp
//
// Description:
// Add a LONG property to a property list if it has changed.
//
// Arguments:
// pwszName [IN] Name of the property.
// nValue [IN] Value of the property to set in the list.
// nPrevValue [IN] Previous value of the property.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScAddProp(
IN LPCWSTR pwszName,
IN LONG nValue,
IN LONG nPrevValue
)
{
Assert( pwszName != NULL );
DWORD _sc = ERROR_SUCCESS;
PCLUSPROP_PROPERTY_NAME _pName;
PCLUSPROP_LONG _pValue;
if ( m_fAlwaysAddProp || ( nValue != nPrevValue ) )
{
size_t _cbNameSize;
size_t _cbValueSize;
//
// Calculate sizes and make sure we have a property list.
//
_cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
+ ALIGN_CLUSPROP( (wcslen( pwszName ) + 1) * sizeof( *pwszName ) );
_cbValueSize = sizeof( CLUSPROP_LONG )
+ sizeof( CLUSPROP_SYNTAX ); // value list endmark
_sc = TW32( ScAllocPropList( _cbNameSize + _cbValueSize ) );
if ( _sc == ERROR_SUCCESS )
{
//
// Set the property name.
//
_pName = m_cbhCurrentProp.pName;
CopyProp( _pName, CLUSPROP_TYPE_NAME, pwszName );
m_cbhCurrentProp.pb += _cbNameSize;
//
// Set the property value.
//
_pValue = m_cbhCurrentProp.pLongValue;
CopyProp( _pValue, CLUSPROP_TYPE_LIST_VALUE, nValue );
m_cbhCurrentProp.pb += _cbValueSize;
//
// Increment the property count and buffer size.
//
m_cbhPropList.pList->nPropertyCount++;
m_cbDataSize += _cbNameSize + _cbValueSize;
} // if: ScAllocPropList successfully grew the proplist
} // if: the value has changed
return _sc;
} //*** CClusPropList::ScAddProp( LONG )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScAddProp
//
// Description:
// Add a binary property to a property list if it has changed.
//
// Arguments:
// pwszName [IN] Name of the property.
// pbValue [IN] Value of the property to set in the list.
// cbValue [IN] Count of bytes in pbValue.
// pbPrevValue [IN] Previous value of the property.
// cbPrevValue [IN] Count of bytes in pbPrevValue.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScAddProp(
IN LPCWSTR pwszName,
IN const unsigned char * pbValue,
IN size_t cbValue,
IN const unsigned char * pbPrevValue,
IN size_t cbPrevValue
)
{
Assert( pwszName != NULL );
DWORD _sc = ERROR_SUCCESS;
BOOL _fChanged = FALSE;
PCLUSPROP_PROPERTY_NAME _pName;
PCLUSPROP_BINARY _pValue;
//
// Determine if the buffer has changed.
//
if ( m_fAlwaysAddProp || (cbValue != cbPrevValue) )
{
_fChanged = TRUE;
} // if: always adding the property or the value size changed
else if ( ( cbValue != 0 ) && ( cbPrevValue != 0 ) )
{
_fChanged = memcmp( pbValue, pbPrevValue, cbValue ) != 0;
} // else if: value length changed
if ( _fChanged )
{
size_t _cbNameSize;
size_t _cbValueSize;
//
// Calculate sizes and make sure we have a property list.
//
_cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
+ ALIGN_CLUSPROP( (wcslen( pwszName ) + 1) * sizeof( *pwszName ) );
_cbValueSize = sizeof( CLUSPROP_BINARY )
+ ALIGN_CLUSPROP( cbValue )
+ sizeof( CLUSPROP_SYNTAX ); // value list endmark
_sc = TW32( ScAllocPropList( _cbNameSize + _cbValueSize ) );
if ( _sc == ERROR_SUCCESS )
{
//
// Set the property name.
//
_pName = m_cbhCurrentProp.pName;
CopyProp( _pName, CLUSPROP_TYPE_NAME, pwszName );
m_cbhCurrentProp.pb += _cbNameSize;
//
// Set the property value.
//
_pValue = m_cbhCurrentProp.pBinaryValue;
CopyProp( _pValue, CLUSPROP_TYPE_LIST_VALUE, pbValue, cbValue );
m_cbhCurrentProp.pb += _cbValueSize;
//
// Increment the property count and buffer size.
//
m_cbhPropList.pList->nPropertyCount++;
m_cbDataSize += _cbNameSize + _cbValueSize;
} // if: ScAllocPropList successfully grew the proplist
} // if: the value has changed
return _sc;
} //*** CClusPropList::ScAddProp( PBYTE )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScAddProp
//
// Routine Description:
// Add a ULONGLONG property to a property list if it has changed.
//
// Arguments:
// pwszName [IN] Name of the property.
// ullValue [IN] Value of the property to set in the list.
// ullPrevValue [IN] Previous value of the property.
//
// Return Value:
// ERROR_SUCCESS or other Win32 error codes.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScAddProp(
IN LPCWSTR pwszName,
IN ULONGLONG ullValue,
IN ULONGLONG ullPrevValue
)
{
Assert( pwszName != NULL );
DWORD _sc = ERROR_SUCCESS;
PCLUSPROP_PROPERTY_NAME _pName;
PCLUSPROP_ULARGE_INTEGER _pValue;
if ( m_fAlwaysAddProp || ( ullValue != ullPrevValue ) )
{
size_t _cbNameSize;
size_t _cbValueSize;
//
// Calculate sizes and make sure we have a property list.
//
_cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
+ ALIGN_CLUSPROP( (wcslen( pwszName ) + 1) * sizeof( *pwszName ) );
_cbValueSize = sizeof( CLUSPROP_ULARGE_INTEGER )
+ sizeof( CLUSPROP_SYNTAX ); // value list endmark
_sc = TW32( ScAllocPropList( _cbNameSize + _cbValueSize ) );
if ( _sc == ERROR_SUCCESS )
{
//
// Set the property name.
//
_pName = m_cbhCurrentProp.pName;
CopyProp( _pName, CLUSPROP_TYPE_NAME, pwszName );
m_cbhCurrentProp.pb += _cbNameSize;
//
// Set the property value.
//
_pValue = m_cbhCurrentProp.pULargeIntegerValue;
CopyProp( _pValue, CLUSPROP_TYPE_LIST_VALUE, ullValue );
m_cbhCurrentProp.pb += _cbValueSize;
//
// Increment the property count and buffer size.
//
m_cbhPropList.pList->nPropertyCount++;
m_cbDataSize += _cbNameSize + _cbValueSize;
} // if: ScAllocPropList successfully grew the proplist
} // if: the value has changed
return _sc;
} //*** CClusPropList::ScAddProp( ULONGLONG )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScAddProp
//
// Routine Description:
// Add a LONGLONG property to a property list if it has changed.
//
// Arguments:
// pwszName [IN] Name of the property.
// llValue [IN] Value of the property to set in the list.
// llPrevValue [IN] Previous value of the property.
//
// Return Value:
// ERROR_SUCCESS or other Win32 status codes.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScAddProp(
IN LPCWSTR pwszName,
IN LONGLONG llValue,
IN LONGLONG llPrevValue
)
{
Assert( pwszName != NULL );
DWORD _sc = ERROR_SUCCESS;
PCLUSPROP_PROPERTY_NAME _pName;
PCLUSPROP_ULARGE_INTEGER _pValue;
if ( m_fAlwaysAddProp || ( llValue != llPrevValue ) )
{
size_t _cbNameSize;
size_t _cbValueSize;
//
// Calculate sizes and make sure we have a property list.
//
_cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
+ ALIGN_CLUSPROP( (wcslen( pwszName ) + 1) * sizeof( *pwszName ) );
_cbValueSize = sizeof( CLUSPROP_LARGE_INTEGER )
+ sizeof( CLUSPROP_SYNTAX ); // value list endmark
_sc = TW32( ScAllocPropList( _cbNameSize + _cbValueSize ) );
if ( _sc == ERROR_SUCCESS )
{
//
// Set the property name.
//
_pName = m_cbhCurrentProp.pName;
CopyProp( _pName, CLUSPROP_TYPE_NAME, pwszName );
m_cbhCurrentProp.pb += _cbNameSize;
//
// Set the property value.
//
_pValue = m_cbhCurrentProp.pULargeIntegerValue;
CopyProp( _pValue, CLUSPROP_TYPE_LIST_VALUE, llValue );
m_cbhCurrentProp.pb += _cbValueSize;
//
// Increment the property count and buffer size.
//
m_cbhPropList.pList->nPropertyCount++;
m_cbDataSize += _cbNameSize + _cbValueSize;
} // if: ScAllocPropList successfully grew the proplist
} // if: the value has changed
return _sc;
} //*** CClusPropList::ScAddProp( LONGLONG )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScSetPropToDefault
//
// Description:
// Add a property to the property list so that it will revert to its
// default value.
//
// Arguments:
// pwszName [IN] Name of the property.
// cpfPropFmt [IN] Format of property
//
// Return Value:
// ERROR_SUCCESS or other Win32 status codes.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScSetPropToDefault(
IN LPCWSTR pwszName,
IN CLUSTER_PROPERTY_FORMAT cpfPropFmt
)
{
Assert( pwszName != NULL );
DWORD _sc = ERROR_SUCCESS;
size_t _cbNameSize;
size_t _cbValueSize;
PCLUSPROP_PROPERTY_NAME _pName;
PCLUSPROP_VALUE _pValue;
// Calculate sizes and make sure we have a property list.
_cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
+ ALIGN_CLUSPROP( (wcslen( pwszName ) + 1) * sizeof( *pwszName ) );
_cbValueSize = sizeof( CLUSPROP_BINARY )
+ sizeof( CLUSPROP_SYNTAX ); // value list endmark
_sc = TW32( ScAllocPropList( _cbNameSize + _cbValueSize ) );
if ( _sc == ERROR_SUCCESS )
{
//
// Set the property name.
//
_pName = m_cbhCurrentProp.pName;
CopyProp( _pName, CLUSPROP_TYPE_NAME, pwszName );
m_cbhCurrentProp.pb += _cbNameSize;
//
// Set the property value.
//
_pValue = m_cbhCurrentProp.pValue;
CopyEmptyProp( _pValue, CLUSPROP_TYPE_LIST_VALUE, cpfPropFmt );
m_cbhCurrentProp.pb += _cbValueSize;
//
// Increment the property count and buffer size.
//
m_cbhPropList.pList->nPropertyCount++;
m_cbDataSize += _cbNameSize + _cbValueSize;
} // if:
return _sc;
} //*** CClusPropList::ScSetPropToDefault
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::CopyProp
//
// Description:
// Copy a string property to a property structure.
//
// Arguments:
// pprop [OUT] Property structure to fill.
// cptPropType [IN] Type of string.
// psz [IN] String to copy.
// cbsz [IN] Count of bytes in pwsz string. If specified as 0,
// the the length will be determined by a call to strlen.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusPropList::CopyProp(
OUT PCLUSPROP_SZ pprop,
IN CLUSTER_PROPERTY_TYPE cptPropType,
IN LPCWSTR psz,
IN size_t cbsz // = 0
)
{
Assert( pprop != NULL );
Assert( psz != NULL );
CLUSPROP_BUFFER_HELPER _cbhProps;
HRESULT _hr;
pprop->Syntax.wFormat = CLUSPROP_FORMAT_SZ;
pprop->Syntax.wType = static_cast< WORD >( cptPropType );
if ( cbsz == 0 )
{
cbsz = (wcslen( psz ) + 1) * sizeof( *psz );
} // if: zero size specified
Assert( cbsz == (wcslen( psz ) + 1) * sizeof( *psz ) );
pprop->cbLength = static_cast< DWORD >( cbsz );
_hr = THR( StringCbCopyW( pprop->sz, cbsz, psz ) );
if ( SUCCEEDED( _hr ) )
{
//
// Set an endmark.
//
_cbhProps.pStringValue = pprop;
_cbhProps.pb += sizeof( *_cbhProps.pStringValue ) + ALIGN_CLUSPROP( cbsz );
_cbhProps.pSyntax->dw = CLUSPROP_SYNTAX_ENDMARK;
}
} //*** CClusPropList::CopyProp
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::CopyMultiSzProp
//
// Description:
// Copy a MULTI_SZ string property to a property structure.
//
// Arguments:
// pprop [OUT] Property structure to fill.
// cptPropType [IN] Type of string.
// psz [IN] String to copy.
// cbsz [IN] Count of bytes in psz string. If specified as 0,
// the the length will be determined by calls to strlen.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusPropList::CopyMultiSzProp(
OUT PCLUSPROP_MULTI_SZ pprop,
IN CLUSTER_PROPERTY_TYPE cptPropType,
IN LPCWSTR psz,
IN size_t cbsz
)
{
Assert( pprop != NULL );
Assert( psz != NULL );
CLUSPROP_BUFFER_HELPER _cbhProps;
pprop->Syntax.wFormat = CLUSPROP_FORMAT_MULTI_SZ;
pprop->Syntax.wType = static_cast< WORD >( cptPropType );
if ( cbsz == 0 )
{
cbsz = (CchMultiSz( psz ) + 1) * sizeof( *psz );
} // if: zero size specified
Assert( cbsz == (CchMultiSz( psz ) + 1) * sizeof( *psz ) );
pprop->cbLength = static_cast< DWORD >( cbsz );
CopyMemory( pprop->sz, psz, cbsz );
//
// Set an endmark.
//
_cbhProps.pMultiSzValue = pprop;
_cbhProps.pb += sizeof( *_cbhProps.pMultiSzValue ) + ALIGN_CLUSPROP( cbsz );
_cbhProps.pSyntax->dw = CLUSPROP_SYNTAX_ENDMARK;
} //*** CClusPropList::CopyMultiSzProp
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::CopyExpandSzProp
//
// Description:
// Copy an EXPAND_SZ string property to a property structure.
//
// Arguments:
// pprop [OUT] Property structure to fill.
// cptPropType [IN] Type of string.
// psz [IN] String to copy.
// cbsz [IN] Count of bytes in psz string.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusPropList::CopyExpandSzProp(
OUT PCLUSPROP_SZ pprop,
IN CLUSTER_PROPERTY_TYPE cptPropType,
IN LPCWSTR psz,
IN size_t cbsz
)
{
Assert( pprop != NULL );
Assert( psz != NULL );
CLUSPROP_BUFFER_HELPER _cbhProps;
HRESULT _hr;
pprop->Syntax.wFormat = CLUSPROP_FORMAT_EXPAND_SZ;
pprop->Syntax.wType = static_cast< WORD >( cptPropType );
if ( cbsz == 0 )
{
cbsz = (wcslen( psz ) + 1) * sizeof( *psz );
} // if: cbsz == 0
Assert( cbsz == (wcslen( psz ) + 1) * sizeof( *psz ) );
pprop->cbLength = static_cast< DWORD >( cbsz );
_hr = THR( StringCbCopyW( pprop->sz, cbsz, psz ) );
if ( SUCCEEDED( _hr ) )
{
//
// Set an endmark.
//
_cbhProps.pStringValue = pprop;
_cbhProps.pb += sizeof( *_cbhProps.pStringValue ) + ALIGN_CLUSPROP( cbsz );
_cbhProps.pSyntax->dw = CLUSPROP_SYNTAX_ENDMARK;
}
} //*** CClusPropList::CopyExpandSzProp
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::CopyProp
//
// Description:
// Copy a DWORD property to a property structure.
//
// Arguments:
// pprop [OUT] Property structure to fill.
// cptPropType [IN] Type of DWORD.
// nValue [IN] Property value to copy.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusPropList::CopyProp(
OUT PCLUSPROP_DWORD pprop,
IN CLUSTER_PROPERTY_TYPE cptPropType,
IN DWORD nValue
)
{
Assert( pprop != NULL );
CLUSPROP_BUFFER_HELPER _cbhProps;
pprop->Syntax.wFormat = CLUSPROP_FORMAT_DWORD;
pprop->Syntax.wType = static_cast< WORD >( cptPropType );
pprop->cbLength = sizeof( DWORD );
pprop->dw = nValue;
//
// Set an endmark.
//
_cbhProps.pDwordValue = pprop;
_cbhProps.pb += sizeof( *_cbhProps.pDwordValue );
_cbhProps.pSyntax->dw = CLUSPROP_SYNTAX_ENDMARK;
} //*** CClusPropList::CopyProp( DWORD )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::CopyProp
//
// Description:
// Copy a LONG property to a property structure.
//
// Arguments:
// pprop [OUT] Property structure to fill.
// cptPropType [IN] Type of LONG.
// nValue [IN] Property value to copy.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusPropList::CopyProp(
OUT PCLUSPROP_LONG pprop,
IN CLUSTER_PROPERTY_TYPE cptPropType,
IN LONG nValue
)
{
Assert( pprop != NULL );
CLUSPROP_BUFFER_HELPER _cbhProps;
pprop->Syntax.wFormat = CLUSPROP_FORMAT_LONG;
pprop->Syntax.wType = static_cast< WORD >( cptPropType );
pprop->cbLength = sizeof( DWORD );
pprop->l = nValue;
//
// Set an endmark.
//
_cbhProps.pLongValue = pprop;
_cbhProps.pb += sizeof( *_cbhProps.pLongValue );
_cbhProps.pSyntax->dw = CLUSPROP_SYNTAX_ENDMARK;
} //*** CClusPropList::CopyProp( LONG )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::CopyProp
//
// Description:
// Copy a ULONGLONG property to a property structure.
//
// Arguments:
// pprop [OUT] Property structure to fill.
// proptype [IN] Type of LONG.
// ullValue [IN] Property value to copy.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusPropList::CopyProp(
OUT PCLUSPROP_ULARGE_INTEGER pprop,
IN CLUSTER_PROPERTY_TYPE proptype,
IN ULONGLONG ullValue
)
{
Assert( pprop != NULL );
CLUSPROP_BUFFER_HELPER _cbhProps;
pprop->Syntax.wFormat = CLUSPROP_FORMAT_ULARGE_INTEGER;
pprop->Syntax.wType = static_cast< WORD >( proptype );
pprop->cbLength = sizeof( ULONGLONG );
//
// pprop may not have the correct alignment for large ints; copy as two
// DWORDs to be safe
//
pprop->li.u = ((ULARGE_INTEGER *)&ullValue)->u;
//
// Set an endmark.
//
_cbhProps.pULargeIntegerValue = pprop;
_cbhProps.pb += sizeof( *_cbhProps.pULargeIntegerValue );
_cbhProps.pSyntax->dw = CLUSPROP_SYNTAX_ENDMARK;
} //*** CClusPropList::CopyProp( ULONGLONG )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::CopyProp
//
// Description:
// Copy a LONGLONG property to a property structure.
//
// Arguments:
// pprop [OUT] Property structure to fill.
// proptype [IN] Type of LONG.
// llValue [IN] Property value to copy.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusPropList::CopyProp(
OUT PCLUSPROP_LARGE_INTEGER pprop,
IN CLUSTER_PROPERTY_TYPE proptype,
IN LONGLONG llValue
)
{
Assert( pprop != NULL );
CLUSPROP_BUFFER_HELPER _cbhProps;
pprop->Syntax.wFormat = CLUSPROP_FORMAT_LARGE_INTEGER;
pprop->Syntax.wType = static_cast< WORD >( proptype );
pprop->cbLength = sizeof( LONGLONG );
//
// pprop may not have the correct alignment for large ints; copy as two
// DWORDs to be safe
//
pprop->li.u = ((LARGE_INTEGER *)&llValue)->u;
//
// Set an endmark.
//
_cbhProps.pLargeIntegerValue = pprop;
_cbhProps.pb += sizeof( *_cbhProps.pLargeIntegerValue );
_cbhProps.pSyntax->dw = CLUSPROP_SYNTAX_ENDMARK;
} //*** CClusPropList::CopyProp( LONGLONG )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::CopyProp
//
// Description:
// Copy a binary property to a property structure.
//
// Arguments:
// pprop [OUT] Property structure to fill.
// cptPropType [IN] Type of string.
// pb [IN] Block to copy.
// cbsz [IN] Count of bytes in pb buffer.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusPropList::CopyProp(
OUT PCLUSPROP_BINARY pprop,
IN CLUSTER_PROPERTY_TYPE cptPropType,
IN const unsigned char * pb,
IN size_t cb
)
{
Assert( pprop != NULL );
CLUSPROP_BUFFER_HELPER _cbhProps;
pprop->Syntax.wFormat = CLUSPROP_FORMAT_BINARY;
pprop->Syntax.wType = static_cast< WORD >( cptPropType );
pprop->cbLength = static_cast< DWORD >( cb );
if ( cb > 0 )
{
CopyMemory( pprop->rgb, pb, cb );
} // if: non-zero data length
//
// Set an endmark.
//
_cbhProps.pBinaryValue = pprop;
_cbhProps.pb += sizeof( *_cbhProps.pStringValue ) + ALIGN_CLUSPROP( cb );
_cbhProps.pSyntax->dw = CLUSPROP_SYNTAX_ENDMARK;
} //*** CClusPropList::CopyProp( PBYTE )
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::CopyEmptyProp
//
// Description:
// Copy an empty property to a property structure.
//
// Arguments:
// pprop [OUT] Property structure to fill.
// cptPropType [IN] Type of property.
// cpfPropFmt [IN] Format of property.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void CClusPropList::CopyEmptyProp(
OUT PCLUSPROP_VALUE pprop,
IN CLUSTER_PROPERTY_TYPE cptPropType,
IN CLUSTER_PROPERTY_FORMAT cptPropFmt
)
{
Assert( pprop != NULL );
CLUSPROP_BUFFER_HELPER _cbhProps;
pprop->Syntax.wFormat = static_cast< WORD >( cptPropFmt );
pprop->Syntax.wType = static_cast< WORD >( cptPropType );
pprop->cbLength = 0;
//
// Set an endmark.
//
_cbhProps.pValue = pprop;
_cbhProps.pb += sizeof( *_cbhProps.pValue );
_cbhProps.pSyntax->dw = CLUSPROP_SYNTAX_ENDMARK;
} //*** CClusPropList::CopyEmptyProp
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScGetNodeProperties
//
// Description:
// Get properties on a node.
//
// Arguments:
// hNode [IN] Handle for the node to get properties from.
// dwControlCode [IN] Control code for the request.
// hHostNode [IN] Handle for the node to direct this request to.
// Defaults to NULL.
// lpInBuffer [IN] Input buffer for the request. Defaults to NULL.
// cbInBufferSize [IN] Size of the input buffer. Defaults to 0.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScGetNodeProperties(
IN HNODE hNode,
IN DWORD dwControlCode,
IN HNODE hHostNode,
IN LPVOID lpInBuffer,
IN size_t cbInBufferSize
)
{
Assert( hNode != NULL );
Assert( (dwControlCode & (CLUSCTL_OBJECT_MASK << CLUSCTL_OBJECT_SHIFT))
== (CLUS_OBJECT_NODE << CLUSCTL_OBJECT_SHIFT) );
DWORD _sc = ERROR_SUCCESS;
DWORD _cbProps = 256;
//
// Overwrite anything that may be in the buffer.
// Allows this class instance to be reused.
//
m_cbDataSize = 0;
//
// Get properties.
//
_sc = TW32( ScAllocPropList( _cbProps ) );
if ( _sc == ERROR_SUCCESS )
{
_sc = TW32E( ClusterNodeControl(
hNode,
hHostNode,
dwControlCode,
lpInBuffer,
static_cast< DWORD >( cbInBufferSize ),
m_cbhPropList.pb,
static_cast< DWORD >( m_cbBufferSize ),
&_cbProps
), ERROR_MORE_DATA );
if ( _sc == ERROR_MORE_DATA )
{
_sc = TW32( ScAllocPropList( _cbProps ) );
if ( _sc == ERROR_SUCCESS )
{
_sc = TW32( ClusterNodeControl(
hNode,
hHostNode,
dwControlCode,
lpInBuffer,
static_cast< DWORD >( cbInBufferSize ),
m_cbhPropList.pb,
static_cast< DWORD >( m_cbBufferSize ),
&_cbProps
) );
} // if: ScAllocPropList succeeded
} // if: buffer too small
} // if: ScAllocPropList succeeded
if ( _sc != ERROR_SUCCESS )
{
DeletePropList();
} // if: error getting properties.
else
{
m_cbDataSize = static_cast< size_t >( _cbProps );
m_cbDataLeft = static_cast< size_t >( _cbProps );
} // else: no errors
return _sc;
} //*** CClusPropList::ScGetNodeProperties
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScGetGroupProperties
//
// Description:
// Get properties on a group.
//
// Arguments:
// hGroup [IN] Handle for the group to get properties from.
// dwControlCode [IN] Control code for the request.
// hHostNode [IN] Handle for the node to direct this request to.
// Defaults to NULL.
// lpInBuffer [IN] Input buffer for the request. Defaults to NULL.
// cbInBufferSize [IN] Size of the input buffer. Defaults to 0.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScGetGroupProperties(
IN HGROUP hGroup,
IN DWORD dwControlCode,
IN HNODE hHostNode,
IN LPVOID lpInBuffer,
IN size_t cbInBufferSize
)
{
Assert( hGroup != NULL );
Assert( (dwControlCode & (CLUSCTL_OBJECT_MASK << CLUSCTL_OBJECT_SHIFT))
== (CLUS_OBJECT_GROUP << CLUSCTL_OBJECT_SHIFT) );
DWORD _sc = ERROR_SUCCESS;
DWORD _cbProps = 256;
//
// Overwrite anything that may be in the buffer.
// Allows this class instance to be reused.
//
m_cbDataSize = 0;
//
// Get properties.
//
_sc = TW32( ScAllocPropList( _cbProps ) );
if ( _sc == ERROR_SUCCESS )
{
_sc = TW32E( ClusterGroupControl(
hGroup,
hHostNode,
dwControlCode,
lpInBuffer,
static_cast< DWORD >( cbInBufferSize ),
m_cbhPropList.pb,
static_cast< DWORD >( m_cbBufferSize ),
&_cbProps
), ERROR_MORE_DATA );
if ( _sc == ERROR_MORE_DATA )
{
_sc = TW32( ScAllocPropList( _cbProps ) );
if ( _sc == ERROR_SUCCESS )
{
_sc = TW32( ClusterGroupControl(
hGroup,
hHostNode,
dwControlCode,
lpInBuffer,
static_cast< DWORD >( cbInBufferSize ),
m_cbhPropList.pb,
static_cast< DWORD >( m_cbBufferSize ),
&_cbProps
) );
} // if: ScAllocPropList succeeded
} // if: buffer too small
} // if: ScAllocPropList succeeded
if ( _sc != ERROR_SUCCESS )
{
DeletePropList();
} // if: error getting properties.
else
{
m_cbDataSize = static_cast< size_t >( _cbProps );
m_cbDataLeft = static_cast< size_t >( _cbProps );
} // else: no errors
return _sc;
} //*** CClusPropList::ScGetGroupProperties
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScGetResourceProperties
//
// Description:
// Get properties on a resource.
//
// Arguments:
// hResource [IN] Handle for the resource to get properties from.
// dwControlCode [IN] Control code for the request.
// hHostNode [IN] Handle for the node to direct this request to.
// Defaults to NULL.
// lpInBuffer [IN] Input buffer for the request. Defaults to NULL.
// cbInBufferSize [IN] Size of the input buffer. Defaults to 0.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScGetResourceProperties(
IN HRESOURCE hResource,
IN DWORD dwControlCode,
IN HNODE hHostNode,
IN LPVOID lpInBuffer,
IN size_t cbInBufferSize
)
{
Assert( hResource != NULL );
Assert( (dwControlCode & (CLUSCTL_OBJECT_MASK << CLUSCTL_OBJECT_SHIFT))
== (CLUS_OBJECT_RESOURCE << CLUSCTL_OBJECT_SHIFT) );
DWORD _sc = ERROR_SUCCESS;
DWORD _cbProps = 256;
//
// Overwrite anything that may be in the buffer.
// Allows this class instance to be reused.
//
m_cbDataSize = 0;
//
// Get properties.
//
_sc = TW32( ScAllocPropList( _cbProps ) );
if ( _sc == ERROR_SUCCESS )
{
_sc = TW32E( ClusterResourceControl(
hResource,
hHostNode,
dwControlCode,
lpInBuffer,
static_cast< DWORD >( cbInBufferSize ),
m_cbhPropList.pb,
static_cast< DWORD >( m_cbBufferSize ),
&_cbProps
), ERROR_MORE_DATA );
if ( _sc == ERROR_MORE_DATA )
{
_sc = TW32( ScAllocPropList( _cbProps ) );
if ( _sc == ERROR_SUCCESS )
{
_sc = TW32( ClusterResourceControl(
hResource,
hHostNode,
dwControlCode,
lpInBuffer,
static_cast< DWORD >( cbInBufferSize ),
m_cbhPropList.pb,
static_cast< DWORD >( m_cbBufferSize ),
&_cbProps
) );
} // if: ScAllocPropList succeeded
} // if: buffer too small
} // if: ScAllocPropList succeeded
if ( _sc != ERROR_SUCCESS )
{
DeletePropList();
} // if: error getting properties.
else
{
m_cbDataSize = static_cast< size_t >( _cbProps );
m_cbDataLeft = static_cast< size_t >( _cbProps );
} // else: no errors
return _sc;
} //*** CClusPropList::ScGetResourceProperties
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScGetResourceTypeProperties
//
// Description:
// Get properties on a resource type.
//
// Arguments:
// hCluster [IN] Handle for the cluster in which the resource
// type resides.
// pwszResTypeName [IN] Name of the resource type.
// dwControlCode [IN] Control code for the request.
// hHostNode [IN] Handle for the node to direct this request to.
// Defaults to NULL.
// lpInBuffer [IN] Input buffer for the request. Defaults to NULL.
// cbInBufferSize [IN] Size of the input buffer. Defaults to 0.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScGetResourceTypeProperties(
IN HCLUSTER hCluster,
IN LPCWSTR pwszResTypeName,
IN DWORD dwControlCode,
IN HNODE hHostNode,
IN LPVOID lpInBuffer,
IN size_t cbInBufferSize
)
{
Assert( hCluster != NULL );
Assert( pwszResTypeName != NULL );
Assert( *pwszResTypeName != L'\0' );
Assert( (dwControlCode & (CLUSCTL_OBJECT_MASK << CLUSCTL_OBJECT_SHIFT))
== (CLUS_OBJECT_RESOURCE_TYPE << CLUSCTL_OBJECT_SHIFT) );
DWORD _sc = ERROR_SUCCESS;
DWORD _cbProps = 256;
//
// Overwrite anything that may be in the buffer.
// Allows this class instance to be reused.
//
m_cbDataSize = 0;
//
// Get properties.
//
_sc = TW32( ScAllocPropList( _cbProps ) );
if ( _sc == ERROR_SUCCESS )
{
_sc = TW32E( ClusterResourceTypeControl(
hCluster,
pwszResTypeName,
hHostNode,
dwControlCode,
lpInBuffer,
static_cast< DWORD >( cbInBufferSize ),
m_cbhPropList.pb,
static_cast< DWORD >( m_cbBufferSize ),
&_cbProps
), ERROR_MORE_DATA );
if ( _sc == ERROR_MORE_DATA )
{
_sc = TW32( ScAllocPropList( _cbProps ) );
if ( _sc == ERROR_SUCCESS )
{
_sc = TW32( ClusterResourceTypeControl(
hCluster,
pwszResTypeName,
hHostNode,
dwControlCode,
lpInBuffer,
static_cast< DWORD >( cbInBufferSize ),
m_cbhPropList.pb,
static_cast< DWORD >( m_cbBufferSize ),
&_cbProps
) );
} // if: ScAllocPropList succeeded
} // if: buffer too small
} // if: ScAllocPropList succeeded
if ( _sc != ERROR_SUCCESS )
{
DeletePropList();
} // if: error getting properties.
else
{
m_cbDataSize = static_cast< size_t >( _cbProps );
m_cbDataLeft = static_cast< size_t >( _cbProps );
} // else: no errors
return _sc;
} //*** CClusPropList::ScGetResourceTypeProperties
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScGetNetworkProperties
//
// Description:
// Get properties on a network.
//
// Arguments:
// hNetwork [IN] Handle for the network to get properties from.
// dwControlCode [IN] Control code for the request.
// hHostNode [IN] Handle for the node to direct this request to.
// Defaults to NULL.
// lpInBuffer [IN] Input buffer for the request. Defaults to NULL.
// cbInBufferSize [IN] Size of the input buffer. Defaults to 0.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScGetNetworkProperties(
IN HNETWORK hNetwork,
IN DWORD dwControlCode,
IN HNODE hHostNode,
IN LPVOID lpInBuffer,
IN size_t cbInBufferSize
)
{
Assert( hNetwork != NULL );
Assert( (dwControlCode & (CLUSCTL_OBJECT_MASK << CLUSCTL_OBJECT_SHIFT))
== (CLUS_OBJECT_NETWORK << CLUSCTL_OBJECT_SHIFT) );
DWORD _sc = ERROR_SUCCESS;
DWORD _cbProps = 256;
//
// Overwrite anything that may be in the buffer.
// Allows this class instance to be reused.
//
m_cbDataSize = 0;
//
// Get properties.
//
_sc = TW32( ScAllocPropList( _cbProps ) );
if ( _sc == ERROR_SUCCESS )
{
_sc = TW32E( ClusterNetworkControl(
hNetwork,
hHostNode,
dwControlCode,
lpInBuffer,
static_cast< DWORD >( cbInBufferSize ),
m_cbhPropList.pb,
static_cast< DWORD >( m_cbBufferSize ),
&_cbProps
), ERROR_MORE_DATA );
if ( _sc == ERROR_MORE_DATA )
{
_sc = TW32( ScAllocPropList( _cbProps ) );
if ( _sc == ERROR_SUCCESS )
{
_sc = TW32( ClusterNetworkControl(
hNetwork,
hHostNode,
dwControlCode,
lpInBuffer,
static_cast< DWORD >( cbInBufferSize ),
m_cbhPropList.pb,
static_cast< DWORD >( m_cbBufferSize ),
&_cbProps
) );
} // if: ScAllocPropList succeeded
} // if: buffer too small
} // if: ScAllocPropList succeeded
if ( _sc != ERROR_SUCCESS )
{
DeletePropList();
} // if: error getting private properties.
else
{
m_cbDataSize = static_cast< size_t >( _cbProps );
m_cbDataLeft = static_cast< size_t >( _cbProps );
} // else: no errors
return _sc;
} //*** CClusPropList::ScGetNetworkProperties
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScGetNetInterfaceProperties
//
// Description:
// Get properties on a network interface.
//
// Arguments:
// hNetInterface [IN] Handle for the network interface to get properties from.
// dwControlCode [IN] Control code for the request.
// hHostNode [IN] Handle for the node to direct this request to.
// Defaults to NULL.
// lpInBuffer [IN] Input buffer for the request. Defaults to NULL.
// cbInBufferSize [IN] Size of the input buffer. Defaults to 0.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScGetNetInterfaceProperties(
IN HNETINTERFACE hNetInterface,
IN DWORD dwControlCode,
IN HNODE hHostNode,
IN LPVOID lpInBuffer,
IN size_t cbInBufferSize
)
{
Assert( hNetInterface != NULL );
Assert( (dwControlCode & (CLUSCTL_OBJECT_MASK << CLUSCTL_OBJECT_SHIFT))
== (CLUS_OBJECT_NETINTERFACE << CLUSCTL_OBJECT_SHIFT) );
DWORD _sc= ERROR_SUCCESS;
DWORD _cbProps = 256;
//
// Overwrite anything that may be in the buffer.
// Allows this class instance to be reused.
//
m_cbDataSize = 0;
//
// Get properties.
//
_sc = TW32( ScAllocPropList( _cbProps ) );
if ( _sc == ERROR_SUCCESS )
{
_sc = TW32E( ClusterNetInterfaceControl(
hNetInterface,
hHostNode,
dwControlCode,
lpInBuffer,
static_cast< DWORD >( cbInBufferSize ),
m_cbhPropList.pb,
static_cast< DWORD >( m_cbBufferSize ),
&_cbProps
), ERROR_MORE_DATA );
if ( _sc == ERROR_MORE_DATA )
{
_sc = TW32( ScAllocPropList( _cbProps ) );
if ( _sc == ERROR_SUCCESS )
{
_sc = TW32( ClusterNetInterfaceControl(
hNetInterface,
hHostNode,
dwControlCode,
lpInBuffer,
static_cast< DWORD >( cbInBufferSize ),
m_cbhPropList.pb,
static_cast< DWORD >( m_cbBufferSize ),
&_cbProps
) );
} // if: ScAllocPropList succeeded
} // if: buffer too small
} // if: ScAllocPropList succeeded
if ( _sc != ERROR_SUCCESS )
{
DeletePropList();
} // if: error getting private properties.
else
{
m_cbDataSize = static_cast< size_t >( _cbProps );
m_cbDataLeft = static_cast< size_t >( _cbProps );
} // else: no errors
return _sc;
} //*** CClusPropList::ScGetNetInterfaceProperties
/////////////////////////////////////////////////////////////////////////////
//++
//
// CClusPropList::ScGetClusterProperties
//
// Description:
// Get properties on a cluster.
//
// Arguments:
// hCluster [IN] Handle for the cluster to get properties from.
// dwControlCode [IN] Control code for the request.
// hHostNode [IN] Handle for the node to direct this request to.
// Defaults to NULL.
// lpInBuffer [IN] Input buffer for the request. Defaults to NULL.
// cbInBufferSize [IN] Size of the input buffer. Defaults to 0.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
DWORD CClusPropList::ScGetClusterProperties(
IN HCLUSTER hCluster,
IN DWORD dwControlCode,
IN HNODE hHostNode,
IN LPVOID lpInBuffer,
IN size_t cbInBufferSize
)
{
Assert( hCluster != NULL );
Assert( (dwControlCode & (CLUSCTL_OBJECT_MASK << CLUSCTL_OBJECT_SHIFT))
== (CLUS_OBJECT_CLUSTER << CLUSCTL_OBJECT_SHIFT) );
DWORD _sc= ERROR_SUCCESS;
DWORD _cbProps = 256;
//
// Overwrite anything that may be in the buffer.
// Allows this class instance to be reused.
//
m_cbDataSize = 0;
//
// Get properties.
//
_sc = TW32( ScAllocPropList( _cbProps ) );
if ( _sc == ERROR_SUCCESS )
{
_sc = TW32E( ClusterControl(
hCluster,
hHostNode,
dwControlCode,
lpInBuffer,
static_cast< DWORD >( cbInBufferSize ),
m_cbhPropList.pb,
static_cast< DWORD >( m_cbBufferSize ),
&_cbProps
), ERROR_MORE_DATA );
if ( _sc == ERROR_MORE_DATA )
{
_sc = TW32( ScAllocPropList( _cbProps ) );
if ( _sc == ERROR_SUCCESS )
{
_sc = TW32( ClusterControl(
hCluster,
hHostNode,
dwControlCode,
lpInBuffer,
static_cast< DWORD >( cbInBufferSize ),
m_cbhPropList.pb,
static_cast< DWORD >( m_cbBufferSize ),
&_cbProps
) );
} // if: ScAllocPropList succeeded
} // if: buffer too small
} // if: ScAllocPropList succeeded
if ( _sc != ERROR_SUCCESS )
{
DeletePropList();
} // if: error getting private properties.
else
{
m_cbDataSize = static_cast< size_t >( _cbProps );
m_cbDataLeft = static_cast< size_t >( _cbProps );
} // else: no errors
return _sc;
} //*** CClusPropList::ScGetClusterProperties