Note

Access to this page requires authorization. You can try signing in or .

Access to this page requires authorization. You can try .

Creating Property Lists

There are two recommended ways of creating a property list:

This distinction is based on the fact that many property table operations require direct access to the cluster database. Resource DLLs are expected to have such access. However, cluster-aware applications should avoid direct cluster database manipulation. See the standard order of preference.

As a third option, the FileShareSample sample resource type (located in the Samples\WinBase\Cluster directory of the Windows SDK) includes the complete implementation of CClusPropList, a sample property list management class.

Example

The following example contains the functions ClusDocEx_CreatePropertyListEntry and ClusDocEx_GrpCreatePropertyList. The first function returns a buffer containing a single property list entry. The second function uses the first function to create multiple entries and "stacks" them into a property list.

#include <windows.h>

//////////////////////////////////////////////////////////////////////

#include "ClusDocEx.h"

//////////////////////////////////////////////////////////////////////

#ifndef _CLUSDOCEX_CREATEPROPERTYLISTENTRY_CPP
#define _CLUSDOCEX_CREATEPROPERTYLISTENTRY_CPP
//--------------------------------------------------------------------
//
// ClusDocEx_CreatePropertyListEntry.
// 
// Returns a buffer containing an entry for a property list,
// formatted as a value list containing the following entries:
// Property Name (syntax, length, data, padding)
// Property Value (syntax, length, data, padding)
// CLUSPROP_SYNTAX_ENDMARK
// 
// Callers must call LocalFree on the returned pointer.
// 
// Arguments:
// IN LPWSTR lpszPropName Name of the property.
// IN DWORD dwSyntax Data syntax (see CLUSPROP_SYNTAX).
// IN DWORD cbLength Data length (see CLUSPROP_VALUE).
// IN LPVOID lpData Pointer to the data.
// OUT LPDWORD lpcbEntrySize Byte size of the resulting entry. 
// 
// Return Value: 
// Pointer to a buffer containing a property list entry.
// 
//-------------------------------------------------------------------- 
LPVOID ClusDocEx_CreatePropertyListEntry( IN LPWSTR lpszPropName,
 IN DWORD dwSyntax,
 IN DWORD cbLength,
 IN LPVOID lpData,
 OUT LPDWORD lpcbEntrySize)
{
 DWORD cbPropNameSize = ( lstrlenW( lpszPropName ) + 1 ) * 
 sizeof( WCHAR );
 DWORD cbNameEntrySize;
 DWORD cbValueEntrySize;

 CLUSPROP_BUFFER_HELPER cbh;
 LPVOID lpEntry = NULL;


 // TODO: Code that checks for bad parameters.

 // Calculate sizes.
 // ClusDocEx_ListEntrySize is defined in ClusDocEx.h.

 cbNameEntrySize = ClusDocEx_ListEntrySize( cbPropNameSize );

 cbValueEntrySize = ClusDocEx_ListEntrySize( cbLength );

 *lpcbEntrySize = cbNameEntrySize +
 cbValueEntrySize +
 sizeof( DWORD );

 lpEntry = LocalAlloc( LPTR, *lpcbEntrySize );

 if( lpEntry != NULL )
 {

 // Position cbh.

 cbh.pb = (LPBYTE) lpEntry;

 // Write the property name.

 cbh.pName->Syntax.dw = CLUSPROP_SYNTAX_NAME;

 cbh.pName->cbLength = cbPropNameSize;

 StringCchCopyW( cbh.pName->sz, cbPropNameSize, lpszPropName );

 // Advance cbh. 

 cbh.pb += cbNameEntrySize;

 // Write syntax and length

 cbh.pValue->Syntax.dw = dwSyntax;

 cbh.pValue->cbLength = cbLength;

 // Position cbh.

 cbh.pb += sizeof( CLUSPROP_VALUE );

 // Copy the data.

 memcpy( cbh.pb, lpData, cbLength );

 // Position cbh. 

 cbh.pb = (PBYTE) lpEntry + cbNameEntrySize + cbValueEntrySize;

 // Set the endmark.

 *cbh.pdw = CLUSPROP_SYNTAX_ENDMARK;
 }

 cbh.pb = NULL;

 return lpEntry;
 }
// end ClusDocEx_CreatePropertyListEntry
//--------------------------------------------------------------------
#endif


//////////////////////////////////////////////////////////////////////


