The STGM constants are flags that indicate conditions for creating and deleting the object and access modes for the object. The STGM constants are included in the IStorage, IStream, and IPropertySetStorage interfaces and in the StgCreateDocfile, StgCreateStorageEx, StgCreateDocfileOnILockBytes, StgOpenStorage, and StgOpenStorageEx functions.
These elements are often combined using an ORoperator. They are interpreted in groups as listed in the following table. It is not valid to use more than one element from a single group.
For more information about transactioning, see the Remarks section.
|Direct SWMR and Simple||STGM_SIMPLE||0x08000000L|
|Delete On Release||STGM_DELETEONRELEASE||0x04000000L|
Indicates that the object is read-only, meaning that modifications cannot be made. For example, if a stream object is opened with STGM_READ, the ISequentialStream::Read method may be called, but the ISequentialStream::Write method may not. Similarly, if a storage object opened with STGM_READ, the IStorage::OpenStream and IStorage::OpenStorage methods may be called, but the IStorage::CreateStream and IStorage::CreateStorage methods may not.
Enables access and modification of object data. For example, if a stream object is created or opened in this mode, it is possible to call both IStream::Read and IStream::Write. Be aware that this constant is not a simple binary OR operation of the STGM_WRITE and STGM_READ elements.
Specifies that subsequent openings of the object are not denied read or write access. If no flag from the sharing group is specified, this flag is assumed.
Prevents others from subsequently opening the object in STGM_READ mode. It is typically used on a root storage object.
Prevents others from subsequently opening the object for STGM_WRITE or STGM_READWRITE access. In transacted mode, sharing of STGM_SHARE_DENY_WRITE or STGM_SHARE_EXCLUSIVE can significantly improve performance because they do not require snapshots. For more information about transactioning, see the Remarks section.
Prevents others from subsequently opening the object in any mode. Be aware that this value is not a simple bitwise OR operation of the STGM_SHARE_DENY_READ and STGM_SHARE_DENY_WRITE values. In transacted mode, sharing of STGM_SHARE_DENY_WRITE or STGM_SHARE_EXCLUSIVE can significantly improve performance because they do not require snapshots. For more information about transactioning, see the Remarks section.
Opens the storage object with exclusive access to the most recently committed version. Thus, other users cannot commit changes to the object while you have it open in priority mode. You gain performance benefits for copy operations, but you prevent others from committing changes. Limit the time that objects are open in priority mode. You must specify STGM_DIRECT and STGM_READ with priority mode, and you cannot specify STGM_DELETEONRELEASE. STGM_DELETEONRELEASE is only valid when creating a root object, such as with StgCreateStorageEx. It is not valid when opening an existing root object, such as with StgOpenStorageEx. It is also not valid when creating or opening a subelement, such as with IStorage::OpenStorage.
Indicates that an existing storage object or stream should be removed before the new object replaces it. A new object is created when this flag is specified only if the existing object has been successfully removed.
This flag is used when attempting to create:
- A storage object on a disk, but a file of that name exists.
- An object inside a storage object, but an object with the specified name exists.
- A byte array object, but one with the specified name exists.
Creates the new object while preserving existing data in a stream named "Contents". In the case of a storage object or a byte array, the old data is formatted into a stream regardless of whether the existing file or byte array currently contains a layered storage object. This flag can only be used when creating a root storage object. It cannot be used within a storage object; for example, in IStorage::CreateStream. It is also not valid to use this flag and the STGM_DELETEONRELEASE flag simultaneously.
Causes the create operation to fail if an existing object with the specified name exists. In this case, STG_E_FILEALREADYEXISTS is returned. This is the default creation mode; that is, if no other create flag is specified, STGM_FAILIFTHERE is implied.
Indicates that, in direct mode, each change to a storage or stream element is written as it occurs. This is the default if neither STGM_DIRECT nor STGM_TRANSACTED is specified.
Indicates that, in transacted mode, changes are buffered and written only if an explicit commit operation is called. To ignore the changes, call the Revert method in the IStream, IStorage, or IPropertyStorage interface. The COM compound file implementation of IStorage does not support transacted streams, which means that streams can be opened only in direct mode, and you cannot revert changes to them, however transacted storages are supported. The compound file, stand-alone, and NTFS file system implementations of IPropertySetStorage similarly do not support transacted, simple property sets because these property sets are stored in streams. However, transactioning of nonsimple property sets, which can be created by specifying the PROPSETFLAG_NONSIMPLE flag in the grfFlags parameter of IPropertySetStorage::Create, are supported.
Indicates that, in transacted mode, a temporary scratch file is usually used to save modifications until the Commit method is called. Specifying STGM_NOSCRATCH permits the unused portion of the original file to be used as work space instead of creating a new file for that purpose. This does not affect the data in the original file, and in certain cases can result in improved performance. It is not valid to specify this flag without also specifying STGM_TRANSACTED, and this flag may only be used in a root open. For more information about NoScratch mode, see the Remarks section.
This flag is used when opening a storage object with STGM_TRANSACTED and without STGM_SHARE_EXCLUSIVE or STGM_SHARE_DENY_WRITE. In this case, specifying STGM_NOSNAPSHOT prevents the system-provided implementation from creating a snapshot copy of the file. Instead, changes to the file are written to the end of the file. Unused space is not reclaimed unless consolidation is performed during the commit, and there is only one current writer on the file. When the file is opened in no snapshot mode, another open operation cannot be performed without specifying STGM_NOSNAPSHOT. This flag may only be used in a root open operation. For more information about NoSnapshot mode, see the Remarks section.
Provides a faster implementation of a compound file in a limited, but frequently used, case. For more information, see the Remarks section.
Supports direct mode for single-writer, multireader file operations. For more information, see the Remarks section.
Indicates that the underlying file is to be automatically destroyed when the root storage object is released. This feature is most useful for creating temporary files. This flag can only be used when creating a root object, such as with StgCreateStorageEx. It is not valid when opening a root object, such as with StgOpenStorageEx, or when creating or opening a subelement, such as with IStorage::CreateStream. It is also not valid to use this flag and the STGM_CONVERT flag simultaneously.
You can combine these flags, but you can only choose one flag from each group of related flags. Typically one flag from each of the access and sharing groups must be specified for all functions and methods which use these constants. Flags from other groups are optional.
When the STGM_DIRECTflag is specified, only one of the following combination of flags may be specified from the access and sharing groups.
STGM_READ | STGM_SHARE_DENY_WRITE
STGM_READWRITE | STGM_SHARE_EXCLUSIVE
STGM_READ | STGM_PRIORITY
Be aware that direct mode is implied by the absence of STGM_TRANSACTED. That is, if neither STGM_DIRECT nor STGM_TRANSACTED is specified, STGM_DIRECT is assumed.
When the STGM_TRANSACTED flag is specified, objects are created or opened in transacted mode. In this mode, changes to an object do not persist until they are committed. For example, changes to a transacted storage object are not persisted until the IStorage::Commit method is called. Changes to such a storage object will be lost if the storage object is released (final release) before the Commit method is called, or if the IStorage::Revert method is called.
When an object is created or opened in transacted mode, the implementation must keep both the original data and updates to this data, so that updates can be reverted if necessary. This is typically performed by writing changes to a scratch area until they are committed, or by creating a copy, called a snapshot, of the most recently committed data.
When a root storage object is opened in transacted mode, the location and behavior of the scratch data and the snapshot copies can be controlled to optimize performance with the STGM_NOSCRATCH and STGM_NOSNAPSHOT flags. (A root storage object is obtained from, for example, the StgOpenStorageEx function; a storage object obtained from the IStorage::OpenStorage method is a substorage object.) Typically, the scratch data and snapshots are stored in temporary files, separate from the storage.
The effect of these flags depends on the number of readers and/or writers accessing the root storage.
In the "single-writer" case, a transacted mode storage object is opened for write access and there can be no other access to the file. That is, the file is opened with STGM_TRANSACTED, access of STGM_WRITE or STGM_READWRITE, and sharing of STGM_SHARE_EXCLUSIVE. In this case, changes to the storage object are written to the scratch area. When those changes are committed, they are copied to the original storage. Therefore, if no changes are actually made to the storage object, there will be no unnecessary data transfer.
In the "multiple-writer" case, a transacted storage object is opened for write access, but is shared in such asway as to allow other writers. That is, the storage object is opened with STGM_TRANSACTED, access of STGM_WRITE or STGM_READWRITE, and sharing of STGM_SHARE_DENY_READ. If sharing of STGM_SHARE_DENY_NONE is specified instead, then the case is "multiple-writer, multiple-reader". In these cases, a snapshot of the original data will be made during the open operation. Therefore, even if no changes are actually made to the storage and/or it is not actually opened by another writer simultaneously, data transfer is still necessary during the open. As a result the best open-time performance can be obtained by opening the storage object in STGM_SHARE_DENY_WRITE or STGM_SHARE_EXCLUSIVE modes. For more information about how changes are committed when there are multiple writers, see IStorage::Commit.
In the "single-writer, multiple-reader" case, a transacted storage object is opened for write access, but is shared with readers. That is, the storage object is opened by the writer with STGM_TRANSACTED, access of STGM_READWRITE or STGM_WRITE, and sharing of STGM_SHARE_DENY_WRITE. The storage is opened by readers with STGM_TRANSACTED, access of STGM_READ, and sharing of STGM_SHARE_DENY_NONE. In this case the writer uses the scratch area to store uncommitted changes. As in the cases above, the reader incurs an open-time performance penalty while a snapshot copy of the data is created.
Typically, the scratch area is a temporary file, separate from the original data. When changes are committed to the original file, the data must be transferred from the temporary file. To avoid this data transfer, the STGM_NOSCRATCHflag may be specified. When this flag is specified, portions of the storage object file are used for the scratch area, rather than a separate temporary file. As a result, committing changes can be performed quickly, because little data transfer is required. The disadvantage is that the storage file can become larger than it would otherwise be, because it must be grown to be large enough for both the original data and the scratch area. To consolidate the data and remove this unnecessary area, reopen the root storage in transacted mode, but without setting the STGM_NOSCRATCH flag. Then, call IStorage::Commit with the STGC_CONSOLIDATE flag set.
The snapshot area, like the scratch area, is also, typically, a temporary file, and this too can be affected with a STGM flag. By specifying the STGM_NOSNAPSHOT flag, a separate temporary snapshot file is not created. Instead, the original data is never modified, even if there are one or more writers per object. When changes are committed, they are added to the file, but the original data remains intact. This mode increases efficiency because it reduces run time by eliminating the requirement of creating a snapshot during the open operation. However, using this mode may result in a very large storage file because data in the file can never be overwritten. This is no limit to the size of files opened in NoSnapshot mode.
As described, it is possible to have a single writer and multiple readers of a storage object, if that object is opened in transacted mode. It is also possible to achieve the single-writer, multireader case in direct mode, by specifying the STGM_DIRECT_SWMR flag.
In STGM_DIRECT_SWMR mode, it is possible for one caller to open an object for read/write access, while other callers simultaneously have the file open for read-only access. It is not valid to use this flag in combination with the STGM_TRANSACTED flag. In this mode, the writer opens the object with the following flags:
STGM_DIRECT_SWMR | STGM_READWRITE | STGM_SHARE_DENYWRITE
and each of the readers opens the object with these flags:
STGM_DIRECT_SWMR | STGM_READ | STGM_SHARE_DENY_NONE
In this mode, to modify the storage object, the writer must get exclusive access to the object. This is possible when all the readers have closed it. The writer uses the IDirectWriterLock interface to obtain this exclusive access.
Simple mode (STGM_SIMPLE) is useful for applications that perform complete save operations. It is efficient, but has the following constraints:
- No support exists for substorages.
- The storage object, and stream objects obtained from it, cannot be marshaled.
- Each stream has a minimum size. If fewer than the minimum bytes are written into a stream when the stream is released, the stream is extended to the minimum size. For example, the minimum size for a particular IStream implementation is 4 KB. A stream is created and 1 KB is written to it. At the final release of that IStream, the stream size will be automatically extended to 4 KB. Subsequently, opening the stream and calling the IStream::Stat method will show a size of 4 KB.
- Not all methods of IStorage or IStream will be supported by the implementation. For more information, see IStorage - Compound File Implementation, and IStream - Compound File Implementation.
Marshaling is the process of packaging, unpackaging, and sending interface method parameters across thread or process boundaries within a Remote Procedure Call (RPC). For more information, see Marshaling Details and Interface Marshaling.
When a storage object is obtained by a Create operation in simple mode:
- Stream elements can be created, but not opened.
- When a stream element is created by calling IStorage::CreateStream, it is not possible to create another stream until that stream object is released.
- After all streams are written, call IStorage::Commit to flush the changes.
When a storage object is obtained by an Open operation in simple mode:
- It is possible to open only one stream element at a time.
- It is not possible to change the size of a stream by calling the IStream::SetSize method or by seeking or writing beyond the end of the stream. However, because all streams are of a minimum size, it is possible to use the stream up to that size, even if less data was originally written to it. To determine the size of a stream, use the IStream::Stat method.
Be aware that, if a storage element is modified by a storage object that is not in simple mode, it will not be possible, again, to open that storage element in simple mode.
Minimum supported client
|Windows 2000 Professional [desktop apps only]|
Minimum supported server
|Windows 2000 Server [desktop apps only]|