Parsing a Value List
The following example parses a value list returned from the CLUSCTL_RESOURCE_TYPE_STORAGE_GET_AVAILABLE_DISKS control code.
#include <windows.h>
//////////////////////////////////////////////////////////////////////
#include "ClusDocEx.h"
//////////////////////////////////////////////////////////////////////
#ifndef _CLUSDOCEX_NODISSIGNATUREAVAILABLE_CPP
#define _CLUSDOCEX_NODISSIGNATUREAVAILABLE_CPP
//--------------------------------------------------------------------
// ClusDocEx_NodIsSignatureAvailable
//
// Tests whether a node can access a disk with a specified signature.
//
// Arguments:
// IN HCLUSTER hCluster Cluster handle.
// IN HNODE hNode Handle to the node to query.
// IN DWORD dwSignature Signature to query for.
//
// Return Value:
// TRUE if the signature is available to the node
// FALSE if not (or if an error occurs)
//
//--------------------------------------------------------------------
BOOL ClusDocEx_NodIsSignatureAvailable
(
IN HCLUSTER hCluster,
IN HNODE hNode,
IN DWORD dwSignature
)
{
DWORD dwResult = ERROR_SUCCESS;
DWORD cbPosition = 0;
DWORD cbListSize = 0;
BOOL bDiskFound = FALSE;
LPVOID lpValueList = NULL;
CLUSPROP_BUFFER_HELPER cbh;
if( ( hCluster == NULL ) ||
( hNode == NULL ) )
{
dwResult = ERROR_BAD_ARGUMENTS;
goto endf;
}
// Get all disks available to the specified node.
lpValueList = ClusDocEx_RtpGetControlCodeOutput(
L"Physical Disk",
hCluster,
hNode,
CLUSCTL_RESOURCE_TYPE_STORAGE_GET_AVAILABLE_DISKS,
&cbListSize );
if( lpValueList == NULL )
{
dwResult = GetLastError();
goto endf;
}
// Parse the buffer. The control code returns a value list.
// The entry for each disk begins with a CLUSPROP_DISK_SIGNATURE structure.
cbh.pb = (PBYTE) lpValueList;
while( 1 )
{
if( ( cbh.pDiskSignatureValue->Syntax.dw == CLUSPROP_SYNTAX_DISK_SIGNATURE ) &&
( cbh.pDiskSignatureValue->dw == dwSignature ) )
{
// Syntax indicates a CLUSPROP_DISK_SIGNATURE structure.
// The signature found matches the specified signature.
bDiskFound = TRUE;
break;
}
else if( cbh.pSyntax->dw == CLUSPROP_SYNTAX_ENDMARK )
// Reached the end of the list.
break;
// Add the size of the current entry to the position indicator
cbPosition += ClusDocEx_ListEntrySize( cbh.pValue->cbLength );
// Compare position indicator to the size of the list.
// Adding sizeof( DWORD ) allows for the read operation at the
// top of the loop.
if( ( cbPosition + sizeof( DWORD ) ) > cbListSize )
break;
// Advance cbh
cbh.pb += ClusDocEx_ListEntrySize( cbh.pValue->cbLength );
}
// End while.
endf:
if( lpValueList != NULL )
LocalFree( lpValueList );
SetLastError( dwResult );
return bDiskFound;
}
// end ClusDocEx_NodIsSignatureAvailable
//--------------------------------------------------------------------
#endif