mirror of https://github.com/tongzx/nt5src
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.
2776 lines
67 KiB
2776 lines
67 KiB
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 1997-1999 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
// PropList.cpp
|
|
//
|
|
// Description:
|
|
// Implementation of the CClusPropList class.
|
|
//
|
|
// Author:
|
|
// David Potter (davidp) February 24, 1997
|
|
//
|
|
// Revision History:
|
|
// Galen Barbee (galenb) December 18, 1998
|
|
// Added parsing methods.
|
|
//
|
|
// Notes:
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "Pch.h"
|
|
#include "proplist.tmh"
|
|
|
|
#ifdef _DEBUG
|
|
#ifdef __AFX_H__
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif // __AFX_H__
|
|
#endif
|
|
|
|
#ifndef __AFX_H__
|
|
class CMemoryException
|
|
{
|
|
public:
|
|
void Delete( void ) { }
|
|
|
|
}; //*** class CMemoryException
|
|
#endif // __AFX_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 != _T( '\0' ) )
|
|
{
|
|
_cchChars = lstrlenW( 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
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifdef __AFX_H__
|
|
IMPLEMENT_DYNAMIC( CClusPropValueList, CObject );
|
|
#endif // __AFX_H__
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// 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_bAtEnd = 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;
|
|
DWORD _cbDataSize;
|
|
CLUSPROP_BUFFER_HELPER _cbhCurrentValue;
|
|
|
|
_cbhCurrentValue = m_cbhCurrentValue;
|
|
|
|
do
|
|
{
|
|
//
|
|
// Don't try to move if we're already at the end.
|
|
//
|
|
if ( m_bAtEnd )
|
|
{
|
|
break;
|
|
} // 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 = ERROR_INVALID_DATA;
|
|
break;
|
|
} // 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 = ERROR_INVALID_DATA;
|
|
break;
|
|
} // 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_bAtEnd = TRUE;
|
|
} // else: next value's syntax is the endmark
|
|
} while ( 0 );
|
|
|
|
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;
|
|
DWORD _cbDataSize;
|
|
|
|
_cbhCurrentValue = m_cbhCurrentValue;
|
|
|
|
do
|
|
{
|
|
//
|
|
// Don't try to recalculate if we already know
|
|
// we're at the end of the list.
|
|
//
|
|
if ( m_bAtEnd )
|
|
{
|
|
break;
|
|
} // 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 = ERROR_INVALID_DATA;
|
|
break;
|
|
} // 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 = ERROR_INVALID_DATA;
|
|
break;
|
|
} // 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
|
|
} while ( 0 );
|
|
|
|
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.
|
|
//
|
|
// Exceptions Thrown:
|
|
// Any exceptions thrown by new. By default, no exceptions are thrown.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
DWORD CClusPropValueList::ScAllocValueList( IN DWORD cbMinimum )
|
|
{
|
|
ASSERT( cbMinimum > 0 );
|
|
|
|
DWORD _sc = ERROR_SUCCESS;
|
|
DWORD _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 = 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.
|
|
//
|
|
// Exceptions Thrown:
|
|
// Any exceptions CClusPropValueList::ScAllocValueList().
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
DWORD CClusPropValueList::ScGetResourceValueList(
|
|
IN HRESOURCE hResource,
|
|
IN DWORD dwControlCode,
|
|
IN HNODE hHostNode,
|
|
IN LPVOID lpInBuffer,
|
|
IN DWORD 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;
|
|
|
|
TracePrint(( "GetResourceValueList entry\n" ));
|
|
|
|
//
|
|
// 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 = ClusterResourceControl(
|
|
hResource,
|
|
hHostNode,
|
|
dwControlCode,
|
|
lpInBuffer,
|
|
cbInBufferSize,
|
|
m_cbhValueList.pb,
|
|
m_cbBufferSize,
|
|
&_cb
|
|
);
|
|
if ( _sc == ERROR_MORE_DATA )
|
|
{
|
|
_sc = ScAllocValueList( _cb );
|
|
if ( _sc == ERROR_SUCCESS )
|
|
{
|
|
_sc = ClusterResourceControl(
|
|
hResource,
|
|
hHostNode,
|
|
dwControlCode,
|
|
lpInBuffer,
|
|
cbInBufferSize,
|
|
m_cbhValueList.pb,
|
|
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 = _cb;
|
|
m_cbDataLeft = _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.
|
|
//
|
|
// Exceptions Thrown:
|
|
// Any exceptions CClusPropValueList::ScAllocValueList().
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
DWORD CClusPropValueList::ScGetResourceTypeValueList(
|
|
IN HCLUSTER hCluster,
|
|
IN LPCWSTR pwszResTypeName,
|
|
IN DWORD dwControlCode,
|
|
IN HNODE hHostNode,
|
|
IN LPVOID lpInBuffer,
|
|
IN DWORD 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;
|
|
|
|
TracePrint(( "GetResourceTypeValueList entry\n" ));
|
|
|
|
//
|
|
// 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 = ClusterResourceTypeControl(
|
|
hCluster,
|
|
pwszResTypeName,
|
|
hHostNode,
|
|
dwControlCode,
|
|
lpInBuffer,
|
|
cbInBufferSize,
|
|
m_cbhValueList.pb,
|
|
m_cbBufferSize,
|
|
&_cb
|
|
);
|
|
if ( _sc == ERROR_MORE_DATA )
|
|
{
|
|
_sc = ScAllocValueList( _cb );
|
|
if ( _sc == ERROR_SUCCESS )
|
|
{
|
|
_sc = ClusterResourceTypeControl(
|
|
hCluster,
|
|
pwszResTypeName,
|
|
hHostNode,
|
|
dwControlCode,
|
|
lpInBuffer,
|
|
cbInBufferSize,
|
|
m_cbhValueList.pb,
|
|
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 = _cb;
|
|
m_cbDataLeft = _cb;
|
|
} // else: no errors
|
|
|
|
return _sc;
|
|
|
|
} //*** CClusPropValueList::ScGetResourceTypeValueList()
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CClusPropList class
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifdef __AFX_H__
|
|
IMPLEMENT_DYNAMIC( CClusPropList, CObject );
|
|
#endif // __AFX_H__
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// 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 DWORD 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 = ERROR_NOT_ENOUGH_MEMORY;
|
|
} // else:
|
|
|
|
return _sc;
|
|
|
|
} //*** CClusPropList::ScCopy()
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusPropList::ScMoveToFirstProperty
|
|
//
|
|
// Description:
|
|
// Move the cursor to the first property 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;
|
|
DWORD _cbDataLeft;
|
|
DWORD _cbDataSize;
|
|
CLUSPROP_BUFFER_HELPER _cbhCurrentValue;
|
|
|
|
TracePrint(( "MoveToFirstProperty: entry\n" ));
|
|
|
|
do
|
|
{
|
|
//
|
|
// Make sure the buffer is big enough for the list header.
|
|
//
|
|
if ( m_cbDataSize < sizeof( m_cbhPropList.pList->nPropertyCount ) )
|
|
{
|
|
_sc = ERROR_INVALID_DATA;
|
|
break;
|
|
} // 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 )
|
|
{
|
|
TracePrint(( "MoveToFirstProperty: no properties found!\n" ));
|
|
_sc = ERROR_NO_MORE_ITEMS;
|
|
break;
|
|
} // 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 = ERROR_INVALID_DATA;
|
|
break;
|
|
} // 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 = ERROR_INVALID_DATA;
|
|
break;
|
|
} // if: not enough data left
|
|
|
|
//
|
|
// Point the value buffer to the first value in the list.
|
|
//
|
|
//TracePrint(( "MoveToFirstProperty: First Property Name = %ws, props remain = %u\n", _cbhCurrentValue.pStringValue->sz, m_nPropsRemaining ));
|
|
_cbhCurrentValue.pb = m_cbhCurrentPropName.pb + _cbDataSize;
|
|
_cbDataLeft = m_cbDataLeft - _cbDataSize;
|
|
m_pvlValues.Init( _cbhCurrentValue, _cbDataLeft );
|
|
|
|
//
|
|
// Indicate we are successful.
|
|
//
|
|
_sc = ERROR_SUCCESS;
|
|
|
|
} while ( 0 );
|
|
|
|
//_cbhCurrentValue = m_pvlValues;
|
|
//TracePrint(( "MoveToFirstProperty: First Property Name = %ws, props remain = %u\n", _cbhCurrentValue.pStringValue->sz, m_nPropsRemaining ));
|
|
|
|
TracePrint(( "MoveToFirstProperty: exit\n" ));
|
|
|
|
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;
|
|
DWORD _cbNameSize;
|
|
DWORD _cbDataLeft;
|
|
DWORD _cbDataSize;
|
|
CLUSPROP_BUFFER_HELPER _cbhCurrentValue;
|
|
CLUSPROP_BUFFER_HELPER _cbhPropName;
|
|
|
|
_cbhCurrentValue = m_pvlValues;
|
|
_cbDataLeft = m_pvlValues.CbDataLeft();
|
|
|
|
//TracePrint(( "CClusPropList:ScMoveToNextProperty entry\n" ));
|
|
|
|
//
|
|
// If we aren't already at the last property, attempt to move to the next one.
|
|
//
|
|
_sc = ScCheckIfAtLastProperty();
|
|
if ( _sc == ERROR_SUCCESS )
|
|
{
|
|
do
|
|
{
|
|
//
|
|
// Make sure the buffer is big enough for the value header.
|
|
//
|
|
if ( _cbDataLeft < sizeof( *_cbhCurrentValue.pValue ) )
|
|
{
|
|
_sc = ERROR_INVALID_DATA;
|
|
break;
|
|
} // 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 = ERROR_INVALID_DATA;
|
|
break;
|
|
} // if: not enough data left
|
|
|
|
//
|
|
// Advance past the value.
|
|
//
|
|
_cbhCurrentValue.pb += _cbDataSize;
|
|
_cbDataLeft -= _cbDataSize;
|
|
} // while: not at endmark
|
|
|
|
if ( _sc != ERROR_SUCCESS )
|
|
{
|
|
break;
|
|
} // 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;
|
|
//TracePrint(( "MoveToNextProperty: name = %ws\n", _cbhPropName.pStringValue->sz ));
|
|
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 = ERROR_INVALID_DATA;
|
|
break;
|
|
} // if: not enough data
|
|
_cbNameSize = sizeof( *_cbhPropName.pName )
|
|
+ ALIGN_CLUSPROP( _cbhPropName.pName->cbLength );
|
|
if ( _cbDataLeft < _cbNameSize + sizeof( CLUSPROP_SYNTAX ) )
|
|
{
|
|
_sc = ERROR_INVALID_DATA;
|
|
break;
|
|
} // 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;
|
|
|
|
} while ( 0 );
|
|
} // if: not at last property
|
|
|
|
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:
|
|
// TRUE if the property was found, FALSE 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 ( lstrcmpiW( m_cbhCurrentPropName.pName->sz, pwszPropName ) == 0 )
|
|
{
|
|
break;
|
|
} // if: property found
|
|
|
|
//
|
|
// Advance to the next property.
|
|
//
|
|
_sc = ScMoveToNextProperty();
|
|
|
|
} 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:
|
|
// None.
|
|
//
|
|
// Exceptions Thrown:
|
|
// Any exceptions thrown by new. By default, no exceptions are thrown.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
DWORD CClusPropList::ScAllocPropList( IN DWORD cbMinimum )
|
|
{
|
|
ASSERT( cbMinimum > 0 );
|
|
|
|
DWORD _sc = ERROR_SUCCESS;
|
|
DWORD _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 = 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 _bValuesDifferent = TRUE;
|
|
PCLUSPROP_PROPERTY_NAME _pName;
|
|
PCLUSPROP_SZ _pValue;
|
|
|
|
if (( pwszPrevValue != NULL ) && ( lstrcmpW( pwszValue, pwszPrevValue ) == 0 ))
|
|
{
|
|
_bValuesDifferent = 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_bAlwaysAddProp || _bValuesDifferent )
|
|
{
|
|
DWORD _cbNameSize;
|
|
DWORD _cbDataSize;
|
|
DWORD _cbValueSize;
|
|
|
|
//
|
|
// Calculate sizes and make sure we have a property list.
|
|
//
|
|
_cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
|
|
+ ALIGN_CLUSPROP( (lstrlenW( pwszName ) + 1) * sizeof( WCHAR ) );
|
|
_cbDataSize = (lstrlenW( pwszValue ) + 1) * sizeof( WCHAR );
|
|
_cbValueSize = sizeof( CLUSPROP_SZ )
|
|
+ ALIGN_CLUSPROP( _cbDataSize )
|
|
+ sizeof( CLUSPROP_SYNTAX ); // value list endmark
|
|
|
|
_sc = 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 _bValuesDifferent = TRUE;
|
|
PCLUSPROP_PROPERTY_NAME _pName;
|
|
PCLUSPROP_MULTI_SZ _pValue;
|
|
|
|
if ( ( pwszPrevValue != NULL ) && ( NCompareMultiSz( pwszValue, pwszPrevValue ) == 0 ) )
|
|
{
|
|
_bValuesDifferent = 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_bAlwaysAddProp || _bValuesDifferent )
|
|
{
|
|
DWORD _cbNameSize;
|
|
DWORD _cbDataSize;
|
|
DWORD _cbValueSize;
|
|
|
|
//
|
|
// Calculate sizes and make sure we have a property list.
|
|
//
|
|
_cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
|
|
+ ALIGN_CLUSPROP( (lstrlenW( pwszName ) + 1) * sizeof( WCHAR ) );
|
|
_cbDataSize = (CchMultiSz( pwszValue ) + 1) * sizeof( WCHAR );
|
|
_cbValueSize = sizeof( CLUSPROP_SZ )
|
|
+ ALIGN_CLUSPROP( _cbDataSize )
|
|
+ sizeof( CLUSPROP_SYNTAX ); // value list endmark
|
|
|
|
_sc = 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 _bValuesDifferent = TRUE;
|
|
PCLUSPROP_PROPERTY_NAME _pName;
|
|
PCLUSPROP_SZ _pValue;
|
|
|
|
if ( ( pwszPrevValue != NULL ) && ( lstrcmpW( pwszValue, pwszPrevValue ) == 0 ) )
|
|
{
|
|
_bValuesDifferent = 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_bAlwaysAddProp || _bValuesDifferent )
|
|
{
|
|
DWORD _cbNameSize;
|
|
DWORD _cbDataSize;
|
|
DWORD _cbValueSize;
|
|
|
|
//
|
|
// Calculate sizes and make sure we have a property list.
|
|
//
|
|
_cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
|
|
+ ALIGN_CLUSPROP( (lstrlenW( pwszName ) + 1) * sizeof( WCHAR ) );
|
|
_cbDataSize = (lstrlenW( pwszValue ) + 1) * sizeof( WCHAR );
|
|
_cbValueSize = sizeof( CLUSPROP_SZ )
|
|
+ ALIGN_CLUSPROP( _cbDataSize )
|
|
+ sizeof( CLUSPROP_SYNTAX ); // value list endmark
|
|
|
|
_sc = 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_bAlwaysAddProp || ( nValue != nPrevValue ) )
|
|
{
|
|
DWORD _cbNameSize;
|
|
DWORD _cbValueSize;
|
|
|
|
//
|
|
// Calculate sizes and make sure we have a property list.
|
|
//
|
|
_cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
|
|
+ ALIGN_CLUSPROP( (lstrlenW( pwszName ) + 1) * sizeof( WCHAR ) );
|
|
_cbValueSize = sizeof( CLUSPROP_DWORD )
|
|
+ sizeof( CLUSPROP_SYNTAX ); // value list endmark
|
|
|
|
_sc = 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 )
|
|
|
|
#if CLUSAPI_VERSION >= 0x0500
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// 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_bAlwaysAddProp || ( nValue != nPrevValue ) )
|
|
{
|
|
DWORD _cbNameSize;
|
|
DWORD _cbValueSize;
|
|
|
|
//
|
|
// Calculate sizes and make sure we have a property list.
|
|
//
|
|
_cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
|
|
+ ALIGN_CLUSPROP( (lstrlenW( pwszName ) + 1) * sizeof( WCHAR ) );
|
|
_cbValueSize = sizeof( CLUSPROP_LONG )
|
|
+ sizeof( CLUSPROP_SYNTAX ); // value list endmark
|
|
|
|
_sc = 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 )
|
|
|
|
#endif // CLUSAPI_VERSION >= 0x0500
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// 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 PBYTE pbValue,
|
|
IN DWORD cbValue,
|
|
IN const PBYTE pbPrevValue,
|
|
IN DWORD cbPrevValue
|
|
)
|
|
{
|
|
ASSERT( pwszName != NULL );
|
|
|
|
DWORD _sc = ERROR_SUCCESS;
|
|
BOOL bChanged = FALSE;
|
|
PCLUSPROP_PROPERTY_NAME _pName;
|
|
PCLUSPROP_BINARY _pValue;
|
|
|
|
//
|
|
// Determine if the buffer has changed.
|
|
//
|
|
if ( m_bAlwaysAddProp || (cbValue != cbPrevValue) )
|
|
{
|
|
bChanged = TRUE;
|
|
} // if: always adding the property or the value size changed
|
|
else if ( ( cbValue != 0 ) && ( cbPrevValue != 0 ) )
|
|
{
|
|
bChanged = memcmp( pbValue, pbPrevValue, cbValue ) != 0;
|
|
} // else if: value length changed
|
|
|
|
if ( bChanged )
|
|
{
|
|
DWORD _cbNameSize;
|
|
DWORD _cbValueSize;
|
|
|
|
//
|
|
// Calculate sizes and make sure we have a property list.
|
|
//
|
|
_cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
|
|
+ ALIGN_CLUSPROP( (lstrlenW( pwszName ) + 1) * sizeof( WCHAR ) );
|
|
_cbValueSize = sizeof( CLUSPROP_BINARY )
|
|
+ ALIGN_CLUSPROP( cbValue )
|
|
+ sizeof( CLUSPROP_SYNTAX ); // value list endmark
|
|
|
|
_sc = 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:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
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_bAlwaysAddProp || ( ullValue != ullPrevValue ) )
|
|
{
|
|
DWORD _cbNameSize;
|
|
DWORD _cbValueSize;
|
|
|
|
//
|
|
// Calculate sizes and make sure we have a property list.
|
|
//
|
|
_cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
|
|
+ ALIGN_CLUSPROP( (lstrlenW( pwszName ) + 1) * sizeof( WCHAR ) );
|
|
_cbValueSize = sizeof( CLUSPROP_ULARGE_INTEGER )
|
|
+ sizeof( CLUSPROP_SYNTAX ); // value list endmark
|
|
|
|
_sc = 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::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:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
DWORD CClusPropList::ScSetPropToDefault(
|
|
IN LPCWSTR pwszName,
|
|
IN CLUSTER_PROPERTY_FORMAT cpfPropFmt
|
|
)
|
|
{
|
|
ASSERT( pwszName != NULL );
|
|
|
|
DWORD _sc = ERROR_SUCCESS;
|
|
DWORD _cbNameSize;
|
|
DWORD _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( (lstrlenW( pwszName ) + 1) * sizeof( WCHAR ) );
|
|
_cbValueSize = sizeof( CLUSPROP_BINARY )
|
|
+ sizeof( CLUSPROP_SYNTAX ); // value list endmark
|
|
|
|
_sc = 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;
|
|
|
|
pprop->Syntax.wFormat = CLUSPROP_FORMAT_SZ;
|
|
pprop->Syntax.wType = static_cast< WORD >( cptPropType );
|
|
if ( cbsz == 0 )
|
|
{
|
|
cbsz = (lstrlenW( psz ) + 1) * sizeof( WCHAR );
|
|
} // if: zero size specified
|
|
ASSERT( cbsz == (lstrlenW( psz ) + 1) * sizeof( WCHAR ) );
|
|
pprop->cbLength = cbsz;
|
|
lstrcpyW( pprop->sz, psz );
|
|
|
|
//
|
|
// 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( WCHAR );
|
|
} // if: zero size specified
|
|
ASSERT( cbsz == (CchMultiSz( psz ) + 1) * sizeof( WCHAR ) );
|
|
pprop->cbLength = 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;
|
|
|
|
pprop->Syntax.wFormat = CLUSPROP_FORMAT_EXPAND_SZ;
|
|
pprop->Syntax.wType = static_cast< WORD >( cptPropType );
|
|
if ( cbsz == 0 )
|
|
{
|
|
cbsz = (lstrlenW( psz ) + 1) * sizeof( WCHAR );
|
|
} // if: cbsz == 0
|
|
ASSERT( cbsz == (lstrlenW( psz ) + 1) * sizeof( WCHAR ) );
|
|
pprop->cbLength = cbsz;
|
|
lstrcpyW( pprop->sz, psz );
|
|
|
|
//
|
|
// 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 )
|
|
|
|
#if CLUSAPI_VERSION >= 0x0500
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// 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 )
|
|
|
|
#endif // CLUSAPI_VERSION >= 0x0500
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusPropList::CopyProp
|
|
//
|
|
// Description:
|
|
// Copy a ULONGLONG property to a property structure.
|
|
//
|
|
// Arguments:
|
|
// pprop [OUT] Property structure to fill.
|
|
// proptype [IN] Type of LONG.
|
|
// nValue [IN] Property value to copy.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CClusPropList::CopyProp(
|
|
OUT PCLUSPROP_ULARGE_INTEGER pprop,
|
|
IN CLUSTER_PROPERTY_TYPE proptype,
|
|
IN ULONGLONG nValue
|
|
)
|
|
{
|
|
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->li.QuadPart = nValue;
|
|
|
|
//
|
|
// 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 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 PBYTE 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 = 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.
|
|
//
|
|
// Exceptions Thrown:
|
|
// Any exceptions CClusPropList::ScAllocPropList().
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
DWORD CClusPropList::ScGetNodeProperties(
|
|
IN HNODE hNode,
|
|
IN DWORD dwControlCode,
|
|
IN HNODE hHostNode,
|
|
IN LPVOID lpInBuffer,
|
|
IN DWORD 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 = ScAllocPropList( _cbProps );
|
|
if ( _sc == ERROR_SUCCESS )
|
|
{
|
|
_sc = ClusterNodeControl(
|
|
hNode,
|
|
hHostNode,
|
|
dwControlCode,
|
|
lpInBuffer,
|
|
cbInBufferSize,
|
|
m_cbhPropList.pb,
|
|
m_cbBufferSize,
|
|
&_cbProps
|
|
);
|
|
if ( _sc == ERROR_MORE_DATA )
|
|
{
|
|
_sc = ScAllocPropList( _cbProps );
|
|
if ( _sc == ERROR_SUCCESS )
|
|
{
|
|
_sc = ClusterNodeControl(
|
|
hNode,
|
|
hHostNode,
|
|
dwControlCode,
|
|
lpInBuffer,
|
|
cbInBufferSize,
|
|
m_cbhPropList.pb,
|
|
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 = _cbProps;
|
|
m_cbDataLeft = _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.
|
|
//
|
|
// Exceptions Thrown:
|
|
// Any exceptions CClusPropList::ScAllocPropList().
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
DWORD CClusPropList::ScGetGroupProperties(
|
|
IN HGROUP hGroup,
|
|
IN DWORD dwControlCode,
|
|
IN HNODE hHostNode,
|
|
IN LPVOID lpInBuffer,
|
|
IN DWORD 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 = ScAllocPropList( _cbProps );
|
|
if ( _sc == ERROR_SUCCESS )
|
|
{
|
|
_sc = ClusterGroupControl(
|
|
hGroup,
|
|
hHostNode,
|
|
dwControlCode,
|
|
lpInBuffer,
|
|
cbInBufferSize,
|
|
m_cbhPropList.pb,
|
|
m_cbBufferSize,
|
|
&_cbProps
|
|
);
|
|
if ( _sc == ERROR_MORE_DATA )
|
|
{
|
|
_sc = ScAllocPropList( _cbProps );
|
|
if ( _sc == ERROR_SUCCESS )
|
|
{
|
|
_sc = ClusterGroupControl(
|
|
hGroup,
|
|
hHostNode,
|
|
dwControlCode,
|
|
lpInBuffer,
|
|
cbInBufferSize,
|
|
m_cbhPropList.pb,
|
|
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 = _cbProps;
|
|
m_cbDataLeft = _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.
|
|
//
|
|
// Exceptions Thrown:
|
|
// Any exceptions CClusPropList::ScAllocPropList().
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
DWORD CClusPropList::ScGetResourceProperties(
|
|
IN HRESOURCE hResource,
|
|
IN DWORD dwControlCode,
|
|
IN HNODE hHostNode,
|
|
IN LPVOID lpInBuffer,
|
|
IN DWORD 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 = ScAllocPropList( _cbProps );
|
|
if ( _sc == ERROR_SUCCESS )
|
|
{
|
|
_sc = ClusterResourceControl(
|
|
hResource,
|
|
hHostNode,
|
|
dwControlCode,
|
|
lpInBuffer,
|
|
cbInBufferSize,
|
|
m_cbhPropList.pb,
|
|
m_cbBufferSize,
|
|
&_cbProps
|
|
);
|
|
if ( _sc == ERROR_MORE_DATA )
|
|
{
|
|
_sc = ScAllocPropList( _cbProps );
|
|
if ( _sc == ERROR_SUCCESS )
|
|
{
|
|
_sc = ClusterResourceControl(
|
|
hResource,
|
|
hHostNode,
|
|
dwControlCode,
|
|
lpInBuffer,
|
|
cbInBufferSize,
|
|
m_cbhPropList.pb,
|
|
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 = _cbProps;
|
|
m_cbDataLeft = _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.
|
|
//
|
|
// Exceptions Thrown:
|
|
// Any exceptions CClusPropList::ScAllocPropList().
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
DWORD CClusPropList::ScGetResourceTypeProperties(
|
|
IN HCLUSTER hCluster,
|
|
IN LPCWSTR pwszResTypeName,
|
|
IN DWORD dwControlCode,
|
|
IN HNODE hHostNode,
|
|
IN LPVOID lpInBuffer,
|
|
IN DWORD 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 = ScAllocPropList( _cbProps );
|
|
if ( _sc == ERROR_SUCCESS )
|
|
{
|
|
_sc = ClusterResourceTypeControl(
|
|
hCluster,
|
|
pwszResTypeName,
|
|
hHostNode,
|
|
dwControlCode,
|
|
lpInBuffer,
|
|
cbInBufferSize,
|
|
m_cbhPropList.pb,
|
|
m_cbBufferSize,
|
|
&_cbProps
|
|
);
|
|
if ( _sc == ERROR_MORE_DATA )
|
|
{
|
|
_sc = ScAllocPropList( _cbProps );
|
|
if ( _sc == ERROR_SUCCESS )
|
|
{
|
|
_sc = ClusterResourceTypeControl(
|
|
hCluster,
|
|
pwszResTypeName,
|
|
hHostNode,
|
|
dwControlCode,
|
|
lpInBuffer,
|
|
cbInBufferSize,
|
|
m_cbhPropList.pb,
|
|
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 = _cbProps;
|
|
m_cbDataLeft = _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.
|
|
//
|
|
// Exceptions Thrown:
|
|
// Any exceptions CClusPropList::ScAllocPropList().
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
DWORD CClusPropList::ScGetNetworkProperties(
|
|
IN HNETWORK hNetwork,
|
|
IN DWORD dwControlCode,
|
|
IN HNODE hHostNode,
|
|
IN LPVOID lpInBuffer,
|
|
IN DWORD 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 = ScAllocPropList( _cbProps );
|
|
if ( _sc == ERROR_SUCCESS )
|
|
{
|
|
_sc = ClusterNetworkControl(
|
|
hNetwork,
|
|
hHostNode,
|
|
dwControlCode,
|
|
lpInBuffer,
|
|
cbInBufferSize,
|
|
m_cbhPropList.pb,
|
|
m_cbBufferSize,
|
|
&_cbProps
|
|
);
|
|
if ( _sc == ERROR_MORE_DATA )
|
|
{
|
|
_sc = ScAllocPropList( _cbProps );
|
|
if ( _sc == ERROR_SUCCESS )
|
|
{
|
|
_sc = ClusterNetworkControl(
|
|
hNetwork,
|
|
hHostNode,
|
|
dwControlCode,
|
|
lpInBuffer,
|
|
cbInBufferSize,
|
|
m_cbhPropList.pb,
|
|
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 = _cbProps;
|
|
m_cbDataLeft = _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.
|
|
//
|
|
// Exceptions Thrown:
|
|
// Any exceptions CClusPropList::ScAllocPropList().
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
DWORD CClusPropList::ScGetNetInterfaceProperties(
|
|
IN HNETINTERFACE hNetInterface,
|
|
IN DWORD dwControlCode,
|
|
IN HNODE hHostNode,
|
|
IN LPVOID lpInBuffer,
|
|
IN DWORD 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 = ScAllocPropList( _cbProps );
|
|
if ( _sc == ERROR_SUCCESS )
|
|
{
|
|
_sc = ClusterNetInterfaceControl(
|
|
hNetInterface,
|
|
hHostNode,
|
|
dwControlCode,
|
|
lpInBuffer,
|
|
cbInBufferSize,
|
|
m_cbhPropList.pb,
|
|
m_cbBufferSize,
|
|
&_cbProps
|
|
);
|
|
if ( _sc == ERROR_MORE_DATA )
|
|
{
|
|
_sc = ScAllocPropList( _cbProps );
|
|
if ( _sc == ERROR_SUCCESS )
|
|
{
|
|
_sc = ClusterNetInterfaceControl(
|
|
hNetInterface,
|
|
hHostNode,
|
|
dwControlCode,
|
|
lpInBuffer,
|
|
cbInBufferSize,
|
|
m_cbhPropList.pb,
|
|
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 = _cbProps;
|
|
m_cbDataLeft = _cbProps;
|
|
} // else: no errors
|
|
|
|
return _sc;
|
|
|
|
} //*** CClusPropList::ScGetNetInterfaceProperties()
|
|
|
|
#if CLUSAPI_VERSION >= 0x0500
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// 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.
|
|
//
|
|
// Exceptions Thrown:
|
|
// Any exceptions CClusPropList::ScAllocPropList().
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
DWORD CClusPropList::ScGetClusterProperties(
|
|
IN HCLUSTER hCluster,
|
|
IN DWORD dwControlCode,
|
|
IN HNODE hHostNode,
|
|
IN LPVOID lpInBuffer,
|
|
IN DWORD 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 = ScAllocPropList( _cbProps );
|
|
if ( _sc == ERROR_SUCCESS )
|
|
{
|
|
_sc = ClusterControl(
|
|
hCluster,
|
|
hHostNode,
|
|
dwControlCode,
|
|
lpInBuffer,
|
|
cbInBufferSize,
|
|
m_cbhPropList.pb,
|
|
m_cbBufferSize,
|
|
&_cbProps
|
|
);
|
|
if ( _sc == ERROR_MORE_DATA )
|
|
{
|
|
_sc = ScAllocPropList( _cbProps );
|
|
if ( _sc == ERROR_SUCCESS )
|
|
{
|
|
_sc = ClusterControl(
|
|
hCluster,
|
|
hHostNode,
|
|
dwControlCode,
|
|
lpInBuffer,
|
|
cbInBufferSize,
|
|
m_cbhPropList.pb,
|
|
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 = _cbProps;
|
|
m_cbDataLeft = _cbProps;
|
|
} // else: no errors
|
|
|
|
return _sc;
|
|
|
|
} //*** CClusPropList::ScGetClusterProperties()
|
|
|
|
|
|
#endif // CLUSAPI_VERSION >= 0x0500
|