diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/BCC/FeatureBCC.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/BCC/FeatureBCC.cs index 27e55ec..9dcdc4f 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/BCC/FeatureBCC.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/BCC/FeatureBCC.cs @@ -44,7 +44,7 @@ namespace Acacia.Features.BCC // Check we're in the SentMail folder using (IFolder folder = mail.Parent) { - if (_folderRegistration.IsApplicable(folder)) + if (folder != null && _folderRegistration.IsApplicable(folder)) CheckBCC(mail); } }; diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SecondaryContacts/FeatureSecondaryContacts.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SecondaryContacts/FeatureSecondaryContacts.cs index 1d9a666..c21316c 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SecondaryContacts/FeatureSecondaryContacts.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SecondaryContacts/FeatureSecondaryContacts.cs @@ -57,6 +57,9 @@ namespace Acacia.Features.SecondaryContacts public override bool IsApplicable(IFolder folder) { + if (folder == null) + return false; + // Check the sync type. // Also allow again if the sync type is user contact, it may not have been fully patched. if (FolderUtils.GetFolderSyncType(folder) != OutlookConstants.SyncType.Unknown && diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/OutlookConstants.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/OutlookConstants.cs index 4e6cc5e..a6d0908 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/OutlookConstants.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/OutlookConstants.cs @@ -89,6 +89,9 @@ namespace Acacia public const string PR_CONTAINER_CLASS = PROP + "3613" + PT_UNICODE; + public const string PR_ENTRYID = PROP + "0FFF" + PT_BINARY; + public const string PR_PARENT_ENTRYID = PROP + "0E09" + PT_BINARY; + #endregion #region Email specific diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AppointmentItemWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AppointmentItemWrapper.cs index 8a77c90..cfc2283 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AppointmentItemWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AppointmentItemWrapper.cs @@ -105,7 +105,7 @@ namespace Acacia.Stubs.OutlookWrappers override public string EntryID { get { return _item.EntryID; } } - override public IFolder Parent + override protected IFolder ParentUnchecked { get { @@ -114,26 +114,6 @@ namespace Acacia.Stubs.OutlookWrappers } } - override public string ParentEntryID - { - get - { - using (IBase parent = Mapping.Wrap(_item.Parent)) - { - return parent.EntryID; - } - } - } - - override public IStore GetStore() - { - using (ComRelease com = new ComRelease()) - { - NSOutlook.Folder parent = com.Add(_item.Parent); - return Mapping.Wrap(parent?.Store); - } - } - override public void Delete() { _item.Delete(); } #endregion diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ContactItemWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ContactItemWrapper.cs index a22816d..7085aa3 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ContactItemWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ContactItemWrapper.cs @@ -220,7 +220,7 @@ namespace Acacia.Stubs.OutlookWrappers override public string EntryID { get { return _item.EntryID; } } - override public IFolder Parent + override protected IFolder ParentUnchecked { get { @@ -229,27 +229,6 @@ namespace Acacia.Stubs.OutlookWrappers } } - override public string ParentEntryID - { - get - { - using (ComRelease com = new ComRelease()) - { - NSOutlook.Folder parent = com.Add(_item.Parent); - return parent?.EntryID; - } - } - } - - override public IStore GetStore() - { - using (ComRelease com = new ComRelease()) - { - NSOutlook.Folder parent = com.Add(_item.Parent); - return Mapping.Wrap(parent?.Store); - } - } - override public void Delete() { _item.Delete(); } #endregion diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/DistributionListWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/DistributionListWrapper.cs index 5cb3f3e..7cd5cb5 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/DistributionListWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/DistributionListWrapper.cs @@ -236,7 +236,7 @@ namespace Acacia.Stubs.OutlookWrappers override public string EntryID { get { return _item.EntryID; } } - override public IFolder Parent + override protected IFolder ParentUnchecked { get { @@ -245,27 +245,6 @@ namespace Acacia.Stubs.OutlookWrappers } } - override public string ParentEntryID - { - get - { - using (ComRelease com = new ComRelease()) - { - NSOutlook.Folder parent = com.Add(_item.Parent); - return parent?.EntryID; - } - } - } - - override public IStore GetStore() - { - using (ComRelease com = new ComRelease()) - { - NSOutlook.Folder parent = com.Add(_item.Parent); - return Mapping.Wrap(parent?.Store); - } - } - override public void Delete() { _item.Delete(); } #endregion diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs index 2c5587b..0fe7af6 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs @@ -79,7 +79,7 @@ namespace Acacia.Stubs.OutlookWrappers public string FullFolderPath { get { return _item.FullFolderPath; } } - override public IFolder Parent + override protected IFolder ParentUnchecked { get { @@ -87,19 +87,7 @@ namespace Acacia.Stubs.OutlookWrappers return Mapping.Wrap(_item.Parent as NSOutlook.Folder); } } - - override public string ParentEntryID - { - get - { - using (ComRelease com = new ComRelease()) - { - NSOutlook.Folder parent = com.Add(_item.Parent); - return parent?.EntryID; - } - } - } - + /// /// Checks if the folder is at the specified depth. The root folder is at depth 0, its children at depth 1, etc. /// This function exists because sometimes it's need to determine if a folder is at a specific depth; using this diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/MailItemWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/MailItemWrapper.cs index aab1323..7589cd5 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/MailItemWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/MailItemWrapper.cs @@ -164,7 +164,7 @@ namespace Acacia.Stubs.OutlookWrappers override public string EntryID { get { return _item.EntryID; } } - override public IFolder Parent + override protected IFolder ParentUnchecked { get { @@ -173,27 +173,6 @@ namespace Acacia.Stubs.OutlookWrappers } } - override public string ParentEntryID - { - get - { - using (ComRelease com = new ComRelease()) - { - NSOutlook.Folder parent = com.Add(_item.Parent); - return parent?.EntryID; - } - } - } - - override public IStore GetStore() - { - using (ComRelease com = new ComRelease()) - { - NSOutlook.Folder parent = com.Add(_item.Parent); - return Mapping.Wrap(parent?.Store); - } - } - override public void Delete() { _item.Delete(); } #endregion diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/MeetingItemWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/MeetingItemWrapper.cs index 3c3adbc..e644fbb 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/MeetingItemWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/MeetingItemWrapper.cs @@ -101,7 +101,7 @@ namespace Acacia.Stubs.OutlookWrappers override public string EntryID { get { return _item.EntryID; } } - override public IFolder Parent + override protected IFolder ParentUnchecked { get { @@ -110,27 +110,6 @@ namespace Acacia.Stubs.OutlookWrappers } } - override public string ParentEntryID - { - get - { - using (ComRelease com = new ComRelease()) - { - NSOutlook.Folder parent = com.Add(_item.Parent); - return parent?.EntryID; - } - } - } - - override public IStore GetStore() - { - using (ComRelease com = new ComRelease()) - { - NSOutlook.Folder parent = com.Add(_item.Parent); - return Mapping.Wrap(parent?.Store); - } - } - override public void Delete() { _item.Delete(); } #endregion diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/NoteItemWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/NoteItemWrapper.cs index 577d0f1..2e128fe 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/NoteItemWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/NoteItemWrapper.cs @@ -76,7 +76,7 @@ namespace Acacia.Stubs.OutlookWrappers override public string EntryID { get { return _item.EntryID; } } - override public IFolder Parent + override protected IFolder ParentUnchecked { get { @@ -85,27 +85,6 @@ namespace Acacia.Stubs.OutlookWrappers } } - override public string ParentEntryID - { - get - { - using (ComRelease com = new ComRelease()) - { - NSOutlook.Folder parent = com.Add(_item.Parent); - return parent?.EntryID; - } - } - } - - override public IStore GetStore() - { - using (ComRelease com = new ComRelease()) - { - NSOutlook.Folder parent = com.Add(_item.Parent); - return Mapping.Wrap(parent?.Store); - } - } - override public void Delete() { _item.Delete(); } #endregion diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookWrapper.cs index 4a2b65f..ae5bb3c 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookWrapper.cs @@ -82,9 +82,45 @@ namespace Acacia.Stubs.OutlookWrappers } } - public abstract string EntryID { get; } - public abstract IFolder Parent { get; } - public abstract string ParentEntryID { get; } + abstract public string EntryID + { + get; + } + + public IFolder Parent + { + get + { + if (!CanAccessParent) + return null; + + return ParentUnchecked; + } + } + + protected abstract IFolder ParentUnchecked { get; } + + private bool CanAccessParent + { + get + { + // [KOE-132]: Somehow when sending mail through other applications, accessing parent + // causes an access violation on Outlook 2013. I have been unable to fully determine + // the exact cause, but the entry id seems to be null and the parent entry id set in + // this case. So just avoid that. + if (GetProperty(OutlookConstants.PR_ENTRYID) == null && GetProperty(OutlookConstants.PR_PARENT_ENTRYID) != null) + return false; + return true; + } + } + + public string ParentEntryID + { + get + { + return StringUtil.BytesToHex((byte[])GetProperty(OutlookConstants.PR_PARENT_ENTRYID)); + } + } virtual public string StoreID { @@ -190,10 +226,18 @@ namespace Acacia.Stubs.OutlookWrappers #endregion + virtual public IStore GetStore() + { + using (IFolder parent = Parent) + { + return parent?.GetStore(); + } + } + public override abstract string ToString(); - public abstract IStore GetStore(); public abstract void Delete(); + override public string DebugContext { get diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StorageItemWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StorageItemWrapper.cs index b183f1c..6e882ab 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StorageItemWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/StorageItemWrapper.cs @@ -74,7 +74,7 @@ namespace Acacia.Stubs.OutlookWrappers override public string EntryID { get { return _item.EntryID; } } - override public IFolder Parent + override protected IFolder ParentUnchecked { get { @@ -83,27 +83,6 @@ namespace Acacia.Stubs.OutlookWrappers } } - override public string ParentEntryID - { - get - { - using (ComRelease com = new ComRelease()) - { - NSOutlook.Folder parent = com.Add(_item.Parent); - return parent?.EntryID; - } - } - } - - override public IStore GetStore() - { - using (ComRelease com = new ComRelease()) - { - NSOutlook.Folder parent = com.Add(_item.Parent); - return Mapping.Wrap(parent?.Store); - } - } - override public void Delete() { _item.Delete(); } #endregion diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/TaskItemWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/TaskItemWrapper.cs index 3448c82..07df207 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/TaskItemWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/TaskItemWrapper.cs @@ -74,7 +74,7 @@ namespace Acacia.Stubs.OutlookWrappers override public string EntryID { get { return _item.EntryID; } } - override public IFolder Parent + override protected IFolder ParentUnchecked { get { @@ -83,27 +83,6 @@ namespace Acacia.Stubs.OutlookWrappers } } - override public string ParentEntryID - { - get - { - using (ComRelease com = new ComRelease()) - { - NSOutlook.Folder parent = com.Add(_item.Parent); - return parent?.EntryID; - } - } - } - - override public IStore GetStore() - { - using (ComRelease com = new ComRelease()) - { - NSOutlook.Folder parent = com.Add(_item.Parent); - return Mapping.Wrap(parent?.Store); - } - } - override public void Delete() { _item.Delete(); } #endregion diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/FolderRegistration.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/FolderRegistration.cs index a15262a..3d5f2b2 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/FolderRegistration.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/FolderRegistration.cs @@ -49,7 +49,7 @@ namespace Acacia.ZPush public override bool IsApplicable(IFolder folder) { - return folder.ItemType == _itemType; + return folder != null && folder.ItemType == _itemType; } public override string ToString() @@ -71,6 +71,8 @@ namespace Acacia.ZPush public override bool IsApplicable(IFolder folder) { + if (folder == null) + return false; // TODO: cache folder id per store using (IStore store = folder.GetStore()) {