Creating Value Lists

This section assumes you are familiar with the architecture described in Value Lists. Creating a value list means creating a sequence of bytes that conforms to the architectural conventions for value lists. As long as the result is correct, any technique that properly sequences and aligns the data is fine.

For example, the easiest way to create a value list is to create a structure:

typedef struct DWORD_VALUE_LIST
 {
  CLUSPROP_DWORD First;
  CLUSPROP_DWORD Second;
  CLUSPROP_DWORD Third;
  CLUSPROP_SYNTAX Endmark;
 } DWORD_VALUE_LIST;

However, this method gets complicated when variable-length data is introduced.

Another way to create a value list is to use CLUSPROP_BUFFER_HELPER. (See Building with CLUSPROP_BUFFER_HELPER.)

Example

The following example creates a required dependencies list for a resource using structures to define the value list. A resource DLL might build a value list like this in response to the CLUSCTL_RESOURCE_GET_REQUIRED_DEPENDENCIES control code.

#include <windows.h>

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

#include "ClusDocEx.h"

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

#ifndef _CLUSDOCEX_CREATEREQUIREDDEPENDENCIESLIST_CPP
#define _CLUSDOCEX_CREATEREQUIREDDEPENDENCIESLIST_CPP


//  Global buffer that will store the required dependencies value list.

    LPVOID g_CLUSDOCEX_REQDEPS = NULL;

    #define RESOURCE_TYPE_NETWORK_NAME L"Network Name"

//--------------------------------------------------------------------
// 
//  ClusDocEx_CreateRequiredDependenciesList
//
//  Creates a value list specifying the required dependencies
//  of a resource. For this example, the dependencies are a Network
//  Name resource and a storage class resource.
//
//--------------------------------------------------------------------
void ClusDocEx_CreateRequiredDependenciesList()
{

//  Define a structure for the value list.
//  Note the use of the CLUSPROP_SZ_DECLARE macro.

    struct DEP_DATA
    {
        CLUSPROP_RESOURCE_CLASS rcStorage;
        CLUSPROP_SZ_DECLARE(    netnameEntry, 
                                sizeof( RESOURCE_TYPE_NETWORK_NAME ) /
                                  sizeof( WCHAR ) );
        CLUSPROP_SYNTAX         endmark;
    };
    DEP_DATA* pdepdata;

    pdepdata = (DEP_DATA*) LocalAlloc( LPTR, sizeof( DEP_DATA ) );

    if( pdepdata != NULL )
    {

    //  Add the Storage class entry.
        pdepdata->rcStorage.Syntax.dw = CLUSPROP_SYNTAX_RESCLASS;
        pdepdata->rcStorage.cbLength = sizeof( pdepdata->rcStorage.rc );
        pdepdata->rcStorage.rc = CLUS_RESCLASS_STORAGE;

    //  Add the Network Name entry.
        pdepdata->netnameEntry.Syntax.dw = CLUSPROP_SYNTAX_NAME;
        pdepdata->netnameEntry.cbLength = sizeof( RESOURCE_TYPE_NETWORK_NAME );
        StringCchCopyW( pdepdata->netnameEntry.sz, 
                        pdepdata->netnameEntry.cbLength, 
                        RESOURCE_TYPE_NETWORK_NAME );

    //  Add the endmark.
        pdepdata->endmark.dw = CLUSPROP_SYNTAX_ENDMARK;
    }

    g_CLUSDOCEX_REQDEPS = (LPVOID) pdepdata;
}
//  End ClusDocEx_CreateRequiredDependenciesList.
//--------------------------------------------------------------------
#endif