Example Code for Freeing a WMDM_FORMAT_CAPABILITY Structure

banner art

A format capability consists of one of more property configurations. For detailed information, see the WMDM_FORMAT_CAPABILITY structure.

Each property configuration contains a preference value and a number of property descriptions. For detailed information, see the WMDM_PROP_CONFIG structure.

A particular property description contains the name of the property it represents and valid values of the properties. For detailed information, see the WMDM_PROP_DESC structure.

The following diagram shows the relationship between these structures.

Format Capability Diagram

Valid property values can have the following forms:

  • No restriction — This means that any value is allowed for this property. This is indicated by WMDM_ENUM_PROP_VALID_VALUES_ANY.
  • Range of values — This means that the device supports a range of values. This is indicated by WMDM_ENUM_PROP_VALID_VALUES_RANGE. For information about how the range is represented, see the WMDM_PROP_VALUES_RANGE structure.
  • Enumerated values — This means that the device supports a list of values. This is indicated by WMDM_ENUM_PROP_VALID_VALUES_ENUM.

The IWMDMDevice3::GetFormatCapability method can be used to get a list of supported properties for a particular format. To do this, the client can look at all the property names in a particular configuration and ignore the valid values.

The client should free the contents of the WMDM_FORMAT_CAPABILITY structure after it is done using the information. The following example code shows how to do this:

void FreeFormatCapability(WMDM_FORMAT_CAPABILITY formatCap)
{
    // nPropConfig is non-zero only when pConfigs is non-NULL.
    for (UINT i=0; i < formatCap.nPropConfig; i++) 
    {
        // nPropDesc is non-zero only when pPropDesc is non-NULL.
        for (UINT j=0; j < formatCap.pConfigs[i].nPropDesc; j++) 
        {
            switch (formatCap.pConfigs[i].pPropDesc[j].ValidValuesForm)
            {
                case WMDM_ENUM_PROP_VALID_VALUES_ENUM:
                    for (UINT k=0; k < formatCap.pConfigs[i].pPropDesc[j].ValidValues.EnumeratedValidValues.cEnumValues; k++)
                    {
                        PropVariantClear (&(formatCap.pConfigs[i].pPropDesc[j].ValidValues.EnumeratedValidValues.pValues[k]));
                    }
                    SAFE_COTASKMEM_FREE (formatCap.pConfigs[i].pPropDesc[j].ValidValues.EnumeratedValidValues.pValues);
                    break;
                case WMDM_ENUM_PROP_VALID_VALUES_RANGE:
                    PropVariantClear (&(formatCap.pConfigs[i].pPropDesc[j].ValidValues.ValidValuesRange.rangeMin));
                    PropVariantClear (&(formatCap.pConfigs[i].pPropDesc[j].ValidValues.ValidValuesRange.rangeMax));
                    PropVariantClear (&(formatCap.pConfigs[i].pPropDesc[j].ValidValues.ValidValuesRange.rangeStep));
                    break;
                case WMDM_ENUM_PROP_VALID_VALUES_ANY:
                    break;
                default:
                    LOG_WARNING(("Unrecoginzed form %d", formatCap.pConfigs[i].pPropDesc[j].ValidValuesForm));
            }

            SAFE_COTASKMEM_FREE(formatCap.pConfigs[i].pPropDesc[j].pwszPropName);
        }
        SAFE_COTASKMEM_FREE (formatCap.pConfigs[i].pPropDesc);
    }

    SAFE_COTASKMEM_FREE (formatCap.pConfigs);
    formatCap.nPropConfig = 0;
}

Where SAFE_COTASKMEM_FREE is defined as:

#define SAFE_COTASKMEM_FREE(p) \
{ \
    CoTaskMemFree (p); \
    (p) = NULL; \
}

See Also