Use MAPItoMIME method for conversion
authorThomas
Tue, 03 Nov 2020 14:04:57 +0100
changeset 3336 a7b84e234579
parent 3332 0874010b37fa
child 3337 4cd26b80d0cd
Use MAPItoMIME method for conversion
Extensions/MailItemExtensions.cs
FPPMessage.cs
MsgConverter.cs
ThisAddIn.cs
--- a/Extensions/MailItemExtensions.cs	Fri Oct 23 11:58:42 2020 +0200
+++ b/Extensions/MailItemExtensions.cs	Tue Nov 03 14:04:57 2020 +0100
@@ -2373,33 +2373,41 @@
         }
 
         /// <summary>
+        /// Save the given Outlook mail item as EML file with a randomized
+        /// file name to the Temp directory.
+        /// </summary>
+        /// <param name="omi">The Outlook mail item to save.</param>
+        /// <param name="fileName">The file name where it was saved to.</param>
+        /// <returns>True if the message was saved correctly, otherwise false.</returns>
+        public static bool SaveAsEml(this Outlook.MailItem omi, out string fileName)
+        {
+            fileName = null;
+
+            // Create a randomized file name for the attachment
+            Random random = new Random();
+            string tempPath = Path.GetTempPath();
+            fileName = tempPath + "message" + random.Next(10000) + ".eml";
+            while (File.Exists(fileName))
+            {
+                fileName = tempPath + "message" + random.Next(10000) + ".eml";
+            }
+
+            return omi.SaveAsEml(fileName);
+        }
+
+        /// <summary>
         /// Saves this Outlook mail item as plain-text (eml) message file.
-        /// If no file path is given, the message is stored with a randomized
-        /// file name in the Temp directory.
         /// </summary>
         /// <param name="omi">The Outlook mail item to process with.</param>
         /// <param name="fileName">The file path where to store the item.</param>
-        /// <returns>The file path where the message was saved or null if an error occured.</returns>
-        public static string SaveAsEml(this Outlook.MailItem omi, string fileName = null)
+        /// <returns>True if the message was saved correctly, otherwise false.</returns>
+        public static bool SaveAsEml(this Outlook.MailItem omi, string fileName)
         {
-            MimeMessage message;
-
-            // If no file name was given, create one. Else, validate file name.
-            if (fileName == null)
-            {
-                // Create a randomized file name for the attachment
-                Random random = new Random();
-                string tempPath = Path.GetTempPath();
-                fileName = tempPath + "message" + random.Next(10000) + ".eml";
-                while (File.Exists(fileName))
-                {
-                    fileName = tempPath + "message" + random.Next(10000) + ".eml";
-                }
-            }
-            else if (fileName.EndsWith(".eml") == false)
+            // Validate file name
+            if (fileName.EndsWith(".eml") == false)
             {
                 fileName = null;
-                Log.Error("SaveAsEml: File name has to have EML file ending.");
+                Log.Error("SaveAsEml: File name has to have EML file extension.");
             }
             else
             {
@@ -2418,19 +2426,26 @@
             // If file path is valid, save mail item and return file path
             if (string.IsNullOrEmpty(fileName) == false)
             {
-                try
+                if (MsgConverter.MAPIToMIME(omi, out string mimeMessage))
                 {
-                    message = omi.ToMIMEMessage();
-                    message.WriteTo(fileName);
+                    try
+                    {
+                        File.WriteAllText(fileName, mimeMessage);
+                    }
+                    catch (Exception ex)
+                    {
+                        fileName = null;
+                        Log.Error("SaveAsEml: Error saving mail item to EML file. " + ex.ToString());
+                    }
                 }
-                catch (Exception ex)
+                else
                 {
+                    Log.Error("SaveAsEml: Error converting MAPI message to MIME message.");
                     fileName = null;
-                    Log.Error("SaveAsEml: Error saving mail item to EML file. " + ex.ToString());
                 }
             }
 
-            return fileName;
+            return (string.IsNullOrEmpty(fileName) == false);
         }
 
         /// <summary>
--- a/FPPMessage.cs	Fri Oct 23 11:58:42 2020 +0200
+++ b/FPPMessage.cs	Tue Nov 03 14:04:57 2020 +0100
@@ -1,5 +1,4 @@
 using MimeKit;
-using pEp.UI.Models;
 using pEp.UI.Views;
 using pEpCOMServerAdapterLib;
 using System;
@@ -992,10 +991,9 @@
         /// that has just to be passed through the engine.
         /// </summary>
         /// <param name="omi">The Outlook mail item to process.</param>
-        /// <returns>The status of this method.</returns>
-        public static Globals.ReturnStatus ProcessOutgoing(Outlook.MailItem omi)
+        /// <returns>True if the method succeeded, otherwise false.</returns>
+        public static bool ProcessOutgoing(Outlook.MailItem omi)
         {
-            Globals.ReturnStatus status = Globals.ReturnStatus.Failure;
             bool convertMessage = true;
             Outlook.Attachments attachments = null;
             Outlook.Attachment attachment = null;
@@ -1032,16 +1030,7 @@
             }
 
             // Convert message if necessary
-            if (convertMessage)
-            {
-                status = FPPMessage.ConvertToForcefullyProtected(omi);
-            }
-            else
-            {
-                status = Globals.ReturnStatus.Success;
-            }
-
-            return status;
+            return convertMessage ? FPPMessage.ConvertToForcefullyProtected(omi) : true;
         }
 
 
