From 9e0603e22fcb134dcfd430469a933e7918064b5a Mon Sep 17 00:00:00 2001 From: Patrick Simpson Date: Wed, 15 Feb 2017 10:15:10 +0100 Subject: [PATCH] Fixed ownership issue in folder watching startup --- .../AcaciaZPushPlugin/Stubs/IAddressBook.cs | 1 + .../AcaciaZPushPlugin/Stubs/IFolder.cs | 2 ++ .../OutlookWrappers/AddressBookWrapper.cs | 11 ++++++++++ .../Stubs/OutlookWrappers/FolderWrapper.cs | 16 +++++++++++++++ .../AcaciaZPushPlugin/ZPush/ZPushFolder.cs | 20 +++++++++++-------- 5 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAddressBook.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAddressBook.cs index 661f326..35fdf34 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAddressBook.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAddressBook.cs @@ -29,5 +29,6 @@ namespace Acacia.Stubs /// void Clear(); + new IAddressBook Clone(); } } diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IFolder.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IFolder.cs index 328df5b..6ff6308 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IFolder.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IFolder.cs @@ -112,5 +112,7 @@ namespace Acacia.Stubs // TODO: remove this. It's a quick hack to find the events associated with this folder for ZPushWatcher. // make event watching part of the folder instead ZPushFolder ZPush { get; set; } + + IFolder Clone(); } } diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddressBookWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddressBookWrapper.cs index ff6a4ce..208bbea 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddressBookWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AddressBookWrapper.cs @@ -33,6 +33,17 @@ namespace Acacia.Stubs.OutlookWrappers } + // TODO: it would be nice if this could return IAddressBook + public override IFolder Clone() + { + return new AddressBookWrapper(CloneComObject()); + } + + IAddressBook IAddressBook.Clone() + { + return new AddressBookWrapper(CloneComObject()); + } + public void Clear() { foreach(dynamic item in _item.Items.RawEnum()) diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs index a8c934f..b2e811f 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/FolderWrapper.cs @@ -39,6 +39,22 @@ namespace Acacia.Stubs.OutlookWrappers base.DoRelease(); } + protected NSOutlook.MAPIFolder CloneComObject() + { + using (ComRelease com = new ComRelease()) + { + NSOutlook.Application app = com.Add(_item.Application); + NSOutlook.NameSpace session = com.Add(app.Session); + NSOutlook.MAPIFolder folder = session.GetFolderFromID(EntryID); + return folder; + } + } + + virtual public IFolder Clone() + { + return new FolderWrapper(CloneComObject()); + } + internal NSOutlook.Folder RawItem { get { return _item; } } protected override NSOutlook.PropertyAccessor GetPropertyAccessor() diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushFolder.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushFolder.cs index 7eb07a1..5c22348 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushFolder.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushFolder.cs @@ -85,7 +85,7 @@ namespace Acacia.ZPush // Recurse the children foreach (IFolder subfolder in _folder.SubFolders) { - Tasks.Task(null, "WatchChild", () => WatchChild(subfolder)); + Tasks.Task(null, "WatchChild", () => WatchChild(subfolder, true)); } } @@ -141,7 +141,7 @@ namespace Acacia.ZPush try { Logger.Instance.Debug(this, "Folder added in {0}: {1}", Name, folder.Name); - WatchChild(folder.Duplicate()); + WatchChild(folder, false); } catch (System.Exception e) { Logger.Instance.Error(this, "Exception in SubFolders_FolderAdd: {0}: {1}", Name, e); } } @@ -205,7 +205,7 @@ namespace Acacia.ZPush // Create it now // This will send a discover notification if required, which is just as good as a change notification Logger.Instance.Debug(this, "Folder change on unreported folder in {0}: {1}, {2}, {3}", Name, folder.Name, folder.EntryID, folder.StoreDisplayName); - WatchChild(folder.Duplicate()); + WatchChild(folder, false); } } catch (System.Exception e) { Logger.Instance.Error(this, "Exception in SubFolders_FolderChange: {0}: {1}", Name, e); } @@ -259,7 +259,7 @@ namespace Acacia.ZPush /// Watches the child folder. /// /// The child folder. Ownership will be taken. - private void WatchChild(IFolder child) + private void WatchChild(IFolder child, bool takeOwnership) { if (!_children.ContainsKey(child.EntryID)) { @@ -267,9 +267,10 @@ namespace Acacia.ZPush { Logger.Instance.Trace(this, "Registering child on {0}: {1}", this, child.FullFolderPath); - // Make sure we register the entry id actually before registering any listerners. + // Make sure we register the entry id actually before registering any listeners. // That will cause change notifications, which require the entryid to be registered. - ZPushFolder folder = new ZPushFolder(_watcher, this, child); + IFolder childEffective = takeOwnership ? child : child.Clone(); + ZPushFolder folder = new ZPushFolder(_watcher, this, childEffective); _children.Add(child.EntryID, folder); folder.Initialise(); return; @@ -280,8 +281,11 @@ namespace Acacia.ZPush } } - // Release the folder if not used - child.Dispose(); + if (takeOwnership) + { + // Release the folder if not used + child.Dispose(); + } } } }