Microsoft KB Archive/839560

= New MAPI function to access native body =

Article ID: 839560

Article Last Modified on 3/20/2007

-

APPLIES TO


 * Microsoft Office Outlook 2003
 * Microsoft Outlook 2002 Standard Edition

-





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



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 &quot;New flags and structures&quot; 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 &quot;New flags and structures&quot; section for additional details about this structure.

Return Values

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:
 * 1) define MAPI_NATIVE_BODY 0x00010000


 * 1) define MAPI_NATIVE_BODY_TYPE_RTF 0x00000001
 * 2) define MAPI_NATIVE_BODY_TYPE_HTML 0x00000002
 * 3) 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:

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:

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(&quot;Body's native type is: &quot;);

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

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

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

return hRes; }

