mirror of
				https://github.com/Kopano-dev/kopano-ol-extension.git
				synced 2023-10-10 11:37:40 +00:00 
			
		
		
		
	Search criteria encoding
This commit is contained in:
		@@ -276,9 +276,16 @@
 | 
				
			|||||||
    <Compile Include="Features\SharedFolders\FolderTreeNode.cs" />
 | 
					    <Compile Include="Features\SharedFolders\FolderTreeNode.cs" />
 | 
				
			||||||
    <Compile Include="GlobalOptions.cs" />
 | 
					    <Compile Include="GlobalOptions.cs" />
 | 
				
			||||||
    <Compile Include="Logging.cs" />
 | 
					    <Compile Include="Logging.cs" />
 | 
				
			||||||
    <Compile Include="Native\MAPI.cs" />
 | 
					 | 
				
			||||||
    <Compile Include="Native\IOleWindow.cs" />
 | 
					    <Compile Include="Native\IOleWindow.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Native\MAPI\Binary.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Native\MAPI\IMAPIContainer.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Native\MAPI\IMAPIFolder.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Native\MAPI\IMAPIProp.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Native\MAPI\Property.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Native\MAPI\Restriction.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Native\NativeEncoder.cs" />
 | 
				
			||||||
    <Compile Include="OutlookConstants.cs" />
 | 
					    <Compile Include="OutlookConstants.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="SearchQuery.cs" />
 | 
				
			||||||
    <Compile Include="Stubs\Enums.cs" />
 | 
					    <Compile Include="Stubs\Enums.cs" />
 | 
				
			||||||
    <Compile Include="Stubs\IAccount.cs" />
 | 
					    <Compile Include="Stubs\IAccount.cs" />
 | 
				
			||||||
    <Compile Include="Stubs\IAddIn.cs" />
 | 
					    <Compile Include="Stubs\IAddIn.cs" />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
using Acacia.Native.MAPI;
 | 
					using Acacia.Native.MAPI;
 | 
				
			||||||
 | 
					using Acacia.Stubs;
 | 
				
			||||||
/// Copyright 2016 Kopano b.v.
 | 
					/// Copyright 2016 Kopano b.v.
 | 
				
			||||||
/// 
 | 
					/// 
 | 
				
			||||||
/// This program is free software: you can redistribute it and/or modify
 | 
					/// This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
