New MAPI function to access native body

Article translations Article translations
Article ID: 839560 - View products that this article applies to.
Expand all | Collapse all

On This Page

INTRODUCTION

The Microsoft Outlook object model provides access to the body of an e-mail message in native format. This access is accomplished by checking the BodyFormat property to determine what format that the e-mail message is in. Then, the appropriate body property is accessed. However, Microsoft Office XP Service Pack 3 and Microsoft Office 2003 introduced tighter security features that cause warning dialog boxes to appear when an application or a Microsoft Outlook add-in tries to access the body of the e-mail message.

The dialog boxes can be avoided by using Extended MAPI to access the body of the e-mail message instead of using the Outlook object model. However, Extended MAPI cannot always access the body of the e-mail message in its native format. When the body of the e-mail message is stored in PR_RTF_COMPRESSED format, the body of the e-mail message must be in Rich Text Format (RTF). Otherwise, the format is undocumented and is therefore unavailable to you.

To address this limitation, we have added a new, exported function that is named WrapCompressedRTFStreamEx to the implementation of Extended MAPI, also known as Msmapi32.dll, in Outlook 2002 and in Outlook 2003. The WrapCompressedRTFStreamEx function lets you access the native body stream that is encapsulated in PR_RTF_COMPRESSED format and then determine what format the stream is in.

This feature is available in the latest service pack for Office 2003. For more information, click the following article number to view the article in the Microsoft Knowledge Base:
870924 How to obtain the latest service pack for Office 2003

More information

Function definition

HRESULT __stdcall WrapCompressedRTFStreamEx(
  LPSTREAM              lpCompressedRTFStream,
  CONST RTF_WCSINFO *   pWCSInfo,
  LPSTREAM *            lppUncompressedRTFStream,
  RTF_WCSRETINFO *      pRetInfo
);
Parameters

lpCompressedRTFStream
[in] This is a pointer to a stream that is opened on the PR_RTF_COMPRESSED property of a message.

pWCSInfo
[in] This is a pointer to a RTF_WCSINFO structure that contains options for the function. See the "New flags and structures" section for additional details about this structure.

lppUncompressedRTFStream
[out] This is a pointer to the location where the WrapCompressedRTFStream function returns a stream for the decompressed RTF.

pRetInfo
[out] This is a pointer to a RTF_WCSRETINFO structure that contains information about the format of the returned decompressed stream. See the "New flags and structures" section for additional details about this structure.

Return Values
Collapse this tableExpand this table
ValueDescription
S_OKThe call succeeded and returned the expected value or values.
MAPI_E_INVALID_PARAMETERThis is returned if the MAPI_NATIVE_BODY flag is combined with the MAPI_MODIFY flag in ulFlags.
Remarks

To use the WrapCompressedRTFStreamEx function, you must load Msmapi32.dll by using the LoadLibrary function. Then, retrieve a function pointer to the WrapCompressedRTFStreamEx function by using the GetProcAddress function.

Because the MAPI_NATIVE_BODY flag cannot be combined with the MAPI_MODIFY flag, you can only access the native body stream in read-only mode.

To access the native body stream in read/write mode, we recommend that you use the WrapCompressedRTFStream function.

For additional information about the WrapCompressedRTFStream function, visit the following Microsoft Developer Network (MSDN) Web site:
http://msdn2.microsoft.com/en-us/library/ms530410.aspx

New flags and structures

The WrapCompressedRTFStreamEx function uses the following new flags that are not defined in the current version of Mapidefs.h:
#define MAPI_NATIVE_BODY 0x00010000

#define MAPI_NATIVE_BODY_TYPE_RTF 0x00000001
#define MAPI_NATIVE_BODY_TYPE_HTML 0x00000002
#define MAPI_NATIVE_BODY_TYPE_PLAINTEXT 0x00000004

RTF_WCSINFO structure

The RTF_WCSINFO structure is defined as follows:
typedef struct {
    ULONG       size;
    ULONG       ulFlags;
    ULONG       ulInCodePage;
    ULONG       ulOutCodePage;
} RTF_WCSINFO;
Members

size
This is the size of the RTF_WCSINFO structure.

ulFlags
This is the bitmask of option flags for the function. The following flags can be set:
Collapse this tableExpand this table
FlagDescription
MAPI_MODIFYThis indicates whether the client intends to read or to write the wrapped stream interface that is returned.
STORE_UNCOMPRESSED_RTFThis indicates whether the decompressed RTF is supposed to be written to the stream that is pointed to by the lpCompressedRTFStream pointer.
MAPI_ NATIVE_BODYThis indicates whether the decompressed stream is additionally converted to the native body before returning the stream.

Important This cannot be combined with the MAPI_MODIFY flag.
ulInCodePage
This is the code page value of the message. Typically, this value is obtained from the PR_INTERNET_CPID property on the message. This value is only used when the MAPI_NATIVE_BODY flag is passed in ulFlags. Otherwise, this value is ignored.

ulOutCodePage
This is the code page value of the returned decompressed stream that you want. If this is set to a non-zero value, the WrapCompressedRTFStreamEx function converts the stream to the specified code page. If this is set to a zero value, MAPI decides which code page to use. This value is only used when the MAPI_NATIVE_BODY flag is passed in ulFlags, and the body format is not RTF. Otherwise, this value is ignored.

RTF_WCSRETINFO structure

The RTF_WCSRETINFO structure is defined as follows:
typedef struct {
    ULONG       size;   
    ULONG       ulStreamFlags;
} RTF_WCSRETINFO;
Members
size
This is the size of the RTF_WCSRETINFO structure.

