Add 'pEp Processing' category and use it to hide messages during processing OUT-507
authorThomas
Wed, 12 Dec 2018 12:33:28 +0100
branchOUT-507
changeset 2501ed057eb9a7c4
parent 2500 3dbf57dc6666
child 2502 d42b3b866648
Add 'pEp Processing' category and use it to hide messages during processing
CryptableMailItem.cs
Extensions/MailItemExtensions.cs
Globals.cs
Mapi.cs
ThisAddIn.cs
     1.1 --- a/CryptableMailItem.cs	Tue Dec 11 11:01:43 2018 +0100
     1.2 +++ b/CryptableMailItem.cs	Wed Dec 12 12:33:28 2018 +0100
     1.3 @@ -1134,7 +1134,7 @@
     1.4                               */
     1.5                              if (accountType != Outlook.OlAccountType.olEas)
     1.6                              {
     1.7 -                                Globals.ThisAddIn.CreatePEPInternalCategory();
     1.8 +                                Globals.ThisAddIn.CreatePEPCategories();
     1.9  
    1.10                                  // Only one category is needed to hide the MailItem -- delete any others
    1.11                                  this.internalMailItem.Categories = Globals.PEP_INTERNAL_CATEGORY_NAME;
    1.12 @@ -1341,9 +1341,9 @@
    1.13                                  }
    1.14                              }
    1.15                          }
    1.16 -                    }
    1.17 +                    }                    
    1.18  
    1.19 -                    if (this.internalMailItem.RemovePEPInternalCategory())
    1.20 +                    if (this.internalMailItem.RemovePEPProcessingCategory())
    1.21                      {
    1.22                          saveInternalMailItem = true;
    1.23                      }
    1.24 @@ -1351,14 +1351,30 @@
    1.25                      // Save internal mail item if necessary
    1.26                      if (saveInternalMailItem)
    1.27                      {
    1.28 +                        bool saveError = false;
    1.29                          try
    1.30                          {
    1.31                              this.internalMailItem.Save();
    1.32                          }
    1.33                          catch (Exception ex)
    1.34                          {
    1.35 +                            saveError = true;
    1.36                              Log.Error("ProcessAndGetRating: Error saving internal mail item. " + ex.ToString());
    1.37                          }
    1.38 +
    1.39 +                        // If an error occured during saving, try to forcefully save
    1.40 +                        if (saveError)
    1.41 +                        {
    1.42 +                            try
    1.43 +                            {
    1.44 +                                int sts = Mapi.ForceSave(this.internalMailItem);
    1.45 +                                Log.Verbose("ProcessAndGetRating: ForceSave returned " + sts.ToString("X"));
    1.46 +                            }
    1.47 +                            catch (Exception ex)
    1.48 +                            {
    1.49 +                                Log.Error("ProcessAndGetRating: Error forcefully saving internal mail item. " + ex.ToString());
    1.50 +                            }
    1.51 +                        }
    1.52                      }
    1.53  
    1.54                      this.Message = processedMessage ?? message;
     2.1 --- a/Extensions/MailItemExtensions.cs	Tue Dec 11 11:01:43 2018 +0100
     2.2 +++ b/Extensions/MailItemExtensions.cs	Wed Dec 12 12:33:28 2018 +0100
     2.3 @@ -1954,10 +1954,10 @@
     2.4          }
     2.5  
     2.6          /// <summary>
     2.7 -        /// Adds the 'pEp Internal' category to a mail item's categories.
     2.8 +        /// Adds the 'pEp Processing' category to a mail item's categories.
     2.9          /// </summary>
    2.10          /// <param name="omi">The Outlook mail item to process with.</param>
    2.11 -        public static void AddPEPInternalCategory(this Outlook.MailItem omi)
    2.12 +        public static void AddPEPProcessingCategory(this Outlook.MailItem omi)
    2.13          {
    2.14              try
    2.15              {
    2.16 @@ -1965,55 +1965,93 @@
    2.17  
    2.18                  if (string.IsNullOrEmpty(categories))
    2.19                  {
    2.20 -                    categories = Globals.PEP_INTERNAL_CATEGORY_NAME;
    2.21 +                    categories = Globals.PEP_PROCESSING_CATEGORY_NAME;
    2.22                  }
    2.23                  else
    2.24                  {
    2.25 -                    categories += Globals.ListDelimiter + Globals.PEP_INTERNAL_CATEGORY_NAME;
    2.26 +                    categories += Globals.ListDelimiter + Globals.PEP_PROCESSING_CATEGORY_NAME;
    2.27                  }
    2.28  
    2.29                  omi.Categories = categories;
    2.30              }
    2.31              catch (Exception ex)
    2.32              {
    2.33 -                Log.Error("AddPEPInternalCategory: Error adding pEp Internal category. " + ex.ToString());
    2.34 +                Log.Error("AddPEPProcessingCategory: Error adding pEp Internal category. " + ex.ToString());
    2.35              }
    2.36          }
    2.37  
    2.38          /// <summary>
    2.39 -        /// Removes the 'pEp Internal' category from the mail item.
    2.40 +        /// Removes the given categories from the mail item.
    2.41          /// </summary>
    2.42          /// <param name="omi">The Outlook mail item to process with.</param>
    2.43 -        /// <param name="removeFromAutoConsume">Whether to remove the category also from an auto consume message.</param>
    2.44 -        /// <returns>True if a category was removed. Otherwise false.</returns>
    2.45 -        public static bool RemovePEPInternalCategory(this Outlook.MailItem omi, bool removeFromAutoConsume = false)
    2.46 +        /// <param name="categories">The categories to remove.</param>
    2.47 +        /// <returns>True if one or more categories have been removed. Otherwise false.</returns>
    2.48 +        public static bool RemoveCategories(this Outlook.MailItem omi, params string[] categories)
    2.49 +        {
    2.50 +            bool categoriesRemoved = false;
    2.51 +
    2.52 +            if (categories?.Length > 0)
    2.53 +            {
    2.54 +                foreach (var category in categories)
    2.55 +                {
    2.56 +                    if (omi.RemoveCategory(category))
    2.57 +                    {
    2.58 +                        categoriesRemoved = true;
    2.59 +                    }
    2.60 +                }
    2.61 +            }
    2.62 +            else
    2.63 +            {
    2.64 +                categoriesRemoved = false;
    2.65 +            }
    2.66 +
    2.67 +            return categoriesRemoved;
    2.68 +        }
    2.69 +
    2.70 +        /// <summary>
    2.71 +        /// Removes the given category from the mail item.
    2.72 +        /// </summary>
    2.73 +        /// <param name="omi">The Outlook mail item to process with.</param>
    2.74 +        /// <param name="category">The category to remove.</param>
    2.75 +        /// <returns>True if the category has been removed. Otherwise false.</returns>
    2.76 +        public static bool RemoveCategory(this Outlook.MailItem omi, string category)
    2.77          {
    2.78              bool categoryRemoved = false;
    2.79  
    2.80              try
    2.81 -            {                
    2.82 -                if ((string.IsNullOrEmpty(omi?.Categories) == false) &&
    2.83 -                    (removeFromAutoConsume || (omi?.GetIsAutoConsume() != true)))
    2.84 +            {
    2.85 +                if (string.IsNullOrEmpty(omi?.Categories) == false)
    2.86                  {
    2.87 -                    List<string> categories = new List<string>(omi.Categories.Split(','));
    2.88 +                    List<string> categories = new List<string>(omi.Categories.Split(Globals.ListDelimiter));
    2.89  
    2.90 -                    if (categories.Exists(a => a.Equals(Globals.PEP_INTERNAL_CATEGORY_NAME)))
    2.91 +                    if (categories.Exists(a => a.Equals(category)))
    2.92                      {
    2.93 -                        categories.Remove(Globals.PEP_INTERNAL_CATEGORY_NAME);
    2.94 -                        omi.Categories = (categories.Count > 0) ? string.Join(",", categories) : null;
    2.95 +                        categories.Remove(category);
    2.96 +                        Mapi.SetMAPIProperties(omi, new MapiProperty.MapiProp[] { MapiProperty.PidLidCategories }, new object[] { categories.ToArray() });
    2.97 +                        omi.Categories = (categories.Count > 0) ? string.Join(Globals.ListDelimiter.ToString(), categories) : null;
    2.98                          categoryRemoved = true;
    2.99                      }
   2.100                  }
   2.101              }
   2.102              catch (Exception ex)
   2.103              {
   2.104 -                Log.Error("RemovePEPInternalCategory: Error removing pEp Internal category. " + ex.ToString());
   2.105 +                Log.Error("RemoveCategory: Error removing category '" + category + "'. " + ex.ToString());
   2.106              }
   2.107  
   2.108              return categoryRemoved;
   2.109          }
   2.110  
   2.111          /// <summary>
   2.112 +        /// Removes the 'pEp Processing' category from the mail item.
   2.113 +        /// </summary>
   2.114 +        /// <param name="omi">The Outlook mail item to process with.</param>
   2.115 +        /// <returns>True if the category has been removed, otherwise false.</returns>
   2.116 +        public static bool RemovePEPProcessingCategory(this Outlook.MailItem omi)
   2.117 +        {
   2.118 +            return omi?.RemoveCategory(Globals.PEP_PROCESSING_CATEGORY_NAME) ?? false;
   2.119 +        }
   2.120 +
   2.121 +        /// <summary>
   2.122          /// Removes the S/MIME encryption and signature flags.
   2.123          /// Note: this method doesn't save the mail item.
   2.124          /// </summary>
     3.1 --- a/Globals.cs	Tue Dec 11 11:01:43 2018 +0100
     3.2 +++ b/Globals.cs	Wed Dec 12 12:33:28 2018 +0100
     3.3 @@ -19,22 +19,23 @@
     3.4      /// </summary>
     3.5      internal sealed partial class Globals
     3.6      {
     3.7 -        public const string CUSTOM_SENT_FOLDER_NAME    = "Sent";
     3.8 -        public const string PEP_INTERNAL_CATEGORY_NAME = "pEp Internal";
     3.9 -        public const string PEP_COPYRIGHT              = "Copyright © 2014-2018 p≡p Security SA, Luxembourg";
    3.10 -        public const string PEP_DATA_FILE_NAME         = "pEp";                           // The file name of the pEp data store. This does NOT include extension (.pst)
    3.11 -        public const string PEP_DISPLAY_NAME           = "p≡p for Outlook";               // Display name to the user
    3.12 -        public const string PEP_DISPLAY_NAME_READER    = "p≡p Reader for Outlook";        // Display name to the user
    3.13 -        public const string PEP_DRAFTS_FOLDER_NAME     = "pEp Drafts";                    // Folder name for secure drafts
    3.14 +        public const string CUSTOM_SENT_FOLDER_NAME         = "Sent";
    3.15 +        public const string PEP_INTERNAL_CATEGORY_NAME      = "pEp Internal";
    3.16 +        public const string PEP_PROCESSING_CATEGORY_NAME    = "pEp Processing";
    3.17 +        public const string PEP_COPYRIGHT                   = "Copyright © 2014-2018 p≡p Security SA, Luxembourg";
    3.18 +        public const string PEP_DATA_FILE_NAME              = "pEp";                           // The file name of the pEp data store. This does NOT include extension (.pst)
    3.19 +        public const string PEP_DISPLAY_NAME                = "p≡p for Outlook";               // Display name to the user
    3.20 +        public const string PEP_DISPLAY_NAME_READER         = "p≡p Reader for Outlook";        // Display name to the user
    3.21 +        public const string PEP_DRAFTS_FOLDER_NAME          = "pEp Drafts";                    // Folder name for secure drafts
    3.22  #if DEBUG
    3.23 -        public const string PEP_NAME_ADDIN_DESC        = "pEp";                           // Description of the add-in within Outlook itself (shared with reader)
    3.24 +        public const string PEP_NAME_ADDIN_DESC             = "pEp";                           // Description of the add-in within Outlook itself (shared with reader)
    3.25  #else
    3.26 -        public const string PEP_NAME_ADDIN_DESC        = "pEp for Outlook";               // Description of the add-in within Outlook itself (shared with reader)
    3.27 +        public const string PEP_NAME_ADDIN_DESC             = "pEp for Outlook";               // Description of the add-in within Outlook itself (shared with reader)
    3.28  #endif
    3.29 -        public const string PEP_NAME_INSTALL           = "pEp for Outlook";               // Name for Windows installer, must sync with installation code (shared with reader)
    3.30 -        public const string PEP_WEBSITE_LINK           = "https://pEp.software";
    3.31 -        public const string PEP_WEBSITE_UPGRADE_LINK   = "https://pEp.software";
    3.32 -        public const string PEP_WEBSITE_READER_LINK    = "https://pEp.security/reader";
    3.33 +        public const string PEP_NAME_INSTALL                = "pEp for Outlook";               // Name for Windows installer, must sync with installation code (shared with reader)
    3.34 +        public const string PEP_WEBSITE_LINK                = "https://pEp.software";
    3.35 +        public const string PEP_WEBSITE_UPGRADE_LINK        = "https://pEp.software";
    3.36 +        public const string PEP_WEBSITE_READER_LINK         = "https://pEp.security/reader";
    3.37  
    3.38  #if READER_RELEASE_MODE
    3.39          public const ReleaseMode RELEASE_MODE = ReleaseMode.Reader;
     4.1 --- a/Mapi.cs	Tue Dec 11 11:01:43 2018 +0100
     4.2 +++ b/Mapi.cs	Wed Dec 12 12:33:28 2018 +0100
     4.3 @@ -740,11 +740,14 @@
     4.4              IntPtr IMAPIProp = IntPtr.Zero;
     4.5  
     4.6              // Structure that will hold the property value
     4.7 -            Mapi.SPropValue propValue;
     4.8 +            Mapi.SPropValue sPropValue;
     4.9  
    4.10              // A pointer that points to the SPropValue structure 
    4.11              IntPtr ptrPropValue = IntPtr.Zero;
    4.12  
    4.13 +            // Pointer to the value
    4.14 +            IntPtr valuePtr = IntPtr.Zero;
    4.15 +
    4.16              // Get MAPI object from mail item
    4.17              object mapiObject = omi?.MAPIOBJECT;
    4.18              if (mapiObject == null)
    4.19 @@ -783,15 +786,148 @@
    4.20                  }
    4.21  
    4.22                  // Create the SPropValue structure
    4.23 -                propValue = new Mapi.SPropValue
    4.24 +                sPropValue = new Mapi.SPropValue
    4.25                  {
    4.26 -                    PropTag = mapiProperty.Tag
    4.27 +                    PropTag = (uint)mapiProperty.Tag
    4.28                  };
    4.29 -                propValue.Value.li = (bool)value ? 1UL : 0UL;
    4.30 +
    4.31 +                // Set the property value's value
    4.32 +                switch (mapiProperty.DataType)
    4.33 +                {
    4.34 +                    case MapiProperty.MapiDataType.PtypBoolean:
    4.35 +                        {
    4.36 +                            try
    4.37 +                            {
    4.38 +                                sPropValue.Value.b = (ushort)Convert.ToInt16((bool)value);
    4.39 +                            }
    4.40 +                            catch (Exception ex)
    4.41 +                            {
    4.42 +                                throw new Exception(string.Format("Error converting to Boolean. Property tag: {0}. Value: {1}. Exception: {2}.", mapiProperty.DaslName, value?.ToString(), ex.ToString()));
    4.43 +                            }
    4.44 +                        }
    4.45 +                        break;
    4.46 +                    case MapiProperty.MapiDataType.PtypString:
    4.47 +                        {
    4.48 +                            try
    4.49 +                            {
    4.50 +                                valuePtr = Marshal.StringToHGlobalUni(value as string);
    4.51 +                                sPropValue.Value.lpszW = valuePtr;
    4.52 +                            }
    4.53 +                            catch (Exception ex)
    4.54 +                            {
    4.55 +                                throw new Exception(string.Format("Error converting to String. Property tag: {0}. Value: {1}. Exception: {2}.", mapiProperty.DaslName, value?.ToString(), ex.ToString()));
    4.56 +                            }
    4.57 +                        }
    4.58 +                        break;
    4.59 +                    case MapiProperty.MapiDataType.PtypString8:
    4.60 +                        {
    4.61 +                            try
    4.62 +                            {
    4.63 +                                valuePtr = Marshal.StringToHGlobalAnsi(value as string);
    4.64 +                                sPropValue.Value.lpszA = valuePtr;
    4.65 +                            }
    4.66 +                            catch (Exception ex)
    4.67 +                            {
    4.68 +                                throw new Exception(string.Format("Error converting to String8. Property tag: {0}. Value: {1}. Exception: {2}.", mapiProperty.DaslName, value?.ToString(), ex.ToString()));
    4.69 +                            }
    4.70 +                        }
    4.71 +                        break;
    4.72 +                    case MapiProperty.MapiDataType.PtypInteger16:
    4.73 +                        {
    4.74 +                            try
    4.75 +                            {
    4.76 +                                sPropValue.Value.i = (short)value;
    4.77 +                            }
    4.78 +                            catch (Exception ex)
    4.79 +                            {
    4.80 +                                throw new Exception(string.Format("Error converting to Short. Property tag: {0}. Value: {1}. Exception: {2}.", mapiProperty.DaslName, value?.ToString(), ex.ToString()));
    4.81 +                            }
    4.82 +                        }
    4.83 +                        break;
    4.84 +                    case MapiProperty.MapiDataType.PtypInteger32:
    4.85 +                        {
    4.86 +                            try
    4.87 +                            {
    4.88 +                                sPropValue.Value.l = (int)value;
    4.89 +                            }
    4.90 +                            catch (Exception ex)
    4.91 +                            {
    4.92 +                                throw new Exception(string.Format("Error converting to Integer. Property tag: {0}. Value: {1}. Exception: {2}.", mapiProperty.DaslName, value?.ToString(), ex.ToString()));
    4.93 +                            }
    4.94 +                        }
    4.95 +                        break;
    4.96 +                    case MapiProperty.MapiDataType.PtypFloating32:
    4.97 +                        {
    4.98 +                            try
    4.99 +                            {
   4.100 +                                sPropValue.Value.flt = (float)value;
   4.101 +                            }
   4.102 +                            catch (Exception ex)
   4.103 +                            {
   4.104 +                                throw new Exception(string.Format("Error converting to Float. Property tag: {0}. Value: {1}. Exception: {2}.", mapiProperty.DaslName, value?.ToString(), ex.ToString()));
   4.105 +                            }
   4.106 +                        }
   4.107 +                        break;
   4.108 +                    case MapiProperty.MapiDataType.PtypFloating64:
   4.109 +                    case MapiProperty.MapiDataType.PtypFloatingTime:
   4.110 +                        {
   4.111 +                            try
   4.112 +                            {
   4.113 +                                sPropValue.Value.at = (double)value;
   4.114 +                            }
   4.115 +                            catch (Exception ex)
   4.116 +                            {
   4.117 +                                throw new Exception(string.Format("Error converting to Double. Property tag: {0}. Value: {1}. Exception: {2}.", mapiProperty.DaslName, value?.ToString(), ex.ToString()));
   4.118 +                            }
   4.119 +                        }
   4.120 +                        break;
   4.121 +                    case MapiProperty.MapiDataType.PtypInteger64:
   4.122 +                        {
   4.123 +                            try
   4.124 +                            {
   4.125 +                                sPropValue.Value.li = (ulong)value;
   4.126 +                            }
   4.127 +                            catch (Exception ex)
   4.128 +                            {
   4.129 +                                throw new Exception(string.Format("Error converting to Ulong. Property tag: {0}. Value: {1}. Exception: {2}.", mapiProperty.DaslName, value?.ToString(), ex.ToString()));
   4.130 +                            }
   4.131 +                        }
   4.132 +                        break;
   4.133 +                    case MapiProperty.MapiDataType.PtypGuid:
   4.134 +                        {
   4.135 +                            try
   4.136 +                            {
   4.137 +                                IntPtr guidPtr = Marshal.AllocHGlobal(Marshal.SizeOf(value));
   4.138 +                                Marshal.StructureToPtr((Guid)value, guidPtr, false);
   4.139 +                                sPropValue.Value.lpguid = guidPtr;
   4.140 +                            }
   4.141 +                            catch (Exception ex)
   4.142 +                            {
   4.143 +                                throw new Exception(string.Format("Error converting to Guid. Property tag: {0}. Value: {1}. Exception: {2}.", mapiProperty.DaslName, value?.ToString(), ex.ToString()));
   4.144 +                            }
   4.145 +                        }
   4.146 +                        break;
   4.147 +                    case MapiProperty.MapiDataType.PtypBinary:
   4.148 +                        {
   4.149 +                            try
   4.150 +                            {
   4.151 +                                sPropValue.Value.bin = (Mapi.SRowSet)value;
   4.152 +                            }
   4.153 +                            catch (Exception ex)
   4.154 +                            {
   4.155 +                                throw new Exception(string.Format("Error converting to Binary. Property tag: {0}. Value: {1}. Exception: {2}.", mapiProperty.DaslName, value?.ToString(), ex.ToString()));
   4.156 +                            }
   4.157 +                        }
   4.158 +                        break;                    
   4.159 +                    default:
   4.160 +                        {
   4.161 +                            throw new Exception(string.Format("Error creating SPropValue. Data type {0} not supported.", Enum.GetName(typeof(MapiProperty.MapiDataType), mapiProperty.DataType)));
   4.162 +                        }
   4.163 +                }
   4.164  
   4.165                  // Get pointer to property value structure
   4.166 -                ptrPropValue = Marshal.AllocHGlobal(Marshal.SizeOf(propValue));
   4.167 -                Marshal.StructureToPtr(propValue, ptrPropValue, false);
   4.168 +                ptrPropValue = Marshal.AllocHGlobal(Marshal.SizeOf(sPropValue));
   4.169 +                Marshal.StructureToPtr(sPropValue, ptrPropValue, false);
   4.170  
   4.171                  // Try to set the property
   4.172                  NativeMethods.HrSetOneProp(IMAPIProp, ptrPropValue);
   4.173 @@ -834,6 +970,66 @@
   4.174  
   4.175              return success;
   4.176          }
   4.177 +
   4.178 +        /// <summary>
   4.179 +        /// Calls SaveChanges() with the FORCE_SAVE flag.
   4.180 +        /// </summary>
   4.181 +        /// <param name="omi">The Outlook mail item to save.</param>
   4.182 +        /// <returns>The status of this method.</returns>
   4.183 +        public static int ForceSave(Outlook.MailItem omi)
   4.184 +        {
   4.185 +            int status = (int)Mapi.HResult.S_FALSE;
   4.186 +
   4.187 +            // Pointer to IUnknown interface
   4.188 +            IntPtr IUnknown = IntPtr.Zero;
   4.189 +
   4.190 +            // A pointer that points to the SPropValue structure 
   4.191 +            IntPtr ptrPropValue = IntPtr.Zero;
   4.192 +
   4.193 +            // Get MAPI object from mail item
   4.194 +            object mapiObject = omi?.MAPIOBJECT;
   4.195 +            if (mapiObject == null)
   4.196 +            {
   4.197 +                Log.Error("SetMAPIProperty: MAPI object is null. Property could not be set.");
   4.198 +                return status;
   4.199 +            }
   4.200 +
   4.201 +            try
   4.202 +            {
   4.203 +                // Initialize MAPI
   4.204 +                NativeMethods.MAPIInitialize(IntPtr.Zero);
   4.205 +
   4.206 +                // Get the IUnknown interface from the MAPI object
   4.207 +                IUnknown = Marshal.GetIUnknownForObject(mapiObject);
   4.208 +
   4.209 +                // Save changes
   4.210 +                Mapi.IMAPIProp mapiProp = (Mapi.IMAPIProp)Marshal.GetTypedObjectForIUnknown(IUnknown, typeof(Mapi.IMAPIProp));
   4.211 +                status = mapiProp.SaveChanges(Mapi.SaveOptions.FORCE_SAVE);
   4.212 +            }
   4.213 +            catch (Exception ex)
   4.214 +            {
   4.215 +                Log.Error("SetMAPIProperty: Error occured. " + ex.ToString());
   4.216 +                status = (int)Mapi.HResult.S_FALSE;
   4.217 +            }
   4.218 +            finally
   4.219 +            {
   4.220 +                // Free used memory structures
   4.221 +                if (ptrPropValue != IntPtr.Zero)
   4.222 +                {
   4.223 +                    NativeMethods.MAPIFreeBuffer(ptrPropValue);
   4.224 +                }
   4.225 +
   4.226 +                // Clean up all references to COM Objects
   4.227 +                if (IUnknown != IntPtr.Zero)
   4.228 +                {
   4.229 +                    Marshal.Release(IUnknown);
   4.230 +                }
   4.231 +
   4.232 +                NativeMethods.MAPIUninitialize();
   4.233 +            }
   4.234 +
   4.235 +            return status;
   4.236 +        }
   4.237          #endregion
   4.238      }
   4.239  }
     5.1 --- a/ThisAddIn.cs	Tue Dec 11 11:01:43 2018 +0100
     5.2 +++ b/ThisAddIn.cs	Wed Dec 12 12:33:28 2018 +0100
     5.3 @@ -1227,7 +1227,7 @@
     5.4                  // Un/set rules and view filters if necessary
     5.5                  if (state.HideInternalMessages != this._Settings.HideInternalMessages)
     5.6                  {
     5.7 -                    this.SetRulesAndViewFilters(state.HideInternalMessages);
     5.8 +                    this.SetRules(state.HideInternalMessages);
     5.9                  }
    5.10                  this._Settings.HideInternalMessages = state.HideInternalMessages;
    5.11  
    5.12 @@ -1980,7 +1980,7 @@
    5.13                                      // Action: assign "pEp internal" category
    5.14                                      try
    5.15                                      {
    5.16 -                                        if (this.CreatePEPInternalCategory() == false)
    5.17 +                                        if (this.CreatePEPCategories() == false)
    5.18                                          {
    5.19                                              categoriesSet = false;
    5.20                                          }
    5.21 @@ -2160,15 +2160,19 @@
    5.22                                          if (account.AccountType == Outlook.OlAccountType.olImap)
    5.23                                          {
    5.24                                              // (1) Hide any deleted IMAP items http://schemas.microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/85700003 = 0
    5.25 -                                            // (2) Hide 'pEp internal' category items
    5.26 +                                            // (2) Hide 'pEp internal' and "pEp processing' category items
    5.27                                              view.Filter = "(\"" + MapiProperty.PidLidImapMarkedForDeletion.DaslName + "\" = 0" +
    5.28                                                            " AND " +
    5.29 -                                                          "\"urn:schemas-microsoft-com:office:office#Keywords\" <> '" + Globals.PEP_INTERNAL_CATEGORY_NAME + "')";
    5.30 +                                                          "\"urn:schemas-microsoft-com:office:office#Keywords\" <> '" + Globals.PEP_INTERNAL_CATEGORY_NAME + "'" +
    5.31 +                                                          " AND " +
    5.32 +                                                          "\"urn:schemas-microsoft-com:office:office#Keywords\" <> '" + Globals.PEP_PROCESSING_CATEGORY_NAME + "')";
    5.33                                          }
    5.34                                          else
    5.35                                          {
    5.36 -                                            // Hide 'pEp internal' category items
    5.37 -                                            view.Filter = "(\"urn:schemas-microsoft-com:office:office#Keywords\" <> '" + Globals.PEP_INTERNAL_CATEGORY_NAME + "')";
    5.38 +                                            // Hide 'pEp internal' and "pEp processing' category items
    5.39 +                                            view.Filter = "(\"urn:schemas-microsoft-com:office:office#Keywords\" <> '" + Globals.PEP_INTERNAL_CATEGORY_NAME + "'" +
    5.40 +                                                          " AND " +
    5.41 +                                                          "\"urn:schemas-microsoft-com:office:office#Keywords\" <> '" + Globals.PEP_PROCESSING_CATEGORY_NAME + "')";
    5.42                                          }
    5.43  
    5.44                                          if ((currentViewName != null) &&
    5.45 @@ -2303,10 +2307,10 @@
    5.46          /// <summary>
    5.47          /// Creates the pEp internal category for the specified account's store unless it already exists.
    5.48          /// </summary>
    5.49 -        internal bool CreatePEPInternalCategory(Outlook.Store deliveryStore)
    5.50 +        internal bool CreatePEPCategories(Outlook.Store deliveryStore)
    5.51          {
    5.52 -            bool exists = false;
    5.53 -            bool success = false;
    5.54 +            bool pEpInternalExists = false;
    5.55 +            bool pEpProcessingExists = false;
    5.56              Outlook.Category category = null;
    5.57              Outlook.Categories categories = null;
    5.58  
    5.59 @@ -2316,28 +2320,36 @@
    5.60                  {
    5.61                      categories = deliveryStore.Categories;
    5.62  
    5.63 -                    // Check if the category already exists
    5.64 +                    // Check if the categories already exists
    5.65                      for (int i = 1; i <= categories?.Count; i++)
    5.66                      {
    5.67                          category = categories[i];
    5.68  
    5.69 -                        if (string.Equals(category?.Name, Globals.PEP_INTERNAL_CATEGORY_NAME, StringComparison.OrdinalIgnoreCase))
    5.70 +                        if (category?.Name?.Equals(Globals.PEP_INTERNAL_CATEGORY_NAME, StringComparison.OrdinalIgnoreCase) == true)
    5.71                          {
    5.72 -                            exists = true;
    5.73 -                            success = true;
    5.74 +                            pEpInternalExists = true;
    5.75 +                        }
    5.76 +                        else if (category?.Name?.Equals(Globals.PEP_PROCESSING_CATEGORY_NAME, StringComparison.OrdinalIgnoreCase) == true)
    5.77 +                        {
    5.78 +                            pEpProcessingExists = true;
    5.79 +                        }
    5.80 +
    5.81 +                        category = null;
    5.82 +
    5.83 +                        if (pEpInternalExists &&
    5.84 +                            pEpProcessingExists)
    5.85 +                        {
    5.86                              break;
    5.87                          }
    5.88 -
    5.89 -                        category = null;
    5.90                      }
    5.91                  }
    5.92                  catch (Exception ex)
    5.93                  {
    5.94 -                    Log.Error("CreatePEPInternalCategory: Error checking if category exists. " + ex.ToString());
    5.95 -                    success = false;
    5.96 +                    Log.Error("CreatePEPCategories: Error checking if category exists. " + ex.ToString());
    5.97  
    5.98                      // Just try to create it anyway, this will throw an exception if it already exists
    5.99 -                    exists = false;
   5.100 +                    pEpInternalExists = false;
   5.101 +                    pEpProcessingExists = false;
   5.102                  }
   5.103                  finally
   5.104                  {
   5.105 @@ -2345,36 +2357,53 @@
   5.106                      categories = null;
   5.107                  }
   5.108  
   5.109 -                // If category was not found, create and add it to account master list
   5.110 -                if (exists == false)
   5.111 +                // If a category was not found, create and add it to account master list
   5.112 +                if (pEpInternalExists == false)
   5.113                  {
   5.114                      try
   5.115                      {
   5.116                          // Add category
   5.117                          categories = deliveryStore.Categories;
   5.118                          categories?.Add(Globals.PEP_INTERNAL_CATEGORY_NAME, Outlook.OlCategoryColor.olCategoryColorDarkGreen);
   5.119 -                        success = true;
   5.120 +                        pEpInternalExists = true;
   5.121                      }
   5.122                      catch (Exception ex)
   5.123                      {
   5.124 -                        Log.Error("CreatePEPInternalCategory: Error checking if category exists. " + ex.ToString());
   5.125 -                        success = false;
   5.126 +                        Log.Error("CreatePEPCategories: Error setting pEp Internal category. " + ex.ToString());
   5.127                      }
   5.128                      finally
   5.129                      {
   5.130                          categories = null;
   5.131                      }
   5.132 -
   5.133 +                }
   5.134 +
   5.135 +                if (pEpProcessingExists == false)
   5.136 +                {
   5.137 +                    try
   5.138 +                    {
   5.139 +                        // Add category
   5.140 +                        categories = deliveryStore.Categories;
   5.141 +                        categories?.Add(Globals.PEP_PROCESSING_CATEGORY_NAME, Outlook.OlCategoryColor.olCategoryColorDarkGreen);
   5.142 +                        pEpProcessingExists = true;
   5.143 +                    }
   5.144 +                    catch (Exception ex)
   5.145 +                    {
   5.146 +                        Log.Error("CreatePEPCategories: Error settising pEp Processing. " + ex.ToString());
   5.147 +                    }
   5.148 +                    finally
   5.149 +                    {
   5.150 +                        categories = null;
   5.151 +                    }
   5.152                  }
   5.153              }
   5.154  
   5.155 -            return success;
   5.156 +            return (pEpInternalExists && pEpProcessingExists);
   5.157          }
   5.158  
   5.159          /// <summary>
   5.160          /// Creates the pEp internal category in Outlook for all accounts.
   5.161          /// </summary>
   5.162 -        internal bool CreatePEPInternalCategory()
   5.163 +        internal bool CreatePEPCategories()
   5.164          {
   5.165              bool success = true;
   5.166              Outlook.Account account = null;
   5.167 @@ -2395,16 +2424,15 @@
   5.168                          account = accounts[i];
   5.169  
   5.170                          // If the account doesn't have pEp enabled, don't create category
   5.171 -                        if ((account?.GetIsPEPEnabled() ?? false) || (account?.GetIsDecryptAlwaysEnabled() ?? false))
   5.172 +                        if ((account?.GetIsPEPEnabled() != true) || (account?.GetIsDecryptAlwaysEnabled() != true))
   5.173                          {
   5.174                              deliveryStore = account?.DeliveryStore;
   5.175 -                            if (deliveryStore != null)
   5.176 +                            if ((deliveryStore == null) ||
   5.177 +                                (this.CreatePEPCategories(deliveryStore) == false))
   5.178                              {
   5.179 -                                if (this.CreatePEPInternalCategory(deliveryStore) == false)
   5.180 -                                {
   5.181 -                                    success = false;
   5.182 -                                }
   5.183 +                                success = false;
   5.184                              }
   5.185 +                            deliveryStore = null;
   5.186                          }
   5.187                      }
   5.188                      catch (Exception ex)
   5.189 @@ -2692,6 +2720,9 @@
   5.190                      // Initialize inbox cleaning timer
   5.191                      this.ToggleInboxCleaning(true);
   5.192  
   5.193 +                    // Create the 'pEp Internal' and 'pEp Processing' categories
   5.194 +                    this.CreatePEPCategories();
   5.195 +
   5.196                      // Initialization complete
   5.197                      Log.Info("ThisAddIn_Startup: Main program started.");
   5.198                      this.initialized = true;
   5.199 @@ -2982,7 +3013,7 @@
   5.200          {
   5.201              deletedMessages = 0;
   5.202              foundMessages = 0;
   5.203 -            const string searchFilter = "[Categories] ='" + Globals.PEP_INTERNAL_CATEGORY_NAME + "'";
   5.204 +            const string searchFilter = "[Categories] ='" + Globals.PEP_INTERNAL_CATEGORY_NAME + "' Or [Categories] ='" + Globals.PEP_PROCESSING_CATEGORY_NAME + "'";
   5.205              Outlook.Items inboxItems = null;
   5.206              Outlook.Items filteredInboxItems = null;
   5.207              Outlook.MailItem mailItem = null;
   5.208 @@ -3016,7 +3047,6 @@
   5.209                                      Log.Verbose("CleanFolder: Processing 'pEp Internal' item " + j + "...");
   5.210  
   5.211                                      // Check if auto consume message and delete if timed out or delete pEp Internal category
   5.212 -                                    bool removeInternalCategory = false;
   5.213                                      if (mailItem.GetIsAutoConsume())
   5.214                                      {
   5.215                                          if (DateTime.UtcNow - (mailItem.ReceivedTime.ToUniversalTime()) > TimeSpan.FromMilliseconds(Globals.TIMEOUT_SYNC_MESSAGE))
   5.216 @@ -3026,19 +3056,18 @@
   5.217                                          }
   5.218                                          else if (Globals.ThisAddIn.Settings.HideInternalMessages == false)
   5.219                                          {
   5.220 -                                            removeInternalCategory = true;
   5.221 +                                            if (mailItem.RemoveCategories(Globals.PEP_INTERNAL_CATEGORY_NAME, Globals.PEP_PROCESSING_CATEGORY_NAME))
   5.222 +                                            {
   5.223 +                                                mailItem.Save();
   5.224 +                                            }
   5.225                                          }
   5.226                                      }
   5.227                                      else
   5.228                                      {
   5.229 -                                        removeInternalCategory = true;
   5.230 -                                    }
   5.231 -
   5.232 -                                    // Remove pEp Internal category if needed
   5.233 -                                    if (removeInternalCategory &&
   5.234 -                                        mailItem.RemovePEPInternalCategory(true))
   5.235 -                                    {
   5.236 -                                        mailItem.Save();
   5.237 +                                        if (mailItem.RemovePEPProcessingCategory())
   5.238 +                                        {
   5.239 +                                            mailItem.Save();
   5.240 +                                        }
   5.241                                      }
   5.242                                  }
   5.243  
   5.244 @@ -3851,7 +3880,7 @@
   5.245                              // If potentially encrypted message, hide during processing
   5.246                              if (omi?.Attachments?.Count == 2)
   5.247                              {
   5.248 -                                omi.AddPEPInternalCategory();
   5.249 +                                omi.AddPEPProcessingCategory();
   5.250                                  omi.Save();
   5.251                              }
   5.252  
   5.253 @@ -3863,6 +3892,10 @@
   5.254                  {
   5.255                      Log.Error("Items_ItemAdd. Error occured. " + ex.ToString());
   5.256                  }
   5.257 +                finally
   5.258 +                {
   5.259 +                    omi = null;
   5.260 +                }
   5.261              }
   5.262  
   5.263              /// <summary>