Last modified: July 23, 2011

Applies to: Outlook

Builds a new IMessage object on top of an existing OLE IStorage object, to be used within a message session.

Header file:


Implemented by:


Called by:

Client applications and service providers

  LPMSGSESS lpMsgSess,
  LPALLOCATEBUFFER lpAllocateBuffer,
  LPALLOCATEMORE lpAllocateMore,
  LPFREEBUFFER lpFreeBuffer,
  LPMALLOC lpmalloc,
  LPVOID lpMapiSup,
  MSGCALLRELEASE FAR * lpfMsgCallRelease,
  ULONG ulCallerData,
  ULONG ulFlags,


[in] Pointer to a message session object within which the new IMessage-on-IStorage object is to be created.


[in] Pointer to the MAPIAllocateBuffer function, to be used to allocate memory.


[in] Pointer to the MAPIAllocateMore function, to be used to allocate additional memory.


[in] Pointer to the MAPIFreeBuffer function, to be used to free memory.


[in] Pointer to a memory allocator object exposing the OLE IMalloc interface. The IMessage interface needs to use this allocation method when working with interfaces such as IStorage and IStream.


[in] Optional pointer to a MAPI support object that a service provider can use to call the methods of the IMAPISupport : IUnknown interface.


[in, out] Pointer to an OLE IStorage object that is open and has read-only or read/write permission. Because IMessage does not support write-only access, OpenIMsgOnIStg does not accept a storage object opened in write-only mode.


[in] Optional pointer to a callback function based on the MSGCALLRELEASE prototype that MAPI is to call following the last release on the IMessage-on-IStorage object.


[in] Caller data saved by MAPI with the IMessage-on-IStorage object and passed to the MSGCALLRELEASE based callback function. The data provides context about the IMessage object being released and the IStorage object on top of which it was built.


[in] Bitmask of flags used to control whether the OLE IStorage::Commit method is called when the client application or service provider calls the IMessage::SaveChanges method. The following flags can be set:


The OLE method IStorage::Commit is not to be called when the client or provider calls SaveChanges.


Enables creation of Unicode .msg files. The resulting IMessage file shows STORE_UNICODE_OK in its PR_STORE_SUPPORT_MASK and supports Unicode properties.

Note Note

The MAPI_UNICODE flag is only supported in this function on Outlook 2003 or higher.


[out] Pointer to a pointer to the opened IMessage object.


The call succeeded and has returned the expected value or values.

Property attributes can only be accessed on property objects, that is, objects implementing the IMAPIProp : IUnknown interface. To make MAPI properties available on an OLE structured storage object, OpenIMsgOnIStg builds an IMessage : IMAPIProp object on top of the OLE IStorage object. The property attributes on such objects can be set or altered with SetAttribIMsgOnIStg and retrieved with GetAttribIMsgOnIStg.

A message session should be opened with OpenIMsgSession before OpenIMsgOnIStg is called. Supplying a valid lpMsgSess parameter make sures that the new message is created within a message session so that it is closed when the session is closed. If lpMsgSess is NULL, the message is created independently of any message session. If the client application or service provider that created the message does not release it, as well as all its attachments and open tables, memory is leaked and may cause the application to terminate.

MAPI uses the functions pointed to by lpAllocateBuffer, lpAllocateMore, and lpFreeBuffer for most memory allocation and deallocation, in particular to allocate memory for use by client applications when calling object interfaces such as IMAPIProp::GetProps and IMAPITable::QueryRows. The lpAllocateBuffer, lpAllocateMore, and lpFreeBuffer pointers are optional when the OpenIMsgOnIStg function is called with a valid lpMapiSup parameter.

Because it is dealing with an underlying OLE object, MAPI also needs to use OLE memory allocation. For more information about OLE structured storage objects and OLE memory allocation, see the OLE Programmer's Reference.

If a valid value is supplied for lpMapiSup, IMessage supports the MAPI_DIALOG and ATTACH_DIALOG flags by calling the IMAPISupport::DoProgressDialog method to supply a progress user interface for the IMAPIProp::CopyTo and IMessage::DeleteAttach methods. Also, the IMessage::ModifyRecipients method attempts to convert short-term entry identifiers to long-term entry identifiers by calling the IMAPISupport::OpenAddressBook method and making calls on the resulting address book object. If NULL is passed for lpMapiSup, IMessage ignores MAPI_DIALOG and ATTACH_DIALOG and stores short-term entry identifiers without conversion.

The IStorage object pointed to by the lpStg parameter must be opened in either the STGM_READ or STGM_READWRITE mode. If the STGM_READWRITE mode is used, the STGM_TRANSACTED mode must also be set.

The callback function pointed to by the lpfMsgCallRelease parameter is optional; if provided, it should be based on the MSGCALLRELEASE function prototype. The IMessage interface calls it when the reference count of the IMessage-on-IStorage object is set to zero by the last call to its Release method. The callback function is commonly used to free the underlying IStorage interface. IMessage will not attempt to access the IStorage object pointed to by the lpStg parameter after making the callback.

Some clients or providers might write additional data to the IStorage object beyond what IMessage itself writes when its SaveChanges method is called. The client or provider can use the IMSG_NO_ISTG_COMMIT flag to prevent IMessage from calling the OLE IStorage::Commit method while processing a SaveChanges call; in this case the client or provider must itself commit the IStorage object when the additional data is written. To aid in this, the IMessage implementation guarantees to name all substorages it creates in the IStorage object starting with the string "__", that is, with two underscores. The client or provider can avoid name collisions by keeping its substorage names out of this namespace.

MAPI does not define the behavior of multiple open operations performed on a subobject of a message, such as an attachment, a stream, or an embedded message. MAPI currently allows a subobject that is already open to be opened once more, but MAPI performs the open operation by incrementing the reference count for the existing open object and returning it to the client or provider that called the IMessage::OpenAttach or IMAPIProp::OpenProperty method. This means the access requested for the first open operation on a subobject is the access provided for all subsequent open operations, regardless of the access requested by the operations.

The correct procedure for placing a message into an attachment is to call the IMAPIProp::OpenProperty method with an interface identifier of IID_IMessage. OpenProperty currently also supports creation of message attachments available directly on the OLE IStorage interface, that is, using the IID_IStorage interface identifier. IStorage access is supported to allow an easy way to put a Microsoft Word document into an attachment without converting it to or from the OLE IStream interface. However, IMessage may not behave predictably if OpenIMsgOnIStg is passed an IStorage pointer to the attachment data and then the objects are released in the wrong order.

For MFCMAPI sample code, see the following table.






MFCMAPI uses the OpenIMsgOnIStg method to open an IMessage interface on top of the .MSG file so that the file may be manipulated with MAPI.