@@ -80,13 +81,21 @@ namespace Acacia.Features.WebApp
 | 
				
			|||||||
            if (account == null)
 | 
					            if (account == null)
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            using (IFolder reminders = account.Account.Store.GetSpecialFolder(SpecialFolder.Reminders))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Logger.Instance.Trace(this, "REMINDERS:\n{0}", reminders.SearchCriteria);
 | 
				
			||||||
 | 
					                using (RestrictionEncoder res = reminders.SearchCriteria.ToRestriction())
 | 
				
			||||||
 | 
					                    Logger.Instance.Trace(this, "REMINDERS2:\n{0}", res.Restriction);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            /*
 | 
				
			||||||
            // Get the url
 | 
					            // Get the url
 | 
				
			||||||
            string url = AutoDiscover(account);
 | 
					            string url = AutoDiscover(account);
 | 
				
			||||||
            if (url == null)
 | 
					            if (url == null)
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Open the browser
 | 
					            // Open the browser
 | 
				
			||||||
            System.Diagnostics.Process.Start(url);
 | 
					            System.Diagnostics.Process.Start(url);*/
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private string AutoDiscover(ZPushAccount account)
 | 
					        private string AutoDiscover(ZPushAccount account)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					using Acacia.Utils;
 | 
				
			||||||
 | 
					/// Copyright 2017 Kopano b.v.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					/// it under the terms of the GNU Affero General Public License, version 3,
 | 
				
			||||||
 | 
					/// as published by the Free Software Foundation.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					/// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
 | 
				
			||||||
 | 
					/// GNU Affero General Public License for more details.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// You should have received a copy of the GNU Affero General Public License
 | 
				
			||||||
 | 
					/// along with this program.If not, see<http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// Consult LICENSE file for details
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Runtime.InteropServices;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Acacia.Native.MAPI
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    unsafe public struct SBinary
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public uint cb;
 | 
				
			||||||
 | 
					        public byte* ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public byte[] Unmarshal()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            byte[] result = new byte[cb];
 | 
				
			||||||
 | 
					            Marshal.Copy((IntPtr)ptr, result, 0, result.Length);
 | 
				
			||||||
 | 
					            return result;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public override string ToString()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            byte[] b = Unmarshal();
 | 
				
			||||||
 | 
					            return b.Length.ToString() + ":" + StringUtil.BytesToHex(b);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    unsafe public struct SBinaryArray
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public uint count;
 | 
				
			||||||
 | 
					        public SBinary* ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public byte[][] Unmarshal()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            byte[][] result = new byte[count][];
 | 
				
			||||||
 | 
					            for (uint i = 0; i < count; ++i)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                result[i] = ptr[i].Unmarshal();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return result;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,74 @@
 | 
				
			|||||||
 | 
					/// Copyright 2017 Kopano b.v.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					/// it under the terms of the GNU Affero General Public License, version 3,
 | 
				
			||||||
 | 
					/// as published by the Free Software Foundation.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					/// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
 | 
				
			||||||
 | 
					/// GNU Affero General Public License for more details.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// You should have received a copy of the GNU Affero General Public License
 | 
				
			||||||
 | 
					/// along with this program.If not, see<http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// Consult LICENSE file for details
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Runtime.InteropServices;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Acacia.Native.MAPI
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [Flags]
 | 
				
			||||||
 | 
					    public enum SearchCriteriaState : UInt32
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        NONE = 0,
 | 
				
			||||||
 | 
					        SEARCH_RUNNING = 1,
 | 
				
			||||||
 | 
					        SEARCH_REBUILD = 2,
 | 
				
			||||||
 | 
					        SEARCH_RECURSIVE = 4,
 | 
				
			||||||
 | 
					        SEARCH_FOREGROUND = 8
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [Flags]
 | 
				
			||||||
 | 
					    public enum SearchCriteriaFlags : UInt32
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        NONE = 0,
 | 
				
			||||||
 | 
					        STOP_SEARCH = 0x00000001,
 | 
				
			||||||
 | 
					        RESTART_SEARCH = 0x00000002,
 | 
				
			||||||
 | 
					        RECURSIVE_SEARCH = 0x00000004,
 | 
				
			||||||
 | 
					        SHALLOW_SEARCH = 0x00000008,
 | 
				
			||||||
 | 
					        FOREGROUND_SEARCH = 0x00000010,
 | 
				
			||||||
 | 
					        BACKGROUND_SEARCH = 0x00000020,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [ComImport]
 | 
				
			||||||
 | 
					    [Guid("0002030B-0000-0000-C000-000000000046")]
 | 
				
			||||||
 | 
					    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
 | 
				
			||||||
 | 
					    unsafe public interface IMAPIContainer : IMAPIProp
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // IMAPIProp
 | 
				
			||||||
 | 
					        new void GetLastError(Int32 hResult, UInt32 flags, out IntPtr ptr);
 | 
				
			||||||
 | 
					        new void SaveChanges(SaveChangesFlags flags);
 | 
				
			||||||
 | 
					        new void GetProps();
 | 
				
			||||||
 | 
					        new void GetPropList();
 | 
				
			||||||
 | 
					        new void OpenProperty();
 | 
				
			||||||
 | 
					        new void SetProps();
 | 
				
			||||||
 | 
					        new void DeleteProps();
 | 
				
			||||||
 | 
					        new void CopyTo();
 | 
				
			||||||
 | 
					        new void CopyProps();
 | 
				
			||||||
 | 
					        new void GetNamesFromIDs();
 | 
				
			||||||
 | 
					        new void GetIDsFromNames();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // IMAPIContainer
 | 
				
			||||||
 | 
					        void GetContentsTable(UInt32 flags, out IntPtr table);
 | 
				
			||||||
 | 
					        void GetHierarchyTable();
 | 
				
			||||||
 | 
					        void OpenEntry();
 | 
				
			||||||
 | 
					        void SetSearchCriteria(SRestriction* lppRestriction, SBinaryArray* lppContainerList, SearchCriteriaFlags flags);
 | 
				
			||||||
 | 
					        void GetSearchCriteria(UInt32 flags, SRestriction** lppRestriction, SBinaryArray** lppContainerList, out SearchCriteriaState state);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,64 @@
 | 
				
			|||||||
 | 
					/// Copyright 2017 Kopano b.v.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					/// it under the terms of the GNU Affero General Public License, version 3,
 | 
				
			||||||
 | 
					/// as published by the Free Software Foundation.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					/// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
 | 
				
			||||||
 | 
					/// GNU Affero General Public License for more details.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// You should have received a copy of the GNU Affero General Public License
 | 
				
			||||||
 | 
					/// along with this program.If not, see<http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// Consult LICENSE file for details
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Runtime.InteropServices;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Acacia.Native.MAPI
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    [ComImport]
 | 
				
			||||||
 | 
					    [Guid("0002030C-0000-0000-C000-000000000046")]
 | 
				
			||||||
 | 
					    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
 | 
				
			||||||
 | 
					    unsafe public interface IMAPIFolder : IMAPIContainer
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // IMAPIProp
 | 
				
			||||||
 | 
					        new void GetLastError(Int32 hResult, UInt32 flags, out IntPtr ptr);
 | 
				
			||||||
 | 
					        new void SaveChanges(SaveChangesFlags flags);
 | 
				
			||||||
 | 
					        new void GetProps();
 | 
				
			||||||
 | 
					        new void GetPropList();
 | 
				
			||||||
 | 
					        new void OpenProperty();
 | 
				
			||||||
 | 
					        new void SetProps();
 | 
				
			||||||
 | 
					        new void DeleteProps();
 | 
				
			||||||
 | 
					        new void CopyTo();
 | 
				
			||||||
 | 
					        new void CopyProps();
 | 
				
			||||||
 | 
					        new void GetNamesFromIDs();
 | 
				
			||||||
 | 
					        new void GetIDsFromNames();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // IMAPIContainer
 | 
				
			||||||
 | 
					        new void GetContentsTable(UInt32 flags, out IntPtr table);
 | 
				
			||||||
 | 
					        new void GetHierarchyTable();
 | 
				
			||||||
 | 
					        new void OpenEntry();
 | 
				
			||||||
 | 
					        new void SetSearchCriteria(SRestriction* lppRestriction, SBinaryArray* lppContainerList, SearchCriteriaFlags flags);
 | 
				
			||||||
 | 
					        new void GetSearchCriteria(UInt32 flags, SRestriction** lppRestriction, SBinaryArray** lppContainerList, out SearchCriteriaState state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // IMAPIFolder
 | 
				
			||||||
 | 
					        void CreateMessage();
 | 
				
			||||||
 | 
					        void CopyMessages();
 | 
				
			||||||
 | 
					        void DeleteMessages();
 | 
				
			||||||
 | 
					        void CreateFolder();
 | 
				
			||||||
 | 
					        void CopyFolder();
 | 
				
			||||||
 | 
					        void DeleteFolder();
 | 
				
			||||||
 | 
					        void SetReadFlags();
 | 
				
			||||||
 | 
					        void GetMessageStatus();
 | 
				
			||||||
 | 
					        void SetMessageStatus();
 | 
				
			||||||
 | 
					        void SaveContentsSort();
 | 
				
			||||||
 | 
					        void EmptyFolder();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					/// Copyright 2017 Kopano b.v.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					/// it under the terms of the GNU Affero General Public License, version 3,
 | 
				
			||||||
 | 
					/// as published by the Free Software Foundation.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					/// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
 | 
				
			||||||
 | 
					/// GNU Affero General Public License for more details.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// You should have received a copy of the GNU Affero General Public License
 | 
				
			||||||
 | 
					/// along with this program.If not, see<http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// Consult LICENSE file for details
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Runtime.InteropServices;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Acacia.Native.MAPI
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    [Flags]
 | 
				
			||||||
 | 
					    public enum SaveChangesFlags : UInt32
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        NONE = 0,
 | 
				
			||||||
 | 
					        KEEP_OPEN_READONLY = 1,
 | 
				
			||||||
 | 
					        KEEP_OPEN_READWRITE = 2,
 | 
				
			||||||
 | 
					        FORCE_SAVE = 4,
 | 
				
			||||||
 | 
					        MAPI_DEFERRED_ERRORS = 8
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [ComImport]
 | 
				
			||||||
 | 
					    [Guid("00020303-0000-0000-C000-000000000046")]
 | 
				
			||||||
 | 
					    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
 | 
				
			||||||
 | 
					    public interface IMAPIProp
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        void GetLastError(Int32 hResult, UInt32 flags, out IntPtr ptr);
 | 
				
			||||||
 | 
					        void SaveChanges(SaveChangesFlags flags);
 | 
				
			||||||
 | 
					        void GetProps();
 | 
				
			||||||
 | 
					        void GetPropList();
 | 
				
			||||||
 | 
					        void OpenProperty();
 | 
				
			||||||
 | 
					        void SetProps();
 | 
				
			||||||
 | 
					        void DeleteProps();
 | 
				
			||||||
 | 
					        void CopyTo();
 | 
				
			||||||
 | 
					        void CopyProps();
 | 
				
			||||||
 | 
					        void GetNamesFromIDs();
 | 
				
			||||||
 | 
					        void GetIDsFromNames();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										140
									
								
								src/AcaciaZPushPlugin/AcaciaZPushPlugin/Native/MAPI/Property.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								src/AcaciaZPushPlugin/AcaciaZPushPlugin/Native/MAPI/Property.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,140 @@
 | 
				
			|||||||
 | 
					/// Copyright 2017 Kopano b.v.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					/// it under the terms of the GNU Affero General Public License, version 3,
 | 
				
			||||||
 | 
					/// as published by the Free Software Foundation.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					/// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
 | 
				
			||||||
 | 
					/// GNU Affero General Public License for more details.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// You should have received a copy of the GNU Affero General Public License
 | 
				
			||||||
 | 
					/// along with this program.If not, see<http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// Consult LICENSE file for details
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Runtime.InteropServices;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Acacia.Native.MAPI
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public enum PropType : ushort
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        BOOLEAN = 0x000B,
 | 
				
			||||||
 | 
					        BINARY = 0x0102,
 | 
				
			||||||
 | 
					        MV_BINARY = 1102,
 | 
				
			||||||
 | 
					        DOUBLE = 0x0005,
 | 
				
			||||||
 | 
					        LONG = 0x0003,
 | 
				
			||||||
 | 
					        OBJECT = 0x000D,
 | 
				
			||||||
 | 
					        STRING8 = 0x001E,
 | 
				
			||||||
 | 
					        MV_STRING8 = 0x101E,
 | 
				
			||||||
 | 
					        SYSTIME = 0x0040,
 | 
				
			||||||
 | 
					        UNICODE = 0x001F,
 | 
				
			||||||
 | 
					        MV_UNICODE = 0x101f
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [StructLayout(LayoutKind.Sequential, Pack = 1)]
 | 
				
			||||||
 | 
					    public struct PropTag
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public PropType type;
 | 
				
			||||||
 | 
					        public ushort prop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public override string ToString()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return "<" + prop.ToString("X4") + ":" + type + ">";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public SearchQuery.PropertyIdentifier ToPropertyIdentifier()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new SearchQuery.PropertyIdentifier(this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [StructLayout(LayoutKind.Explicit)]
 | 
				
			||||||
 | 
					    unsafe public struct PropValue
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        [FieldOffset(0)]
 | 
				
			||||||
 | 
					        public PropTag ulPropTag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [FieldOffset(4)]
 | 
				
			||||||
 | 
					        public uint dwAlignPad;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //	short int			i;			/* case PT_I2 */
 | 
				
			||||||
 | 
					        //	LONG				l;			/* case PT_LONG */
 | 
				
			||||||
 | 
					        //	ULONG				ul;			/* alias for PT_LONG */
 | 
				
			||||||
 | 
					        //	LPVOID				lpv;		/* alias for PT_PTR */
 | 
				
			||||||
 | 
					        //	float				flt;		/* case PT_R4 */
 | 
				
			||||||
 | 
					        //	double				dbl;		/* case PT_DOUBLE */
 | 
				
			||||||
 | 
					        //	unsigned short int	b;			/* case PT_BOOLEAN */
 | 
				
			||||||
 | 
					        [FieldOffset(8), MarshalAs(UnmanagedType.U2)]
 | 
				
			||||||
 | 
					        public bool b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //	CURRENCY			cur;		/* case PT_CURRENCY */
 | 
				
			||||||
 | 
					        //	double				at;			/* case PT_APPTIME */
 | 
				
			||||||
 | 
					        //	FILETIME			ft;			/* case PT_SYSTIME */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //	LPSTR				lpszA;		/* case PT_STRING8 */
 | 
				
			||||||
 | 
					        [FieldOffset(8), MarshalAs(UnmanagedType.LPStr)]
 | 
				
			||||||
 | 
					        public sbyte* lpszA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //	SBinary				bin;		/* case PT_BINARY */
 | 
				
			||||||
 | 
					        [FieldOffset(8)]
 | 
				
			||||||
 | 
					        public SBinary bin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //	LPWSTR				lpszW;		/* case PT_UNICODE */
 | 
				
			||||||
 | 
					        [FieldOffset(8), MarshalAs(UnmanagedType.LPWStr)]
 | 
				
			||||||
 | 
					        public char* lpszW;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //	LPGUID				lpguid;		/* case PT_CLSID */
 | 
				
			||||||
 | 
					        //	LARGE_INTEGER		li;			/* case PT_I8 */
 | 
				
			||||||
 | 
					        //	SShortArray			MVi;		/* case PT_MV_I2 */
 | 
				
			||||||
 | 
					        //	SLongArray			MVl;		/* case PT_MV_LONG */
 | 
				
			||||||
 | 
					        //	SRealArray			MVflt;		/* case PT_MV_R4 */
 | 
				
			||||||
 | 
					        //	SDoubleArray		MVdbl;		/* case PT_MV_DOUBLE */
 | 
				
			||||||
 | 
					        //	SCurrencyArray		MVcur;		/* case PT_MV_CURRENCY */
 | 
				
			||||||
 | 
					        //	SAppTimeArray		MVat;		/* case PT_MV_APPTIME */
 | 
				
			||||||
 | 
					        //	SDateTimeArray		MVft;		/* case PT_MV_SYSTIME */
 | 
				
			||||||
 | 
					        //	SBinaryArray		MVbin;		/* case PT_MV_BINARY */
 | 
				
			||||||
 | 
					        //	SLPSTRArray			MVszA;		/* case PT_MV_STRING8 */
 | 
				
			||||||
 | 
					        //	SWStringArray		MVszW;		/* case PT_MV_UNICODE */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //	SGuidArray			MVguid;		/* case PT_MV_CLSID */
 | 
				
			||||||
 | 
					        //	SLargeIntegerArray	MVli;		/* case PT_MV_I8 */
 | 
				
			||||||
 | 
					        //	SCODE				err;		/* case PT_ERROR */
 | 
				
			||||||
 | 
					        //	LONG				x;			/* case PT_NULL, PT_OBJECT (no usable value) */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public override string ToString()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return ToObject()?.ToString() ?? "<unknown>";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public object ToObject()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            switch (ulPropTag.type)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                case PropType.BOOLEAN:
 | 
				
			||||||
 | 
					                    return b;
 | 
				
			||||||
 | 
					                case PropType.STRING8:
 | 
				
			||||||
 | 
					                    return new string(lpszA);
 | 
				
			||||||
 | 
					                case PropType.BINARY:
 | 
				
			||||||
 | 
					                    return bin;
 | 
				
			||||||
 | 
					                    //case PropType.UNICODE:
 | 
				
			||||||
 | 
					                    // return lpszW.ToString();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static PropValue* FromObject(NativeEncoder encoder, object value)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            throw new NotImplementedException();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,4 +1,7 @@
 | 
				
			|||||||
/// Copyright 2017 Kopano b.v.
 | 
					
 | 
				
			||||||
 | 
					using Acacia.Stubs;
 | 
				
			||||||
 | 
					using Acacia.Utils;
 | 
				
			||||||
 | 
					/// Copyright 2017 Kopano b.v.
 | 
				
			||||||
/// 
 | 
					/// 
 | 
				
			||||||
/// This program is free software: you can redistribute it and/or modify
 | 
					/// This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
/// it under the terms of the GNU Affero General Public License, version 3,
 | 
					/// it under the terms of the GNU Affero General Public License, version 3,
 | 
				
			||||||
@@ -13,8 +16,6 @@
 | 
				
			|||||||
/// along with this program.If not, see<http://www.gnu.org/licenses/>.
 | 
					/// along with this program.If not, see<http://www.gnu.org/licenses/>.
 | 
				
			||||||
/// 
 | 
					/// 
 | 
				
			||||||
/// Consult LICENSE file for details
 | 
					/// Consult LICENSE file for details
 | 
				
			||||||
 | 
					 | 
				
			||||||
using Acacia.Utils;
 | 
					 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
@@ -24,167 +25,6 @@ using System.Threading.Tasks;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Acacia.Native.MAPI
 | 
					namespace Acacia.Native.MAPI
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    [Flags]
 | 
					 | 
				
			||||||
    public enum SaveChangesFlags : UInt32
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        NONE = 0,
 | 
					 | 
				
			||||||
        KEEP_OPEN_READONLY = 1,
 | 
					 | 
				
			||||||
        KEEP_OPEN_READWRITE = 2,
 | 
					 | 
				
			||||||
        FORCE_SAVE = 4,
 | 
					 | 
				
			||||||
        MAPI_DEFERRED_ERRORS = 8
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [ComImport]
 | 
					 | 
				
			||||||
    [Guid("00020303-0000-0000-C000-000000000046")]
 | 
					 | 
				
			||||||
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
 | 
					 | 
				
			||||||
    public interface IMAPIProp
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        void GetLastError(Int32 hResult, UInt32 flags, out IntPtr ptr);
 | 
					 | 
				
			||||||
        void SaveChanges(SaveChangesFlags flags);
 | 
					 | 
				
			||||||
        void GetProps();
 | 
					 | 
				
			||||||
        void GetPropList();
 | 
					 | 
				
			||||||
        void OpenProperty();
 | 
					 | 
				
			||||||
        void SetProps();
 | 
					 | 
				
			||||||
        void DeleteProps();
 | 
					 | 
				
			||||||
        void CopyTo();
 | 
					 | 
				
			||||||
        void CopyProps();
 | 
					 | 
				
			||||||
        void GetNamesFromIDs();
 | 
					 | 
				
			||||||
        void GetIDsFromNames();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    unsafe public struct SBinary
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public uint cb;
 | 
					 | 
				
			||||||
        public byte* ptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public byte[] Unmarshal()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            byte[] result = new byte[cb];
 | 
					 | 
				
			||||||
            Marshal.Copy((IntPtr)ptr, result, 0, result.Length);
 | 
					 | 
				
			||||||
            return result;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public override string ToString()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            byte[] b = Unmarshal();
 | 
					 | 
				
			||||||
            return b.Length.ToString() + ":" + StringUtil.BytesToHex(b);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    unsafe public struct SBinaryArray
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public uint count;
 | 
					 | 
				
			||||||
        public SBinary* ptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public byte[][] Unmarshal()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            byte[][] result = new byte[count][];
 | 
					 | 
				
			||||||
            for (uint i = 0; i < count; ++i)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                result[i] = ptr[i].Unmarshal();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return result;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public enum PropType : ushort
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        BOOLEAN = 0x000B,
 | 
					 | 
				
			||||||
        BINARY = 0x0102,
 | 
					 | 
				
			||||||
        MV_BINARY = 1102,
 | 
					 | 
				
			||||||
        DOUBLE = 0x0005,
 | 
					 | 
				
			||||||
        LONG = 0x0003,
 | 
					 | 
				
			||||||
        OBJECT = 0x000D,
 | 
					 | 
				
			||||||
        STRING8 = 0x001E,
 | 
					 | 
				
			||||||
        MV_STRING8 = 0x101E,
 | 
					 | 
				
			||||||
        SYSTIME = 0x0040,
 | 
					 | 
				
			||||||
        UNICODE = 0x001F,
 | 
					 | 
				
			||||||
        MV_UNICODE = 0x101f
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
 | 
					 | 
				
			||||||
    public struct PropTag
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public PropType type;
 | 
					 | 
				
			||||||
        public ushort prop;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public override string ToString()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return "<" + prop.ToString("X4") + ":" + type + ">";
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [StructLayout(LayoutKind.Explicit)]
 | 
					 | 
				
			||||||
    unsafe public struct PropValue
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        [FieldOffset(0)]
 | 
					 | 
				
			||||||
        public PropTag ulPropTag;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [FieldOffset(4)]
 | 
					 | 
				
			||||||
        public uint dwAlignPad;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //	short int			i;			/* case PT_I2 */
 | 
					 | 
				
			||||||
        //	LONG				l;			/* case PT_LONG */
 | 
					 | 
				
			||||||
        //	ULONG				ul;			/* alias for PT_LONG */
 | 
					 | 
				
			||||||
        //	LPVOID				lpv;		/* alias for PT_PTR */
 | 
					 | 
				
			||||||
        //	float				flt;		/* case PT_R4 */
 | 
					 | 
				
			||||||
        //	double				dbl;		/* case PT_DOUBLE */
 | 
					 | 
				
			||||||
        //	unsigned short int	b;			/* case PT_BOOLEAN */
 | 
					 | 
				
			||||||
        [FieldOffset(8), MarshalAs(UnmanagedType.U2)]
 | 
					 | 
				
			||||||
        public bool b;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //	CURRENCY			cur;		/* case PT_CURRENCY */
 | 
					 | 
				
			||||||
        //	double				at;			/* case PT_APPTIME */
 | 
					 | 
				
			||||||
        //	FILETIME			ft;			/* case PT_SYSTIME */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //	LPSTR				lpszA;		/* case PT_STRING8 */
 | 
					 | 
				
			||||||
        [FieldOffset(8), MarshalAs(UnmanagedType.LPStr)]
 | 
					 | 
				
			||||||
        public sbyte* lpszA;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //	SBinary				bin;		/* case PT_BINARY */
 | 
					 | 
				
			||||||
        [FieldOffset(8)]
 | 
					 | 
				
			||||||
        public SBinary bin;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //	LPWSTR				lpszW;		/* case PT_UNICODE */
 | 
					 | 
				
			||||||
        [FieldOffset(8), MarshalAs(UnmanagedType.LPWStr)]
 | 
					 | 
				
			||||||
        public char* lpszW;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //	LPGUID				lpguid;		/* case PT_CLSID */
 | 
					 | 
				
			||||||
        //	LARGE_INTEGER		li;			/* case PT_I8 */
 | 
					 | 
				
			||||||
        //	SShortArray			MVi;		/* case PT_MV_I2 */
 | 
					 | 
				
			||||||
        //	SLongArray			MVl;		/* case PT_MV_LONG */
 | 
					 | 
				
			||||||
        //	SRealArray			MVflt;		/* case PT_MV_R4 */
 | 
					 | 
				
			||||||
        //	SDoubleArray		MVdbl;		/* case PT_MV_DOUBLE */
 | 
					 | 
				
			||||||
        //	SCurrencyArray		MVcur;		/* case PT_MV_CURRENCY */
 | 
					 | 
				
			||||||
        //	SAppTimeArray		MVat;		/* case PT_MV_APPTIME */
 | 
					 | 
				
			||||||
        //	SDateTimeArray		MVft;		/* case PT_MV_SYSTIME */
 | 
					 | 
				
			||||||
        //	SBinaryArray		MVbin;		/* case PT_MV_BINARY */
 | 
					 | 
				
			||||||
        //	SLPSTRArray			MVszA;		/* case PT_MV_STRING8 */
 | 
					 | 
				
			||||||
        //	SWStringArray		MVszW;		/* case PT_MV_UNICODE */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //	SGuidArray			MVguid;		/* case PT_MV_CLSID */
 | 
					 | 
				
			||||||
        //	SLargeIntegerArray	MVli;		/* case PT_MV_I8 */
 | 
					 | 
				
			||||||
        //	SCODE				err;		/* case PT_ERROR */
 | 
					 | 
				
			||||||
        //	LONG				x;			/* case PT_NULL, PT_OBJECT (no usable value) */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public override string ToString()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            switch(ulPropTag.type)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                case PropType.BOOLEAN:
 | 
					 | 
				
			||||||
                    return b.ToString();
 | 
					 | 
				
			||||||
                case PropType.STRING8:
 | 
					 | 
				
			||||||
                    return new string(lpszA);
 | 
					 | 
				
			||||||
                case PropType.BINARY:
 | 
					 | 
				
			||||||
                    return bin.ToString();
 | 
					 | 
				
			||||||
                //case PropType.UNICODE:
 | 
					 | 
				
			||||||
                   // return lpszW.ToString();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return "<unknown>";
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe public struct CommentRestriction
 | 
					    unsafe public struct CommentRestriction
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -207,6 +47,13 @@ namespace Acacia.Native.MAPI
 | 
				
			|||||||
            s += "\n";
 | 
					            s += "\n";
 | 
				
			||||||
            return s;
 | 
					            return s;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public SearchQuery ToSearchQuery()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new SearchQuery.PropertyCompare(ulPropTag.ToPropertyIdentifier(),
 | 
				
			||||||
 | 
					                (SearchQuery.ComparisonOperation)(int)relop,
 | 
				
			||||||
 | 
					                prop->ToObject());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Flags]
 | 
					    [Flags]
 | 
				
			||||||
@@ -223,18 +70,26 @@ namespace Acacia.Native.MAPI
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    unsafe public struct ContentRestriction
 | 
					    unsafe public struct ContentRestriction
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public FuzzyLevel fuzzy;
 | 
					        public FuzzyLevel ulFuzzyLevel;
 | 
				
			||||||
        public PropTag ulPropTag;
 | 
					        public PropTag ulPropTag;
 | 
				
			||||||
        public PropValue* prop;
 | 
					        public PropValue* prop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public string ToString(int depth)
 | 
					        public string ToString(int depth)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            string indent = new string(' ', depth);
 | 
					            string indent = new string(' ', depth);
 | 
				
			||||||
            string s = indent + fuzzy + ":" + ulPropTag.ToString();
 | 
					            string s = indent + ulFuzzyLevel + ":" + ulPropTag.ToString();
 | 
				
			||||||
            s += ":" + prop->ToString();
 | 
					            s += ":" + prop->ToString();
 | 
				
			||||||
            s += "\n";
 | 
					            s += "\n";
 | 
				
			||||||
            return s;
 | 
					            return s;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public SearchQuery ToSearchQuery()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new SearchQuery.PropertyContent(ulPropTag.ToPropertyIdentifier(),
 | 
				
			||||||
 | 
					                (SearchQuery.ContentMatchOperation)((uint)ulFuzzyLevel & 0xF),
 | 
				
			||||||
 | 
					                (SearchQuery.ContentMatchModifiers)(((uint)ulFuzzyLevel & 0xF0000) >> 16),
 | 
				
			||||||
 | 
					                prop->ToObject());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO: merge with ISearch
 | 
					    // TODO: merge with ISearch
 | 
				
			||||||
@@ -269,6 +124,16 @@ namespace Acacia.Native.MAPI
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            return s;
 | 
					            return s;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public SearchQuery ToSearchQuery(bool and)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SearchQuery.MultiOperator oper = and ? (SearchQuery.MultiOperator)new SearchQuery.And() : new SearchQuery.Or(); ;
 | 
				
			||||||
 | 
					            for (uint i = 0; i < cb; ++i)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                oper.Add(ptr[i].ToSearchQuery());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return oper;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe public struct NotRestriction
 | 
					    unsafe public struct NotRestriction
 | 
				
			||||||
@@ -280,6 +145,11 @@ namespace Acacia.Native.MAPI
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            return ptr->ToString(depth);
 | 
					            return ptr->ToString(depth);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public SearchQuery ToSearchQuery()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new SearchQuery.Not(ptr->ToSearchQuery());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public enum BMR : uint
 | 
					    public enum BMR : uint
 | 
				
			||||||
@@ -303,6 +173,11 @@ namespace Acacia.Native.MAPI
 | 
				
			|||||||
            string indent = new string(' ', depth);
 | 
					            string indent = new string(' ', depth);
 | 
				
			||||||
            return indent + ToString() + "\n";
 | 
					            return indent + ToString() + "\n";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public SearchQuery ToSearchQuery()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new SearchQuery.PropertyBitMask(prop.ToPropertyIdentifier(), (SearchQuery.BitMaskOperation)(int)bmr, mask);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe public struct ExistRestriction
 | 
					    unsafe public struct ExistRestriction
 | 
				
			||||||
@@ -320,6 +195,11 @@ namespace Acacia.Native.MAPI
 | 
				
			|||||||
            string indent = new string(' ', depth);
 | 
					            string indent = new string(' ', depth);
 | 
				
			||||||
            return indent + prop.ToString() + "\n";
 | 
					            return indent + prop.ToString() + "\n";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public SearchQuery ToSearchQuery()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new SearchQuery.PropertyExists(prop.ToPropertyIdentifier());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [StructLayout(LayoutKind.Explicit)]
 | 
					    [StructLayout(LayoutKind.Explicit)]
 | 
				
			||||||
@@ -328,6 +208,7 @@ namespace Acacia.Native.MAPI
 | 
				
			|||||||
        [FieldOffset(0)]
 | 
					        [FieldOffset(0)]
 | 
				
			||||||
        public RestrictionType rt;
 | 
					        public RestrictionType rt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // And/Or
 | 
				
			||||||
        [FieldOffset(8)]
 | 
					        [FieldOffset(8)]
 | 
				
			||||||
        public SubRestriction sub;
 | 
					        public SubRestriction sub;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -349,6 +230,37 @@ namespace Acacia.Native.MAPI
 | 
				
			|||||||
        [FieldOffset(8)]
 | 
					        [FieldOffset(8)]
 | 
				
			||||||
        public CommentRestriction comment;
 | 
					        public CommentRestriction comment;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public SearchQuery ToSearchQuery()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            switch (rt)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                case RestrictionType.AND:
 | 
				
			||||||
 | 
					                    return sub.ToSearchQuery(true);
 | 
				
			||||||
 | 
					                case RestrictionType.OR:
 | 
				
			||||||
 | 
					                    return sub.ToSearchQuery(false);
 | 
				
			||||||
 | 
					                case RestrictionType.NOT:
 | 
				
			||||||
 | 
					                    return not.ToSearchQuery();
 | 
				
			||||||
 | 
					                case RestrictionType.CONTENT:
 | 
				
			||||||
 | 
					                    return content.ToSearchQuery();
 | 
				
			||||||
 | 
					                case RestrictionType.PROPERTY:
 | 
				
			||||||
 | 
					                    return prop.ToSearchQuery();
 | 
				
			||||||
 | 
					                case RestrictionType.BITMASK:
 | 
				
			||||||
 | 
					                    return bitMask.ToSearchQuery();
 | 
				
			||||||
 | 
					                case RestrictionType.EXIST:
 | 
				
			||||||
 | 
					                    return exist.ToSearchQuery();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    /* TODO        COMPAREPROPS,
 | 
				
			||||||
 | 
					                            BITMASK,
 | 
				
			||||||
 | 
					                            SIZE,
 | 
				
			||||||
 | 
					                            SUBRESTRICTION,
 | 
				
			||||||
 | 
					                            COMMENT,
 | 
				
			||||||
 | 
					                            COUNT,
 | 
				
			||||||
 | 
					                            ANNOTATION*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public override string ToString()
 | 
					        public override string ToString()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return ToString(0);
 | 
					            return ToString(0);
 | 
				
			||||||
@@ -358,7 +270,7 @@ namespace Acacia.Native.MAPI
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            string indent = new string(' ', depth);
 | 
					            string indent = new string(' ', depth);
 | 
				
			||||||
            string s = indent + rt.ToString() + "\n" + indent + "{\n";
 | 
					            string s = indent + rt.ToString() + "\n" + indent + "{\n";
 | 
				
			||||||
            switch(rt)
 | 
					            switch (rt)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                case RestrictionType.AND:
 | 
					                case RestrictionType.AND:
 | 
				
			||||||
                case RestrictionType.OR:
 | 
					                case RestrictionType.OR:
 | 
				
			||||||
@@ -394,69 +306,143 @@ namespace Acacia.Native.MAPI
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Flags]
 | 
					    /// <summary>
 | 
				
			||||||
    public enum GetSearchCriteriaState : UInt32
 | 
					    /// Encodes a search as an SRestriction. Note that as memory needs to be managed for the miscellaneous structures,
 | 
				
			||||||
 | 
					    /// the SRestriction is only valid until RestrictionEncoder is disposed.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    unsafe public class RestrictionEncoder : NativeEncoder, ISearchEncoder
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        NONE = 0,
 | 
					        private class EncodingStack
 | 
				
			||||||
        SEARCH_RUNNING = 1,
 | 
					        {
 | 
				
			||||||
        SEARCH_REBUILD = 2,
 | 
					            public SRestriction[] array;
 | 
				
			||||||
        SEARCH_RECURSIVE = 4,
 | 
					            public int index;
 | 
				
			||||||
        SEARCH_FOREGROUND = 8
 | 
					            public SRestriction* ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public EncodingStack(int count, Allocation<SRestriction[]> alloc)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                array = alloc.Object;
 | 
				
			||||||
 | 
					                index = 0;
 | 
				
			||||||
 | 
					                ptr = (SRestriction*)alloc.Pointer;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        private readonly Stack<EncodingStack> _current = new Stack<EncodingStack>();
 | 
				
			||||||
 | 
					        private readonly EncodingStack _root;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public RestrictionEncoder()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Create an object for the root element
 | 
				
			||||||
 | 
					            _root = Begin(1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected override void DoRelease()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // TODO
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public SRestriction Restriction
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get { return _root.array[0]; }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private SRestriction* Current
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                EncodingStack top = _current.Peek();
 | 
				
			||||||
 | 
					                return top.ptr + top.index;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Encode(SearchQuery.PropertyExists part)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            throw new NotImplementedException();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Encode(SearchQuery.Or part)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            throw new NotImplementedException();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Encode(SearchQuery.PropertyIdentifier part)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            throw new NotImplementedException();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Encode(SearchQuery.Not part)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            throw new NotImplementedException();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Encode(SearchQuery.And part)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Current->rt = RestrictionType.AND;
 | 
				
			||||||
 | 
					            Current->sub.cb = (uint)part.Operands.Count;
 | 
				
			||||||
 | 
					            Current->sub.ptr = EncodePointer(part.Operands);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private SRestriction* EncodePointer(IEnumerable<SearchQuery> operands)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            EncodingStack alloc = Begin(operands.Count());
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                foreach (SearchQuery operand in operands)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    operand.Encode(this);
 | 
				
			||||||
 | 
					                    ++alloc.index;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            finally
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                End();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return alloc.ptr;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private EncodingStack Begin(int count)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Allocate and push the array
 | 
				
			||||||
 | 
					            EncodingStack alloc = new EncodingStack(count, Allocate(new SRestriction[count]));
 | 
				
			||||||
 | 
					            _current.Push(alloc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return alloc;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void End()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _current.Pop();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Encode(SearchQuery.PropertyContent part)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            throw new NotImplementedException();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Encode(SearchQuery.PropertyCompare part)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Current->rt = RestrictionType.PROPERTY;
 | 
				
			||||||
 | 
					            Current->prop.relop = (SearchOperation)part.Operation;
 | 
				
			||||||
 | 
					            Current->prop.ulPropTag = part.Property.Tag;
 | 
				
			||||||
 | 
					            Current->prop.prop = PropValue.FromObject(this, part.Value);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Encode(SearchQuery.PropertyBitMask part)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            throw new NotImplementedException();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Flags]
 | 
					    public static class RestrictionExensions
 | 
				
			||||||
    public enum SetSearchCriteriaFlags : UInt32
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        NONE = 0,
 | 
					        /// <summary>
 | 
				
			||||||
        STOP_SEARCH				= 0x00000001,
 | 
					        /// Encodes the search as an SRestriction.
 | 
				
			||||||
        RESTART_SEARCH			= 0x00000002,
 | 
					        /// </summary>
 | 
				
			||||||
        RECURSIVE_SEARCH		= 0x00000004,
 | 
					        /// <returns>The encoder containing the restriction. The caller is responsible for disposing.</returns>
 | 
				
			||||||
        SHALLOW_SEARCH			= 0x00000008,
 | 
					        public static RestrictionEncoder ToRestriction(this SearchQuery search)
 | 
				
			||||||
        FOREGROUND_SEARCH		= 0x00000010,
 | 
					        {
 | 
				
			||||||
        BACKGROUND_SEARCH		= 0x00000020,
 | 
					            RestrictionEncoder encoder = new RestrictionEncoder();
 | 
				
			||||||
    }
 | 
					            search.Encode(encoder);
 | 
				
			||||||
 | 
					            return encoder;
 | 
				
			||||||
    [ComImport]
 | 
					        }
 | 
				
			||||||
    [Guid("0002030B-0000-0000-C000-000000000046")]
 | 
					 | 
				
			||||||
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
 | 
					 | 
				
			||||||
    unsafe public interface IMAPIContainer// TODO : IMAPIProp
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // IMAPIProp
 | 
					 | 
				
			||||||
        void GetLastError(Int32 hResult, UInt32 flags, out IntPtr ptr);
 | 
					 | 
				
			||||||
        void SaveChanges(SaveChangesFlags flags);
 | 
					 | 
				
			||||||
        void GetProps();
 | 
					 | 
				
			||||||
        void GetPropList();
 | 
					 | 
				
			||||||
        void OpenProperty();
 | 
					 | 
				
			||||||
        void SetProps();
 | 
					 | 
				
			||||||
        void DeleteProps();
 | 
					 | 
				
			||||||
        void CopyTo();
 | 
					 | 
				
			||||||
        void CopyProps();
 | 
					 | 
				
			||||||
        void GetNamesFromIDs();
 | 
					 | 
				
			||||||
        void GetIDsFromNames();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void GetContentsTable(UInt32 flags, out IntPtr table);
 | 
					 | 
				
			||||||
        void GetHierarchyTable();
 | 
					 | 
				
			||||||
        void OpenEntry();
 | 
					 | 
				
			||||||
        void SetSearchCriteria(SRestriction* lppRestriction, SBinaryArray* lppContainerList, SetSearchCriteriaFlags flags);
 | 
					 | 
				
			||||||
        void GetSearchCriteria(UInt32 flags, SRestriction** lppRestriction, SBinaryArray** lppContainerList, out GetSearchCriteriaState state);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [ComImport]
 | 
					 | 
				
			||||||
    [Guid("0002030C-0000-0000-C000-000000000046")]
 | 
					 | 
				
			||||||
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
 | 
					 | 
				
			||||||
    public interface IMAPIFolder : IMAPIContainer
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        void CreateMessage();
 | 
					 | 
				
			||||||
        void CopyMessages();
 | 
					 | 
				
			||||||
        void DeleteMessages();
 | 
					 | 
				
			||||||
        void CreateFolder();
 | 
					 | 
				
			||||||
        void CopyFolder();
 | 
					 | 
				
			||||||
        void DeleteFolder();
 | 
					 | 
				
			||||||
        void SetReadFlags();
 | 
					 | 
				
			||||||
        void GetMessageStatus();
 | 
					 | 
				
			||||||
        void SetMessageStatus();
 | 
					 | 
				
			||||||
        void SaveContentsSort();
 | 
					 | 
				
			||||||
        void EmptyFolder();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Example search code
 | 
					    /* Example search code
 | 
				
			||||||
@@ -0,0 +1,82 @@
 | 
				
			|||||||
 | 
					using Acacia.Utils;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Runtime.InteropServices;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Acacia.Native
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    /// Helper for encoding objects into native structures.
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    abstract public class NativeEncoder : DisposableWrapper
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        abstract protected class AllocationBase
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            protected readonly object _obj;
 | 
				
			||||||
 | 
					            protected readonly GCHandle _handle;
 | 
				
			||||||
 | 
					            protected readonly IntPtr _ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public AllocationBase(Type type, int size)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _ptr = Marshal.AllocHGlobal(size);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public AllocationBase(object obj)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                this._obj = obj;
 | 
				
			||||||
 | 
					                _handle = GCHandle.Alloc(obj, GCHandleType.Pinned);
 | 
				
			||||||
 | 
					                _ptr = _handle.AddrOfPinnedObject();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // TODO: release
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        unsafe protected class Allocation<ObjType> : AllocationBase
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public Allocation(int size) : base(typeof(ObjType), size)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public Allocation(ObjType obj) : base(obj)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public ObjType Object
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                get
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return (ObjType)_obj;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public IntPtr Pointer
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                get
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return _ptr;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private readonly List<AllocationBase> _allocs = new List<AllocationBase>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Allocates an object of the specified type. The allocation is managed by this encoder.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name="size">If larger than 0, the size to allocate. Otherwise, the size of the object is used.</param>
 | 
				
			||||||
 | 
					        /// <returns>The allocated object.</returns>
 | 
				
			||||||
 | 
					        protected Allocation<ObjType> Allocate<ObjType>(int size = -1)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            throw new NotImplementedException();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected Allocation<ObjType> Allocate<ObjType>(ObjType obj)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Allocation<ObjType> alloc = new Allocation<ObjType>(obj);
 | 
				
			||||||
 | 
					            _allocs.Add(alloc);
 | 
				
			||||||
 | 
					            return alloc;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										364
									
								
								src/AcaciaZPushPlugin/AcaciaZPushPlugin/SearchQuery.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										364
									
								
								src/AcaciaZPushPlugin/AcaciaZPushPlugin/SearchQuery.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,364 @@
 | 
				
			|||||||
 | 
					/// Copyright 2017 Kopano b.v.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					/// it under the terms of the GNU Affero General Public License, version 3,
 | 
				
			||||||
 | 
					/// as published by the Free Software Foundation.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					/// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
 | 
				
			||||||
 | 
					/// GNU Affero General Public License for more details.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// You should have received a copy of the GNU Affero General Public License
 | 
				
			||||||
 | 
					/// along with this program.If not, see<http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					/// 
 | 
				
			||||||
 | 
					/// Consult LICENSE file for details
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using Acacia.Native.MAPI;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Acacia
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public interface ISearchEncoder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        void Encode(SearchQuery.PropertyBitMask part);
 | 
				
			||||||
 | 
					        void Encode(SearchQuery.PropertyCompare part);
 | 
				
			||||||
 | 
					        void Encode(SearchQuery.PropertyContent part);
 | 
				
			||||||
 | 
					        void Encode(SearchQuery.PropertyExists part);
 | 
				
			||||||
 | 
					        void Encode(SearchQuery.And part);
 | 
				
			||||||
 | 
					        void Encode(SearchQuery.Or part);
 | 
				
			||||||
 | 
					        void Encode(SearchQuery.Not part);
 | 
				
			||||||
 | 
					        void Encode(SearchQuery.PropertyIdentifier part);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public class ToStringEncoder : ISearchEncoder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private readonly StringBuilder _builder = new StringBuilder();
 | 
				
			||||||
 | 
					        private int _indent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void Indent()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _builder.Append(new String(' ', _indent));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Encode(SearchQuery.And part)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            EncodeMulti("AND", part.Operands);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Encode(SearchQuery.Or part)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            EncodeMulti("OR", part.Operands);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Encode(SearchQuery.Not part)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            EncodeMulti("NOT", new[] { part.Operand });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void EncodeMulti(string oper, IEnumerable<SearchQuery> parts)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Indent();
 | 
				
			||||||
 | 
					            _builder.Append(oper).Append("\n");
 | 
				
			||||||
 | 
					            Indent();
 | 
				
			||||||
 | 
					            _builder.Append("{\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ++_indent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach (SearchQuery operand in parts)
 | 
				
			||||||
 | 
					                operand.Encode(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            --_indent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Indent();
 | 
				
			||||||
 | 
					            _builder.Append("}\n");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Encode(SearchQuery.PropertyBitMask part)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Indent();
 | 
				
			||||||
 | 
					            _builder.Append("BITMASK{");
 | 
				
			||||||
 | 
					            part.Property.Encode(this);
 | 
				
			||||||
 | 
					            _builder.Append(" ").Append(part.Operation).Append(" ");
 | 
				
			||||||
 | 
					            _builder.Append(part.Mask.ToString("X8"));
 | 
				
			||||||
 | 
					            _builder.Append("}\n");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static readonly string[] COMPARISON_OPERATORS = {"<", "<=", ">", ">=", "==", "!=", "LIKE"};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Encode(SearchQuery.PropertyCompare part)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Indent();
 | 
				
			||||||
 | 
					            _builder.Append("COMPARE{");
 | 
				
			||||||
 | 
					            part.Property.Encode(this);
 | 
				
			||||||
 | 
					            _builder.Append(" ").Append(COMPARISON_OPERATORS[(int)part.Operation]).Append(" ");
 | 
				
			||||||
 | 
					            _builder.Append(part.Value);
 | 
				
			||||||
 | 
					            _builder.Append("}\n"); 
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Encode(SearchQuery.PropertyContent part)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Indent();
 | 
				
			||||||
 | 
					            _builder.Append("CONTENT{");
 | 
				
			||||||
 | 
					            part.Property.Encode(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            List<string> options = new List<string>();
 | 
				
			||||||
 | 
					            if (part.Operation != SearchQuery.ContentMatchOperation.Full)
 | 
				
			||||||
 | 
					                options.Add(part.Operation.ToString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (part.Modifiers != SearchQuery.ContentMatchModifiers.None)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                options.Add(part.Modifiers.ToString());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            string optionsString = options.Count == 0 ? "" : ("(" + string.Join(",", options) + ")");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            _builder.Append(" ==").Append(optionsString).Append(" ");
 | 
				
			||||||
 | 
					            _builder.Append(part.Content);
 | 
				
			||||||
 | 
					            _builder.Append("}\n");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Encode(SearchQuery.PropertyExists part)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Indent();
 | 
				
			||||||
 | 
					            _builder.Append("EXISTS{");
 | 
				
			||||||
 | 
					            part.Property.Encode(this);
 | 
				
			||||||
 | 
					            _builder.Append("}\n");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Encode(SearchQuery.PropertyIdentifier part)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _builder.Append(part.Id);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string GetValue()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return _builder.ToString();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    abstract public class SearchQuery
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        #region Interface
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        override public string ToString()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            ToStringEncoder encoder = new ToStringEncoder();
 | 
				
			||||||
 | 
					            Encode(encoder);
 | 
				
			||||||
 | 
					            return encoder.GetValue();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        abstract public void Encode(ISearchEncoder encoder);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #region Implementations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        abstract public class MultiOperator : SearchQuery
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            private readonly List<SearchQuery> _operands = new List<SearchQuery>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public void Add(SearchQuery operand)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (operand == null)
 | 
				
			||||||
 | 
					                    throw new ArgumentNullException();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                _operands.Add(operand);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public ICollection<SearchQuery> Operands
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                get { return _operands; }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public class And : MultiOperator
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public override void Encode(ISearchEncoder encoder)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                encoder.Encode(this);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public class Or : MultiOperator
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public override void Encode(ISearchEncoder encoder)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                encoder.Encode(this);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public class Not : SearchQuery
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public SearchQuery Operand
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                get;
 | 
				
			||||||
 | 
					                set;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public Not(SearchQuery operand)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                this.Operand = operand;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public override void Encode(ISearchEncoder encoder)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                encoder.Encode(this);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// TODO: this is globally useful
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        public class PropertyIdentifier
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public string Id { get; private set; }
 | 
				
			||||||
 | 
					            public PropTag Tag { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public PropertyIdentifier(PropTag tag)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                this.Tag = tag;
 | 
				
			||||||
 | 
					                Id = string.Format("{0:X4}{1:X4}", tag.prop, (int)tag.type);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public void Encode(ISearchEncoder encoder)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                encoder.Encode(this);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public override string ToString()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return Id;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        abstract public class PropertyQuery : SearchQuery
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public PropertyIdentifier Property { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            protected PropertyQuery(PropertyIdentifier property)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                this.Property = property;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Order matches MAPI RELOP_ constants
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        public enum ComparisonOperation : uint
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Smaller,
 | 
				
			||||||
 | 
					            SmallerEqual,
 | 
				
			||||||
 | 
					            Greater,
 | 
				
			||||||
 | 
					            GreaterEqual,
 | 
				
			||||||
 | 
					            Equal,
 | 
				
			||||||
 | 
					            NotEqual,
 | 
				
			||||||
 | 
					            Like
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public class PropertyCompare : PropertyQuery
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public ComparisonOperation Operation { get; set; }
 | 
				
			||||||
 | 
					            public object Value { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public PropertyCompare(PropertyIdentifier property, ComparisonOperation operation, object value) : base(property)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                this.Operation = operation;
 | 
				
			||||||
 | 
					                this.Value = value;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public override void Encode(ISearchEncoder encoder)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                encoder.Encode(this);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public class PropertyExists : PropertyQuery
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public PropertyExists(PropertyIdentifier property) : base(property)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public override void Encode(ISearchEncoder encoder)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                encoder.Encode(this);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public enum ContentMatchOperation
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            /// <summary>
 | 
				
			||||||
 | 
					            /// Match full content
 | 
				
			||||||
 | 
					            /// </summary>
 | 
				
			||||||
 | 
					            Full,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /// <summary>
 | 
				
			||||||
 | 
					            /// Match part of the content
 | 
				
			||||||
 | 
					            /// </summary>
 | 
				
			||||||
 | 
					            SubString,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /// <summary>
 | 
				
			||||||
 | 
					            /// Match the start of the content
 | 
				
			||||||
 | 
					            /// </summary>
 | 
				
			||||||
 | 
					            Prefix
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Flags]
 | 
				
			||||||
 | 
					        public enum ContentMatchModifiers
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            None = 0,
 | 
				
			||||||
 | 
					            CaseInsensitive = 1,
 | 
				
			||||||
 | 
					            IgnoreNonSpace = 2,
 | 
				
			||||||
 | 
					            Loose = 4
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public class PropertyContent : PropertyQuery
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public ContentMatchOperation Operation { get; set; }
 | 
				
			||||||
 | 
					            public ContentMatchModifiers Modifiers { get; set; }
 | 
				
			||||||
 | 
					            public object Content { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public PropertyContent(PropertyIdentifier property, ContentMatchOperation operation, ContentMatchModifiers modifiers, object content) : base(property)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                this.Operation = operation;
 | 
				
			||||||
 | 
					                this.Modifiers = modifiers;
 | 
				
			||||||
 | 
					                this.Content = content;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public override void Encode(ISearchEncoder encoder)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                encoder.Encode(this);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public enum BitMaskOperation
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            EQZ, NEZ
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public class PropertyBitMask : PropertyQuery
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public BitMaskOperation Operation { get; set; }
 | 
				
			||||||
 | 
					            public uint Mask { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public PropertyBitMask(PropertyIdentifier property, BitMaskOperation operation, uint mask) : base(property)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                this.Operation = operation;
 | 
				
			||||||
 | 
					                this.Mask = mask;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public override void Encode(ISearchEncoder encoder)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                encoder.Encode(this);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #endregion
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -62,6 +62,13 @@ namespace Acacia.Stubs
 | 
				
			|||||||
        SuggestedContacts = 30
 | 
					        SuggestedContacts = 30
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Replacement for OlSpecialFolders
 | 
				
			||||||
 | 
					    public enum SpecialFolder
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        AllTasks = 0,
 | 
				
			||||||
 | 
					        Reminders = 1
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public enum AccountType
 | 
					    public enum AccountType
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // TODO
 | 
					        // TODO
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -114,5 +114,11 @@ namespace Acacia.Stubs
 | 
				
			|||||||
        ZPushFolder ZPush { get; set; }
 | 
					        ZPushFolder ZPush { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        IFolder Clone();
 | 
					        IFolder Clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SearchQuery SearchCriteria
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get;
 | 
				
			||||||
 | 
					            set;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,10 +53,14 @@ namespace Acacia.Stubs
 | 
				
			|||||||
        ISearchField AddField(string name, bool isUserField = false);
 | 
					        ISearchField AddField(string name, bool isUserField = false);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public interface ISearch<ItemType> : ISearchOperator, IDisposable
 | 
					    public interface ISearchQuery : ISearchOperator
 | 
				
			||||||
    where ItemType : IItem
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        ISearchOperator AddOperator(SearchOperator oper);
 | 
					        ISearchOperator AddOperator(SearchOperator oper);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public interface ISearch<ItemType> : ISearchQuery, IDisposable
 | 
				
			||||||
 | 
					    where ItemType : IItem
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        IEnumerable<ItemType> Search(int maxResults = int.MaxValue);
 | 
					        IEnumerable<ItemType> Search(int maxResults = int.MaxValue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,6 +40,12 @@ namespace Acacia.Stubs
 | 
				
			|||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        string GetDefaultFolderId(DefaultFolder folder);
 | 
					        string GetDefaultFolderId(DefaultFolder folder);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Returns a special folder.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <returns>The special folder. The caller is responsible for disposing.</returns>
 | 
				
			||||||
 | 
					        IFolder GetSpecialFolder(SpecialFolder folder);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        IItem GetItemFromID(string id);
 | 
					        IItem GetItemFromID(string id);
 | 
				
			||||||
        string DisplayName { get; }
 | 
					        string DisplayName { get; }
 | 
				
			||||||
        string StoreID { get; }
 | 
					        string StoreID { get; }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,6 +23,7 @@ using System.Collections;
 | 
				
			|||||||
using Acacia.Utils;
 | 
					using Acacia.Utils;
 | 
				
			||||||
using Acacia.ZPush;
 | 
					using Acacia.ZPush;
 | 
				
			||||||
using NSOutlook = Microsoft.Office.Interop.Outlook;
 | 
					using NSOutlook = Microsoft.Office.Interop.Outlook;
 | 
				
			||||||
 | 
					using Acacia.Native.MAPI;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Acacia.Stubs.OutlookWrappers
 | 
					namespace Acacia.Stubs.OutlookWrappers
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -371,5 +372,31 @@ namespace Acacia.Stubs.OutlookWrappers
 | 
				
			|||||||
            get;
 | 
					            get;
 | 
				
			||||||
            set;
 | 
					            set;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        unsafe public SearchQuery SearchCriteria
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                IMAPIFolder imapi = _item.MAPIOBJECT as IMAPIFolder;
 | 
				
			||||||
 | 
					                try
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    SearchCriteriaState state;
 | 
				
			||||||
 | 
					                    SBinaryArray* sb1;
 | 
				
			||||||
 | 
					                    SRestriction* restrict;
 | 
				
			||||||
 | 
					                    imapi.GetSearchCriteria(0, &restrict, &sb1, out state);
 | 
				
			||||||
 | 
					                    Logger.Instance.Warning(this, "SEARCH:\n{0}", restrict->ToString());
 | 
				
			||||||
 | 
					                    return restrict->ToSearchQuery();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                finally
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    ComRelease.Release(imapi);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            set
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -67,6 +67,18 @@ namespace Acacia.Stubs.OutlookWrappers
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IFolder GetSpecialFolder(SpecialFolder folder)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return _item.GetSpecialFolder((NSOutlook.OlSpecialFolders)(int)folder).Wrap();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public IItem GetItemFromID(string id)
 | 
					        public IItem GetItemFromID(string id)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            using (ComRelease com = new ComRelease())
 | 
					            using (ComRelease com = new ComRelease())
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user