The topic you requested is included in another documentation set. For convenience, it's displayed below. Choose Switch to see the topic in its original location.


This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

Makes permanent any changes that were made to an object since the last save operation.

HRESULT SaveChanges(
  ULONG ulFlags


[in] A bitmask of flags that controls what happens to the object when the IMAPIProp::SaveChanges method is called. The following flags can be set:


Changes should be written to the object, overriding any previous changes that were made to the object, and the object should be closed. Read/write permission must be set for the operation to succeed. The FORCE_SAVE flag is used after a previous call to SaveChanges returned MAPI_E_OBJECT_CHANGED.


Changes should be committed and the object should be kept open for reading. No additional changes will be made.


Changes should be committed and the object should be kept open for read/write permission. This flag is usually set when the object was first opened for read/write permission. Subsequent changes to the object are allowed.


Allows SaveChanges to return successfully, possibly before the changes have been fully committed.


The commitment of changes was successful.


SaveChanges cannot keep the object open for read-only permission, if KEEP_OPEN_READONLY is set, or read/write permission, if KEEP_OPEN_READWRITE is set. No changes are committed.


The object has changed since it was opened.


The object has been deleted since it was opened.

The IMAPIProp::SaveChanges method makes property changes permanent for objects that support the transaction model of processing, such as messages, attachments, address book containers, and messaging user objects. Objects that do not support transactions, such as folders, message stores, and profile sections, make changes permanent immediately. No call to SaveChanges is required.

Because service providers do not need to generate an entry identifier for their objects until all properties have been saved, an object's PR_ENTRYID (PidTagEntryId) property might not be available until after its SaveChanges method has been called. Some providers wait until the KEEP_OPEN_READONLY flag is set on the SaveChanges call. KEEP_OPEN_READONLY indicates that the changes to be saved in the current call will be the last changes that will be made on the object.

Some message store implementations do not show newly created messages in a folder until a client saves the message changes by using SaveChanges and releases the message objects by using the IUnknown::Release method. In addition, some object implementations cannot generate a PR_ENTRYID property for a newly created object until after SaveChanges has been called, and some can do so only after SaveChanges has been called with KEEP_OPEN_READONLY set in ulFlags .

If you receive the KEEP_OPEN_READONLY flag, you have the option of leaving the object's access as read/write. However, in no case can a provider leave an object in a read-only state when the KEEP_OPEN_READWRITE flag is passed.

When a client saves multiple attachments to multiple messages, it calls the SaveChanges method for every attachment and every message. Often clients will set MAPI_DEFERRED_ERRORS for each of these calls except for the last one. You can return errors either with the last call or earlier calls. You can even ignore the flag.

If either KEEP_OPEN_READWRITE or KEEP_OPEN_READONLY is set together with MAPI_DEFERRED_ERRORS, you can ignore the error deferment request. If MAPI_DEFERRED_ERRORS is not set in ulFlags, one of the previously deferred errors can be returned for the SaveChanges call.

Whether a remote transport provider provides a functional implementation of this method is optional and will probably depend on other design choices in your implementation. If you implement this method, do so according to the documentation here. Because folder objects and status objects are not transacted, at a minimum a remote transport provider's implementation of SaveChanges must return S_OK without actually doing any work.

If a client passes KEEP_OPEN_READONLY, calls the IMAPIProp::SetProps method, and then calls SaveChanges again, the same implementation might fail.

After receiving MAPI_E_NO_ACCESS from a call in which you set KEEP_OPEN_READWRITE, you will continue to have read/write permission to the object. You can call SaveChanges again, passing either the KEEP_OPEN_READONLY flag or no flags with KEEP_OPEN_SUFFIX.

Whether a provider supports the KEEP_OPEN_READWRITE flag depends on the provider's implementation.

To indicate that the only call to be made on the object after SaveChanges will be IUnknown::Release, set no flags for the ulFlags parameter. An error from SaveChanges indicates that it could not make the pending changes permanent. Different providers handle the absence of flags on the SaveChanges call differently. Some treat this state the same as KEEP_OPEN_READONLY; others interpret it the same as KEEP_OPEN_READWRITE. Still other providers shut down the object when they do not receive flags on the SaveChanges call.

Some properties, typically computed properties, cannot be processed until you call SaveChanges and, in particular cases, Release.

When you make bulk changes, such as saving attachments to multiple messages, defer error processing by setting the MAPI_DEFERRED_ERRORS flag in ulFlags. If you save multiple attachments to multiple messages, make one SaveChanges call to each attachment and one SaveChanges call to each message. Set the MAPI_DEFERRED_ERRORS flag for each attachment call and for all messages except for the last one.

If SaveChanges returns MAPI_E_OBJECT_CHANGED, check whether the original object has been modified. If so, warn the user, who can either request that the changes overwrite the previous changes or save the object somewhere else. If the original object has been deleted, warn the user to give the user the opportunity to save the object in another location.

You cannot call SaveChanges with the FORCE_SAVE flag on an open object that has been deleted.

If SaveChanges returns an error, the object whose changes were to be saved remains open, regardless of the flags set in the ulFlags parameter.

For more information, see Saving MAPI Properties.