BOOL CMapiMessage::FetchHeaders( void) { LPSPropValue pVal = CMapiApi::GetMapiProperty( m_lpMsg, PR_TRANSPORT_MESSAGE_HEADERS); if (pVal && CMapiApi::IsLargeProperty( pVal)) { m_headers.Truncate(); CMapiApi::GetLargeStringProperty( m_lpMsg, PR_TRANSPORT_MESSAGE_HEADERS, m_headers); } else if (pVal && (PROP_TYPE( pVal->ulPropTag) == PT_TSTRING) && (pVal->Value.LPSZ) && (*(pVal->Value.LPSZ))) { m_headers = pVal->Value.LPSZ; } else { // Need to build the headers from the other stuff m_headers.Truncate(); BuildHeaders(); } if (pVal) CMapiApi::MAPIFreeBuffer( pVal); m_fromLine.Truncate(); if (NeedsFromLine()) { BuildFromLine(); } if (!m_fromLine.IsEmpty()) { MAPI_DUMP_STRING(m_fromLine.get()); } MAPI_DUMP_STRING(m_headers.get()); MAPI_TRACE0("\r\n"); ProcessHeaders(); if (!m_headers.IsEmpty()) { if (!m_bHasSubject) AddSubject( m_headers); if (!m_bHasFrom) AddFrom( m_headers); if (!m_bHasDate) AddDate( m_headers); m_headers.Trim( kWhitespace, PR_FALSE, PR_TRUE); m_headers += "\x0D\x0A"; } return( !m_headers.IsEmpty()); }
BOOL CMapiMessage::FetchBody( void) { m_bodyIsHtml = FALSE; m_body.Truncate(); // Is it html? LPSPropValue pVal = CMapiApi::GetMapiProperty( m_lpMsg, 0x1013001e); if (pVal && CMapiApi::IsLargeProperty( pVal)) CMapiApi::GetLargeStringProperty( m_lpMsg, 0x1013001e, m_body); else if (pVal && (PROP_TYPE( pVal->ulPropTag) == PT_TSTRING) && (pVal->Value.LPSZ) && (*(pVal->Value.LPSZ))) m_body = pVal->Value.LPSZ; // kind-hearted Outlook will give us html even for a plain text message. But it will include // a comment saying it did the conversion. We'll use this as a hack to really use // the plain text part. if (!m_body.IsEmpty() && m_body.Find("<!-- Converted from text/plain format -->") == kNotFound) m_bodyIsHtml = TRUE; else { pVal = CMapiApi::GetMapiProperty( m_lpMsg, PR_BODY); if (pVal) { if (pVal && CMapiApi::IsLargeProperty( pVal)) { CMapiApi::GetLargeStringProperty( m_lpMsg, PR_BODY, m_body); } else { if (pVal && (PROP_TYPE( pVal->ulPropTag) == PT_TSTRING) && (pVal->Value.LPSZ) && (*(pVal->Value.LPSZ))) { m_body = pVal->Value.LPSZ; } } } } if (pVal) CMapiApi::MAPIFreeBuffer( pVal); MAPI_DUMP_STRING(m_body.get()); MAPI_TRACE0("\r\n"); return( TRUE); }
bool CMapiMessage::FetchBody(void) { m_bodyIsHtml = false; m_body.Truncate(); // Get the Outlook codepage info; if unsuccessful then it defaults to 0 (CP_ACP) -> system default // Maybe we can use this info later? unsigned int codepage=0; LPSPropValue pVal = CMapiApi::GetMapiProperty(m_lpMsg, PR_INTERNET_CPID); if (pVal) { if (PROP_TYPE(pVal->ulPropTag) == PT_LONG) codepage = pVal->Value.l; CMapiApi::MAPIFreeBuffer(pVal); } unsigned long nativeBodyType = 0; if (CMapiApi::GetRTFPropertyDecodedAsUTF16(m_lpMsg, m_body, nativeBodyType, codepage)) { m_bodyIsHtml = nativeBodyType == MAPI_NATIVE_BODY_TYPE_HTML; } else { // Cannot get RTF version // Is it html? pVal = CMapiApi::GetMapiProperty(m_lpMsg, PR_BODY_HTML_W); if (pVal) { if (CMapiApi::IsLargeProperty(pVal)) CMapiApi::GetLargeStringProperty(m_lpMsg, PR_BODY_HTML_W, m_body); else if ((PROP_TYPE(pVal->ulPropTag) == PT_UNICODE) && (pVal->Value.lpszW) && (*(pVal->Value.lpszW))) m_body.Assign(pVal->Value.lpszW); CMapiApi::MAPIFreeBuffer(pVal); } // Kind-hearted Outlook will give us html even for a plain text message. // But it will include a comment saying it did the conversion. // We'll use this as a hack to really use the plain text part. // // Sadly there are cases where this string is returned despite the fact // that the message is indeed HTML. // // To detect the "true" plain text messages, we look for our string // immediately following the <BODY> tag. if (!m_body.IsEmpty() && m_body.Find("<BODY>\r\n<!-- Converted from text/plain format -->") == kNotFound) { m_bodyIsHtml = true; } else { pVal = CMapiApi::GetMapiProperty(m_lpMsg, PR_BODY_W); if (pVal) { if (CMapiApi::IsLargeProperty(pVal)) CMapiApi::GetLargeStringProperty(m_lpMsg, PR_BODY_W, m_body); else if ((PROP_TYPE(pVal->ulPropTag) == PT_UNICODE) && (pVal->Value.lpszW) && (*(pVal->Value.lpszW))) m_body.Assign(pVal->Value.lpszW); CMapiApi::MAPIFreeBuffer(pVal); } } } // OK, now let's restore the original encoding! // 1. We may have a header defining the charset (we already called the FetchHeaders(), and there ProcessHeaders(); // in this case, the m_mimeCharset is set. See nsOutlookMail::ImportMailbox()) // 2. We may have the codepage walue provided by Outlook ("codepage" at the very beginning of this function) // 3. We may have an HTML charset header. bool bFoundCharset = false; if (!m_mimeCharset.IsEmpty()) // The top-level header data bFoundCharset = CheckBodyInCharsetRange(m_mimeCharset.get()); // No valid charset in the message header - try the HTML header. // arguably may be useless if (!bFoundCharset && m_bodyIsHtml) { ExtractMetaCharset(m_body.get(), m_body.Length(), m_mimeCharset); if (!m_mimeCharset.IsEmpty()) bFoundCharset = CheckBodyInCharsetRange(m_mimeCharset.get()); } // Get from Outlook (seems like it keeps the MIME part header encoding info) if (!bFoundCharset && codepage) { const char* charset = CpToCharset(codepage); if (charset) { bFoundCharset = CheckBodyInCharsetRange(charset); if (bFoundCharset) m_mimeCharset.Assign(charset); } } if (!bFoundCharset) { // Use system default const char* charset = nsMsgI18NFileSystemCharset(); if (charset) { bFoundCharset = CheckBodyInCharsetRange(charset); if (bFoundCharset) m_mimeCharset.Assign(charset); } } if (!bFoundCharset) // Everything else failed, let's use the lossless utf-8... m_mimeCharset.Assign("utf-8"); MAPI_DUMP_STRING(m_body.get()); MAPI_TRACE0("\r\n"); return true; }