@@ -1053,9 +1042,9 @@
         /// </summary>
         /// <param name="omi">The Outlook mail item to process with.</param>
         /// <returns>True if the Outlook mail item was converted successfully, otherwise false.</returns>
-        public static Globals.ReturnStatus ConvertToForcefullyProtected(Outlook.MailItem omi)
+        public static bool ConvertToForcefullyProtected(Outlook.MailItem omi)
         {
-            Globals.ReturnStatus status = Globals.ReturnStatus.Failure;
+            bool success = false;
             Outlook.Attachments attachments = null;
             string key = null;
 
@@ -1066,9 +1055,7 @@
                 ///////////////////////////
 
                 // Save message as EML file on disk
-                string messagePath = omi.SaveAsEml();
-
-                if (string.IsNullOrEmpty(messagePath))
+                if (omi.SaveAsEml(out string messagePath) == false)
                 {
                     throw new Exception("Error saving message in EML format");
                 }
@@ -1169,7 +1156,7 @@
                     Log.Error("MailItemExtensions.ConvertToForcefullyProtected: Error deleting original mail from disk. " + ex.ToString());
                 }
 
-                status = Globals.ReturnStatus.Success;
+                success = true;
             }
             catch (Exception ex)
             {
@@ -1180,7 +1167,7 @@
                 attachments = null;
             }
 
-            return status;
+            return success;
         }
         #endregion
     }
--- a/MsgConverter.cs	Fri Oct 23 11:58:42 2020 +0200
+++ b/MsgConverter.cs	Tue Nov 03 14:04:57 2020 +0100
@@ -1,16 +1,14 @@
-
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.ComTypes;
+using System.Text;
+using Outlook = Microsoft.Office.Interop.Outlook;
+
+
 namespace pEp
 {
-    using System;
-    using System.Collections.Generic;
-    using System.Diagnostics;
-    using System.IO;
-    using System.Linq;
-    using System.Runtime.InteropServices;
-    using System.Runtime.InteropServices.ComTypes;
-    using System.Text;
-    using Outlook = Microsoft.Office.Interop.Outlook;
-
     /// <summary>
     /// Helper class to convert attached Messages to standard, internet-readable formats.
     /// </summary>
@@ -28,6 +26,53 @@
             return session;
         }
 
+        /// <summary>
+        /// Converts an Outlook mail item into a MIME message string.
+        /// </summary>
+        /// <param name="omi">The Outlook mail item to convert.</param>
+        /// <param name="mimeMessage">The resulting MIME message string.</param>
+        /// <returns>True if the conversion was successful, otherwise false.</returns>
+        public static bool MAPIToMIME(Outlook.MailItem omi, out string mimeMessage)
+        {
+            mimeMessage = null;
+
+            try
+            {
+                var myStream = new MemoryStreamComMinimalWrapper();
+                IStream iStream = myStream;
+
+                object mapiObject = omi?.MAPIOBJECT;
+                if (mapiObject == null)
+                {
+                    Log.Error("MAPIToMIME: No MAPI object found.");
+                    return false;
+                }
+
+                var mapiMessage = (IMessage)mapiObject;
+
+                IConverterSession session = CreateConverterSession();
+                try
+                {
+                    var hr = session.MAPIToMIMEStm(mapiMessage, iStream, CCSF.SMTP | CCSF.EightBITHEADERS);
+                    Marshal.ThrowExceptionForHR(hr);
+                }
+                finally
+                {
+                    // This COM object is locally scoped, noone else has a reference, so we release it to clean up ressources.
+                    Marshal.FinalReleaseComObject(session);
+                }
+
+                var bytes = myStream.ToArray();
+                mimeMessage = Encoding.ASCII.GetString(bytes);
+            }
+            catch (Exception ex)
+            {
+                Log.Error("MAPIToMIME: Error occured. " + ex.ToString());
+            }
+
+            return (string.IsNullOrEmpty(mimeMessage) == false);
+        }
+
         public static byte[] TryConvertEmbeddedItemToOpenFormat(Outlook.Attachment attachment, ref string fileName, ref string mimeType)
         {
             // Convert an attached embedded item (e. G. "forward as attachment") to an
--- a/ThisAddIn.cs	Fri Oct 23 11:58:42 2020 +0200
+++ b/ThisAddIn.cs	Tue Nov 03 14:04:57 2020 +0100
@@ -2996,7 +2996,7 @@
                         // If ForceProtected, create special mail
                         Log.Info("Application_ItemSend: Sending forcefully protected message.");
 
-                        if (FPPMessage.ProcessOutgoing(omi) == Globals.ReturnStatus.Success)
+                        if (FPPMessage.ProcessOutgoing(omi))
                         {
                             Log.Verbose("Application_ItemSend: Successfully processed outgoing message.");
                         }