#ifndef _CLUSDOCEX_GRPCREATEPROPERTYLIST_CPP
#define _CLUSDOCEX_GRPCREATEPROPERTYLIST_CPP
//--------------------------------------------------------------------
//
// ClusDocEx_GrpCreatePropertyList(
// 
// Returns a property list containing all of the read/write common
// properties for a group.
// 
// Callers must call LocalFree on the returned pointer.
// 
// Arguments:
// LPDWORD lpcbPropListSize Byte size of the resulting 
// property list. 
// Use the remaining arguments to assign new values to the 
// read/write group common properties.
// 
// Return Value: 
// Pointer to a buffer containing a property list.
//-------------------------------------------------------------------- 
LPVOID
ClusDocEx_GrpCreatePropertyList( LPDWORD lpcbPropListSize,
 DWORD dwAutoFailbackType,
 LPWSTR lpszDescription,
 DWORD dwFailbackWindowEnd,
 DWORD dwFailbackWindowStart,
 DWORD dwFailoverPeriod,
 DWORD dwFailoverThreshold,
 DWORD dwPersistentState )
 {
 LPVOID lpPropList;
 LPVOID lpAutoFailbackType; 
 LPVOID lpDescription; 
 LPVOID lpFailbackWindowEnd; 
 LPVOID lpFailbackWindowStart; 
 LPVOID lpFailoverPeriod; 
 LPVOID lpFailoverThreshold; 
 LPVOID lpPersistentState; 

 DWORD dwPropCount = 7;
 DWORD cbPropEntrySize[7];
 DWORD cbPosition = 0;
 DWORD cb, dw;

 CLUSPROP_BUFFER_HELPER cbh_write, cbh_read;

 // Create the property list entries for each property.

 lpAutoFailbackType = ClusDocEx_CreatePropertyListEntry(
 L"AutoFailbackType",
 CLUSPROP_SYNTAX_LIST_VALUE_DWORD,
 sizeof( DWORD ),
 (LPVOID) &amp;dwAutoFailbackType,
 &amp;cbPropEntrySize[0] );

 lpDescription = ClusDocEx_CreatePropertyListEntry(
 L"Description",
 CLUSPROP_SYNTAX_LIST_VALUE_SZ,
 (lstrlenW(lpszDescription) + 1)*sizeof(WCHAR),
 (LPVOID) lpszDescription,
 &amp;cbPropEntrySize[1] );

 lpFailbackWindowEnd = ClusDocEx_CreatePropertyListEntry(
 L"FailbackWindowEnd",
 CLUSPROP_SYNTAX_LIST_VALUE_DWORD,
 sizeof( DWORD ),
 (LPVOID) &amp;dwFailbackWindowEnd,
 &amp;cbPropEntrySize[2] );

 lpFailbackWindowStart = ClusDocEx_CreatePropertyListEntry(
 L"FailbackWindowStart",
 CLUSPROP_SYNTAX_LIST_VALUE_DWORD,
 sizeof( DWORD ),
 (LPVOID) &amp;dwFailbackWindowStart,
 &amp;cbPropEntrySize[3] );

 lpFailoverPeriod = ClusDocEx_CreatePropertyListEntry(
 L"FailoverPeriod",
 CLUSPROP_SYNTAX_LIST_VALUE_DWORD,
 sizeof( DWORD ),
 (LPVOID) &amp;dwFailoverPeriod,
 &amp;cbPropEntrySize[4] );

 lpFailoverThreshold = ClusDocEx_CreatePropertyListEntry(
 L"FailoverThreshold",
 CLUSPROP_SYNTAX_LIST_VALUE_DWORD,
 sizeof( DWORD ),
 (LPVOID) &amp;dwFailoverThreshold,
 &amp;cbPropEntrySize[5] );

 lpPersistentState = ClusDocEx_CreatePropertyListEntry(
 L"PersistentState",
 CLUSPROP_SYNTAX_LIST_VALUE_DWORD,
 sizeof( DWORD ),
 (LPVOID) &amp;dwPersistentState,
 &amp;cbPropEntrySize[6] );

 // Calculate the required size, which should be the sum of each entry
 // plus the size of the property count.

 *lpcbPropListSize = sizeof( DWORD ); // property count.

 for( cb = 0 ; cb < dwPropCount ; cb++ )
 *lpcbPropListSize += cbPropEntrySize[cb];

 lpPropList = LocalAlloc( LPTR, *lpcbPropListSize );

 // Position cbh and write the property count.

 cbh_write.pb = (PBYTE) lpPropList;

 *cbh_write.pdw = dwPropCount;

 cbPosition = sizeof( DWORD );

 // Iterate through the property list entries and copy each entry
 // to the property list buffer.

 for( dw = 0 ; dw < dwPropCount ; dw++ )
 {
 switch( dw )
 {
 case 0: cbh_read.pb = (PBYTE) lpAutoFailbackType; break;
 case 1: cbh_read.pb = (PBYTE) lpDescription; break;
 case 2: cbh_read.pb = (PBYTE) lpFailbackWindowEnd; break;
 case 3: cbh_read.pb = (PBYTE) lpFailbackWindowStart; break;
 case 4: cbh_read.pb = (PBYTE) lpFailoverPeriod; break;
 case 5: cbh_read.pb = (PBYTE) lpFailoverThreshold; break;
 case 6: cbh_read.pb = (PBYTE) lpPersistentState; break;
 default: break;
 }

 // cbPosition is the index into the property list buffer.
 // cb is the index into the current entry buffer.
 // dw iterates the entries.

 for( cb = 0 ; cb < cbPropEntrySize[dw] ; cb++, cbPosition++ )
 cbh_write.pb[cbPosition] = cbh_read.pb[cb];
 }

 // Free the memory allocated by ClusDocEx_CreatePropertyListEntry

 LocalFree( lpAutoFailbackType ); 
 LocalFree( lpDescription ); 
 LocalFree( lpFailbackWindowEnd ); 
 LocalFree( lpFailbackWindowStart ); 
 LocalFree( lpFailoverPeriod ); 
 LocalFree( lpFailoverThreshold ); 
 LocalFree( lpPersistentState ); 

 return lpPropList;

 }
// end ClusDocEx_GrpCreatePropertyList
//--------------------------------------------------------------------
#endif

Additional resources