locked
Embedding a email Message into another email with CDO RRS feed

  • Question

  • We implemented an Exchange Transport agent in C#.NET by subclassing RoutingAgentFactory and RoutingAgent from the Microsoft.Exchange.Data.Transport.Routing namespace.

    I have created a handler for the ResolvedMessageEventHandler event which writes the data to a file directly from the stream returned from MailItem.GetMimeReadStream() without altering it any way. I am then able to open the vast majority of these files written to disk in any email client successfully.

    There is however a problem with TNEF messages that have a HTML content. These message types occur when sending between users in the same routing group and they have the following headers.

    Content-Type: application/ms-tnef;

         name="winmail.dat"

    As it is the TNEF format email, and we can handle that TNEF format email. And we have some filter for the email content, and if the email violate the policy, and trigger the quarantined entire message action of our product, then the email would be saved as the quarantined_email.eml as the local file from the stream returned from MailItem.GetMimeReadStream().

    We also design the resend the quarantined email function, and the administrator can resend the quarantined email to the original receiver, and that function, we just use the CDO API to compose a new email, and add the quarantined_email.eml as the embedded email message attachment and the Content-Type message/rfc822, and these code refer the following link by Microsoft.

    http://msdn.microsoft.com/en-us/library/ms527570(v=exchg.10).aspx

    http://msdn.microsoft.com/en-us/library/ms527302(v=exchg.10).aspx

    And as I test that with the test program I write,

    Exchange 2010, windows server 2008 and here is the result:

    l  The internal receiver that use the outlook2007 can receive the email as the right format, the quarantined_email.eml can be opened as the right email message.

    l  The external receiver just like yahoo gmail, and that would some issue with the quarantined_email.eml, it still has the TNEF in the header.

    Content-Type: application/ms-tnef;

             name="winmail.dat"

    Another test with the EWS API that can be ok for all the internal and external email receiver. With the EWS solution, and I still write the test program, and load the quarantined_email.eml as the EmailMessage ItemAttachment.

    So we just can’t embedding a Message(from the stream returned from MailItem.GetMimeReadStream()) into the email with CDO. Could it be same solution for it. We just need that for the resend quarantined email function.

    Here is code:

               CDO::IBodyPartPtr spBodyPart;

               m_pCdoMsg->get_BodyPart(&spBodyPart);

               CDO::IBodyPartPtr pBody;

               spBodyPart->AddBodyPart(-1, &pBody);

               try

               {

                  ADODB::_StreamPtr spFile(__uuidof(ADODB::Stream ));;

                  std::wcout<<  strAttachmentFullPathName.c_str() << std::endl;

                  _variant_t varOptional(DISP_E_PARAMNOTFOUND,VT_ERROR);

                  try {

                      spFile->Open(

                              varOptional,

                           ADODB::adModeUnknown,

                           ADODB::adOpenStreamUnspecified,

                              NULL,

                              NULL);

                      spFile->LoadFromFile(_bstr_t(strAttachmentFullPathName.c_str()));

                      long size = 0;

                      spFile->get_Size(&size);

               }

               catch(_com_error e)

               {

                    throw e;

               }

                  spFile->Flush();

                  CDO::IMessagePtr pMsg(__uuidof(CDO::Message));

                  CDO::IDataSourcePtr  iDsrc;

                  iDsrc = pMsg;

                  if (iDsrc->OpenObject(spFile, _bstr_t("_Stream")) == S_OK)

                  {

                      std::cout << "iDsrc->OpenObject Success" << std::endl;

                  }

                  else

                  {

                      std::cout << "iDsrc->OpenObject Fail" << std::endl;

                  }

                  Save_Message_to_File(pMsg, _bstr_t("pMsg.eml"));

                  CDO::IDataSourcePtr iDsrc1;

                  iDsrc1 = pMsg;

                  iDsrc1->SaveToObject(pBody, _bstr_t("IBodyPart"));

    Thursday, January 31, 2013 8:04 AM