// MimeDecoder.cpp : Implementation of CMimeDecoder
#include "stdafx.h"
#include "MimeSniffer.h"
#include "MimeDecoder.h"
#include "FileSystemStorage.h"
#include "DateTime.h"
#include "MimeBody.h"
#include "Quote.h"
#include "MIMECode.h"
#include "ISSHelper.h"
extern void MimeDecInit();
extern int MimeDecparse();
CMutex CMimeDecoder::s_Mutex;
CMimeDecoder* CMimeDecoder::s_pCurrentMimeDec = NULL;
/////////////////////////////////////////////////////////////////////////////
// CMimeDecoder
static ULONG __Write(LPSTREAM pStm, const char* text)
{
ULONG nWritten = 0;
pStm->Write(text, strlen(text), &nWritten);
return nWritten;
}
CMimeDecoder::CMimeDecoder()
{
m_nVersionMajor = 1;
m_nVersionMinor = 0;
m_bInterpretReceivedAsRaw = true;
m_bInterpretEmbeddedMails = true;
m_bErrorOccured = false;
m_pParent = NULL;
ATLTRACE(_T("----------------- CMimeDecoder() -----------------\n"));
}
CMimeDecoder::~CMimeDecoder()
{
ATLTRACE(_T("-----------------~CMimeDecoder() -----------------\n"));
}
STDMETHODIMP CMimeDecoder::InitNew()
{
m_nVersionMajor = 1;
m_nVersionMinor = 0;
m_ReturnPath.Init();
m_listReceived.clear();
m_ReplyTo.Init();
m_From.Init();
m_Sender.Init();
m_ResentReplyTo.Init();
m_ResentFrom.Init();
m_ResentSender.Init();
m_Date.Init();
m_ResentDate.Init();
m_To.Init();
m_ResentTo.Init();
m_CC.Init();
m_ResentCC.Init();
m_BCC.Init();
m_ResentBCC.Init();
m_Subject.Init();
m_MessageID.Init();
m_ReturnReceiptTo.Init();
return S_OK;
}
void CMimeDecoder::SaveMailboxes(LPSTREAM pStm, const char* Intro, CYYSType& addr)
{
__Write(pStm, Intro);
if (addr.GetType() == CYYSType::type_ParamMap)
{
string str;
CYYSType temp;
for (CYYSType::param_map::reverse_iterator i = addr.m_mVal.rbegin(); i != addr.m_mVal.rend(); ++i)
{
if (i != addr.m_mVal.rbegin())
__Write(pStm, "\t\t, ");
else
__Write(pStm, "\t");
temp = *i;
temp.FormatAsMailbox(str);
__Write(pStm, str.c_str());
__Write(pStm, "\r\n");
}
}
else
{
string str;
addr.FormatAsMailbox(str);
__Write(pStm, str.c_str());
__Write(pStm, "\r\n");
}
}
STDMETHODIMP CMimeDecoder::Load(LPSTREAM pStm)
{
if (pStm != NULL)
{
int nInitPri = GetThreadPriority(GetCurrentThread());
if (m_pRawCopy != NULL)
m_pRawCopy.Release();
m_pRawCopy = new CISSHelper(true);
do
{
// freien Slot suchen
if (s_Mutex.Lock(0))
{
// alte Priorit�t wieder herstellen!
if (nInitPri != GetThreadPriority(GetCurrentThread()))
SetThreadPriority(GetCurrentThread(), nInitPri);
ATLASSERT(s_pCurrentMimeDec == NULL);
s_pCurrentMimeDec = this;
m_pStream = pStm;
ATLTRACE(_T("--> Parsing with Slot #0"));
m_bErrorOccured = false;
MimeDecInit();
MimeDecparse();
ATLTRACE(_T("<-- Parsing with Slot #0"));
m_pStream.Release();
s_pCurrentMimeDec = NULL;
s_Mutex.Unlock();
return m_bErrorOccured ? E_ABORT : S_OK;
}
ATLTRACE(_T("No Slot found!"));
// keinen Slot gefunden :-(
// in dem Fall mit niedriger Priorit�t weiter versuchen
if (nInitPri == GetThreadPriority(GetCurrentThread()))
{
BOOL bSuc = SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
ATLASSERT(bSuc);
}
}
while(true);
}
return E_INVALIDARG;
}
void CMimeDecoder::Modified()
{
if (!m_bErrorOccured)
{
m_bModified = true;
if (m_pRawCopy != NULL)
m_pRawCopy.Release();
if (m_pCommit != NULL)
{
SETSIZEOF_STREAM(0, m_pCommit)
Save(m_pCommit, FALSE);
}
if (m_pParent != NULL)
m_pParent->Modified();
}
}
void CMimeDecoder::IsProxy(LPSTREAM pStream, CMimeDecoder* pParent)
{
ATLASSERT(pStream != NULL);
ATLASSERT(pParent != NULL);
m_pCommit = pStream;
m_pParent = pParent;
Load(pStream);
}
STDMETHODIMP CMimeDecoder::Save(LPSTREAM pStm, BOOL fClearDirty)
{
// Solange der Stream nicht ver�ndert wurde,
// geben wir die rohe Kopie unver�ndert
// weiter!
if (m_pRawCopy != NULL && pStm != NULL)
{
CMIMECodeRaw copy;
copy.Decode(m_pRawCopy, pStm);
return S_OK;
}
if (pStm != NULL)
{
bool bSaveInterpretEmbeddedMails = m_bInterpretEmbeddedMails;
m_bInterpretEmbeddedMails = false;
char buf[512];
USES_CONVERSION;
// Zun�chst mal alle Received-Felder
if (!m_listReceived.empty())
{
for (list<pair<CYYSType, CYYSType> >::iterator i = m_listReceived.begin(); i != m_listReceived.end(); ++i)
{
const CYYSType& received = i->first;
const CYYSType& dt = i->second;
if (received.GetType() == CYYSType::type_ParamMap)
{
__Write(pStm, "Received: ");
for (CYYSType::param_map::const_iterator i = received.m_mVal.begin(); i != received.m_mVal.end(); ++i)
{
if (i != received.m_mVal.begin())
{
__Write(pStm, "\r\n\t\t");
}
__Write(pStm, i->first.c_str());
__Write(pStm, " ");
if (i->second.vt == VT_BSTR)
{
__Write(pStm, OLE2CA(i->second.bstrVal));
}
else
{
CComVariant vtVal(i->second);
vtVal.ChangeType(VT_BSTR);
if (vtVal.vt == VT_BSTR)
{
__Write(pStm, OLE2CA(vtVal.bstrVal));
}
}
}
__Write(pStm, "; ");
__Write(pStm, dt);
__Write(pStm, "\r\n");
}
else
{
ATLASSERT(dt.GetType() == CYYSType::type_Param);
if (dt.GetType() == CYYSType::type_Param)
{
__Write(pStm, dt.m_pVal.first.c_str());
__Write(pStm, dt);
__Write(pStm, "\r\n");
}
}
}
}
// Return-Path
if (m_ReturnPath.IsValid())
{
ATLASSERT(m_ReturnPath.GetType() == CYYSType::type_Param);
if (m_ReturnPath.GetType() == CYYSType::type_Param)
{
__Write(pStm, "Return-path: ");
__Write(pStm, m_ReturnPath.m_pVal.first.c_str());
__Write(pStm, "\r\n");
}
}
// Date
if (!m_Date.IsValid())
{
CDT now = CDT::GetCurrentTime();
m_Date.PutAsDate(now);
}
if (m_Date.IsValid())
{
__Write(pStm, "Date: ");
__Write(pStm, m_Date);
__Write(pStm, "\r\n");
}
// Resent-Date
if (m_ResentDate.IsValid())
{
__Write(pStm, "Resent-Date: ");
__Write(pStm, m_ResentDate);
__Write(pStm, "\r\n");
}
// Sender
if (m_Sender.IsValid())
{
SaveMailboxes(pStm, "Sender: ", m_Sender);
}
// From
if (m_From.IsValid())
{
SaveMailboxes(pStm, "From: ", m_From);
}
// Reply-To
if (m_ReplyTo.IsValid())
{
SaveMailboxes(pStm, "Reply-To: ", m_ReplyTo);
}
// Resent-Sender
if (m_ResentSender.IsValid())
{
SaveMailboxes(pStm, "Resent-Sender: ", m_ResentSender);
}
// Resent-From
if (m_ResentFrom.IsValid())
{
SaveMailboxes(pStm, "Resent-From: ", m_ResentFrom);
}
// Resent-Reply-To
if (m_ResentReplyTo.IsValid())
{
SaveMailboxes(pStm, "Resent-Reply-To: ", m_ResentReplyTo);
}
// To
if (m_To.IsValid())
{
SaveMailboxes(pStm, "To: ", m_To);
}
// Resent-To
if (m_ResentTo.IsValid())
{
SaveMailboxes(pStm, "Resent-To: ", m_ResentTo);
}
// CC
if (m_CC.IsValid())
{
SaveMailboxes(pStm, "cc: ", m_CC);
}
// Resent-cc
if (m_ResentCC.IsValid())
{
SaveMailboxes(pStm, "Resent-cc: ", m_ResentCC);
}
// BCC
if (m_BCC.IsValid())
{
SaveMailboxes(pStm, "bcc: ", m_BCC);
}
// Resent-cc
if (m_ResentBCC.IsValid())
{
SaveMailboxes(pStm, "Resent-bcc: ", m_ResentBCC);
}
// MIME-Version
sprintf(buf, "MIME-Version: %ld.%ld\r\n", m_nVersionMajor, m_nVersionMinor);
__Write(pStm, buf);
// Message-ID
if (m_MessageID.IsValid())
{
__Write(pStm, "Message-ID: ");
__Write(pStm, m_MessageID);
__Write(pStm, "\r\n");
}
// Subject
if (m_Subject.IsValid())
{
__Write(pStm, "Subject: ");
__Write(pStm, m_Subject);
__Write(pStm, "\r\n");
}
// Return-Receipt-To
if (m_ReturnReceiptTo.IsValid())
{
SaveMailboxes(pStm, "Return-Receipt-To: ", m_ReturnReceiptTo);
}
// Alle Bodies
IPersistStreamPtr pBody;
if (SUCCEEDED(CMimeBody::CreateInstance(&pBody)))
{
((CMimeBody*)((IPersistStream*)pBody))->Init(&m_Body, this);
pBody->Save(pStm, fClearDirty);
}
// End of Message (as long we are not a proxy)!
if (m_pParent == NULL)
__Write(pStm, ".\r\n");
m_bInterpretEmbeddedMails = bSaveInterpretEmbeddedMails;
return S_OK;
}
return E_INVALIDARG;
}
void CMimeDecoder::OnError(const char* strError, long nLine)
{
m_bErrorOccured = true;
CMIMECodeRaw copy;
if (m_pStream != NULL && m_pRawCopy != NULL)
copy.Decode(m_pStream, m_pRawCopy);
#ifdef _DEBUG
USES_CONVERSION;
Fire_OnError(A2OLE(strError), nLine);
#endif
}
STDMETHODIMP CMimeDecoder::LoadFromFile(BSTR Path, VARIANT_BOOL* pbvarResult)
{
USES_CONVERSION;
/*
m_strPath = OLE2CT(Path);
*pbvarResult = VARIANT_TRUE;
Start(10000);
*/
*pbvarResult = VARIANT_FALSE;
HANDLE hFile = ::CreateFile(OLE2CT(Path), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
CFileSystemStream* pStream = new CFileSystemStream(hFile);
*pbvarResult = SUCCEEDED(Load(pStream)) ? VARIANT_TRUE : VARIANT_FALSE;
pStream->Release();
}
return S_OK;
}
STDMETHODIMP CMimeDecoder::SaveToFile(BSTR Path, VARIANT_BOOL *pbvarResult)
{
USES_CONVERSION;
*pbvarResult = VARIANT_FALSE;
HANDLE hFile = ::CreateFile(OLE2CT(Path), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
CFileSystemStream* pStream = new CFileSystemStream(hFile);
Save(pStream, TRUE);
pStream->Release();
*pbvarResult = VARIANT_TRUE;
}
return S_OK;
}
void CMimeDecoder::SetVersion(const CYYSType& nMajor, const CYYSType& nMinor)
{
#ifdef _DEBUG
ATLASSERT(nMajor.GetType() == CYYSType::type_Long && nMinor.GetType() == CYYSType::type_Long);
ATLTRACE(_T("MIME-Version is: %ld . %ld\n"), (long)nMajor, (long)nMinor);
#endif
m_nVersionMajor = (long)nMajor;
m_nVersionMinor = (long)nMinor;
}
void CMimeDecoder::SetReturnPath(const CYYSType& addr)
{
#ifdef _DEBUG
USES_CONVERSION;
ATLASSERT(addr.GetType() == CYYSType::type_Param);
ATLTRACE(_T("Return-Path is: %s\n"), addr.m_pVal.first.c_str());
#endif
m_ReturnPath = addr;
}
void CMimeDecoder::AddReceived(const CYYSType& received, const CYYSType& dt)
{
#ifdef _DEBUG
USES_CONVERSION;
ATLTRACE(_T("Received: %s\n"), (const char*)dt);
ATLASSERT(received.GetType() == CYYSType::type_ParamMap);
for (CYYSType::param_map::const_iterator i = received.m_mVal.begin(); i != received.m_mVal.end(); ++i)
{
CComVariant vtVal(i->second);
vtVal.ChangeType(VT_BSTR);
if (vtVal.vt == VT_BSTR)
{
ATLTRACE(_T(" Parameter:%s Value:%s\n"), i->first.c_str(), OLE2CT(vtVal.bstrVal));
}
}
#endif
m_listReceived.push_back(pair<CYYSType, CYYSType>(received, dt));
}
void CMimeDecoder::AddReceivedRaw(const CYYSType& field)
{
ATLASSERT(field.GetType() == CYYSType::type_Param);
ATLTRACE(_T("%s%s\n"), field.m_pVal.first.c_str(), (const char*)field);
m_listReceived.push_back(pair<CYYSType, CYYSType>(CYYSType(), field));
}
void CMimeDecoder::SetReplyTo(const CYYSType& addr)
{
#ifdef _DEBUG
USES_CONVERSION;
ATLASSERT(addr.GetType() == CYYSType::type_Param);
ATLTRACE(_T("ReplyTo: %s\n"), addr.m_pVal.first.c_str());
#endif
m_ReplyTo = addr;
}
void CMimeDecoder::SetFrom(const CYYSType& addr)
{
#ifdef _DEBUG
USES_CONVERSION;
if (addr.GetType() == CYYSType::type_ParamMap)
{
for (CYYSType::param_map::const_iterator i = addr.m_mVal.begin(); i != addr.m_mVal.end(); ++i)
{
CComVariant vtVal(i->second);
vtVal.ChangeType(VT_BSTR);
if (vtVal.vt == VT_BSTR)
{
ATLTRACE(_T("From: %s %s\n"), OLE2CT(vtVal.bstrVal), i->first.c_str());
}
}
}
else
{
ATLASSERT(addr.GetType() == CYYSType::type_Param);
CComVariant vtVal(addr.m_pVal.second);
vtVal.ChangeType(VT_BSTR);
ATLTRACE(_T("From: %s %s\n"), OLE2CT(vtVal.bstrVal), addr.m_pVal.first.c_str());
}
#endif
m_From = addr;
}
void CMimeDecoder::SetSender(const CYYSType& addr)
{
#ifdef _DEBUG
USES_CONVERSION;
ATLASSERT(addr.GetType() == CYYSType::type_Param);
ATLTRACE(_T("Sender: %s\n"), addr.m_pVal.first.c_str());
#endif
m_Sender = addr;
}
void CMimeDecoder::SetResentReplyTo(const CYYSType& addr)
{
#ifdef _DEBUG
USES_CONVERSION;
ATLASSERT (addr.GetType() == CYYSType::type_ParamMap);
for (CYYSType::param_map::const_iterator i = addr.m_mVal.begin(); i != addr.m_mVal.end(); ++i)
{
CComVariant vtVal(i->second);
vtVal.ChangeType(VT_BSTR);
if (vtVal.vt == VT_BSTR)
{
ATLTRACE(_T("From: %s %s\n"), OLE2CT(vtVal.bstrVal), i->first.c_str());
}
}
#endif
m_ResentReplyTo = addr;
}
void CMimeDecoder::SetResentFrom(const CYYSType& addr)
{
#ifdef _DEBUG
USES_CONVERSION;
if (addr.GetType() == CYYSType::type_ParamMap)
{
for (CYYSType::param_map::const_iterator i = addr.m_mVal.begin(); i != addr.m_mVal.end(); ++i)
{
CComVariant vtVal(i->second);
vtVal.ChangeType(VT_BSTR);
if (vtVal.vt == VT_BSTR)
{
ATLTRACE(_T("From: %s %s\n"), OLE2CT(vtVal.bstrVal), i->first.c_str());
}
}
}
else
{
ATLASSERT(addr.GetType() == CYYSType::type_Param);
CComVariant vtVal(addr.m_pVal.second);
vtVal.ChangeType(VT_BSTR);
ATLTRACE(_T("From: %s %s\n"), OLE2CT(vtVal.bstrVal), addr.m_pVal.first.c_str());
}
#endif
m_ResentFrom = addr;
}
void CMimeDecoder::SetResentSender(const CYYSType& addr)
{
#ifdef _DEBUG
USES_CONVERSION;
ATLASSERT(addr.GetType() == CYYSType::type_Param);
ATLTRACE(_T("Sender: %s\n"), addr.m_pVal.first.c_str());
#endif
m_ResentSender = addr;
}
void CMimeDecoder::SetDate(const CYYSType& dt)
{
ATLTRACE(_T("Date: %s\n"), (const char*)dt);
m_Date = dt;
}
void CMimeDecoder::SetResentDate(const CYYSType& dt)
{
ATLTRACE(_T("ResentDate: %s\n"), (const char*)dt);
m_ResentDate = dt;
}
void CMimeDecoder::SetTo(const CYYSType& addr)
{
#ifdef _DEBUG
USES_CONVERSION;
ATLASSERT (addr.GetType() == CYYSType::type_ParamMap);
for (CYYSType::param_map::const_iterator i = addr.m_mVal.begin(); i != addr.m_mVal.end(); ++i)
{
CComVariant vtVal(i->second);
vtVal.ChangeType(VT_BSTR);
if (vtVal.vt == VT_BSTR)
{
ATLTRACE(_T("To: %s %s\n"), OLE2CT(vtVal.bstrVal), i->first.c_str());
}
}
#endif
m_To = addr;
}
void CMimeDecoder::SetReturnReceiptTo(const CYYSType& addr)
{
#ifdef _DEBUG
USES_CONVERSION;
ATLASSERT (addr.GetType() == CYYSType::type_ParamMap);
for (CYYSType::param_map::const_iterator i = addr.m_mVal.begin(); i != addr.m_mVal.end(); ++i)
{
CComVariant vtVal(i->second);
vtVal.ChangeType(VT_BSTR);
if (vtVal.vt == VT_BSTR)
{
ATLTRACE(_T("ReturnReceiptTo: %s %s\n"), OLE2CT(vtVal.bstrVal), i->first.c_str());
}
}
#endif
m_ReturnReceiptTo = addr;
}
void CMimeDecoder::SetResentTo(const CYYSType& addr)
{
#ifdef _DEBUG
USES_CONVERSION;
ATLASSERT (addr.GetType() == CYYSType::type_ParamMap);
for (CYYSType::param_map::const_iterator i = addr.m_mVal.begin(); i != addr.m_mVal.end(); ++i)
{
CComVariant vtVal(i->second);
vtVal.ChangeType(VT_BSTR);
if (vtVal.vt == VT_BSTR)
{
ATLTRACE(_T("ResentTo: %s %s\n"), OLE2CT(vtVal.bstrVal), i->first.c_str());
}
}
#endif
m_ResentTo = addr;
}
void CMimeDecoder::SetCC(const CYYSType& addr)
{
#ifdef _DEBUG
USES_CONVERSION;
ATLASSERT (addr.GetType() == CYYSType::type_ParamMap);
for (CYYSType::param_map::const_iterator i = addr.m_mVal.begin(); i != addr.m_mVal.end(); ++i)
{
CComVariant vtVal(i->second);
vtVal.ChangeType(VT_BSTR);
if (vtVal.vt == VT_BSTR)
{
ATLTRACE(_T("CC: %s %s\n"), OLE2CT(vtVal.bstrVal), i->first.c_str());
}
}
#endif
m_CC = addr;
}
void CMimeDecoder::SetResentCC(const CYYSType& addr)
{
#ifdef _DEBUG
USES_CONVERSION;
ATLASSERT (addr.GetType() == CYYSType::type_ParamMap);
for (CYYSType::param_map::const_iterator i = addr.m_mVal.begin(); i != addr.m_mVal.end(); ++i)
{
CComVariant vtVal(i->second);
vtVal.ChangeType(VT_BSTR);
if (vtVal.vt == VT_BSTR)
{
ATLTRACE(_T("ResentCC: %s %s\n"), OLE2CT(vtVal.bstrVal), i->first.c_str());
}
}
#endif
m_ResentCC = addr;
}
void CMimeDecoder::SetBCC(const CYYSType& addr)
{
#ifdef _DEBUG
USES_CONVERSION;
ATLASSERT (addr.GetType() == CYYSType::type_ParamMap);
for (CYYSType::param_map::const_iterator i = addr.m_mVal.begin(); i != addr.m_mVal.end(); ++i)
{
CComVariant vtVal(i->second);
vtVal.ChangeType(VT_BSTR);
if (vtVal.vt == VT_BSTR)
{
ATLTRACE(_T("BCC: %s %s\n"), OLE2CT(vtVal.bstrVal), i->first.c_str());
}
}
#endif
m_BCC = addr;
}
void CMimeDecoder::SetResentBCC(const CYYSType& addr)
{
#ifdef _DEBUG
USES_CONVERSION;
ATLASSERT (addr.GetType() == CYYSType::type_ParamMap);
for (CYYSType::param_map::const_iterator i = addr.m_mVal.begin(); i != addr.m_mVal.end(); ++i)
{
CComVariant vtVal(i->second);
vtVal.ChangeType(VT_BSTR);
if (vtVal.vt == VT_BSTR)
{
ATLTRACE(_T("ResentBCC: %s %s\n"), OLE2CT(vtVal.bstrVal), i->first.c_str());
}
}
#endif
m_ResentBCC = addr;
}
void CMimeDecoder::SetSubject(const CYYSType& str)
{
ATLTRACE(_T("Subject is: %s\n"), (const char*)str);
m_Subject = str;
}
void CMimeDecoder::SetMessageID(const CYYSType& id)
{
ATLTRACE(_T("Message-ID is: %s\n"), (const char*)id);
m_MessageID = id;
}
void CMimeDecoder::SetBody(const CYYSType& body)
{
ATLTRACE(_T("Found Body:\n"));
#ifdef _DEBUG
body.Dump();
#endif
m_Body = body;
}
STDMETHODIMP CMimeDecoder::get_ReturnPath(VARIANT *pVal)
{
CComVariant vtResult;
if (m_ReturnPath.IsValid())
{
if (!m_ReturnPath.GetAsMailAddress(vtResult))
return E_FAIL;
}
return ::VariantCopyInd(pVal, &vtResult);
}
STDMETHODIMP CMimeDecoder::put_ReturnPath(VARIANT newVal)
{
m_ReturnPath.PutAsMailAddress(newVal);
Modified();
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_MajorMimeVersion(long *pVal)
{
*pVal = m_nVersionMajor;
return S_OK;
}
STDMETHODIMP CMimeDecoder::put_MajorMimeVersion(long newVal)
{
m_nVersionMajor = newVal;
Modified();
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_MinorMimeVersion(long *pVal)
{
*pVal = m_nVersionMinor;
return S_OK;
}
STDMETHODIMP CMimeDecoder::put_MinorMimeVersion(long newVal)
{
m_nVersionMinor = newVal;
Modified();
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_ReplyTo(VARIANT *pVal)
{
CComVariant vtResult;
if (m_ReplyTo.IsValid())
{
if (!m_ReplyTo.GetAsMailAddress(vtResult))
return E_FAIL;
}
return ::VariantCopyInd(pVal, &vtResult);
}
STDMETHODIMP CMimeDecoder::put_ReplyTo(VARIANT newVal)
{
m_ReplyTo.PutAsMailAddress(newVal);
Modified();
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_From(VARIANT *pVal)
{
CComVariant vtResult;
if (m_From.IsValid())
{
if (m_From.GetType() == CYYSType::type_ParamMap)
{
if (!m_From.GetAsMailAddresses(vtResult))
return E_FAIL;
}
else
{
if (!m_From.GetAsMailAddress(vtResult))
return E_FAIL;
}
}
return ::VariantCopyInd(pVal, &vtResult);
}
STDMETHODIMP CMimeDecoder::put_From(VARIANT newVal)
{
bool bMultiple = false;
if (newVal.vt == VT_DISPATCH)
{
CComDispatchDriverEx dummy(newVal.pdispVal);
IEnumVARIANTPtr pTest;
if (SUCCEEDED(dummy.Enum(&pTest)))
bMultiple = true;
}
if (bMultiple)
m_From.PutAsMailAddresses(newVal);
else
m_From.PutAsMailAddress(newVal);
Modified();
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_Sender(VARIANT *pVal)
{
CComVariant vtResult;
if (m_Sender.IsValid())
{
if (!m_Sender.GetAsMailAddress(vtResult))
return E_FAIL;
}
return ::VariantCopyInd(pVal, &vtResult);
}
STDMETHODIMP CMimeDecoder::put_Sender(VARIANT newVal)
{
m_Sender.PutAsMailAddress(newVal);
Modified();
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_ResentReplyTo(VARIANT *pVal)
{
CComVariant vtResult;
if (m_ResentReplyTo.IsValid())
{
if (!m_ResentReplyTo.GetAsMailAddresses(vtResult))
return E_FAIL;
}
return ::VariantCopyInd(pVal, &vtResult);
}
STDMETHODIMP CMimeDecoder::put_ResentReplyTo(VARIANT newVal)
{
m_ResentReplyTo.PutAsMailAddresses(newVal);
Modified();
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_ResentFrom(VARIANT *pVal)
{
CComVariant vtResult;
if (m_ResentFrom.IsValid())
{
if (!m_ResentFrom.GetAsMailAddresses(vtResult))
return E_FAIL;
}
return ::VariantCopyInd(pVal, &vtResult);
}
STDMETHODIMP CMimeDecoder::put_ResentFrom(VARIANT newVal)
{
m_ResentFrom.PutAsMailAddresses(newVal);
Modified();
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_ResentSender(VARIANT *pVal)
{
CComVariant vtResult;
if (m_ResentSender.IsValid())
{
if (!m_ResentSender.GetAsMailAddress(vtResult))
return E_FAIL;
}
return ::VariantCopyInd(pVal, &vtResult);
}
STDMETHODIMP CMimeDecoder::put_ResentSender(VARIANT newVal)
{
m_ResentSender.PutAsMailAddress(newVal);
Modified();
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_Date(VARIANT *pVal)
{
CComVariant vtResult;
if (m_Date.IsValid())
{
if (!m_Date.GetAsDate(vtResult))
return E_FAIL;
}
return ::VariantCopyInd(pVal, &vtResult);
}
STDMETHODIMP CMimeDecoder::put_Date(VARIANT newVal)
{
m_Date.PutAsDate(newVal);
Modified();
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_ResentDate(VARIANT *pVal)
{
CComVariant vtResult;
if (m_ResentDate.IsValid())
{
if (!m_ResentDate.GetAsDate(vtResult))
return E_FAIL;
}
return ::VariantCopyInd(pVal, &vtResult);
}
STDMETHODIMP CMimeDecoder::put_ResentDate(VARIANT newVal)
{
m_ResentDate.PutAsDate(newVal);
Modified();
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_To(VARIANT *pVal)
{
CComVariant vtResult;
if (m_To.IsValid())
{
if (!m_To.GetAsMailAddresses(vtResult))
return E_FAIL;
}
return ::VariantCopyInd(pVal, &vtResult);
}
STDMETHODIMP CMimeDecoder::put_To(VARIANT newVal)
{
m_To.PutAsMailAddresses(newVal);
Modified();
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_CC(VARIANT *pVal)
{
CComVariant vtResult;
if (m_CC.IsValid())
{
if (!m_CC.GetAsMailAddresses(vtResult))
return E_FAIL;
}
return ::VariantCopyInd(pVal, &vtResult);
}
STDMETHODIMP CMimeDecoder::put_CC(VARIANT newVal)
{
m_CC.PutAsMailAddresses(newVal);
Modified();
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_BCC(VARIANT *pVal)
{
CComVariant vtResult;
if (m_BCC.IsValid())
{
if (!m_BCC.GetAsMailAddresses(vtResult))
return E_FAIL;
}
return ::VariantCopyInd(pVal, &vtResult);
}
STDMETHODIMP CMimeDecoder::put_BCC(VARIANT newVal)
{
m_BCC.PutAsMailAddresses(newVal);
Modified();
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_Subject(VARIANT *pVal)
{
CComVariant vtResult;
if (m_Subject.IsValid())
{
if (!m_Subject.GetAsUnQuotedText(vtResult))
return E_FAIL;
}
return ::VariantCopyInd(pVal, &vtResult);
}
STDMETHODIMP CMimeDecoder::put_Subject(VARIANT newVal)
{
m_Subject.PutAsQuotedInlineText(newVal);
Modified();
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_SubjectRaw(VARIANT *pVal)
{
CComVariant vtResult;
if (m_Subject.IsValid())
{
if (!m_Subject.GetAsPlainText(vtResult))
return E_FAIL;
}
return ::VariantCopyInd(pVal, &vtResult);
}
STDMETHODIMP CMimeDecoder::put_SubjectRaw(VARIANT newVal)
{
m_Subject.PutAsPlainText(newVal);
Modified();
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_MessageID(VARIANT *pVal)
{
CComVariant vtResult;
if (m_MessageID.IsValid())
{
if (!m_MessageID.GetAsPlainText(vtResult))
return E_FAIL;
}
return ::VariantCopyInd(pVal, &vtResult);
}
STDMETHODIMP CMimeDecoder::put_MessageID(VARIANT newVal)
{
m_MessageID.PutAsPlainText(newVal);
Modified();
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_ReceivedFieldAsRaw(VARIANT_BOOL *pVal)
{
*pVal = m_bInterpretReceivedAsRaw ? VARIANT_TRUE : VARIANT_FALSE;
return S_OK;
}
STDMETHODIMP CMimeDecoder::put_ReceivedFieldAsRaw(VARIANT_BOOL newVal)
{
m_bInterpretReceivedAsRaw = newVal != VARIANT_FALSE ? true : false;
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_InterpretEmbeddedMails(VARIANT_BOOL *pVal)
{
*pVal = m_bInterpretEmbeddedMails ? VARIANT_TRUE : VARIANT_FALSE;
return S_OK;
}
STDMETHODIMP CMimeDecoder::put_InterpretEmbeddedMails(VARIANT_BOOL newVal)
{
m_bInterpretEmbeddedMails = newVal != VARIANT_FALSE ? true : false;
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_ReturnReceiptTo(VARIANT *pVal)
{
CComVariant vtResult;
if (m_ReturnReceiptTo.IsValid())
{
if (!m_ReturnReceiptTo.GetAsMailAddresses(vtResult))
return E_FAIL;
}
return ::VariantCopyInd(pVal, &vtResult);
}
STDMETHODIMP CMimeDecoder::put_ReturnReceiptTo(VARIANT newVal)
{
m_ReturnReceiptTo.PutAsMailAddresses(newVal);
Modified();
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_Body(VARIANT *pVal)
{
HRESULT hr;
if (pVal->vt != VT_EMPTY)
::VariantClear(pVal);
if (!m_bErrorOccured)
{
pVal->pdispVal = NULL;
if (SUCCEEDED(hr = CMimeBody::CreateInstance(&pVal->pdispVal)))
{
((CMimeBody*)pVal->pdispVal)->Init(&m_Body, this);
pVal->vt = VT_DISPATCH;
}
}
else
hr = S_OK;
return hr;
}
STDMETHODIMP CMimeDecoder::put_Body(VARIANT newVal)
{
HRESULT hr = E_FAIL;
if (newVal.vt == VT_BSTR)
{
CComDispatchDriverEx body;
if (SUCCEEDED(hr = CMimeBody::CreateInstance(&body.p)))
{
((CMimeBody*)body.p)->Init(&m_Body, this);
long val = mimetype_text;
body.PutProperty(L"MajorContentType", val);
val = text_subtype_plain;
body.PutProperty(L"MinorContentType", val);
val = mechanism_quoted_printable;
body.PutProperty(L"Encoding", val);
body.PutPropertyByName(L"Value", &newVal);
}
}
return hr;
}
STDMETHODIMP CMimeDecoder::Load(LPDISPATCH StreamObject, VARIANT_BOOL *pbvarRestult)
{
IStreamPtr pStream;
*pbvarRestult = VARIANT_FALSE;
if (SUCCEEDED(StreamObject->QueryInterface(&pStream)))
{
*pbvarRestult = SUCCEEDED(Load(pStream)) ? VARIANT_TRUE : VARIANT_FALSE;
}
return S_OK;
}
STDMETHODIMP CMimeDecoder::Save(LPDISPATCH StreamObject, VARIANT_BOOL *pbvarRestult)
{
IStreamPtr pStream;
*pbvarRestult = VARIANT_FALSE;
if (SUCCEEDED(StreamObject->QueryInterface(&pStream)))
{
*pbvarRestult = SUCCEEDED(Save(pStream, TRUE)) ? VARIANT_TRUE : VARIANT_FALSE;
}
return S_OK;
}
STDMETHODIMP CMimeDecoder::get_CanUpdateName(VARIANT_BOOL *pVal)
{
*pVal = VARIANT_TRUE;
return S_OK;
}
STDMETHODIMP CMimeDecoder::put_UpdateName(BSTR newVal)
{
CComVariant var(newVal);
HRESULT hr = put_Subject(var);
return hr;
}