--- a/Extensions/MailItemExtensions.cs Tue Mar 05 14:45:53 2019 +0100
+++ b/Extensions/MailItemExtensions.cs Mon Mar 25 13:27:16 2019 +0100
@@ -367,214 +367,228 @@
Outlook.MailItem mirror = null;
Outlook.Folder folder = omi.GetMirrorFolder();
- /* If S/MIME is enabled by default, the mirror creation by new mail item fails during the
- * Save() method.
- */
- if ((Globals.ThisAddIn.OutlookOptions.IsSMIMEEnabled == false) &&
- (omi.GetIsSMIMEEnabled() == false))
+ try
{
+ Log.Verbose("CreateMirrorOMI: Creating by new mail item.");
+
+ // Try to create the new mail item directly in the pEp store
+ Outlook.Application application = null;
+ try
+ {
+ mirror = (Outlook.MailItem)folder.Items.Add(Outlook.OlItemType.olMailItem);
+ }
+ catch (Exception ex)
+ {
+ // If this fails, log the error and try to create the item with backup method
+ Log.Warning("CreateMirrorOMI: Error creating mirror via Items.ItemAdd. " + ex.ToString());
+
+ // If backup fails, let error get thrown out to outer catch
+ application = Globals.ThisAddIn.Application;
+ mirror = application.CreateItem(Outlook.OlItemType.olMailItem);
+ Log.Verbose("CreateMirrorOMI: mail item successfully created via backup method 1.");
+ }
+ finally
+ {
+ application = null;
+ }
+
+ // Set the mirror as read
+ mirror.UnRead = false;
+
+ try
+ {
+ MapiHelper.SetProperty(mirror, MapiProperty.PidTagMessageDeliveryTime, omi.ReceivedTime.ToUniversalTime());
+ MapiHelper.SetProperty(mirror, MapiProperty.PidTagClientSubmitTime, omi.SentOn.ToUniversalTime());
+ }
+ catch (Exception ex)
+ {
+ Log.Verbose("CreateMirrorOMI: Failed to set received and sent time. " + ex.ToString());
+ throw;
+ }
+
+ // Attempt to set sender information
+ try
+ {
+ mirror.Sender = omi.Sender;
+ }
+ catch (Exception ex)
+ {
+ Log.Verbose("CreateMirrorOMI: Failed to set sender directly. " + ex.ToString());
+ }
+
+ try
+ {
+ MapiHelper.SetProperty(mirror, MapiProperty.PidTagSenderName, omi.SenderName);
+ MapiHelper.SetProperty(mirror, MapiProperty.PidTagSenderEmailAddress, omi.SenderEmailAddress);
+
+ // Entry ID is needed to resolve the sender so a reply is possible without having to re-enter address, this is last in case it fails
+ MapiHelper.SetProperty(mirror, MapiProperty.PidTagSenderEntryId, MapiHelper.GetProperty(omi, MapiProperty.PidTagSenderEntryId));
+ }
+ catch (Exception ex)
+ {
+ Log.Verbose("CreateMirrorOMI: Failed to set sender through MAPI properties. " + ex.ToString());
+ throw;
+ }
+
+ try
+ {
+ mirror.SendUsingAccount = omi.SendUsingAccount;
+ }
+ catch (Exception ex)
+ {
+ Log.Verbose("CreateMirrorOMI: Failed to set SendUsingAccount. " + ex.ToString());
+ }
+
+ // Set flags
+ messageFlags = (System.Int32)MapiHelper.GetProperty(mirror, MapiProperty.PidTagMessageFlags);
+ messageFlags &= ~((System.Int32)MapiPropertyValue.EnumPidTagMessageFlags.mfUnsent); // Clear UNSENT flag -- must be done before save
+ messageFlags |= ((System.Int32)MapiPropertyValue.EnumPidTagMessageFlags.mfRead); // Mark as read
try
{
- Log.Verbose("CreateMirrorOMI: Creating by new mail item.");
-
- mirror = (Outlook.MailItem)folder.Items.Add(Outlook.OlItemType.olMailItem);
- mirror.UnRead = false;
-
- // Set received and sent time
- try
- {
- MapiHelper.SetProperty(mirror, MapiProperty.PidTagMessageDeliveryTime, omi.ReceivedTime.ToUniversalTime());
- MapiHelper.SetProperty(mirror, MapiProperty.PidTagClientSubmitTime, omi.SentOn.ToUniversalTime());
- }
- catch (Exception ex)
- {
- Log.Verbose("CreateMirrorOMI: Failed to set received and sent time. " + ex.ToString());
- throw;
- }
-
- // Attempt to set sender information
- try
- {
- mirror.Sender = omi.Sender;
- }
- catch (Exception ex)
- {
- Log.Verbose("CreateMirrorOMI: Failed to set sender directly. " + ex.ToString());
- }
-
- try
- {
- MapiHelper.SetProperty(mirror, MapiProperty.PidTagSenderName, omi.SenderName);
- MapiHelper.SetProperty(mirror, MapiProperty.PidTagSenderEmailAddress, omi.SenderEmailAddress);
-
- // Entry ID is needed to resolve the sender so a reply is possible without having to re-enter address, this is last in case it fails
- MapiHelper.SetProperty(mirror, MapiProperty.PidTagSenderEntryId, MapiHelper.GetProperty(omi, MapiProperty.PidTagSenderEntryId));
- }
- catch (Exception ex)
+ MapiHelper.SetProperty(mirror, MapiProperty.PidTagMessageFlags, messageFlags);
+ }
+ catch (Exception ex)
+ {
+ Log.Verbose("CreateMirrorOMI: Failed to set message flags. " + ex.ToString());
+ }
+
+ // Conversation information
+ try
+ {
+ /* Note: PidTagConversationId cannot be set even through the MAPI accessor.
+ * This is by design since this property is computed automatically from other properties.
+ * See: https://msdn.microsoft.com/en-us/library/ee204279.aspx
+ */
+
+ str = omi.ConversationIndex;
+ bytes = MapiHelper.StringToPtypBinary(str);
+ if (bytes?.Length > 0)
{
- Log.Verbose("CreateMirrorOMI: Failed to set sender through MAPI properties. " + ex.ToString());
- throw;
- }
-
- try
- {
- mirror.SendUsingAccount = omi.SendUsingAccount;
+ MapiHelper.SetProperty(mirror, MapiProperty.PidTagConversationIndex, bytes);
}
- catch (Exception ex)
- {
- Log.Verbose("CreateMirrorOMI: Failed to set SendUsingAccount. " + ex.ToString());
- }
-
- // Set flags
- messageFlags = (System.Int32)MapiHelper.GetProperty(mirror, MapiProperty.PidTagMessageFlags);
- messageFlags &= ~((System.Int32)MapiPropertyValue.EnumPidTagMessageFlags.mfUnsent); // Clear UNSENT flag -- must be done before save
- messageFlags |= ((System.Int32)MapiPropertyValue.EnumPidTagMessageFlags.mfRead); // Mark as read
- try
+
+ MapiHelper.SetProperty(mirror, MapiProperty.PidTagConversationIndexTracking, true);
+ MapiHelper.SetProperty(mirror, MapiProperty.PidTagConversationTopic, omi.ConversationTopic);
+ }
+ catch (Exception ex)
+ {
+ Log.Verbose("CreateMirrorOMI: Failed to set conversation information. " + ex.ToString());
+ }
+
+ // Remove S/MIME flags if necessary
+ mirror.RemoveSMIMEFlags();
+
+ mirror.To = omi.To;
+ mirror.CC = omi.CC;
+ mirror.BCC = omi.BCC;
+ mirror.Subject = omi.Subject;
+ mirror.Body = string.Empty;
+ mirror.Save();
+
+ /* Set all received-by information
+ *
+ * This must be stored as a user-property because settings MAPI properties such as "PR_RECEIVED_BY_EMAIL_ADDRESS"
+ * is not supported by Outlook. The user-properties are named the same as the MAPI property for simplicity.
+ *
+ * In most situations the received-by information will not be needed.
+ * Decryption for example uses the recipients/identities in the original mail item itself.
+ * However, the GetMyIdentity(omi) method requires this information in some cases:
+ * • The true 'myself' identity of a mail item is not an account registerd in Outlook. This can happen
+ * using aliases or when forwarding emails from another account.
+ * • This is primarily needed when displaying mirrors themselves then opening the handshake dialog.
+ */
+ try
+ {
+ /* Get the "received by" email address. In case this returns an internal X500 Exchange address ("/O=DOMAIN/OU=EXCHANGE ADMINISTRATIVE GROUP..."),
+ * compare it with the recipients' addresses and take the primary SMTP address.
+ */
+ string email = MapiHelper.GetProperty(omi, MapiProperty.PidTagReceivedByEmailAddress) as string;
+ if (email.StartsWith("/O"))
{
- MapiHelper.SetProperty(mirror, MapiProperty.PidTagMessageFlags, messageFlags);
- }
- catch (Exception ex)
- {
- Log.Verbose("CreateMirrorOMI: Failed to set message flags. " + ex.ToString());
- }
-
- // Conversation information
- try
- {
- /* Note: PidTagConversationId cannot be set even through the MAPI accessor.
- * This is by design since this property is computed automatically from other properties.
- * See: https://msdn.microsoft.com/en-us/library/ee204279.aspx
- */
-
- str = omi.ConversationIndex;
- bytes = MapiHelper.StringToPtypBinary(str);
- if (bytes?.Length > 0)
+ Outlook.Recipients recipients = null;
+ Outlook.Recipient recipient = null;
+ Outlook.AddressEntry addressEntry = null;
+ Outlook.ExchangeUser exchangeUser = null;
+
+ try
{
- MapiHelper.SetProperty(mirror, MapiProperty.PidTagConversationIndex, bytes);
- }
-
- MapiHelper.SetProperty(mirror, MapiProperty.PidTagConversationIndexTracking, true);
- MapiHelper.SetProperty(mirror, MapiProperty.PidTagConversationTopic, omi.ConversationTopic);
- }
- catch (Exception ex)
- {
- Log.Verbose("CreateMirrorOMI: Failed to set conversation information. " + ex.ToString());
- }
-
- // Remove S/MIME flags if necessary
- mirror.RemoveSMIMEFlags();
-
- mirror.To = omi.To;
- mirror.CC = omi.CC;
- mirror.BCC = omi.BCC;
- mirror.Subject = omi.Subject;
- mirror.Body = string.Empty;
- mirror.Save();
-
- /* Set all received-by information
- *
- * This must be stored as a user-property because settings MAPI properties such as "PR_RECEIVED_BY_EMAIL_ADDRESS"
- * is not supported by Outlook. The user-properties are named the same as the MAPI property for simplicity.
- *
- * In most situations the received-by information will not be needed.
- * Decryption for example uses the recipients/identities in the original mail item itself.
- * However, the GetMyIdentity(omi) method requires this information in some cases:
- * • The true 'myself' identity of a mail item is not an account registerd in Outlook. This can happen
- * using aliases or when forwarding emails from another account.
- * • This is primarily needed when displaying mirrors themselves then opening the handshake dialog.
- */
- try
- {
- /* Get the "received by" email address. In case this returns an internal X500 Exchange address ("/O=DOMAIN/OU=EXCHANGE ADMINISTRATIVE GROUP..."),
- * compare it with the recipients' addresses and take the primary SMTP address.
- */
- string email = MapiHelper.GetProperty(omi, MapiProperty.PidTagReceivedByEmailAddress) as string;
- if (email.StartsWith("/O"))
- {
- Outlook.Recipients recipients = null;
- Outlook.Recipient recipient = null;
- Outlook.AddressEntry addressEntry = null;
- Outlook.ExchangeUser exchangeUser = null;
-
- try
+ recipients = omi.Recipients;
+
+ for (int i = 1; i <= recipients.Count; i++)
{
- recipients = omi.Recipients;
-
- for (int i = 1; i <= recipients.Count; i++)
+ recipient = recipients[i];
+ addressEntry = recipient?.AddressEntry;
+ exchangeUser = addressEntry?.GetExchangeUser();
+
+ if (email.ToUpperInvariant().Equals(exchangeUser?.Address?.ToUpperInvariant()))
{
- recipient = recipients[i];
- addressEntry = recipient?.AddressEntry;
- exchangeUser = addressEntry?.GetExchangeUser();
-
- if (email.ToUpperInvariant().Equals(exchangeUser?.Address?.ToUpperInvariant()))
- {
- email = exchangeUser?.PrimarySmtpAddress;
- break;
- }
-
- recipient = null;
- addressEntry = null;
- exchangeUser = null;
+ email = exchangeUser?.PrimarySmtpAddress;
+ break;
}
- }
- catch (Exception ex)
- {
- Log.Error("CreateMirrorOMI: Error getting ReceivedByEmailAddress. " + ex.ToString());
- }
- finally
- {
- recipients = null;
+
recipient = null;
addressEntry = null;
exchangeUser = null;
}
}
- mirror.SetUserProperty(MapiProperty.PidTagReceivedByEmailAddress.DaslName, email,
- Outlook.OlUserPropertyType.olText);
- mirror.SetUserProperty(MapiProperty.PidTagReceivedByName.DaslName,
- MapiHelper.GetProperty(omi, MapiProperty.PidTagReceivedByName),
- Outlook.OlUserPropertyType.olText);
- }
- catch (Exception ex)
- {
- Log.Verbose("CreateMirrorOMI: Failed to set received-by information. " + ex.ToString());
+ catch (Exception ex)
+ {
+ Log.Error("CreateMirrorOMI: Error getting ReceivedByEmailAddress. " + ex.ToString());
+ }
+ finally
+ {
+ recipients = null;
+ recipient = null;
+ addressEntry = null;
+ exchangeUser = null;
+ }
}
-
- // Mark the mail item as a mirror
- mirror.SetUserProperty(MailItemExtensions.USER_PROPERTY_KEY_IS_MIRROR, true, Outlook.OlUserPropertyType.olYesNo);
-
- /* Set the incoming status of the new mail item.
- * This is necessary because manually setting the PR_RECEIVED_BY_ENTRYID fails if called by user code.
- * PR_RECEIVED_BY_ENTRYID is only set when copying the original mail item.
- */
- if (omi.GetIsIncoming())
- {
- mirror.SetUserProperty(MailItemExtensions.USER_PROPERTY_KEY_IS_INCOMING, true, Outlook.OlUserPropertyType.olYesNo);
- }
- else
- {
- mirror.SetUserProperty(MailItemExtensions.USER_PROPERTY_KEY_IS_INCOMING, false, Outlook.OlUserPropertyType.olYesNo);
- }
-
- // Add the original EntryID or the messageId if the latter has been passed
- mirror.SetUserProperty(MailItemExtensions.USER_PROPERTY_KEY_ORIG_ENTRY_ID, messageId ?? omi.EntryID);
- mirror.Save();
-
- // Move the mirror copy to the correct folder
- // This is needed as some account-types/office versions will still create a mail item in the default folder
- // even if folder.Items.Add is used to specify a location.
- // WARNING: this creates a new mail item that will no longer be referenced here!!
- mirror.Move(folder);
- created = true;
+ mirror.SetUserProperty(MapiProperty.PidTagReceivedByEmailAddress.DaslName, email,
+ Outlook.OlUserPropertyType.olText);
+ mirror.SetUserProperty(MapiProperty.PidTagReceivedByName.DaslName,
+ MapiHelper.GetProperty(omi, MapiProperty.PidTagReceivedByName),
+ Outlook.OlUserPropertyType.olText);
}
catch (Exception ex)
{
- Log.Verbose("CreateMirrorOMI: Creating new mail item failed. " + ex.ToString());
- mirror.PermanentlyDelete();
- mirror = null;
+ Log.Verbose("CreateMirrorOMI: Failed to set received-by information. " + ex.ToString());
+ }
+
+ // Mark the mail item as a mirror
+ mirror.SetUserProperty(MailItemExtensions.USER_PROPERTY_KEY_IS_MIRROR, true, Outlook.OlUserPropertyType.olYesNo);
+
+ /* Set the incoming status of the new mail item.
+ * This is necessary because manually setting the PR_RECEIVED_BY_ENTRYID fails if called by user code.
+ * PR_RECEIVED_BY_ENTRYID is only set when copying the original mail item.
+ */
+ if (omi.GetIsIncoming())
+ {
+ mirror.SetUserProperty(MailItemExtensions.USER_PROPERTY_KEY_IS_INCOMING, true, Outlook.OlUserPropertyType.olYesNo);
+ }
+ else
+ {
+ mirror.SetUserProperty(MailItemExtensions.USER_PROPERTY_KEY_IS_INCOMING, false, Outlook.OlUserPropertyType.olYesNo);
}
+
+ // Add the original EntryID or the messageId if the latter has been passed
+ mirror.SetUserProperty(MailItemExtensions.USER_PROPERTY_KEY_ORIG_ENTRY_ID, messageId ?? omi.EntryID);
+ mirror.Save();
+
+ // Move the mirror copy to the correct folder
+ // This is needed as some account-types/office versions will still create a mail item in the default folder
+ // even if folder.Items.Add is used to specify a location.
+ // WARNING: this creates a new mail item that will no longer be referenced here!!
+ mirror.Move(folder);
+ created = true;
}
-
+ catch (Exception ex)
+ {
+ Log.Verbose("CreateMirrorOMI: Creating new mail item failed. " + ex.ToString());
+ mirror.PermanentlyDelete();
+ mirror = null;
+ }
+
+ // Backup method
if (created == false)
{
try
--- a/Mapi.cs Tue Mar 05 14:45:53 2019 +0100
+++ b/Mapi.cs Mon Mar 25 13:27:16 2019 +0100
@@ -135,7 +135,35 @@
#region Interfaces
/// <summary>
- /// Performs operations on the messages and subfolders in a folder..
+ /// Manages high-level operations on container objects such as address books, distribution lists, and folders.
+ /// </summary>
+ [
+ ComImport,
+ ComVisible(false),
+ InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
+ Guid(Mapi.MAPIInterfaceIds.IMAPIContainer)
+ ]
+ internal interface IMAPIContainer : IMAPIProp
+ {
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int GetContentsTable();
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int GetHierarchyTable();
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int OpenEntry(uint cbEntryId, IntPtr entryId, ref Guid iid, uint flags, out IntPtr type, out IntPtr iUnk);
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int SetSearchCriteria();
+ [return: MarshalAs(UnmanagedType.I4)]
+ [PreserveSig]
+ int GetSearchCriteria();
+ }
+
+ /// <summary>
+ /// Performs operations on the messages and subfolders in a folder.
/// </summary>
[
ComImport,
@@ -143,7 +171,7 @@
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid(Mapi.MAPIInterfaceIds.IMAPIFolder)
]
- internal interface IMAPIFolder
+ internal interface IMAPIFolder : IMAPIContainer
{
/// <summary>
/// Creates a new message.
@@ -158,7 +186,7 @@
/// <returns>The status of this method.</returns>
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
- int CreateMessage(IntPtr _interface, uint flags, [MarshalAs(UnmanagedType.Interface)] ref IMessage message);
+ int CreateMessage(ref Guid lpiid, uint flags, [MarshalAs(UnmanagedType.Interface)] out IMessage message);
/// <summary>
/// Copies or moves one or more messages.
@@ -469,7 +497,7 @@
/// The IMessage interface defines methods and properties used to manage messages.
/// </summary>
[ComImport()]
- [Guid("00020307-0000-0000-C000-000000000046")]
+ [Guid(Mapi.MAPIInterfaceIds.IMessage)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IMessage
{
@@ -487,7 +515,7 @@
int GetNamesFromIDs(out IntPtr lppPropTags, ref Guid lpPropSetGuid, uint ulFlags, out uint lpcPropNames, out IntPtr lpppPropNames);
int GetIDsFromNames(uint cPropNames, ref IntPtr lppPropNames, uint ulFlags, out IntPtr lppPropTags);
int GetAttachmentTable(uint ulFlags, out IMAPITable lppTable);
- //int OpenAttach(uint ulAttachmentNum, ref Guid lpInterface, uint ulFlags, out IAttach lppAttach);
+ int OpenAttach(uint ulAttachmentNum, ref Guid lpInterface, uint ulFlags, out IAttach lppAttach);
int CreateAttach();
int DeleteAttach();
int GetRecipientTable(uint ulFlags, out IMAPITable lppTable);
@@ -496,6 +524,12 @@
int SetReadFlag(uint ulFlags);
}
+ [ComImport()]
+ [Guid(Mapi.MAPIInterfaceIds.IAttachment)]
+ [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ public interface IAttach : IMAPIProp
+ { }
+
#endregion
#region Structures
@@ -692,6 +726,95 @@
}
/// <summary>
+ /// Gets an attachment's properties.
+ /// </summary>
+ /// <param name="omi">The Outlook mail item that contains the attachment.</param>
+ /// <param name="index">The attachment's index. 0-based.</param>
+ /// <param name="mapiProperties">The MAPI properties to get its values for.</param>
+ /// <param name="propertyValues">The property values that have been returned.</param>
+ /// <returns>The status (Mapi.HResult) of this method.</returns>
+ public static int GetAttachmentProperties(Outlook.MailItem omi,
+ int index,
+ List<MapiProperty.MapiProp> mapiProperties,
+ out MAPIProperties propertyValues)
+ {
+ int result = (int)Mapi.HResult.S_FALSE;
+ propertyValues = null;
+
+ try
+ {
+ // Get the IMessage interface
+ IMessage iMessage = (IMessage)omi?.MAPIOBJECT;
+ if (iMessage == null)
+ {
+ throw new Exception("Could not get IMessage interface.");
+ }
+
+ // Open the attachment
+ Guid guid = (typeof(Mapi.IAttach)).GUID;
+ result = iMessage.OpenAttach((uint)index, ref guid, 0, out IAttach attachment);
+
+ // If we can't open the attachment, throw error
+ if (result != 0)
+ {
+ throw new Exception("Error opening attachment. " + Mapi.GetHResultError(result));
+ }
+
+ // Create the SPropValue structure
+ Mapi.SPropValue sPropValue = new Mapi.SPropValue();
+ int propValueSize = Marshal.SizeOf(sPropValue);
+
+ // Allocate memory for the array of SPropValues to set
+ int propertiesCount = mapiProperties.Count;
+ IntPtr propTagArray = Marshal.AllocHGlobal(propValueSize * propertiesCount);
+
+ // Create the property values array
+ uint[] propertyTags = new uint[propertiesCount + 1];
+ propertyTags[0] = (uint)propertiesCount;
+ for (int i = 0; i < propertiesCount; i++)
+ {
+ propertyTags[i + 1] = (uint)mapiProperties[i].Tag;
+ }
+
+ // Get properties
+ result = attachment.GetProps(propertyTags, Mapi.MAPI_UNICODE, out uint valuesCount, out IntPtr propArray);
+
+ // If an error occured, just log at this point.
+ if (result != 0)
+ {
+ Log.Error("OpenAttachment: Error getting attachment properties. " + Mapi.GetHResultError(result));
+ }
+
+ // Convert the retrieved values
+ object[] values = new object[valuesCount];
+ for (int i = 0; i < valuesCount; i++)
+ {
+ sPropValue = (SPropValue)Marshal.PtrToStructure((propArray + (i * propValueSize)), typeof(SPropValue));
+ values[i] = Mapi.ConvertSPropValueToObject(mapiProperties[i], sPropValue);
+ }
+
+ // Check if returned values match properties count
+ if (propertiesCount != valuesCount)
+ {
+ throw new Exception("Properties count doesn't match values count.");
+ }
+
+ // Create return dictionary
+ propertyValues = new MAPIProperties();
+ for (int i = 0; i < valuesCount; i++)
+ {
+ propertyValues.Add(mapiProperties[i], values[i]);
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error("OpenAttachment: Error getting attachment. " + ex.ToString());
+ }
+
+ return result;
+ }
+
+ /// <summary>
/// Gets the attachment table of an Outlook mail item.
/// </summary>
/// <param name="omi">The Outlook mail item to get its attachment table for.</param>
--- a/Properties/AssemblyInfo.cs Tue Mar 05 14:45:53 2019 +0100
+++ b/Properties/AssemblyInfo.cs Mon Mar 25 13:27:16 2019 +0100
@@ -46,5 +46,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.209.0")]
-[assembly: AssemblyFileVersion("1.0.209.0")]
+[assembly: AssemblyVersion("1.0.210.0")]
+[assembly: AssemblyFileVersion("1.0.210.0")]
--- a/ThisAddIn.cs Tue Mar 05 14:45:53 2019 +0100
+++ b/ThisAddIn.cs Mon Mar 25 13:27:16 2019 +0100
@@ -1547,7 +1547,6 @@
/// </summary>
private void OpenPEPStoreRootFolder()
{
- string path;
Outlook.Store pEpStore = null;
Outlook.Store store = null;
Outlook.Stores stores = null;
@@ -1555,9 +1554,18 @@
try
{
+ // The path to store the pEp store to
+ string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "pEp", (Globals.PEP_DATA_FILE_NAME + ".pst"));
+
+ /* For Outlook installations from the Windows Trusted Store the AddStoreEx function to add a store seems to
+ * convert "%LOCALAPPDATA%" to "%LOCALAPPDATA\Packages\Microsoft.Office.Desktop_8wekyb3d8bbwe\LocalCache\Local\".
+ * This is also confirmed on several sites/blogs. No official documentation has been found so far, though.
+ * In any case, we also use the above mentioned path to search for the pEp store.
+ */
+ string winStorePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Packages", "Microsoft.Office.Desktop_8wekyb3d8bbwe", "LocalCache", "Local", "pEp", (Globals.PEP_DATA_FILE_NAME + ".pst"));
+
ns = this.Application.Session;
stores = ns.Stores;
- path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "pEp", (Globals.PEP_DATA_FILE_NAME + ".pst"));
// Try to find an existing store based on file name
for (int i = 1; i <= stores.Count; i++)
@@ -1576,7 +1584,8 @@
Log.Warning("OpenPEPStoreRootFolder: Failed to get store, " + ex.ToString());
}
- if (store?.FilePath == path)
+ if ((store?.FilePath?.Equals(path) == true) ||
+ (store?.FilePath?.Equals(winStorePath) == true))
{
pEpStore = store;
break;
@@ -1588,7 +1597,7 @@
// If no store was found, create new
if (pEpStore == null)
{
- /* Will create the file and add it as a store, otherwise it will use the existing one.
+ /* Create the file and add it as a store, otherwise use the existing one.
* This can throw an error if a user either modified the list of Outlook data stores
* or the pEp.pst file itself.
*/
@@ -1616,12 +1625,15 @@
Log.Warning("OpenPEPStoreRootFolder: Failed to get store, " + ex.ToString());
}
- if (store?.FilePath == path)
+ if ((store?.FilePath?.Equals(path) == true) ||
+ (store?.FilePath?.Equals(winStorePath) == true))
{
pEpStore = store;
pEpStore.GetRootFolder().Name = Globals.PEP_DATA_FILE_NAME;
break; // Break before releasing
}
+
+ store = null;
}
}
@@ -1632,14 +1644,14 @@
else
{
// Try again using fallback solution for file paths with prefixes
- Log.Warning("OpenPEPStoreRootFolder: No pEp store found. Trying fallback. \npEp path is " + path);
+ Log.Warning("OpenPEPStoreRootFolder: No pEp store found. Trying fallback. pEp path is " + path);
for (int i = 1; i <= stores.Count; i++)
{
try
{
store = stores[i];
- Log.Warning("OpenPEPStoreRootFolder: file path of store " + i + ": " + store?.FilePath ?? "<null>");
+ Log.Info("OpenPEPStoreRootFolder: file path of store " + i + " (" + (store?.DisplayName ?? "<null>") + "): " + store?.FilePath ?? "<null>");
}
catch (Exception ex)
{
@@ -1647,18 +1659,21 @@
}
// Custom comparison of file paths independently of their (known) prefixes
- if (Comparisons.FilePathsAreEqual(store?.FilePath, path))
+ if (Comparisons.FilePathsAreEqual(store?.FilePath, path) ||
+ Comparisons.FilePathsAreEqual(store?.FilePath, winStorePath))
{
pEpStore = store;
pEpStore.GetRootFolder().Name = Globals.PEP_DATA_FILE_NAME;
break;
}
+
+ store = null;
}
// If pEp store was found, use it. Else throw error.
if (pEpStore != null)
{
- this._PEPStoreRootFolder = (Outlook.Folder)pEpStore.GetRootFolder();
+ this._PEPStoreRootFolder = pEpStore.GetRootFolder() as Outlook.Folder;
}
else
{
--- a/UI/FormRegionPreviewUnencrypted.cs Tue Mar 05 14:45:53 2019 +0100
+++ b/UI/FormRegionPreviewUnencrypted.cs Mon Mar 25 13:27:16 2019 +0100
@@ -21,44 +21,41 @@
// Use e.OutlookItem to get a reference to the current Outlook item.
private void FormRegionPreviewUnencryptedFactory_FormRegionInitializing(object sender, Microsoft.Office.Tools.Outlook.FormRegionInitializingEventArgs e)
{
- Outlook.MailItem omi;
-
- try
+ if (e?.OutlookItem is Outlook.MailItem omi)
{
- omi = (Outlook.MailItem)e.OutlookItem;
+ // Do not load if the mail item itself is not stored encrypted or pEp is disabled
+ if ((omi.GetIsSecurelyStored() == false) ||
+ (omi.GetIsPEPEnabled() == false) && (omi.GetIsDecryptAlwaysEnabled() == false))
+ {
+ e.Cancel = true;
+ }
+ else if (string.IsNullOrEmpty(CryptableMailItem.PreviewAttachedMailId) == false)
+ {
+ HeaderList headers = omi.GetParsedTransportMessageHeaders();
+ string messageId = null;
+
+ try
+ {
+ messageId = headers[HeaderId.MessageId];
+ }
+ catch (Exception ex)
+ {
+ Log.Verbose("FormRegionPreviewUnencryptedFactory_FormRegionInitializing: Error getting MessageId from item. " + ex.ToString());
+ }
+
+ e.Cancel = (messageId?.Equals(CryptableMailItem.PreviewAttachedMailId) != true);
+ }
+ else
+ {
+ e.Cancel = false;
+ }
+
+ omi = null;
}
- catch
+ else
{
// Never load if it's not a MailItem
e.Cancel = true;
- return;
- }
-
- // Do not load if the mail item itself is not stored encrypted or pEp is disabled
- if ((omi.GetIsSecurelyStored() == false) ||
- (omi.GetIsPEPEnabled() == false) && (omi.GetIsDecryptAlwaysEnabled() == false))
- {
- e.Cancel = true;
- }
- else if (string.IsNullOrEmpty(CryptableMailItem.PreviewAttachedMailId) == false)
- {
- HeaderList headers = omi.GetParsedTransportMessageHeaders();
- string messageId = null;
-
- try
- {
- messageId = headers[HeaderId.MessageId];
- }
- catch (Exception ex)
- {
- Log.Verbose("FormRegionPreviewUnencryptedFactory_FormRegionInitializing: Error getting MessageId from item. " + ex.ToString());
- }
-
- e.Cancel = (messageId?.Equals(CryptableMailItem.PreviewAttachedMailId) != true);
- }
- else
- {
- e.Cancel = false;
}
Log.Verbose("FormRegionPreviewUnencryptedFactory_FormRegionInitializing: e.Cancel = " + e.Cancel.ToString());
--- a/pEpForOutlook.csproj Tue Mar 05 14:45:53 2019 +0100
+++ b/pEpForOutlook.csproj Mon Mar 25 13:27:16 2019 +0100
@@ -44,7 +44,7 @@
<PublishUrl>publish\</PublishUrl>
<InstallUrl>https://pep-project.org/</InstallUrl>
<TargetCulture>en</TargetCulture>
- <ApplicationVersion>1.0.209.0</ApplicationVersion>
+ <ApplicationVersion>1.0.210.0</ApplicationVersion>
<AutoIncrementApplicationRevision>true</AutoIncrementApplicationRevision>
<UpdateEnabled>true</UpdateEnabled>
<UpdateInterval>0</UpdateInterval>