Published: July 16, 2012
Makes permanent any changes that were made to an object since the last save operation.
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 have 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 by using 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, a provider can never 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 depends 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 is 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 providers treat this state the same as KEEP_OPEN_READONLY; other providers 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 some 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 elsewhere. If the original object has been deleted, warn the user to give them 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.
The ulFlags NON_EMS_XP_SAVE and SPAMFILTER_ONSAVE might not be defined in the downloadable header file you currently have, in which case you can add it to your code using the following values:
#define SPAMFILTER_ONSAVE ((ULONG) 0x00000080)
#define NON_EMS_XP_SAVE ((ULONG) 0x00001000)
For more information, see Saving MAPI Properties.