ulStreamFlags
This is a value that indicates the format of the native body. This value is only valid if the MAPI_NATIVE_BODY flag is passed in the ulFlags parameter of the RTF_WCSINFO structure that is passed to the WrapCompressedRTFStreamEx function. This can be one of the following values:
Collapse this tableExpand this table
ValueDescription
MAPI_NATIVE_BODY_TYPE_RTFThis value is only used if ulFlags includes the MAPI_NATIVE_BODY flag, and the body is RTF.
MAPI_NATIVE_BODY_TYPE_PLAIN_TEXTThis value is only used if ulFlags includes the MAPI_NATIVE_BODY flag, and the body is plain text format.
MAPI_NATIVE_BODY_TYPE_HTMLThis value is only used if ulFlags includes the MAPI_NATIVE_BODY flag, and the body is HTML format.

Sample code

The following sample code shows you how to use the WrapCompressedRTFStreamEx function:
//These are definitions for the WrapCompressedRTFStreamEx function.
typedef HRESULT (STDMETHODCALLTYPE WRAPCOMPRESSEDRTFSTREAMEX) (
    LPSTREAM lpCompressedRTFStream, CONST RTF_WCSINFO * pWCSInfo, LPSTREAM * lppUncompressedRTFStream, RTF_WCSRETINFO * pRetInfo);
typedef WRAPCOMPRESSEDRTFSTREAMEX *LPWRAPCOMPRESSEDRTFSTREAMEX;

HRESULT TestWrapCompressedRTFStreamEx(LPMESSAGE lpMsg)
{
    HRESULT         hRes = S_OK;
    LPSTREAM        lpCompressed = NULL;
    LPSTREAM        lpUncompressed = NULL;
    char            szBody[1024] = {0};
    ULONG           ulRead = 0;
    RTF_WCSINFO     wcsinfo = {0};
    RTF_WCSRETINFO  retinfo = {0};
    LPSPropValue    lpPropCPID = NULL;

    retinfo.size = sizeof(RTF_WCSRETINFO);

    wcsinfo.size = sizeof(RTF_WCSINFO);
    wcsinfo.ulFlags = MAPI_NATIVE_BODY;
    wcsinfo.ulOutCodePage = 0;

    // Retrieve the value of the Internet code page.
    // Pass this value to the WrapCompressedRTFStreamEx function.
    // If the property is not found, the default is 0.
    if(SUCCEEDED(hRes = HrGetOneProp(lpMsg, PR_INTERNET_CPID, &lpPropCPID)))
    {
        wcsinfo.ulInCodePage = lpPropCPID->Value.l;
    }

    // Open the compressed RTF stream.
    if(SUCCEEDED(hRes = lpMsg->OpenProperty(PR_RTF_COMPRESSED,
                                         &IID_IStream,
                                         STGM_READ | STGM_DIRECT,
                                         0,
                                         (LPUNKNOWN*)&lpCompressed)))
    {

        // Notice that the WrapCompressedRTFStreamEx function has been loaded
        // by using the GetProcAddress function into pfnWrapEx.

        // Call the WrapCompressedRTFStreamEx function.
        if(SUCCEEDED(hRes = pfnWrapEx(lpCompressed,
                                   &wcsinfo,
                                   &lpUncompressed,
                                   &retinfo)))
        {

            printf("Body's native type is: ");

            // Check what the native body type is.
            switch(retinfo.ulStreamFlags)
            {
            case MAPI_NATIVE_BODY_TYPE_RTF:
                printf("MAPI_NATIVE_BODY_TYPE_RTF\n");
                break;
            case MAPI_NATIVE_BODY_TYPE_HTML:
                printf("MAPI_NATIVE_BODY_TYPE_HTML\n");
                break;
            case MAPI_NATIVE_BODY_TYPE_PLAINTEXT:
                printf("MAPI_NATIVE_BODY_TYPE_PLAINTEXT\n");
                break;
            default:
                printf("UNKNOWN\n");
            }

            // Read the first 1,000 characters out of the stream.
            if(SUCCEEDED(hRes = lpUncompressed->Read(szBody, 1024, &ulRead)))
            {
                printf("First %d characters of the native body stream:\n%s\n", ulRead, szBody);
            }
        }
    }

    MAPIFreeBuffer(lpPropCPID);
    if(lpUncompressed)lpUncompressed->Release();
    if(lpCompressed)lpCompressed->Release();

    return hRes;
}

References

For more information about how to obtain this new function for Outlook 2002, click the following article number to view the article in the Microsoft Knowledge Base:
883924 Description of the Outlook 2002 post-Service Pack 3 hotfix package: August 26, 2004
For more information about how to determine the path of Msmapi32.dll, click the following article number to view the article in the Microsoft Knowledge Base:
229700 How to locate the correct path to the Mapisvc.inf file in Microsoft Outlook
For more information about the security changes in Outlook 2002 that are introduced in Office XP Service Pack 3, click the following article number to view the article in the Microsoft Knowledge Base:
838871 Description of the developer-related security changes in Outlook 2002 Service Pack 3

Properties

Article ID: 839560 - Last Review: September 3, 2013 - Revision: 8.0
Applies to
  • Microsoft Office Outlook 2003
  • Microsoft Outlook 2002 Standard Edition
Keywords: 
kboffice2003sp2fix kbtshoot kbinfo kbmsg kbhotfixserver KB839560

Give Feedback

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com