IPropertyStorage-Stand-alone Implementation

The system-provided, stand-alone implementation of IPropertySetStorage includes an implementation of IPropertyStorage, the interface that reads and writes properties in a property set storage. The IPropertySetStorage interface creates and opens property sets in a storage. The IEnumSTATPROPSTG and IEnumSTATPROPSETSTG interfaces are also provided in the stand-alone implementation.

To get a pointer to the stand-alone implementation of IPropertyStorage, call the StgCreatePropStg function to create a new property set or StgOpenPropStg to obtain the interface pointer on an existing property set (or call the Create or Open methods of the IPropertySetStorage stand-alone implementation).

The stand-alone implementation of IPropertyStorage creates property sets on any storage or stream object, not just on compound file storages and streams. The stand-alone implementation does not depend on compound files and can be used with any implementation of structured storages. For more information about the compound file implementation of this interface, see IPropertyStorage-Compound File Implementation.

When to Use

Use IPropertyStorage to manage properties within a single property set. Its methods support reading, writing, and deleting both properties and the optional string names that can be associated with property IDs. Other methods support the standard commit and revert storage operations. There is also a method that sets times associated with the property storage, and another that permits the assignment of a CLSID to be used to associate other code, such as user interface code, with the property set. The Enum method supplies a pointer to the stand-alone implementation of IEnumSTATPROPSTG, which enumerates the properties in the set.

Version 0 and Version 1 Property Set Formats

The stand-alone implementation of IPropertyStorage supports both the version 0 and the version 1 property set serialization formats. For more information, see Property Set Serialization. Property sets are created in version 0 format and remain in that format unless new features are requested. At that time, the format is updated to version 1.

For example, if a property set is created with the PROPSETFLAG_DEFAULT flag, its format is version 0. As long as property types that conform to the version 0 format are written to and read from that property set, the property set remains in version 0 format. If a version 1 property type is written to the property set, the property set is automatically updated to version 1. Subsequently, that property set can no longer be read by implementations that only understand version 0.

IPropertyStorage and Variant Types

The stand-alone implementation of IPropertyStorage does not support the variant types VT_UNKNOWN or VT_DISPATCH in the vt member of the PROPVARIANT structure.

The following variant types are supported within a SafeArray; that is, these values can be combined with VT_ARRAY in the vt member of the PROPVARIANT structure.

Variant types supported within SafeArray by compound file implementation of IPropertyStorage




















When VT_VARIANT is combined with VT_ARRAY, the SafeArray itself holds PROPVARIANT structures. However, the types of these elements must be taken from the preceding list, cannot be VT_VARIANT, and cannot include the VT_VECTOR, VT_ARRAY, or VT_BYREF indicators.

IPropertyStorage Methods

The stand-alone implementation of IPropertyStorage supports the following methods:


Reads the properties specified in the rgpspec array and supplies the values of all valid properties in the rgvar array of PROPVARIANT elements.

In the system-provided, stand-alone implementation, duplicate property identifiers that refer to stream- or storage-types result in multiple calls to IStorage::OpenStream or IStorage::OpenStorage and the success or failure of ReadMultiple depends on the underlying storage implementation's ability to share open storages.

In addition, to ensure thread-safe operation if the same stream- or storage-valued property is requested multiple times through the same IPropertyStorage pointer, the open will succeed or fail depending on whether or not the property is already open and on whether the underlying file system handles multiple opens of a stream or storage. Thus, the ReadMultiple operation on a stream- or storage-valued property always results in a call to IStorage::OpenStream, or IStorage::OpenStorage, passing the access (STGM_READWRITE, for example) and share values (STGM_SHARE_EXCLUSIVE, for example) specified when the property set was originally opened or created.

If the method fails, the values written to rgvar[] are undefined. If some stream- or storage-valued properties are opened successfully but an error occurs before execution is complete, these properties should be released before the method returns.


Writes the properties specified in the rgpspec[] array, assigning them the PROPVARIANT tags and values specified in rgvar[]. Properties that already exist are assigned the specified PROPVARIANT values, and properties that do not currently exist are created.


Deletes the properties specified in the rgpspec[].


Reads existing string names associated with the property IDs specified in the rgpropid[] array.


Assigns string names specified in the rglpwstrName array to property IDs specified in the rgpropid array.


Deletes the string names of the property IDs specified in the rgpropid array by writing NULL to the property name.


Sets the CLSID of the property set stream. In the stand-alone implementation, setting the CLSID on a nonsimple property set (one that can contain storage- or stream-valued properties, as described in IPropertySetStorage::Create) also sets the CLSID on the underlying substorage so that it can be obtained through a call to IStorage::Stat.


For both simple and nonsimple property sets, flushes the memory image to the disk subsystem. In addition, for nonsimple transacted-mode property sets, this method calls IStorage::Commit on the property set.


For nonsimple property sets only, calls the Revert method of the underlying storage and reopens the 'contents' stream. For simple property sets, only returns E_OK.


Creates an enumerator object that implements IEnumSTATPROPSTG, the methods of which can be called to enumerate the STATPROPSTG structures that provide information about each of the properties in the set.

This implementation creates an array into which the entire property set is read and which can be shared when IEnumSTATPROPSTG::Clone is called.


Fills in the members of a STATPROPSETSTG structure, which contains information about the property set as a whole. On return, supplies a pointer to the structure.

For nonsimple storage sets, this implementation calls IStorage::Stat (or IStream::Stat) to get the information from the underlying storage or stream.


For nonsimple property sets only, sets the times supported by the underlying storage. This implementation of SetTimes calls the IStorage::SetElementTimes method of the underlying storage to modify the times. It supports the times supported by the underlying method which can be modification time, access time, or creation time.

IPropertySetStorage-Stand-alone Implementation