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();
+ }
}
}
}