From d85c3ae19ddc26adf6172544cf6caec2846af84c Mon Sep 17 00:00:00 2001 From: Patrick Simpson Date: Wed, 26 Sep 2018 13:08:46 +0300 Subject: [PATCH] [KOE-176] Possible fix for memory issue --- .../AcaciaZPushPlugin.csproj | 1 + .../Features/Signatures/FeatureSignatures.cs | 4 +- .../Stubs/OutlookWrappers/AccountWrapper.cs | 12 ++--- .../AcaciaZPushPlugin/Utils/MemUtil.cs | 51 +++++++++++++++++++ 4 files changed, 60 insertions(+), 8 deletions(-) create mode 100644 src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MemUtil.cs diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj index 0b8109f..a0a38e9 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj @@ -396,6 +396,7 @@ + diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Signatures/FeatureSignatures.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Signatures/FeatureSignatures.cs index 3166bce..f21ee07 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Signatures/FeatureSignatures.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Signatures/FeatureSignatures.cs @@ -134,8 +134,8 @@ namespace Acacia.Features.Signatures if (serverSignatureHash != null) { Logger.Instance.Trace(this, "Checking signature hash for account {0}: {1}", account, serverSignatureHash); - if (serverSignatureHash == account.LocalSignaturesHash) - return; + //if (serverSignatureHash == account.LocalSignaturesHash) + // return; } // Fetch signatures if there is a change diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AccountWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AccountWrapper.cs index e3d0a0e..5fee322 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AccountWrapper.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AccountWrapper.cs @@ -246,16 +246,16 @@ namespace Acacia.Stubs.OutlookWrappers { case PropType.UNICODE: Logger.Instance.Trace(this, "SetAccountProp5: {0}: {1}", propTag, value); - fixed (char* ptr = ((string)value).ToCharArray()) + using (MapiAlloc mem = MapiAlloc.FromString((string)value)) { ACCT_VARIANT val = new ACCT_VARIANT() { dwType = (uint)PropType.UNICODE, - lpszW = ptr + lpszW = (char*)mem.Ptr }; - //olk.SetProp(propTag, &val); + olk.SetProp(propTag, &val); Logger.Instance.Trace(this, "SetAccountProp6: {0}: {1}", propTag, value); - //olk.SaveChanges(0); + olk.SaveChanges(0); Logger.Instance.Trace(this, "SetAccountProp7: {0}: {1}", propTag, value); } break; @@ -267,9 +267,9 @@ namespace Acacia.Stubs.OutlookWrappers dwType = (uint)PropType.LONG, dw = (uint)value }; - //olk.SetProp(propTag, &val); + olk.SetProp(propTag, &val); Logger.Instance.Trace(this, "SetAccountProp9: {0}: {1}", propTag, value); - //olk.SaveChanges(0); + olk.SaveChanges(0); Logger.Instance.Trace(this, "SetAccountPropA: {0}: {1}", propTag, value); break; } diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MemUtil.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MemUtil.cs new file mode 100644 index 0000000..d08581c --- /dev/null +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MemUtil.cs @@ -0,0 +1,51 @@ +using Acacia.Native; +using Acacia.Native.MAPI; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace Acacia.Utils +{ + public class MapiAlloc : IDisposable + { + public IntPtr Ptr { get; private set; } + + private MapiAlloc(IntPtr ptr) + { + this.Ptr = ptr; + } + + public void Dispose() + { + MAPI.MAPIFreeBuffer(Ptr); + Ptr = IntPtr.Zero; + } + + public static MapiAlloc FromString(string value, Encoding encoding = null) + { + if (encoding == null) + encoding = Encoding.Unicode; + + byte[] data = encoding.GetBytes(value); + byte[] term = encoding.GetBytes(new char[] { (char)0 }); + + // Allocate the buffer + int size = data.Length + term.Length; + IntPtr ptr = IntPtr.Zero; + IntPtr res = MAPI.MAPIAllocateBuffer((uint)size, ref ptr); + if (res != IntPtr.Zero) + throw new InvalidOperationException("MAPI Allocation failed: " + res); + + // Zero it + Kernel32.ZeroMemory(ptr, size); + + // And copy the data + Marshal.Copy(data, 0, ptr, data.Length); + + return new MapiAlloc(ptr); + } + } +}