IPropertyStorage-Standalone Implementation

The system-provided, standalone 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 standalone implementation.

To get a pointer to the standalone implementation of IPropertyStorage, call the StgCreatePropStg function if you are creating a new property set or StgOpenPropStg if you want to obtain the interface pointer on an existing property set (or call the Create or Open methods of the IPropertySetStorage standalone implementation).

The standalone implementation of IPropertyStorage creates property sets on any storage or stream object, not just on compound file storages and streams. The standalone implementation does not depend on compound files and can be used with any implementation of structured storages. See the section IPropertyStorage-Compound File Implementation in the Object Services section of the Platform SDK for more information on the compound file implementation of this interface.

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 identifiers. 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 that can be used to associate other code, such as user interface code, with the property set. The Enum method supplies a pointer to the standalone implementation of IEnumSTATPROPSTG, which enumerates the properties in the set.

Remarks

There are some differences between the standalone implementation of the property set interfaces and the compound file implementation. In the compound file implementation of stream, storage, property set storage, and property storage objects, the various interfaces are able to coordinate with one another because they are part of a common implementation. In the standalone implementation, the interface implementations are distinct from one another.

As a result, the compound-file implementation handles concurrency issues and synchronizes the property set object with the storage or stream object. With the standalone implementation, the client is responsible for handling concurrency and synchronization issues between the storage or stream object and the property set. A client can meet these requirements by following two simple rules. First, never manipulate a property set using its stream or storage interfaces while a property storage object is opened on it. And, second, always Commit a property storage object before calling Commit, CopyTo, or MoveElementTo on an ancestor storage object. Specifically, the following items require client attention:

The standalone implementation of IPropertyStorage supports the following methods:

IPropertyStorage::ReadMultiple
Reads the properties specified in the rgpspec array and supplies the values of all valid properties in the rgvar array of PROPVARIANTs.

In the system-provided, standalone 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.

IPropertyStorage::WriteMultiple
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.
IPropertyStorage::DeleteMultiple
Deletes the properties specified in the rgpspec[].
IPropertyStorage::ReadPropertyNames
Reads existing string names associated with the property identifiers specified in the rgpropid[] array.
IPropertyStorage::WritePropertyNames
Assigns string names specified in the rglpwstrName array to property identifiers specified in the rgpropid array.
IPropertyStorage::DeletePropertyNames
Deletes the string names of the property identifiers specified in the rgpropid array by writing NULL to the property name.
IPropertyStorage::SetClass
Sets the CLSID field of the property set stream. In the standalone implementation, setting the CLSID on a non-simple property set (one that can contain storage- or stream-valued properties, as described in IPropertySetStorage::Create) also sets the CLSID on the underlying sub-storage so it can be obtained through a call to IStorage::Stat.
IPropertyStorage::Commit
For both simple and non-simple property sets, flushes the memory image to the disk subsystem. In addition, for non-simple transacted-mode property sets, this method calls IStorage::Commit on the property set.
IPropertyStorage::Revert
For non-simple property sets only, calls the underlying storage's Revert method and re-opens the 'contents' stream. For simple property sets, only returns E_OK.
IPropertyStorage::Enum
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.

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

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

IPropertyStorage::SetTimes
For non-simple 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.

Programming Information

Windows NT 4.0/SP2 or with IPROP.DLL
Win95 Yes; requires IPROP.DLL
Win32s No
Unicode Yes
Import Library IPROP.DLL
Header File IPROPIDL.H

See Also

IPropertySetStorage-Standalone Implementation, IPropertyStorage, IStorage::SetElementTimes, StgOpenPropStg, StgCreatePropStg, StgCreatePropSetStg