ThisAddIn.cs
author Thomas
Mon, 29 Jul 2019 11:21:16 +0200
branchsync
changeset 2686 f2e370d69120
parent 2667 1a7d192f0d56
child 2689 7cd444e4eaa0
permissions -rw-r--r--
Formatting
Thomas@2628
     1
using Microsoft.Win32;
Thomas@2628
     2
using pEp.Extensions;
Thomas@2551
     3
using pEp.UI;
Dean@155
     4
using pEpCOMServerAdapterLib;
Dean@155
     5
using System;
vb@0
     6
using System.Collections.Generic;
Dean@1262
     7
using System.ComponentModel;
Dean@155
     8
using System.Globalization;
Dean@1262
     9
using System.IO;
vb@0
    10
using System.Runtime.InteropServices;
Thomas@2328
    11
using System.Threading.Tasks;
vb@47
    12
using System.Windows.Forms;
Dean@714
    13
using Office = Microsoft.Office.Core;
vb@0
    14
using Outlook = Microsoft.Office.Interop.Outlook;
vb@0
    15
vb@0
    16
namespace pEp
vb@0
    17
{
vb@0
    18
    public partial class ThisAddIn
vb@0
    19
    {
Dean@190
    20
        #region VSTO generated code
Dean@190
    21
Dean@190
    22
        /// <summary>
Dean@190
    23
        /// Required method for Designer support - do not modify
Dean@190
    24
        /// the contents of this method with the code editor.
Dean@190
    25
        /// </summary>
Dean@190
    26
        private void InternalStartup()
Dean@190
    27
        {
Dean@190
    28
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
Dean@190
    29
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
Dean@190
    30
        }
markus@201
    31
Dean@190
    32
        #endregion
Dean@190
    33
Dean@1441
    34
        /// <summary>
Dean@1441
    35
        /// Custom event for when the add-in is starting for the first time.
Dean@1441
    36
        /// </summary>
Dean@1441
    37
        internal event EventHandler FirstStartup;
Dean@1441
    38
Dean@1262
    39
        private List<KeyValuePair<CultureInfo, string>> _LanguageList       = null;
Dean@1262
    40
        private static pEpEngine                        _PEPEngine          = null;
markus@1987
    41
        private static Exception                        _PEPEngineException = null;
Thomas@2652
    42
        private string                                  _PEPStoreEntryId    = null;
Dean@1262
    43
        private Outlook.Folder                          _PEPStoreRootFolder = null;
Dean@1262
    44
        private PEPSettings                             _Settings           = null;
Thomas@1948
    45
        private OutlookOptions                          _OutlookOptions     = null;
Thomas@1770
    46
        private static DecryptionStack                  _DecryptionStack    = null;
Thomas@2659
    47
        private static SyncQueue                        _SyncQueue          = null;
vb@64
    48
Dean@1405
    49
#if !READER_RELEASE_MODE
Dean@1405
    50
        private AdapterCallbacks adapterCallbacks = null;
Dean@1405
    51
#endif
Dean@1405
    52
Thomas@2293
    53
        private bool                        initialized                 = false;
Thomas@2293
    54
        private bool                        isItemSendHandlerEnabled    = true;
Thomas@2293
    55
        private FormControlOptions.State    lastOptionsState            = null;
Thomas@2293
    56
        private List<WatchedFolder>         watchedFolders              = new List<WatchedFolder>();
Thomas@2293
    57
        private System.Windows.Forms.Timer  inboxCleaner                = null;
Thomas@2293
    58
Thomas@2293
    59
        private List<WatchedExplorer>       watchedExplorers            = new List<WatchedExplorer>();
Thomas@2359
    60
        private List<WatchedInspector>      watchedInspectors           = new List<WatchedInspector>();
Thomas@2293
    61
        private object                      mutexWatchedExplorers       = new object();
Thomas@2359
    62
        private object                      mutexWatchedInspectors      = new object();
Thomas@2293
    63
        private Outlook.Explorers           explorers                   = null;
Thomas@2359
    64
        private Outlook.Inspectors          inspectors                  = null;
Dean@190
    65
Dean@190
    66
        /**************************************************************
Dean@190
    67
         * 
Dean@190
    68
         * Property Accessors
Dean@190
    69
         * 
Dean@190
    70
         *************************************************************/
Dean@190
    71
Dean@190
    72
        /// <summary>
Dean@854
    73
        /// Gets the list of languages supported in the pEp engine.
Dean@935
    74
        /// The list of language includes a key-value pair of the culture as well as a 
Dean@935
    75
        /// display phrase in the native language for the trustwords.
Dean@935
    76
        /// (phrase example: "I want to display the trustwords in English language")
Dean@854
    77
        /// </summary>
Dean@935
    78
        internal List<KeyValuePair<CultureInfo, string>> LanguageList
Dean@854
    79
        {
Dean@854
    80
            get
Dean@854
    81
            {
Dean@854
    82
                string code;
Dean@935
    83
                string phrase;
Dean@854
    84
                string engineList;
Dean@854
    85
                string[] languages;
Dean@854
    86
                string[] language;
Dean@854
    87
Dean@854
    88
                if (this._LanguageList == null)
Dean@854
    89
                {
Dean@935
    90
                    this._LanguageList = new List<KeyValuePair<CultureInfo, string>>();
Dean@935
    91
Dean@935
    92
                    try
Dean@935
    93
                    {
markus@1343
    94
                        engineList = ThisAddIn.PEPEngine.GetLanguageList();
Dean@935
    95
                    }
Dean@935
    96
                    catch
Dean@935
    97
                    {
Dean@935
    98
                        engineList = "";
Dean@1262
    99
                        Log.Error("LanguageList: Failed to get list from engine.");
Dean@935
   100
                    }
Dean@935
   101
Dean@854
   102
                    languages = engineList.Split('\n');
Dean@854
   103
Dean@854
   104
                    // Go through each language group
Dean@854
   105
                    for (int i = 0; i < languages.Length; i++)
Dean@854
   106
                    {
Dean@854
   107
                        language = languages[i].Split(',');
Dean@854
   108
Dean@935
   109
                        if (language.Length == 3)
Dean@854
   110
                        {
Dean@854
   111
                            code = language[0].Trim();
Dean@854
   112
                            code = code.Replace("\"", "");
Dean@854
   113
Thomas@1583
   114
                            phrase = language[1].Trim();
Dean@935
   115
                            phrase = phrase.Replace("\"", "");
Dean@935
   116
Dean@935
   117
                            this._LanguageList.Add(new KeyValuePair<CultureInfo, string>(new CultureInfo(code),
Dean@935
   118
                                                                                         phrase));
Dean@854
   119
                        }
Dean@854
   120
                    }
Dean@854
   121
                }
Dean@854
   122
Dean@854
   123
                return (this._LanguageList);
Dean@854
   124
            }
Dean@854
   125
        }
Dean@854
   126
Dean@854
   127
        /// <summary>
Dean@1262
   128
        /// Gets the static pEp engine reference.
Dean@190
   129
        /// </summary>
Dean@1262
   130
        internal static pEpEngine PEPEngine
vb@64
   131
        {
vb@64
   132
            get
vb@64
   133
            {
Dean@1262
   134
                if (ThisAddIn._PEPEngine == null)
vb@64
   135
                {
vb@64
   136
                    try
vb@64
   137
                    {
Dean@1262
   138
                        ThisAddIn._PEPEngine = new pEpEngine();
vb@64
   139
                    }
Dean@467
   140
                    catch (Exception ex)
vb@64
   141
                    {
markus@1987
   142
                        // As Globals.StopAndSendCrashReport below internally tries to access the engine
markus@1987
   143
                        // several times, we need to prevent infinite recursion in case of engine
markus@1987
   144
                        // initializaition failure.
markus@1987
   145
                        if (_PEPEngineException != null)
Thomas@2003
   146
                            return null;
markus@1987
   147
                        _PEPEngineException = ex;
markus@1987
   148
Dean@467
   149
                        string summaryMessage = Properties.Resources.Message_InitError + " " +
Dean@467
   150
                                                Properties.Resources.Message_Reinstall;
Dean@860
   151
                        Globals.StopAndSendCrashReport(ex, summaryMessage, false, true);
Dean@460
   152
Dean@1262
   153
                        return (null);
vb@64
   154
                    }
vb@64
   155
                }
vb@64
   156
Dean@1262
   157
                return (ThisAddIn._PEPEngine);
vb@64
   158
            }
vb@64
   159
        }
vb@64
   160
Dean@611
   161
        /// <summary>
Thomas@2652
   162
        /// Gets the entry id of the pEp mirror store.
Thomas@2652
   163
        /// </summary>
Thomas@2652
   164
        internal string PEPStoreEntryId
Thomas@2652
   165
        {
Thomas@2652
   166
            get { return this._PEPStoreEntryId; }
Thomas@2652
   167
        }
Thomas@2652
   168
Thomas@2652
   169
        /// <summary>
Dean@1262
   170
        /// Gets the root folder of the pEp data store.
Dean@1262
   171
        /// This is primarily used to save unencrypted outlook mail items (mirrors).
Dean@1115
   172
        /// </summary>
Dean@1262
   173
        internal Outlook.Folder PEPStoreRootFolder
Dean@1115
   174
        {
Dean@1262
   175
            get { return (this._PEPStoreRootFolder); }
Dean@1262
   176
        }
Dean@1262
   177
Dean@1262
   178
        /// <summary>
Dean@1262
   179
        /// Gets the current pEp settings for the add-in.
Dean@1262
   180
        /// </summary>
Dean@1262
   181
        internal PEPSettings Settings
Dean@1262
   182
        {
Dean@1262
   183
            get { return (this._Settings); }
Dean@1090
   184
        }
Dean@1090
   185
Thomas@1770
   186
        /// <summary>
Thomas@1948
   187
        /// Gets the Outlook options set in the program.
Thomas@1948
   188
        /// </summary>
Thomas@1948
   189
        internal OutlookOptions OutlookOptions
Thomas@1948
   190
        {
Thomas@1948
   191
            get { return (this._OutlookOptions); }
Thomas@1948
   192
        }
Thomas@1948
   193
Thomas@1948
   194
        /// <summary>
Thomas@1770
   195
        /// Gets the decryption stack.
Thomas@1770
   196
        /// </summary>
Thomas@1770
   197
        internal static DecryptionStack DecryptionStack
Thomas@1770
   198
        {
Thomas@1770
   199
            get
Thomas@1770
   200
            {
Thomas@1770
   201
                if (ThisAddIn._DecryptionStack == null)
Thomas@1770
   202
                {
Thomas@1770
   203
                    ThisAddIn._DecryptionStack = new DecryptionStack();
Thomas@1770
   204
                }
Thomas@1770
   205
Thomas@1770
   206
                return ThisAddIn._DecryptionStack;
Thomas@1770
   207
            }
Thomas@1770
   208
        }
Thomas@1770
   209
Thomas@2659
   210
        /// <summary>
Thomas@2659
   211
        /// Gets the decryption stack.
Thomas@2659
   212
        /// </summary>
Thomas@2659
   213
        internal static SyncQueue SyncQueue
Thomas@2659
   214
        {
Thomas@2659
   215
            get
Thomas@2659
   216
            {
Thomas@2659
   217
                if (ThisAddIn._SyncQueue == null)
Thomas@2659
   218
                {
Thomas@2659
   219
                    ThisAddIn._SyncQueue = new SyncQueue();
Thomas@2659
   220
                }
Thomas@2659
   221
Thomas@2659
   222
                return ThisAddIn._SyncQueue;
Thomas@2659
   223
            }
Thomas@2659
   224
        }
Thomas@2659
   225
Dean@190
   226
        /**************************************************************
Dean@190
   227
         * 
Dean@190
   228
         * Methods
Dean@190
   229
         * 
Dean@190
   230
         *************************************************************/
Dean@335
   231
Dean@361
   232
        /// <summary>
Dean@361
   233
        /// Required override to add ribbon extensions.
Dean@361
   234
        /// </summary>
Dean@326
   235
        protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()
Dean@326
   236
        {
Dean@340
   237
            return new RibbonCustomizations();
Dean@335
   238
        }
vb@0
   239
Thomas@1734
   240
        /// <summary>
Thomas@2293
   241
        /// Adds a new WatchedExplorer to the list of watched explorers.
Thomas@2293
   242
        /// </summary>
Thomas@2293
   243
        /// <param name="watchedExplorer">The WatchedExplorer to add.</param>
Thomas@2293
   244
        internal void AddToWatchedExplorers(WatchedExplorer watchedExplorer)
Thomas@2293
   245
        {
Thomas@2293
   246
            lock (mutexWatchedExplorers)
Thomas@2293
   247
            {
Thomas@2293
   248
                this.watchedExplorers.Add(watchedExplorer);
Thomas@2293
   249
            }
Thomas@2293
   250
        }
Thomas@2293
   251
Thomas@2293
   252
        /// <summary>
Thomas@2359
   253
        /// Adds a new WatchedInspector to the list of watched inspectors.
Thomas@2359
   254
        /// </summary>
Thomas@2359
   255
        /// <param name="watchedInspector">The WatchedInspector to add.</param>
Thomas@2359
   256
        internal void AddToWatchedInspectors(WatchedInspector watchedInspector)
Thomas@2359
   257
        {
Thomas@2359
   258
            lock (mutexWatchedInspectors)
Thomas@2359
   259
            {
Thomas@2359
   260
                this.watchedInspectors.Add(watchedInspector);
Thomas@2359
   261
            }
Thomas@2359
   262
        }
Thomas@2359
   263
Thomas@2359
   264
        /// <summary>
Thomas@2293
   265
        /// Removes a WatchedExplorer from the list of watched explorers.
Thomas@2293
   266
        /// </summary>
Thomas@2293
   267
        /// <param name="watchedExplorer">The WatchedExplorer to remove.</param>
Thomas@2293
   268
        internal void RemoveFromWatchedExplorers(WatchedExplorer watchedExplorer)
Thomas@2293
   269
        {
Thomas@2293
   270
            lock (mutexWatchedExplorers)
Thomas@2293
   271
            {
Thomas@2293
   272
                this.watchedExplorers.Remove(watchedExplorer);
Thomas@2293
   273
            }
Thomas@2293
   274
        }
Thomas@2293
   275
Thomas@2293
   276
        /// <summary>
Thomas@2359
   277
        /// Removes a WatchedInspector from the list of watched inspectors.
Thomas@2359
   278
        /// </summary>
Thomas@2359
   279
        /// <param name="WatchedInspector">The WatchedInspector to remove.</param>
Thomas@2359
   280
        internal void RemoveFromWatchedInspectors(WatchedInspector watchedInspector)
Thomas@2359
   281
        {
Thomas@2359
   282
            lock (mutexWatchedInspectors)
Thomas@2359
   283
            {
Thomas@2359
   284
                this.watchedInspectors.Remove(watchedInspector);
Thomas@2359
   285
            }
Thomas@2359
   286
        }
Thomas@2359
   287
Thomas@2359
   288
        /// <summary>
Thomas@2359
   289
        /// Gets the WatchedExplorer or WatchedInspector in which the given mail item resides.
Thomas@2359
   290
        /// </summary>
Thomas@2359
   291
        /// <param name="omi">The Outlook mail item to process with.</param>
Thomas@2359
   292
        /// <returns>The WatchedExplorer or WatchedInspector the mail item resides in or null if an error occured.</returns>
Thomas@2359
   293
        internal WatchedWindow GetWatchedParentWindow(Outlook.MailItem omi)
Thomas@2359
   294
        {
Thomas@2359
   295
            try
Thomas@2359
   296
            {
Thomas@2359
   297
                // First, check all watched explorers
Thomas@2359
   298
                foreach (var watchedExplorer in this.watchedExplorers)
Thomas@2359
   299
                {
Thomas@2361
   300
                    if (watchedExplorer?.CurrentMailItem?.MAPIOBJECT?.Equals(omi?.MAPIOBJECT) == true)
Thomas@2359
   301
                    {
Thomas@2359
   302
                        return watchedExplorer;
Thomas@2359
   303
                    }
Thomas@2359
   304
                }
Thomas@2359
   305
Thomas@2359
   306
                // If window hasn't been found yet, check inspectors
Thomas@2359
   307
                foreach (var watchedInspector in this.watchedInspectors)
Thomas@2359
   308
                {
Thomas@2361
   309
                    if (watchedInspector?.CurrentMailItem?.MAPIOBJECT?.Equals(omi?.MAPIOBJECT) == true)
Thomas@2359
   310
                    {
Thomas@2359
   311
                        return watchedInspector;
Thomas@2359
   312
                    }
Thomas@2359
   313
                }
Thomas@2359
   314
            }
Thomas@2359
   315
            catch (Exception ex)
Thomas@2359
   316
            {
Thomas@2359
   317
                Log.Error("GetWatchedParentWindow: Error getting window. " + ex.ToString());
Thomas@2359
   318
            }
Thomas@2359
   319
Thomas@2359
   320
            // If no window has been found, return null
Thomas@2359
   321
            return null;
Thomas@2359
   322
        }
Thomas@2359
   323
Thomas@2359
   324
        /// <summary>
Thomas@2359
   325
        /// Gets the watched window for an Inspector or Explorer object.
Thomas@2359
   326
        /// </summary>
Thomas@2359
   327
        /// <param name="window">The Inspector or Explorer window to get its WatchedWindow for.</param>
Thomas@2359
   328
        /// <returns>The watched window or null if not found.</returns>
Thomas@2359
   329
        internal WatchedWindow GetWatchedWindow(dynamic window)
Thomas@2359
   330
        {
Thomas@2359
   331
            Outlook.Explorer explorer = null;
Thomas@2359
   332
            Outlook.Inspector inspector = null;
Thomas@2359
   333
            WatchedWindow watchedWindow = null;
Thomas@2359
   334
Thomas@2359
   335
            try
Thomas@2359
   336
            {
Thomas@2359
   337
                // First, try if window is an explorer
Thomas@2359
   338
                explorer = window as Outlook.Explorer;
Thomas@2359
   339
                if (explorer != null)
Thomas@2359
   340
                {
Thomas@2359
   341
                    if (this.watchedExplorers.Count == 1)
Thomas@2359
   342
                    {
Thomas@2359
   343
                        watchedWindow = this.watchedExplorers[0];
Thomas@2359
   344
                    }
Thomas@2359
   345
                    else
Thomas@2359
   346
                    {
Thomas@2359
   347
                        foreach (var watchedExplorer in this.watchedExplorers)
Thomas@2359
   348
                        {
Thomas@2359
   349
                            if (watchedExplorer?.Explorer?.Equals(explorer) == true)
Thomas@2359
   350
                            {
Thomas@2359
   351
                                watchedWindow = watchedExplorer;
Thomas@2359
   352
                                break;
Thomas@2359
   353
                            }
Thomas@2359
   354
                        }
Thomas@2359
   355
                    }
Thomas@2359
   356
                }
Thomas@2359
   357
                else
Thomas@2359
   358
                {
Thomas@2359
   359
                    // If window is no explorer, try if it is an inspector
Thomas@2359
   360
                    inspector = window as Outlook.Inspector;
Thomas@2359
   361
                    if (inspector != null)
Thomas@2359
   362
                    {
Thomas@2359
   363
                        if (this.watchedInspectors.Count == 1)
Thomas@2359
   364
                        {
Thomas@2359
   365
                            watchedWindow = this.watchedInspectors[0];
Thomas@2359
   366
                        }
Thomas@2359
   367
                        else
Thomas@2359
   368
                        {
Thomas@2359
   369
                            foreach (var watchedInspector in this.watchedInspectors)
Thomas@2359
   370
                            {
Thomas@2359
   371
                                if (watchedInspector?.Inspector?.Equals(inspector) == true)
Thomas@2359
   372
                                {
Thomas@2359
   373
                                    watchedWindow = watchedInspector;
Thomas@2359
   374
                                    break;
Thomas@2359
   375
                                }
Thomas@2359
   376
                            }
Thomas@2359
   377
                        }
Thomas@2359
   378
                    }
Thomas@2359
   379
                }
Thomas@2359
   380
            }
Thomas@2359
   381
            catch (Exception ex)
Thomas@2359
   382
            {
Thomas@2359
   383
                Log.Error("GetWatchedWindow: Error occured. " + ex.ToString());
Thomas@2359
   384
            }
Thomas@2359
   385
            finally
Thomas@2359
   386
            {
Thomas@2359
   387
                explorer = null;
Thomas@2359
   388
                inspector = null;
Thomas@2359
   389
            }
Thomas@2359
   390
Thomas@2359
   391
            return watchedWindow;
Thomas@2359
   392
        }
Thomas@2499
   393
Thomas@2359
   394
        /// <summary>
Thomas@1557
   395
        /// This updates the accounts list in pEp settings with the ones found in Outlook, adding new accounts and removing
Thomas@1557
   396
        /// all accounts that are not there anymore.
Dean@1262
   397
        /// </summary>
Thomas@1557
   398
        internal void SyncAccountsList()
Dean@1262
   399
        {
Thomas@2513
   400
            bool accountAdded = false;
Dean@1262
   401
            bool exists;
Thomas@1556
   402
            string dialogMessage = string.Empty;
Dean@1499
   403
            Outlook.NameSpace ns = null;
Dean@1499
   404
            Outlook.Account account = null;
Dean@1499
   405
            Outlook.Accounts accounts = null;
Thomas@2513
   406
            Outlook.Store store = null;
Thomas@2513
   407
            Outlook.Stores stores = null;
Thomas@1564
   408
            PEPSettings.PEPAccountSettings acctSettings;
Thomas@2513
   409
            List<string> sharedAccountStores = new List<string>();
Dean@1262
   410
Dean@1262
   411
            try
Dean@1262
   412
            {
Dean@1499
   413
                ns = Application.Session;
Thomas@1557
   414
                accounts = ns?.Accounts;
Dean@1499
   415
Dean@1262
   416
                if (this._Settings != null)
Dean@1262
   417
                {
Dean@1262
   418
                    // Add any new Outlook accounts to the account settings list
Dean@1262
   419
                    for (int i = 1; i <= accounts.Count; i++)
Dean@1262
   420
                    {
Dean@1499
   421
                        account = accounts[i];
Dean@1499
   422
Dean@1499
   423
                        if (string.IsNullOrWhiteSpace(account.SmtpAddress) == false)
Dean@1262
   424
                        {
Thomas@1564
   425
                            // Check if it is already in the list
Thomas@2686
   426
                            if (this._Settings.GetAccountSettings(account.SmtpAddress) is PEPSettings.PEPAccountSettings accountSettings)
Thomas@2063
   427
                            {
Thomas@2063
   428
                                // Check for properties that might have not been set correctly due to errors
Thomas@2063
   429
                                // UserName
Thomas@2063
   430
                                if (string.IsNullOrEmpty(accountSettings.UserName))
Thomas@2063
   431
                                {
Thomas@2063
   432
                                    try
Thomas@2063
   433
                                    {
Thomas@2063
   434
                                        accountSettings.UserName = account.UserName;
Thomas@2063
   435
                                    }
Thomas@2063
   436
                                    catch (Exception ex)
Thomas@2063
   437
                                    {
Thomas@2063
   438
                                        Log.Error("SyncAccountsList: Error adding user name. " + ex.ToString());
Thomas@2063
   439
                                    }
Thomas@2063
   440
                                }
Thomas@2063
   441
                            }
Thomas@2686
   442
                            else
Thomas@2686
   443
                            {
Thomas@2686
   444
                                // Create pEp settings for the new account
Thomas@2686
   445
                                account.CreatePEPSettings();
Thomas@2686
   446
                                accountAdded = true;
Thomas@2686
   447
                            }
Dean@1262
   448
                        }
Dean@1262
   449
                        else
Dean@1262
   450
                        {
Thomas@2063
   451
                            Log.Warning("SyncAccountsList: Invalid Smtp address detected, skipping account.");
Dean@1262
   452
                        }
Dean@1262
   453
Dean@1499
   454
                        account = null;
Dean@1262
   455
                    }
Dean@1262
   456
Thomas@2513
   457
                    // Add shared mail boxes
Thomas@2513
   458
                    stores = ns?.Stores;
Thomas@2513
   459
                    for (int i = 1; i <= stores.Count; i++)
Thomas@2513
   460
                    {
Thomas@2513
   461
                        store = stores[i];
Thomas@2513
   462
                        if (store.ExchangeStoreType == Outlook.OlExchangeStoreType.olExchangeMailbox)
Thomas@2513
   463
                        {
Thomas@2513
   464
                            if (store.GetSmtpAddress(out string address, out string userName))
Thomas@2513
   465
                            {
Thomas@2513
   466
                                if (this.Settings.GetAccountSettings(address) == null)
Thomas@2513
   467
                                {
Thomas@2513
   468
                                    // Add to account settings if necessary
Thomas@2513
   469
                                    Log.Verbose("GetSmtpAddress: Adding shared account " + address);
Thomas@2513
   470
                                    this.Settings.AccountSettingsList.Add(new PEPSettings.PEPAccountSettings()
Thomas@2513
   471
                                    {
Thomas@2513
   472
                                        SmtpAddress = address,
Thomas@2513
   473
                                        IsSecureStorageEnabled = false,
Thomas@2562
   474
                                        IsSyncEnabled = false,
Thomas@2514
   475
                                        Type = Outlook.OlAccountType.olExchange.ToString(),
Thomas@2513
   476
                                        UserName = userName
Thomas@2513
   477
                                    });
Thomas@2513
   478
Thomas@2513
   479
                                    accountAdded = true;
Thomas@2513
   480
                                }
Thomas@2513
   481
Thomas@2513
   482
                                sharedAccountStores.Add(address);
Thomas@2513
   483
                            }
Thomas@2513
   484
                        }
Thomas@2513
   485
                    }
Thomas@2513
   486
Dean@1262
   487
                    // Remove any entries of the account settings list not in Outlook
Dean@1499
   488
                    // This is needed to skip any entries in the registry that may be invalid, user created, or no longer in Outlook
Dean@1262
   489
                    for (int i = (this._Settings.AccountSettingsList.Count - 1); i >= 0; i--)
Dean@1262
   490
                    {
Thomas@1564
   491
                        acctSettings = this._Settings.AccountSettingsList[i];
Dean@1262
   492
Dean@1262
   493
                        // Check if it exists in Outlook
Dean@1262
   494
                        exists = false;
Dean@1262
   495
                        for (int j = 1; j <= accounts.Count; j++)
Dean@1262
   496
                        {
Dean@1499
   497
                            account = accounts[j];
Thomas@1522
   498
Thomas@2063
   499
                            if (acctSettings.EqualsByAddress(account.SmtpAddress))
Dean@1262
   500
                            {
Dean@1262
   501
                                exists = true;
Dean@1262
   502
                            }
Dean@1262
   503
Dean@1499
   504
                            account = null;
Dean@1262
   505
Thomas@2328
   506
                            if (exists)
Thomas@2328
   507
                            {
Thomas@2328
   508
                                break;
Thomas@2328
   509
                            }
Thomas@2644
   510
                        }
Dean@1262
   511
Dean@1262
   512
                        // Delete if necessary
Thomas@2063
   513
                        if ((exists == false) &&
Thomas@2513
   514
                            (Globals.ThisAddIn.Settings?.AccountsAddedWhileRunningList?.Contains(acctSettings?.SmtpAddress) != true) &&
Thomas@2513
   515
                            (sharedAccountStores.Contains(acctSettings.SmtpAddress) == false))
Dean@1262
   516
                        {
Dean@1262
   517
                            this._Settings.AccountSettingsList.RemoveAt(i);
Dean@1262
   518
                        }
Dean@1262
   519
                    }
Thomas@2513
   520
Thomas@2513
   521
                    if (accountAdded)
Thomas@2513
   522
                    {
Thomas@2513
   523
                        // Set view filters and rules
Thomas@2513
   524
                        this.SetRulesAndViewFilters(this._Settings?.HideInternalMessages ?? PEPSettings.HIDE_INTERNAL_MESSAGES_DEFAULT);
Thomas@2513
   525
                    }
Thomas@1557
   526
                }
Thomas@1557
   527
            }
Thomas@1936
   528
            catch (Exception ex)
Thomas@1557
   529
            {
Thomas@1936
   530
                Log.Error("SyncAccountsList: Error occured. " + ex.ToString());
Thomas@1557
   531
            }
Thomas@1557
   532
            finally
Thomas@1557
   533
            {
Thomas@1992
   534
                ns = null;
Thomas@1992
   535
                account = null;
Thomas@1992
   536
                accounts = null;
Thomas@1557
   537
            }
Thomas@1557
   538
        }
Thomas@1557
   539
Thomas@1557
   540
        /// <summary>
Thomas@1557
   541
        /// Syncronizes the current settings class with the pEp for Outlook instance and the pEp engine.
Thomas@1557
   542
        /// Warning: This code should be kept synchronized with the Settings_PropertyChanged event.
Thomas@1557
   543
        /// <param name="syncAccountsList">Whether to also update the accounts list in pEp settings. 
Thomas@1557
   544
        /// </summary>
Thomas@1557
   545
        internal void SyncWithSettings(bool syncAccountsList = false)
Thomas@1557
   546
        {
Thomas@1557
   547
            bool exists;
Thomas@1557
   548
            string dialogMessage = string.Empty;
Thomas@1557
   549
            pEpIdentity[] ownIdentities;
Thomas@1557
   550
            List<KeyValuePair<CultureInfo, string>> languages;
Thomas@1557
   551
Thomas@1557
   552
            try
Thomas@1557
   553
            {
Thomas@1557
   554
                if (this._Settings != null)
Thomas@1557
   555
                {
Thomas@1557
   556
                    // Update the Outlook accounts list with the one maintained in pEp settings if needed.
Thomas@1557
   557
                    if (syncAccountsList)
Thomas@1557
   558
                    {
Thomas@1557
   559
                        this.SyncAccountsList();
Thomas@1557
   560
                    }
Dean@1262
   561
Thomas@1522
   562
                    /* Sync the account settings with the engine's own identity flags.
Thomas@1522
   563
                     * Warning: RegisterMyself() must already have been called so the engine has all own identities.
Thomas@1522
   564
                     * The engine can commonly have more own identities than what is in the accounts list.
Thomas@1522
   565
                     * This isn't a problem though and engine-only identities will not be changed here.
Thomas@1522
   566
                     */
Dean@1499
   567
                    ownIdentities = ThisAddIn.PEPEngine.OwnIdentitiesRetrieve();
Dean@1499
   568
                    foreach (PEPSettings.PEPAccountSettings acctSettings in this._Settings.AccountSettingsList)
Dean@1499
   569
                    {
Dean@1499
   570
                        // Find the own identity that matches with the account settings
Dean@1499
   571
                        foreach (pEpIdentity ident in ownIdentities)
Dean@1499
   572
                        {
Thomas@1522
   573
                            pEpIdentity ownIdent = ident;
Thomas@1522
   574
Thomas@1522
   575
                            if (acctSettings.EqualsByAddress(ownIdent.Address))
Dean@1499
   576
                            {
Thomas@1576
   577
                                // Sync the engine's own identity flags with the account or global settings
Thomas@1577
   578
                                if (this._Settings.IsSyncEnabledForAllAccounts)
Thomas@1576
   579
                                {
Thomas@1577
   580
                                    if (ownIdent.GetIsSyncEnabled() == false)
Thomas@1576
   581
                                    {
Thomas@1577
   582
                                        ThisAddIn.PEPEngine.UnsetIdentityFlags(ref ownIdent, pEpIdentityFlags.pEpIdfNotForSync);
Thomas@1576
   583
                                    }
Thomas@1576
   584
                                }
Thomas@1576
   585
                                else if (ownIdent.GetIsSyncEnabled() != acctSettings.IsSyncEnabled)
Thomas@1522
   586
                                {
Thomas@1522
   587
                                    if (acctSettings.IsSyncEnabled)
Thomas@1522
   588
                                    {
Thomas@1522
   589
                                        ThisAddIn.PEPEngine.UnsetIdentityFlags(ref ownIdent, pEpIdentityFlags.pEpIdfNotForSync);
Thomas@1522
   590
                                    }
Thomas@1522
   591
                                    else
Thomas@1522
   592
                                    {
Thomas@1522
   593
                                        ThisAddIn.PEPEngine.SetIdentityFlags(ref ownIdent, pEpIdentityFlags.pEpIdfNotForSync);
Thomas@1522
   594
                                    }
Thomas@1522
   595
                                }
Dean@1499
   596
                                break;
Dean@1499
   597
                            }
Dean@1499
   598
                        }
Dean@1499
   599
                    }
Dean@1499
   600
Dean@1262
   601
                    // Sync IsPassiveModeEnabled with engine
markus@1337
   602
                    ThisAddIn.PEPEngine.PassiveMode(this._Settings.IsPassiveModeEnabled);
Dean@1262
   603
Dean@1262
   604
                    // Sync IsPEPFolderVisible with Outlook
Dean@1262
   605
                    this.SetPEPStoreRootFolderVisibility(this._Settings.IsPEPFolderVisible);
Dean@1262
   606
Dean@1262
   607
                    // Sync IsUnencryptedSubjectEnabled with engine
markus@1337
   608
                    ThisAddIn.PEPEngine.UnencryptedSubject(this._Settings.IsUnencryptedSubjectEnabled);
Dean@1262
   609
Dean@1262
   610
                    // Sync IsVerboseLoggingEnabled with engine
markus@1337
   611
                    ThisAddIn.PEPEngine.VerboseLogging(this._Settings.IsVerboseLoggingEnabled);
Dean@1262
   612
Dean@1262
   613
                    // Sync TrustwordsCulture with engine
Dean@1262
   614
                    if (this._Settings.TrustwordsCulture != null)
Dean@1262
   615
                    {
Dean@1262
   616
                        // Validate it exists in the engine list
Dean@1262
   617
                        exists = false;
Dean@1262
   618
                        languages = this.LanguageList;
Dean@1262
   619
                        foreach (KeyValuePair<CultureInfo, string> entry in languages)
Dean@1262
   620
                        {
Dean@1262
   621
                            if (entry.Key.LCID == this._Settings.TrustwordsCulture.LCID)
Dean@1262
   622
                            {
Dean@1262
   623
                                exists = true;
Dean@1262
   624
                                break;
Dean@1262
   625
                            }
Dean@1262
   626
                        }
Dean@1262
   627
Dean@1262
   628
                        if (exists == false)
Dean@1262
   629
                        {
Dean@1262
   630
                            // Reset to default
Dean@1351
   631
                            this._Settings.TrustwordsCulture = this.GetActiveUICulture();
Dean@1262
   632
                            Log.Warning("SyncWithSettings: Invalid TrustwordsCulture detected, setting to default.");
Dean@1262
   633
                        }
Dean@1262
   634
                    }
Dean@1262
   635
                    else
Dean@1262
   636
                    {
Dean@1262
   637
                        // Reset to default
Dean@1351
   638
                        this._Settings.TrustwordsCulture = this.GetActiveUICulture();
Dean@1262
   639
                    }
Dean@1262
   640
                }
Dean@1262
   641
            }
Dean@1499
   642
            catch (Exception ex)
Dean@1499
   643
            {
Dean@1499
   644
                Log.Error("SyncWithSettings: Failure occured, " + ex.ToString());
Dean@1499
   645
            }
Dean@1262
   646
        }
Dean@1262
   647
Dean@1262
   648
        /// <summary>
Dean@1441
   649
        /// Compares the given settings with the current state of Outlook and detects any changes.
Thomas@1580
   650
        /// This is currently only used to identify first startup.
Dean@1441
   651
        /// </summary>
Dean@1441
   652
        /// <param name="lastSettings">The last settings to compare with. 
Dean@1441
   653
        /// This should be the settings just loaded from the registry at startup (last saved settings).</param>
Dean@1441
   654
        private void DetectChangesFromLastSettings(PEPSettings lastSettings)
Dean@1441
   655
        {
Dean@1441
   656
            // Detect first startup
Dean@1441
   657
            if (lastSettings.IsFirstStartupComplete == false)
Dean@1441
   658
            {
Dean@1441
   659
                this.FirstStartup?.Invoke(this, new EventArgs());
Dean@1441
   660
            }
Dean@1441
   661
        }
Dean@1441
   662
Dean@1441
   663
        /// <summary>
Dean@626
   664
        /// Detects and disables GPG for Windows GpgOL Outlook add-in.
Dean@626
   665
        /// </summary>
Dean@626
   666
        /// <returns>True if the GpgOL add-in was disabled.</returns>
Dean@626
   667
        private bool DisableGpgOL()
Dean@626
   668
        {
Dean@626
   669
            bool wasDisabled = false;
Dean@830
   670
            Office.COMAddIns comAddIns = null;
Dean@626
   671
Dean@830
   672
            try
Dean@626
   673
            {
Dean@830
   674
                comAddIns = Globals.ThisAddIn.Application.COMAddIns;
Dean@830
   675
                foreach (Office.COMAddIn addin in comAddIns)
Dean@626
   676
                {
Dean@830
   677
                    if (string.Equals(addin.Description, "GpgOL - The GnuPG Outlook Plugin", StringComparison.OrdinalIgnoreCase))
Dean@830
   678
                    {
Dean@830
   679
                        addin.Connect = false;
Dean@830
   680
                        wasDisabled = true;
Dean@626
   681
Dean@1262
   682
                        Log.Info("DisableGpgOL: GpgOL was detected and disabled.");
Dean@830
   683
                    }
Dean@830
   684
                }
Dean@830
   685
            }
Dean@830
   686
            catch (Exception ex)
Dean@830
   687
            {
Dean@1262
   688
                Log.Error("DisableGpgOL: Error trying to disable GpgOL, " + ex.ToString());
Dean@830
   689
            }
Dean@830
   690
            finally
Dean@830
   691
            {
Dean@830
   692
                if (comAddIns != null)
Dean@830
   693
                {
vb@1507
   694
                    // Marshal.ReleaseComObject(comAddIns);
Dean@830
   695
                    comAddIns = null;
Dean@626
   696
                }
Dean@626
   697
            }
Dean@626
   698
Dean@626
   699
            return (wasDisabled);
Dean@626
   700
        }
Dean@626
   701
Dean@626
   702
        /// <summary>
Thomas@2359
   703
        /// Sends a request to recalculate the message rating of all open windows (except one) again.
Thomas@2359
   704
        /// </summary>
Thomas@2359
   705
        /// <param name="windowToExclude">The window to not calculate its rating for</param>
Thomas@2359
   706
        internal void RecalculateAllWindows(WatchedWindow windowToExclude)
Thomas@2359
   707
        {
Thomas@2359
   708
            for (int i = 0; i < this.watchedExplorers.Count; i++)
Thomas@2359
   709
            {
Thomas@2359
   710
                if ((windowToExclude as WatchedExplorer)?.Equals(this.watchedExplorers[i]) != true)
Thomas@2359
   711
                {
Thomas@2359
   712
                    this.watchedExplorers[i].RequestRatingAndUIUpdate();
Thomas@2359
   713
                }
Thomas@2359
   714
            }
Thomas@2359
   715
Thomas@2359
   716
            for (int i = 0; i < this.watchedInspectors.Count; i++)
Thomas@2359
   717
            {
Thomas@2359
   718
                if ((windowToExclude as WatchedInspector)?.Equals(this.watchedInspectors[i]) != true)
Thomas@2359
   719
                {
Thomas@2359
   720
                    this.watchedInspectors[i].RequestRatingAndUIUpdate();
Thomas@2359
   721
                }
Thomas@2359
   722
            }
Thomas@2359
   723
        }
Thomas@2359
   724
Thomas@2359
   725
        /// <summary>
Dean@1497
   726
        /// Registers each own identity in the pEp engine.
Dean@1497
   727
        /// An own identity represents each account in Outlook.
Dean@361
   728
        /// </summary>
Dean@910
   729
        internal void RegisterMyself()
vb@0
   730
        {
Thomas@2003
   731
            if (Globals.ThisAddIn.Settings.AccountSettingsList != null)
vb@12
   732
            {
Thomas@2058
   733
                foreach (var acctSettings in Globals.ThisAddIn.Settings.AccountSettingsList)
Dean@575
   734
                {
Thomas@2058
   735
                    this.RegisterMyself(acctSettings);
Dean@575
   736
                }
Dean@1497
   737
            }
Dean@190
   738
        }
Dean@190
   739
Dean@190
   740
        /// <summary>
Thomas@2058
   741
        /// Registers a pEpIdentity in the pEp engine.
Thomas@2058
   742
        /// </summary>
Thomas@2058
   743
        internal void RegisterMyself(PEPSettings.PEPAccountSettings acctSettings)
Thomas@2058
   744
        {
Thomas@2058
   745
            pEpIdentity ownIdentity;
Thomas@2058
   746
Thomas@2058
   747
            if (acctSettings != null)
Thomas@2058
   748
            {
Thomas@2058
   749
                // Create pEpIdentity
Thomas@2058
   750
                ownIdentity = new pEpIdentity
Thomas@2058
   751
                {
Thomas@2058
   752
                    Address = acctSettings.SmtpAddress,
Thomas@2058
   753
                    UserId = PEPSettings.PEP_OWN_USER_ID,
Thomas@2058
   754
                    UserName = acctSettings.UserName
Thomas@2058
   755
                };
Thomas@2058
   756
Thomas@2058
   757
                // Set not for sync flag if necessary
Thomas@2637
   758
                if ((Globals.ThisAddIn.Settings.IsSyncEnabledForAllAccounts == false) &&
Thomas@2637
   759
                     (acctSettings.IsSyncEnabled == false))
Thomas@2058
   760
                {
Thomas@2058
   761
                    ownIdentity.Flags = pEpIdentityFlags.pEpIdfNotForSync;
Thomas@2058
   762
                }
Thomas@2058
   763
Thomas@2058
   764
                // Log information if invalid
Thomas@2058
   765
                if (string.IsNullOrWhiteSpace(ownIdentity.Address))
Thomas@2058
   766
                {
Thomas@2058
   767
                    Log.Warning("RegisterMyself: Myself doesn't have an address.");
Thomas@2058
   768
                }
Thomas@2058
   769
Thomas@2058
   770
                if (string.IsNullOrWhiteSpace(ownIdentity.UserName))
Thomas@2058
   771
                {
Thomas@2058
   772
                    Log.Warning("RegisterMyself: Myself doesn't have a user name.");
Thomas@2058
   773
                }
Thomas@2058
   774
Thomas@2058
   775
                /* Call engine to register myself (doesn't matter if already done in a past instance)
Thomas@2058
   776
                 * Note that key generation can take place during the call to Myself if it's a new installation
Thomas@2058
   777
                 * and the engine is unable to elect a key. In this situation key generation can take some time.
Thomas@2058
   778
                 * It takes long-enough for the call to the adapter to timeout here and throw an exception.
Thomas@2058
   779
                 * However, since the fingerprint of the own identity is not actually needed here, the assumption is 
Thomas@2058
   780
                 * made that the engine will be OK and continue processing.
Thomas@2058
   781
                 * The exception is simply ignored and we go to the next identity. 
Thomas@2058
   782
                 */
Thomas@2058
   783
                try
Thomas@2058
   784
                {
Thomas@2058
   785
                    ThisAddIn.PEPEngine.Myself(ownIdentity);
Thomas@2058
   786
                }
Thomas@2058
   787
                catch (COMException ex)
Thomas@2058
   788
                {
Thomas@2058
   789
                    Log.Warning("RegisterMyself: Engine returned exception, " + ex.ToString());
Thomas@2058
   790
                }
Thomas@2058
   791
            }
Thomas@2058
   792
            else
Thomas@2058
   793
            {
Thomas@2058
   794
                Log.Error("RegisterMyself: account settings are null.");
Thomas@2058
   795
            }
Thomas@2058
   796
        }
Thomas@2058
   797
Thomas@2058
   798
        /// <summary>
Dean@738
   799
        /// Create a new Outlook MailItem from the given PEPMessage and send it.
Dean@738
   800
        /// The sent message will not be processed by the 'Application_ItemSend' event.
Dean@744
   801
        /// WARNING: Exchange ActiveSync accounts ignore the deleteAfterSend parameter (always false).
Dean@455
   802
        /// </summary>
Dean@455
   803
        /// <param name="message">The message to send.</param>
Dean@475
   804
        /// <param name="deleteAfterSend">Whether the message is deleted after sending (true) or a copy is saved (false).</param>
Dean@1455
   805
        /// <param name="validateSendingAccount">Validates that the SendingAccount matches the From identity of the given message.
Dean@1455
   806
        /// This can catch situations (and throw exceptions) where the default account would be used instead.</param>
Thomas@1833
   807
        /// <param name="processMessage">Whether or not to process this message through the pEp engine.</param>
Thomas@1833
   808
        internal void CreateAndSendMessage(PEPMessage message,
Thomas@1833
   809
                                           bool deleteAfterSend,
Thomas@1833
   810
                                           bool validateSendingAccount,
Thomas@2584
   811
                                           bool processMessage = false)
Dean@455
   812
        {
Dean@455
   813
            Outlook.MailItem newItem;
Dean@1262
   814
            Globals.ReturnStatus sts;
Dean@455
   815
Thomas@1833
   816
            this.isItemSendHandlerEnabled = processMessage;
Dean@1394
   817
Dean@1394
   818
            try
Dean@1262
   819
            {
Dean@1394
   820
                newItem = Application.CreateItem(Outlook.OlItemType.olMailItem);
Thomas@1467
   821
Thomas@1467
   822
                /* Notes:
Thomas@1467
   823
                 * Do NOT include internal Header Fields (MAPI properties) on outgoing messages!
Thomas@1467
   824
                 * The sender must be set from the from identity (setSender=true)
Thomas@1467
   825
                 */
Thomas@1467
   826
                sts = message.ApplyTo(newItem, false, true);
Dean@1394
   827
Dean@1394
   828
                if (sts == Globals.ReturnStatus.Success)
Dean@1394
   829
                {
Dean@1455
   830
                    // Check that the sending account is the From identity
Dean@1455
   831
                    if ((validateSendingAccount) &&
Dean@1455
   832
                        (message.From != null))
Dean@1455
   833
                    {
Thomas@2565
   834
                        if (newItem.SetSendUsingAccount(message.From.Address) == false)
Dean@1455
   835
                        {
Thomas@2565
   836
                            throw new Exception("Sending account does not match from identity or error setting Send account");
Dean@1455
   837
                        }
Dean@1455
   838
                    }
Dean@1455
   839
Dean@1394
   840
                    // Do not allow TNEF/RTF format with 'winmail.dat' attachment
Dean@1394
   841
                    MapiHelper.SetProperty(newItem, MapiProperty.PidLidUseTnef, false);
Dean@1394
   842
Thomas@2587
   843
                    // If ForceUnencrypted property is set, add it to mail item (only if message is to be processed)
Thomas@2644
   844
                    if (processMessage &&
Thomas@2587
   845
                        message.ForceUnencrypted)
Thomas@2102
   846
                    {
Thomas@2102
   847
                        newItem.SetPEPProperty(MailItemExtensions.PEPProperty.ForceUnencrypted, true);
Thomas@2102
   848
                    }
Thomas@2102
   849
Dean@1394
   850
                    /* Send
Dean@1394
   851
                     * 
Dean@1394
   852
                     * Note: For ActiveSync accounts, the DeleteAfterSubmit property is ignored.
Dean@1394
   853
                     * This means the message will always appear in the sent folder by default.
Dean@1394
   854
                     * The reason for this is unknown.
Dean@1394
   855
                     * 
Dean@1394
   856
                     * It's possible this is related to the ActiveSync specification version
Dean@1394
   857
                     * and therefore may behave differently depending on Outlook version.
Dean@1394
   858
                     * More research is needed here.
Dean@1394
   859
                     */
Dean@1394
   860
                    newItem.DeleteAfterSubmit = deleteAfterSend;
Dean@1394
   861
                    ((Outlook._MailItem)newItem).Send();
Dean@1394
   862
Dean@1394
   863
                    newItem = null;
Dean@1394
   864
                }
Dean@1394
   865
                else
Dean@1394
   866
                {
Dean@1394
   867
                    newItem.PermanentlyDelete();
Dean@1394
   868
                    newItem = null;
Dean@1394
   869
Dean@1394
   870
                    throw new Exception("Failed to create MailItem to send");
Dean@1394
   871
                }
Dean@1262
   872
            }
Dean@1394
   873
            catch
Dean@1262
   874
            {
Thomas@1822
   875
                throw new Exception("CreateMessageAndSend: Failed to send MailItem.");
Dean@1394
   876
            }
Dean@1394
   877
            finally
Dean@1394
   878
            {
Dean@1394
   879
                this.isItemSendHandlerEnabled = true;
Dean@1262
   880
            }
Dean@455
   881
        }
Dean@455
   882
Dean@455
   883
        /// <summary>
Dean@1262
   884
        /// Create a new 'sent' Outlook MailItem and place it in the given store.
Dean@744
   885
        /// WARNING: Exchange ActiveSync accounts are not supported by this method. The sent
Dean@744
   886
        /// message will always appear in the drafts folder.
Dean@738
   887
        /// </summary>
Dean@1262
   888
        /// <param name="sendingStore">The store to save the sent message to.</param>
Dean@1262
   889
        /// <param name="acctSettings">The sending account settings.</param>
Dean@738
   890
        /// <param name="sentMessage">The message that is sent.</param>
Dean@1262
   891
        /// <param name="storedRating">The rating to store to the sent message mail item.
Dean@970
   892
        /// Will only be set if not undefined (default). Warning: Only use this on trusted servers.</param>
Dean@1262
   893
        private void CreateNewSentMail(Outlook.Store sendingStore,
Dean@1262
   894
                                       PEPSettings.PEPAccountSettings acctSettings,
Dean@970
   895
                                       PEPMessage sentMessage,
markus@1337
   896
                                       pEpRating storedRating = pEpRating.pEpRatingUndefined)
Dean@738
   897
        {
Dean@1262
   898
            Int32 messageFlags;
Dean@738
   899
            Outlook.MailItem sentMailItem = null;
Dean@1262
   900
            Outlook.Folder sentFolder = null;
Dean@1262
   901
            Outlook.NameSpace ns = Application.Session;
vb@1511
   902
            Outlook.Folder rootFolder = null;
Dean@1262
   903
            Outlook.Folders folders = null;
Dean@1262
   904
            Outlook.Folder folder = null;
Dean@1262
   905
Dean@1262
   906
            /* The process is:
Dean@1262
   907
             * 1. Use the Store.GetDefaultFolder(olFolderSentMail) to try to get the default Sent folder. 
Dean@1262
   908
             *    However, this can fail for a number of reasons, depending on server and folder configuration.
Dean@1262
   909
             * 2. As a fallback, search for the Sent folder by matching the Sent folder Entry ID
Dean@1262
   910
             *    However, this can also fail if no Sent folder Entry ID has been recorded.
Dean@1262
   911
             * 3. As another fallback, search by Folder name ("SENT") for an existing Sent folder
Dean@1262
   912
             *    If found, record the folder's Entry ID. If not, goto point 4.
Dean@1262
   913
             * 4. If everything of the above fails, create a new Sent folder and record the Entry ID.     
Dean@1262
   914
             */
Dean@738
   915
Dean@738
   916
            try
Dean@738
   917
            {
Dean@1262
   918
                if ((sendingStore != null) &&
Dean@1262
   919
                    (acctSettings != null) &&
Dean@1262
   920
                    (sentMessage != null))
Thomas@1108
   921
                {
Thomas@1522
   922
                    rootFolder = (Outlook.Folder)sendingStore.GetRootFolder();
Dean@1262
   923
                    if (rootFolder != null)
Dean@1262
   924
                    {
Dean@1262
   925
                        folders = rootFolder.Folders;
Dean@1262
   926
                    }
Dean@1262
   927
Dean@1262
   928
                    // Step 1
Dean@1262
   929
                    try
Dean@1262
   930
                    {
Dean@1262
   931
                        sentFolder = (Outlook.Folder)sendingStore.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);
Dean@1262
   932
                    }
Dean@1262
   933
                    catch
Dean@1262
   934
                    {
Dean@1262
   935
                        if (sentFolder != null)
Dean@1262
   936
                        {
vb@1507
   937
                            // Marshal.ReleaseComObject(sentFolder);
Dean@1262
   938
                            sentFolder = null;
Dean@1262
   939
                        }
Dean@1262
   940
                    }
Dean@1262
   941
Dean@1262
   942
                    // Step 2
Dean@1262
   943
                    if (sentFolder == null)
Dean@1262
   944
                    {
Dean@1262
   945
                        try
Dean@1262
   946
                        {
Dean@1348
   947
                            /* Search for folder by entry ID
Dean@1348
   948
                             * Normally, the way to go would be the following line:
Dean@1348
   949
                             * sentFolder = (Outlook.Folder)ns.GetItemFromID(acctSettings.SentFolderEntryId, sendingStore.StoreID);
Dean@1262
   950
                             * However, for some reason, this can come up with the following error: "Could not open the item. Try again."
Dean@1262
   951
                             * Therefore, the below solution is used:
Dean@1262
   952
                             */
Dean@1262
   953
                            if (folders != null)
Dean@1262
   954
                            {
Dean@1262
   955
                                for (int i = 1; i <= folders.Count; i++)
Dean@1262
   956
                                {
Dean@1262
   957
                                    folder = (Outlook.Folder)folders[i];
Dean@1262
   958
Dean@1262
   959
                                    if (folder != null)
Dean@1262
   960
                                    {
Dean@1262
   961
                                        if ((string.IsNullOrEmpty(folder.EntryID) == false) &&
Dean@1348
   962
                                            (string.Equals(folder.EntryID, acctSettings.SentFolderEntryId)))
Dean@1262
   963
                                        {
Dean@1262
   964
                                            sentFolder = folder;
Dean@1262
   965
                                            break;
Dean@1262
   966
                                        }
Dean@1262
   967
vb@1516
   968
                                        // Marshal.ReleaseComObject(folder);
Dean@1262
   969
                                        folder = null;
Dean@1262
   970
                                    }
Dean@1262
   971
                                }
Dean@1262
   972
                            }
Dean@1262
   973
                        }
Dean@1262
   974
                        catch
Dean@1262
   975
                        {
Dean@1262
   976
                            if (sentFolder != null)
Dean@1262
   977
                            {
vb@1507
   978
                                // Marshal.ReleaseComObject(sentFolder);
Dean@1262
   979
                                sentFolder = null;
Dean@1262
   980
                            }
Dean@1262
   981
                        }
Dean@1262
   982
                    }
Dean@1262
   983
Dean@1262
   984
                    // Step 3
Dean@1262
   985
                    if (sentFolder == null)
Dean@1262
   986
                    {
Dean@1262
   987
                        try
Dean@1262
   988
                        {
Dean@1262
   989
                            //Search for folder by name
Dean@1262
   990
                            if (folders != null)
Dean@1262
   991
                            {
Dean@1262
   992
                                for (int i = 1; i <= folders.Count; i++)
Dean@1262
   993
                                {
Dean@1262
   994
                                    folder = (Outlook.Folder)folders[i];
Dean@1262
   995
Dean@1262
   996
                                    if (folder != null)
Dean@1262
   997
                                    {
Dean@1262
   998
                                        if ((string.IsNullOrEmpty(folder.Name) == false) &&
Dean@1262
   999
                                            (folder.Name.Trim().StartsWith(Globals.CUSTOM_SENT_FOLDER_NAME, StringComparison.OrdinalIgnoreCase)))
Dean@1262
  1000
                                        {
Dean@1262
  1001
                                            sentFolder = folder;
Dean@1262
  1002
                                            break;
Dean@1262
  1003
                                        }
Dean@1262
  1004
vb@1516
  1005
                                        // Marshal.ReleaseComObject(folder);
Dean@1262
  1006
                                        folder = null;
Dean@1262
  1007
                                    }
Dean@1262
  1008
                                }
Dean@1262
  1009
                            }
Dean@1262
  1010
                        }
Dean@1262
  1011
                        catch
Dean@1262
  1012
                        {
Dean@1262
  1013
                            if (sentFolder != null)
Dean@1262
  1014
                            {
vb@1507
  1015
                                // Marshal.ReleaseComObject(sentFolder);
Dean@1262
  1016
                                sentFolder = null;
Dean@1262
  1017
                            }
Dean@1262
  1018
                        }
Dean@1262
  1019
                    }
Dean@1262
  1020
Dean@1262
  1021
                    // Step 4
Dean@1262
  1022
                    if (sentFolder == null)
Dean@1262
  1023
                    {
Dean@1262
  1024
                        try
Dean@1262
  1025
                        {
Dean@1262
  1026
                            // Create folder
Dean@1262
  1027
                            if (folders != null)
Dean@1262
  1028
                            {
Dean@1262
  1029
                                sentFolder = (Outlook.Folder)folders.Add(Globals.CUSTOM_SENT_FOLDER_NAME);
Dean@1262
  1030
                            }
Dean@1262
  1031
                        }
Dean@1262
  1032
                        catch (Exception ex)
Dean@1262
  1033
                        {
Dean@1262
  1034
                            if (sentFolder != null)
Dean@1262
  1035
                            {
vb@1507
  1036
                                // Marshal.ReleaseComObject(sentFolder);
Dean@1262
  1037
                                sentFolder = null;
Dean@1262
  1038
                            }
Dean@1262
  1039
Dean@1262
  1040
                            Log.Error("CreateNewSentMail: No Sent folder found and no new Sent folder could be created because of the following error: " + ex.ToString());
Dean@1262
  1041
                        }
Dean@1262
  1042
                    }
Dean@1262
  1043
Dean@1262
  1044
                    if (sentFolder != null)
Dean@1262
  1045
                    {
Dean@1348
  1046
                        acctSettings.SentFolderEntryId = sentFolder.EntryID;
Dean@1262
  1047
Dean@1262
  1048
                        // Create the basic sent mail item
Dean@1262
  1049
                        sentMailItem = (Outlook.MailItem)sentFolder.Items.Add(Outlook.OlItemType.olMailItem);
Thomas@1299
  1050
                        sentMessage.ApplyTo(sentMailItem, false, true); // Do NOT include internal Header Fields (MAPI properties)!
Dean@1262
  1051
Dean@1262
  1052
                        // Set the date and time the mail item was sent
Dean@1275
  1053
                        try
Dean@1275
  1054
                        {
Dean@1350
  1055
                            MapiHelper.SetProperty(sentMailItem, MapiProperty.PidTagClientSubmitTime, DateTime.Now.ToUniversalTime());
Dean@1275
  1056
                        }
Dean@1275
  1057
                        catch { }
Dean@1262
  1058
Dean@1262
  1059
                        // Set flags
Dean@1275
  1060
                        try
Dean@1275
  1061
                        {
Dean@1350
  1062
                            messageFlags = (System.Int32)MapiHelper.GetProperty(sentMailItem, MapiProperty.PidTagMessageFlags);
Dean@1350
  1063
                            messageFlags &= ~((System.Int32)MapiPropertyValue.EnumPidTagMessageFlags.mfUnsent);  // Clear UNSENT flag -- must be done before save
Dean@1350
  1064
                            messageFlags |= ((System.Int32)MapiPropertyValue.EnumPidTagMessageFlags.mfRead);     // Mark as read
Dean@1350
  1065
                            MapiHelper.SetProperty(sentMailItem, MapiProperty.PidTagMessageFlags, messageFlags);
Dean@1275
  1066
                        }
Dean@1275
  1067
                        catch { }
Dean@1262
  1068
Dean@1262
  1069
                        // Save pEp rating
Dean@1275
  1070
                        try
Dean@1275
  1071
                        {
Dean@1303
  1072
                            sentMailItem.SetPEPProperty(MailItemExtensions.PEPProperty.Rating, storedRating);
Dean@1275
  1073
                        }
Dean@1275
  1074
                        catch { }
Dean@1262
  1075
Dean@1262
  1076
                        // Save changes to the mail item (must be done last for some properties)
Dean@1262
  1077
                        sentMailItem.Save();
Dean@1262
  1078
Dean@1262
  1079
                        /* Attempt to move to the sent folder.
Dean@1262
  1080
                         * For ActiveSync accounts, this will fail with the error:
Dean@1262
  1081
                         * 'Sorry, Exchange ActiveSync doesn't support what you're trying to do.'
Dean@1262
  1082
                         * This is because the .Items.Add(folder) will ignore the specified folder and create in local Drafts.
Dean@1262
  1083
                         * Then "Exchange ActiveSync doesn’t support the Drafts folder" so it can't be moved out.
Dean@1262
  1084
                         * Even in the Outlook UI a draft cannot be 'dragged' out of the drafts folder.
Dean@1262
  1085
                         */
Dean@1262
  1086
                        try
Dean@1262
  1087
                        {
Dean@1262
  1088
                            sentMailItem.Move(sentFolder);
Dean@1262
  1089
                        }
Dean@1262
  1090
                        catch { }
Dean@1262
  1091
                    }
Dean@738
  1092
                }
Dean@738
  1093
            }
Dean@743
  1094
            catch (Exception ex)
Dean@743
  1095
            {
Dean@1262
  1096
                Log.Error("CreateNewSentMail: Error occured, " + ex.ToString());
Dean@886
  1097
                throw;
Dean@743
  1098
            }
Dean@738
  1099
            finally
Dean@738
  1100
            {
Thomas@2328
  1101
                folder = null;
Thomas@2328
  1102
                folders = null;
Thomas@2328
  1103
                ns = null;
Thomas@2328
  1104
                rootFolder = null;
Thomas@2328
  1105
                sentFolder = null;
Thomas@2328
  1106
                sentMailItem = null;
Dean@738
  1107
            }
Dean@738
  1108
        }
Dean@1340
  1109
Dean@745
  1110
        /// <summary>
Dean@671
  1111
        /// Gets whether the given account is trusted (on the account whitelist).
Dean@671
  1112
        /// Character case and whitespace is ignored during comparison.
Dean@671
  1113
        /// </summary>
Dean@671
  1114
        /// <param name="address">The address of the account.</param>
Dean@671
  1115
        /// <returns>True if the account with the given address is trusted by default (on the whitelist), otherwise false.</returns>
Dean@671
  1116
        private bool GetIsAccountTrusted(string address)
Dean@671
  1117
        {
Dean@671
  1118
            bool isTrusted = false;
Dean@1349
  1119
            string searchAddress = address.ToUpperInvariant().Trim();
Dean@671
  1120
            string searchDomain = searchAddress.Contains("@") ? searchAddress.Substring(searchAddress.LastIndexOf("@")) : null;
Dean@671
  1121
            string whitelistAccount;
Dean@671
  1122
Dean@1262
  1123
            for (int i = 0; i < this._Settings.AccountWhitelist.Length; i++)
Dean@671
  1124
            {
Dean@1349
  1125
                whitelistAccount = this._Settings.AccountWhitelist[i].ToUpperInvariant().Trim();
Dean@671
  1126
Dean@671
  1127
                // Check for exact match
Dean@671
  1128
                if (searchAddress == whitelistAccount)
Dean@671
  1129
                {
Dean@671
  1130
                    isTrusted = true;
Dean@671
  1131
                    break;
Dean@671
  1132
                }
Dean@671
  1133
Dean@671
  1134
                // Check for domain match
Dean@671
  1135
                if ((searchDomain != null) &&
Dean@671
  1136
                    whitelistAccount.StartsWith("@") &&
Dean@671
  1137
                    (searchDomain == whitelistAccount))
Dean@671
  1138
                {
Dean@671
  1139
                    isTrusted = true;
Dean@671
  1140
                    break;
Dean@671
  1141
                }
Dean@671
  1142
            }
Dean@671
  1143
Dean@671
  1144
            return (isTrusted);
Dean@671
  1145
        }
Dean@671
  1146
Dean@671
  1147
        /// <summary>
Dean@1262
  1148
        /// Copies any necessary data from the given options form state back into this add-ins current state.
Dean@1262
  1149
        /// The registry is also updated by this method.
Dean@1050
  1150
        /// </summary>
Dean@1262
  1151
        /// <param name="state">The state to copy data from.</param>
Dean@1262
  1152
        internal void SetOptionsState(FormControlOptions.State state)
Dean@1050
  1153
        {
Dean@1262
  1154
            bool isBlacklisted;
Dean@1262
  1155
            string fpr1;
Dean@1262
  1156
            string fpr2;
Dean@1262
  1157
            string[] blacklist;
Dean@1262
  1158
            PEPSettings.PEPAccountSettings acctSettings;
Dean@1262
  1159
Dean@1262
  1160
            if (state != null)
Dean@1050
  1161
            {
Dean@1382
  1162
                // Get the blacklist
Dean@1262
  1163
                try
Dean@1050
  1164
                {
Dean@1379
  1165
                    blacklist = ThisAddIn.PEPEngine.BlacklistRetrieve();
Dean@1262
  1166
                }
Dean@1262
  1167
                catch (COMException ex)
Dean@1262
  1168
                {
Dean@1262
  1169
                    blacklist = new string[0];
Dean@1262
  1170
                    Log.Error("SetOptionsState: Error getting blacklist from engine. " + ex.ToString());
Dean@1262
  1171
                }
Dean@1262
  1172
Dean@1382
  1173
                // Remove any fingerprints no longer in the engine blacklist
Dean@1262
  1174
                if (blacklist != null)
Dean@1262
  1175
                {
Dean@1262
  1176
                    for (int i = (blacklist.Length - 1); i >= 0; i--)
Dean@1050
  1177
                    {
Dean@1262
  1178
                        fpr1 = this.RemoveFprFormatting(blacklist[i]);
Dean@1262
  1179
                        isBlacklisted = false;
Dean@1262
  1180
Dean@1262
  1181
                        if (string.IsNullOrEmpty(fpr1) == false)
Dean@1050
  1182
                        {
Dean@1262
  1183
                            // Check if fingerprint is still blacklisted
Dean@1382
  1184
                            foreach (KVPair<PEPIdentity, bool> entry in state.Blacklist)
Dean@1050
  1185
                            {
Dean@1262
  1186
                                fpr2 = this.RemoveFprFormatting(entry.Key.Fingerprint);
Dean@1262
  1187
Dean@1262
  1188
                                // Value is true if the entry is blacklisted
Dean@1382
  1189
                                if ((string.Equals(fpr1, fpr2, StringComparison.OrdinalIgnoreCase)) &&
Dean@1262
  1190
                                    (entry.Value))
Dean@1050
  1191
                                {
Dean@1262
  1192
                                    isBlacklisted = true;
Dean@1262
  1193
                                    break;
Dean@1050
  1194
                                }
Dean@1050
  1195
                            }
Dean@1050
  1196
Dean@1262
  1197
                            if (isBlacklisted == false)
Dean@1050
  1198
                            {
Dean@1262
  1199
                                try
Dean@1050
  1200
                                {
markus@1337
  1201
                                    ThisAddIn.PEPEngine.BlacklistDelete(fpr1);
Dean@1050
  1202
                                }
Dean@1262
  1203
                                catch (COMException ex)
Dean@1050
  1204
                                {
Dean@1262
  1205
                                    Log.Error("SetOptionsState: Failed to delete blacklist entry, " + ex.ToString());
Dean@1050
  1206
                                }
Dean@1050
  1207
                            }
Dean@1050
  1208
                        }
Dean@1050
  1209
                    }
Dean@1050
  1210
                }
Dean@1262
  1211
Dean@1382
  1212
                // Add any new fingerprints to the engine blacklist
Dean@1382
  1213
                foreach (KVPair<PEPIdentity, bool> entry in state.Blacklist)
Dean@839
  1214
                {
Dean@1262
  1215
                    fpr1 = this.RemoveFprFormatting(entry.Key.Fingerprint);
Dean@1262
  1216
Dean@1262
  1217
                    // Value is true if the entry is blacklisted
Dean@1262
  1218
                    if ((entry.Value) &&
Dean@1262
  1219
                        (string.IsNullOrEmpty(fpr1) == false))
Dean@839
  1220
                    {
Dean@1262
  1221
                        try
Dean@839
  1222
                        {
markus@1337
  1223
                            if (ThisAddIn.PEPEngine.BlacklistIsListed(fpr1) == false)
Dean@839
  1224
                            {
markus@1337
  1225
                                ThisAddIn.PEPEngine.BlacklistAdd(fpr1);
Dean@839
  1226
                            }
Dean@1050
  1227
                        }
Dean@1262
  1228
                        catch (COMException ex)
Dean@1050
  1229
                        {
Dean@1262
  1230
                            Log.Error("SetOptionsState: Failed to add new blacklist entry, " + ex.ToString());
Dean@839
  1231
                        }
Dean@839
  1232
                    }
Dean@839
  1233
                }
Dean@839
  1234
Dean@1460
  1235
                foreach (FormControlOptions.AccountState entry in state.AccountSettingsList)
Dean@839
  1236
                {
Dean@1262
  1237
                    /* pEp internally uses account types as defined by microsoft.
Dean@1262
  1238
                     * This means they have 'ol' before the type (Example: 'olImap').
Dean@1262
  1239
                     * This isn't always user friendly so for the options UI the 'ol' is removed.
Dean@1262
  1240
                     * However, when comparing again with the settings list, this 'ol' must be added back.
Dean@1262
  1241
                     */
Thomas@1522
  1242
                    acctSettings = this._Settings.GetAccountSettings(entry.SmtpAddress);
Dean@1262
  1243
Dean@1262
  1244
                    if (acctSettings != null)
Dean@839
  1245
                    {
Dean@1262
  1246
                        // Modify existing value
Dean@1348
  1247
                        // The following are skipped: SentFolderEntryId, SmtpAddress & Type
Thomas@1790
  1248
                        acctSettings.IsDecryptAlwaysEnabled = entry.IsDecryptAlwaysEnabled;
Dean@1262
  1249
                        acctSettings.IsPEPEnabled = entry.IsPEPEnabled;
Dean@1262
  1250
                        acctSettings.IsSecureStorageEnabled = entry.IsSecureStorageEnabled;
Dean@1488
  1251
                        acctSettings.IsSyncEnabled = entry.IsSyncEnabled;
Dean@203
  1252
                    }
Dean@1166
  1253
                    else
Dean@1166
  1254
                    {
Dean@1460
  1255
                        Log.Warning("SetOptionsState: Existing account settings not found.");
Dean@1166
  1256
                    }
Dean@203
  1257
                }
Dean@203
  1258
Thomas@2432
  1259
                // Un/set rules and view filters if necessary
Thomas@2432
  1260
                if (state.HideInternalMessages != this._Settings.HideInternalMessages)
Thomas@2432
  1261
                {
Thomas@2501
  1262
                    this.SetRules(state.HideInternalMessages);
Thomas@2432
  1263
                }
Thomas@2432
  1264
                this._Settings.HideInternalMessages = state.HideInternalMessages;
Thomas@2432
  1265
Dean@1262
  1266
                this._Settings.IsAutoUpdateEnabled = state.IsAutoUpdateEnabled;
Dean@1262
  1267
                this._Settings.IsEncryptAllAccountsEnabled = state.IsEncryptAllAccountsEnabled;
Dean@1314
  1268
                this._Settings.IsNeverUnsecureOptionVisible = state.IsNeverUnsecureOptionVisible;
Thomas@2150
  1269
                this._Settings.IsPassiveModeEnabled = state.IsPassiveModeEnabled;
Dean@1262
  1270
                this._Settings.IsPEPFolderVisible = state.IsPEPFolderVisible;
Thomas@2410
  1271
                this._Settings.IsPrivacyStatusBarEnabled = state.IsPrivacyStatusBarEnabled;
Dean@1262
  1272
                this._Settings.IsSecurityLossWarningEnabled = state.IsSecurityLossWarningEnabled;
Thomas@1577
  1273
                this._Settings.IsSyncEnabledForAllAccounts = state.IsSyncEnabledForAllAccounts;
Dean@1262
  1274
                this._Settings.IsUnencryptedSubjectEnabled = state.IsUnencryptedSubjectEnabled;
Dean@1262
  1275
                this._Settings.IsVerboseLoggingEnabled = state.IsVerboseLoggingEnabled;
Dean@1262
  1276
                this._Settings.TrustwordsCulture = ((state.TrustwordsCulture != null) ? new CultureInfo(state.TrustwordsCulture.LCID) : null);
Dean@659
  1277
Dean@219
  1278
                // Save last state for next options opening
Dean@219
  1279
                this.lastOptionsState = state.Copy();
Dean@219
  1280
Dean@203
  1281
                // Update registry (in case of unforseen app shutdown)
Dean@1262
  1282
                this._Settings.SaveToRegistry();
Dean@203
  1283
            }
Dean@203
  1284
        }
Dean@203
  1285
Dean@203
  1286
        /// <summary>
Dean@203
  1287
        /// Builds a new options form state using this add-ins current state.
Dean@203
  1288
        /// </summary>
Dean@203
  1289
        /// <returns>A new options form state.</returns>
Dean@1262
  1290
        internal FormControlOptions.State GetOptionsState()
Dean@203
  1291
        {
Dean@818
  1292
            bool isDefaultStore = false;
Dean@1382
  1293
            bool exists;
Dean@1262
  1294
            string fpr1;
Dean@1262
  1295
            string fpr2;
Dean@839
  1296
            string[] blacklist;
markus@1337
  1297
            StringPair[] keylist;
Dean@1262
  1298
            PEPIdentity newIdent;
Dean@1262
  1299
            PEPSettings.PEPAccountSettings newAcctSettings;
Dean@1262
  1300
            FormControlOptions.State state;
Dean@919
  1301
            Outlook.NameSpace ns = this.Application.Session;
Dean@818
  1302
            Outlook.Store defaultStore = null;
Dean@818
  1303
Dean@818
  1304
            // Check if pEp is the default store
Dean@818
  1305
            try
Dean@818
  1306
            {
Dean@818
  1307
                defaultStore = ns.DefaultStore;
Dean@1262
  1308
                isDefaultStore = (defaultStore.StoreID == this._PEPStoreRootFolder.StoreID);
Dean@818
  1309
            }
Dean@818
  1310
            catch
Dean@818
  1311
            {
Dean@818
  1312
                isDefaultStore = false;
Dean@818
  1313
            }
Dean@219
  1314
Dean@219
  1315
            // Load from last state if possible
Dean@219
  1316
            if (this.lastOptionsState != null)
Dean@219
  1317
            {
Dean@219
  1318
                state = this.lastOptionsState.Copy();
Dean@219
  1319
            }
Dean@219
  1320
            else
Dean@219
  1321
            {
Dean@1262
  1322
                state = new FormControlOptions.State();
Dean@219
  1323
            }
Dean@203
  1324
Dean@1262
  1325
            // Get complete OpenPGP key list
Dean@1250
  1326
            try
Dean@1250
  1327
            {
markus@1343
  1328
                keylist = ThisAddIn.PEPEngine.OpenPGPListKeyinfo(null);
Dean@1262
  1329
            }
Dean@1262
  1330
            catch (COMException ex)
Dean@1262
  1331
            {
markus@1337
  1332
                keylist = new StringPair[0];
Dean@1262
  1333
                Log.Error("GetOptionsState: Error getting OpenPGP keylist from engine. " + ex.ToString());
Dean@1262
  1334
            }
Dean@1262
  1335
Dean@1262
  1336
            // Get the blacklist
Dean@1262
  1337
            try
Dean@1262
  1338
            {
Dean@1379
  1339
                blacklist = ThisAddIn.PEPEngine.BlacklistRetrieve();
Dean@931
  1340
            }
Dean@931
  1341
            catch (COMException ex)
Dean@931
  1342
            {
Dean@931
  1343
                blacklist = new string[0];
Dean@1262
  1344
                Log.Error("GetOptionsState: Error getting blacklist from engine. " + ex.ToString());
Dean@931
  1345
            }
Dean@931
  1346
Dean@1382
  1347
            // Add the OpenPGP keylist to the UI blacklist
Dean@1382
  1348
            state.Blacklist.Clear();
Dean@1262
  1349
            if (keylist != null)
Dean@1209
  1350
            {
markus@1337
  1351
                foreach (StringPair ident in keylist)
Dean@839
  1352
                {
markus@1347
  1353
                    fpr1 = this.RemoveFprFormatting(ident.Name);
Dean@1382
  1354
                    exists = false;
Dean@1262
  1355
Dean@1262
  1356
                    if (string.IsNullOrEmpty(fpr1) == false)
Dean@1262
  1357
                    {
Dean@1262
  1358
                        // Check if it exists in the blacklist
Dean@1262
  1359
                        if (blacklist != null)
Dean@1262
  1360
                        {
Dean@1382
  1361
                            foreach (string fpr in blacklist)
Dean@1262
  1362
                            {
Dean@1382
  1363
                                fpr2 = this.RemoveFprFormatting(fpr);
Dean@1382
  1364
Dean@1382
  1365
                                if (string.Equals(fpr1, fpr2, StringComparison.OrdinalIgnoreCase))
Dean@1262
  1366
                                {
Dean@1382
  1367
                                    exists = true;
Dean@1262
  1368
                                    break;
Dean@1262
  1369
                                }
Dean@1262
  1370
                            }
Dean@1262
  1371
                        }
Dean@1262
  1372
Dean@1262
  1373
                        // Build entry to add
markus@1347
  1374
                        newIdent = PEPIdentity.Parse(ident.Value);
Dean@1262
  1375
                        newIdent.Fingerprint = this.ToQuadruple(fpr1, false);
Dean@1262
  1376
Dean@1382
  1377
                        state.Blacklist.Add(new KVPair<PEPIdentity, bool>(newIdent, exists));
Dean@1262
  1378
                    }
Dean@839
  1379
                }
Dean@839
  1380
            }
Dean@1382
  1381
Dean@1382
  1382
            // Add any fingerprints that exist only in the engine blacklist to the UI blacklist
Dean@1382
  1383
            if (blacklist != null)
Dean@1382
  1384
            {
Dean@1382
  1385
                foreach (string fpr in blacklist)
Dean@1382
  1386
                {
Dean@1382
  1387
                    fpr1 = this.RemoveFprFormatting(fpr);
Dean@1382
  1388
                    exists = false;
Dean@1382
  1389
Dean@1382
  1390
                    // Check if it already exists in the UI blacklist by fingerprint
Dean@1382
  1391
                    foreach (KVPair<PEPIdentity, bool> entry in state.Blacklist)
Dean@1382
  1392
                    {
Dean@1382
  1393
                        fpr2 = this.RemoveFprFormatting(entry.Key.Fingerprint);
Dean@1382
  1394
Dean@1382
  1395
                        if (string.Equals(fpr1, fpr2, StringComparison.OrdinalIgnoreCase))
Dean@1382
  1396
                        {
Dean@1382
  1397
                            exists = true;
Dean@1382
  1398
                            break;
Dean@1382
  1399
                        }
Dean@1382
  1400
                    }
Dean@1382
  1401
Dean@1382
  1402
                    if (exists == false)
Dean@1382
  1403
                    {
Thomas@2507
  1404
                        newIdent = new PEPIdentity
Thomas@2507
  1405
                        {
Thomas@2507
  1406
                            Fingerprint = this.ToQuadruple(fpr1, false)
Thomas@2507
  1407
                        };
Dean@1382
  1408
Dean@1382
  1409
                        // Always put at the beginning so it's easier for the user to find
Dean@1382
  1410
                        state.Blacklist.Insert(0, new KVPair<PEPIdentity, bool>(newIdent, true));
Dean@1382
  1411
                    }
Dean@1382
  1412
                }
Dean@1382
  1413
            }
Dean@1382
  1414
Dean@1382
  1415
            state.BlacklistEnteredFingerprint = null;
Dean@1382
  1416
            state.BlacklistSelectedIndex = -1;
Dean@1262
  1417
Dean@1262
  1418
            // Build AccountSettingsList
Dean@1262
  1419
            state.AccountSettingsList.Clear();
Dean@1262
  1420
            for (int i = 0; i < this._Settings.AccountSettingsList.Count; i++)
Dean@203
  1421
            {
Dean@1262
  1422
                newAcctSettings = this._Settings.AccountSettingsList[i].Copy();
Dean@1262
  1423
Dean@1262
  1424
                /* pEp internally uses account types as defined by microsoft.
Dean@1262
  1425
                 * This means they have 'ol' before the type (Example: 'olImap').
Dean@1262
  1426
                 * This isn't always user friendly so for the options UI the 'ol' is removed.
Dean@1166
  1427
                 */
Dean@1262
  1428
                if ((string.IsNullOrEmpty(newAcctSettings.Type) == false) &&
Dean@1262
  1429
                    (newAcctSettings.Type.StartsWith("ol", StringComparison.OrdinalIgnoreCase)))
Dean@1166
  1430
                {
Dean@1262
  1431
                    newAcctSettings.Type = newAcctSettings.Type.Substring(2);
Dean@1166
  1432
                }
Dean@1166
  1433
Dean@1460
  1434
                state.AccountSettingsList.Add(new FormControlOptions.AccountState(newAcctSettings));
Dean@203
  1435
            }
Thomas@1110
  1436
Thomas@2432
  1437
            state.HideInternalMessages = this._Settings.HideInternalMessages;
Dean@1262
  1438
            state.IsAutoUpdateEnabled = this._Settings.IsAutoUpdateEnabled;
Dean@1262
  1439
            state.IsDeveloperModeEnabled = this._Settings.IsDeveloperModeEnabled;
Dean@1262
  1440
            state.IsEncryptAllAccountsEnabled = this._Settings.IsEncryptAllAccountsEnabled;
Thomas@2643
  1441
            state.IsGrouped = this._Settings.IsGrouped;
Dean@1314
  1442
            state.IsNeverUnsecureOptionVisible = this._Settings.IsNeverUnsecureOptionVisible;
Thomas@2150
  1443
            state.IsPassiveModeEnabled = this._Settings.IsPassiveModeEnabled;
Dean@818
  1444
            state.IsPEPFolderDefaultStore = isDefaultStore;
Dean@1262
  1445
            state.IsPEPFolderVisible = (isDefaultStore ? true : this._Settings.IsPEPFolderVisible);
Thomas@2417
  1446
            state.IsPrivacyStatusBarEnabled = this._Settings.IsPrivacyStatusBarEnabled;
Dean@1262
  1447
            state.IsSecurityLossWarningEnabled = this._Settings.IsSecurityLossWarningEnabled;
Thomas@1577
  1448
            state.IsSyncEnabledForAllAccounts = this._Settings.IsSyncEnabledForAllAccounts;
Dean@1262
  1449
            state.IsTNEFDisabled = this._Settings.IsTNEFDisabled;
Dean@1262
  1450
            state.IsUnencryptedSubjectEnabled = this._Settings.IsUnencryptedSubjectEnabled;
Dean@1262
  1451
            state.IsVerboseLoggingEnabled = this._Settings.IsVerboseLoggingEnabled;
Dean@860
  1452
            state.PEPCopyright = Globals.PEP_COPYRIGHT;
Dean@1262
  1453
            state.PEPName = (Globals.RELEASE_MODE == Globals.ReleaseMode.Reader ? Globals.PEP_DISPLAY_NAME_READER : Globals.PEP_DISPLAY_NAME);
Dean@1262
  1454
            state.SystemInfo = Globals.GetSystemInfoList();
Dean@1262
  1455
            state.TrustwordsCulture = ((this._Settings.TrustwordsCulture != null) ? new CultureInfo(this._Settings.TrustwordsCulture.LCID) : null);
Dean@444
  1456
Dean@818
  1457
            // Release objects
Thomas@2499
  1458
            defaultStore = null;
Thomas@2499
  1459
            ns = null;
Dean@818
  1460
Dean@203
  1461
            return (state);
Dean@190
  1462
        }
Dean@190
  1463
Dean@190
  1464
        /// <summary>
Dean@1503
  1465
        /// Connects events for folder/item detection in Outlook.
Dean@1503
  1466
        /// Included folders are:
Dean@1503
  1467
        ///  • Default Sent folders for only ActiveSync accounts
Dean@1503
  1468
        ///  • Default Inbox folders for all accounts
Dean@750
  1469
        /// </summary>
Dean@1503
  1470
        private void ConnectWatchedFolders()
Thomas@1651
  1471
        {
Dean@1422
  1472
            Outlook.Store store = null;
Dean@1422
  1473
            Outlook.Stores stores = null;
Dean@1422
  1474
            Outlook.Folder folder = null;
Dean@1422
  1475
            Outlook.NameSpace ns = null;
Dean@1422
  1476
Dean@1422
  1477
            try
Dean@750
  1478
            {
Dean@1422
  1479
                ns = this.Application.Session;
Dean@1422
  1480
                stores = ns.Stores;
Dean@1422
  1481
Dean@1422
  1482
                for (int i = 1; i <= stores.Count; i++)
Dean@750
  1483
                {
Dean@1422
  1484
                    // Note: accessing the stores can fail if the data file is missing or is in use by another program. 
Dean@837
  1485
                    try
Dean@837
  1486
                    {
Dean@1422
  1487
                        store = stores[i];
Dean@837
  1488
                    }
Thomas@1764
  1489
                    catch (Exception ex)
Dean@837
  1490
                    {
Thomas@1764
  1491
                        Log.Warning("ConnectWatchedFolders: Failed to get store, " + ex.ToString());
Dean@1422
  1492
                    }
Dean@1422
  1493
Thomas@2652
  1494
                    if (store?.StoreID?.Equals(Globals.ThisAddIn.PEPStoreEntryId) != true)
Dean@1422
  1495
                    {
Dean@1503
  1496
                        // Add default inbox folder
Thomas@1555
  1497
                        folder = null;
Thomas@1555
  1498
                        try
Thomas@1555
  1499
                        {
Thomas@1555
  1500
                            folder = (Outlook.Folder)store.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
Thomas@1555
  1501
                        }
Thomas@1764
  1502
                        catch (Exception ex)
Thomas@1555
  1503
                        {
Thomas@2652
  1504
                            folder = null;
Thomas@1764
  1505
                            Log.Warning("ConnectWatchedFolders: Failure getting default inbox folder. " + ex.ToString());
Thomas@1555
  1506
                        }
Thomas@1555
  1507
Thomas@1555
  1508
                        // Add the folder to the watched list (do not release it)
Thomas@1555
  1509
                        if (folder != null)
Thomas@1555
  1510
                        {
Thomas@1555
  1511
                            this.watchedFolders.Add(new WatchedFolder(folder, Outlook.OlDefaultFolders.olFolderInbox));
Thomas@1555
  1512
                        }
Dean@1503
  1513
Thomas@1718
  1514
                        // Add Sent folder. This is needed so sent mails get decrypted on trusted servers to make the search function working
Thomas@1718
  1515
                        try
Dean@1422
  1516
                        {
Thomas@1718
  1517
                            folder = (Outlook.Folder)store.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);
Thomas@1718
  1518
                        }
Thomas@1764
  1519
                        catch (Exception ex)
Thomas@1718
  1520
                        {
Thomas@2652
  1521
                            folder = null;
Thomas@1764
  1522
                            Log.Warning("ConnectWatchedFolders: Failure getting default sent folder. " + ex.ToString());
Thomas@1718
  1523
                        }
Thomas@1718
  1524
Thomas@1718
  1525
                        // Add the folder to the watched list (do not release it)
Thomas@1718
  1526
                        if (folder != null)
Thomas@1718
  1527
                        {
Thomas@1718
  1528
                            this.watchedFolders.Add(new WatchedFolder(folder, Outlook.OlDefaultFolders.olFolderSentMail));
Dean@1422
  1529
                        }
Dean@1422
  1530
Dean@1422
  1531
                        store = null;
Dean@837
  1532
                    }
Dean@837
  1533
                }
Dean@1422
  1534
            }
Dean@1422
  1535
            catch (Exception ex)
Dean@1422
  1536
            {
Dean@1503
  1537
                Log.Error("ConnectWatchedFolders: Failure occured, " + ex.ToString());
Dean@1422
  1538
            }
Dean@1422
  1539
            finally
Dean@1422
  1540
            {
Thomas@2328
  1541
                ns = null;
Thomas@2328
  1542
                store = null;
Thomas@2328
  1543
                stores = null;
Dean@750
  1544
            }
Dean@750
  1545
        }
Dean@750
  1546
Dean@750
  1547
        /// <summary>
Dean@1262
  1548
        /// Opens the pEp data store root folder and saves the reference for further use.
Dean@190
  1549
        /// If none already exists, a new one is created.
Dean@190
  1550
        /// </summary>
Dean@1262
  1551
        private void OpenPEPStoreRootFolder()
Dean@190
  1552
        {
Dean@1262
  1553
            Outlook.Store pEpStore = null;
Dean@1422
  1554
            Outlook.Store store = null;
Dean@666
  1555
            Outlook.Stores stores = null;
Dean@919
  1556
            Outlook.NameSpace ns = null;
Dean@190
  1557
Dean@474
  1558
            try
Dean@190
  1559
            {
Thomas@2605
  1560
                // The path to store the pEp store to
Thomas@2667
  1561
                string path = Path.Combine(Globals.PEPUserFolder, (Globals.PEP_DATA_FILE_NAME + ".pst"));
Thomas@2644
  1562
Thomas@2605
  1563
                /* For Outlook installations from the Windows Trusted Store the AddStoreEx function to add a store seems to
Thomas@2605
  1564
                 * convert "%LOCALAPPDATA%" to "%LOCALAPPDATA\Packages\Microsoft.Office.Desktop_8wekyb3d8bbwe\LocalCache\Local\".
Thomas@2605
  1565
                 * This is also confirmed on several sites/blogs. No official documentation has been found so far, though.
Thomas@2605
  1566
                 * In any case, we also use the above mentioned path to search for the pEp store.
Thomas@2605
  1567
                 */
Thomas@2663
  1568
                string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
Thomas@2663
  1569
                string winStorePath = null;
Thomas@2663
  1570
                if (path.ToLowerInvariant().Contains(localAppData.ToLowerInvariant()))
Thomas@2663
  1571
                {
Thomas@2663
  1572
                    winStorePath = path.ToLowerInvariant().Replace(localAppData.ToLowerInvariant(), Path.Combine(localAppData, "Packages", "Microsoft.Office.Desktop_8wekyb3d8bbwe", "LocalCache", "Local"));
Thomas@2663
  1573
                }
Thomas@2605
  1574
Dean@919
  1575
                ns = this.Application.Session;
Dean@666
  1576
                stores = ns.Stores;
Thomas@1627
  1577
Thomas@1627
  1578
                // Try to find an existing store based on file name
Dean@666
  1579
                for (int i = 1; i <= stores.Count; i++)
Dean@190
  1580
                {
Dean@1262
  1581
                    /* Note: accessing the stores can fail if the data file is missing or is in use by another program. 
Thomas@2663
  1582
                     * This is usually OK as long as it isn't  the pEp file.
Dean@1262
  1583
                     * However, here the assumption is made that any error is not the pEp file and execution will continue.
Dean@1262
  1584
                     * If for some reason the error prevents detecting an existing pEp.pst file, this will be caught in the next step.
Dean@1262
  1585
                     */
Dean@1262
  1586
                    try
Dean@190
  1587
                    {
Dean@1422
  1588
                        store = stores[i];
Dean@1262
  1589
                    }
Thomas@1936
  1590
                    catch (Exception ex)
Dean@1262
  1591
                    {
Thomas@1936
  1592
                        Log.Warning("OpenPEPStoreRootFolder: Failed to get store, " + ex.ToString());
Dean@1262
  1593
                    }
Dean@1262
  1594
Thomas@2663
  1595
                    if ((store?.FilePath?.Equals(path, StringComparison.InvariantCultureIgnoreCase) == true) ||
Thomas@2663
  1596
                        (store?.FilePath?.Equals(winStorePath, StringComparison.InvariantCultureIgnoreCase) == true))
Dean@1262
  1597
                    {
Thomas@1627
  1598
                        pEpStore = store;
Thomas@1627
  1599
                        break;
Dean@474
  1600
                    }
Thomas@1627
  1601
Thomas@1627
  1602
                    store = null;
Dean@474
  1603
                }
Dean@474
  1604
Thomas@1637
  1605
                // If no store was found, create new 
Dean@1262
  1606
                if (pEpStore == null)
Dean@1262
  1607
                {
Thomas@2605
  1608
                    /* Create the file and add it as a store, otherwise use the existing one.
Thomas@1638
  1609
                     * This can throw an error if a user either modified the list of Outlook data stores
Thomas@1638
  1610
                     * or the pEp.pst file itself.
Thomas@1651
  1611
                     */
Thomas@1638
  1612
                    try
Thomas@1638
  1613
                    {
Thomas@1638
  1614
                        ns.AddStoreEx(path, Outlook.OlStoreType.olStoreUnicode);
Thomas@1638
  1615
                    }
Thomas@1936
  1616
                    catch (Exception ex)
Thomas@1638
  1617
                    {
Thomas@2330
  1618
                        Log.Error("OpenPEPStoreRootFolder: Failed to add pEp store. " + ex.ToString());
Thomas@1638
  1619
                    }
Dean@1262
  1620
Dean@1262
  1621
                    for (int i = 1; i <= stores.Count; i++)
Dean@1262
  1622
                    {
Thomas@1638
  1623
                        /* Search again for the newly created store.
Thomas@1638
  1624
                         * Note: As the creation itself might have failed, this is not guaranteed to work.
Thomas@1638
  1625
                         * We then try again in the next step or throw an error if the store cannot be accessed.
Thomas@1651
  1626
                         */
Dean@1262
  1627
                        try
Dean@1262
  1628
                        {
Dean@1422
  1629
                            store = stores[i];
Dean@1262
  1630
                        }
Thomas@1936
  1631
                        catch (Exception ex)
Thomas@1637
  1632
                        {
Thomas@1936
  1633
                            Log.Warning("OpenPEPStoreRootFolder: Failed to get store, " + ex.ToString());
Thomas@1637
  1634
                        }
Thomas@1637
  1635
Thomas@2663
  1636
                        if ((store?.FilePath?.Equals(path, StringComparison.InvariantCultureIgnoreCase) == true) ||
Thomas@2663
  1637
                            (store?.FilePath?.Equals(winStorePath, StringComparison.InvariantCultureIgnoreCase) == true))
Dean@1262
  1638
                        {
Thomas@1627
  1639
                            pEpStore = store;
Thomas@1627
  1640
                            pEpStore.GetRootFolder().Name = Globals.PEP_DATA_FILE_NAME;
Thomas@1627
  1641
                            break; // Break before releasing
Dean@1262
  1642
                        }
Thomas@2605
  1643
Thomas@2605
  1644
                        store = null;
Dean@1262
  1645
                    }
Dean@1262
  1646
                }
Dean@1262
  1647
Dean@1262
  1648
                if (pEpStore != null)
Dean@1262
  1649
                {
Dean@1262
  1650
                    this._PEPStoreRootFolder = (Outlook.Folder)pEpStore.GetRootFolder();
Thomas@2652
  1651
                    this._PEPStoreEntryId = pEpStore.StoreID;
Dean@1262
  1652
                }
Dean@1262
  1653
                else
Dean@1262
  1654
                {
Thomas@1638
  1655
                    // Try again using fallback solution for file paths with prefixes
Thomas@2605
  1656
                    Log.Warning("OpenPEPStoreRootFolder: No pEp store found. Trying fallback. pEp path is " + path);
Thomas@1637
  1657
Thomas@1637
  1658
                    for (int i = 1; i <= stores.Count; i++)
Thomas@1637
  1659
                    {
Thomas@1637
  1660
                        try
Thomas@1637
  1661
                        {
Thomas@1637
  1662
                            store = stores[i];
Thomas@2605
  1663
                            Log.Info("OpenPEPStoreRootFolder: file path of store " + i + " (" + (store?.DisplayName ?? "<null>") + "): " + store?.FilePath ?? "<null>");
Thomas@1637
  1664
                        }
Thomas@1936
  1665
                        catch (Exception ex)
Thomas@1637
  1666
                        {
Thomas@1936
  1667
                            Log.Warning("OpenPEPStoreRootFolder: Failed to get store, " + ex.ToString());
Thomas@1637
  1668
                        }
Thomas@1637
  1669
Thomas@1638
  1670
                        // Custom comparison of file paths independently of their (known) prefixes
Thomas@2605
  1671
                        if (Comparisons.FilePathsAreEqual(store?.FilePath, path) ||
Thomas@2605
  1672
                            Comparisons.FilePathsAreEqual(store?.FilePath, winStorePath))
Thomas@1638
  1673
                        {
Thomas@1638
  1674
                            pEpStore = store;
Thomas@1638
  1675
                            pEpStore.GetRootFolder().Name = Globals.PEP_DATA_FILE_NAME;
Thomas@1638
  1676
                            break;
Thomas@1638
  1677
                        }
Thomas@2605
  1678
Thomas@2605
  1679
                        store = null;
Thomas@1637
  1680
                    }
Thomas@1637
  1681
Thomas@1638
  1682
                    // If pEp store was found, use it. Else throw error.
Thomas@1638
  1683
                    if (pEpStore != null)
Thomas@1638
  1684
                    {
Thomas@2605
  1685
                        this._PEPStoreRootFolder = pEpStore.GetRootFolder() as Outlook.Folder;
Thomas@2652
  1686
                        this._PEPStoreEntryId = pEpStore.StoreID;
Thomas@1638
  1687
                    }
Thomas@1638
  1688
                    else
Thomas@1638
  1689
                    {
Thomas@1638
  1690
                        throw new Exception("Cannot open required pEp.pst file.");
Thomas@1638
  1691
                    }
Dean@1262
  1692
                }
Dean@474
  1693
            }
Dean@474
  1694
            catch (Exception ex)
Dean@474
  1695
            {
Dean@860
  1696
                Globals.StopAndSendCrashReport(ex);
Dean@190
  1697
            }
Dean@666
  1698
            finally
Dean@666
  1699
            {
Thomas@2328
  1700
                ns = null;
Thomas@2328
  1701
                pEpStore = null;
Thomas@2328
  1702
                store = null;
Thomas@2328
  1703
                stores = null;
Dean@666
  1704
            }
Dean@190
  1705
        }
Dean@190
  1706
Dean@190
  1707
        /// <summary>
Dean@1262
  1708
        /// Resets the pEp data store.
Dean@596
  1709
        /// This will delete all files.
Dean@596
  1710
        /// </summary>
Dean@1262
  1711
        internal void ResetPEPStore()
Dean@596
  1712
        {
Dean@596
  1713
            Outlook.Folder deletedFolder = null;
Dean@596
  1714
            Outlook.Folders folders = null;
Dean@596
  1715
            Outlook.Items items = null;
Dean@597
  1716
            Outlook.Store store = null;
Dean@608
  1717
            Outlook.Folder contacts = null;
Dean@608
  1718
            Outlook.Folders contactsFolders = null;
Dean@596
  1719
Dean@596
  1720
            try
Dean@596
  1721
            {
Dean@1262
  1722
                if (this._PEPStoreRootFolder != null)
Dean@596
  1723
                {
Dean@1262
  1724
                    store = this._PEPStoreRootFolder.Store;
Dean@605
  1725
Dean@597
  1726
                    // Move all folders to deleted folder
Dean@1262
  1727
                    folders = this._PEPStoreRootFolder.Folders;
Dean@597
  1728
                    for (int i = folders.Count; i > 0; i--)
Dean@597
  1729
                    {
Dean@597
  1730
                        // Default folders cannot be deleted and are skipped
Dean@597
  1731
                        try
Dean@597
  1732
                        {
Dean@597
  1733
                            folders[i].Delete();
Dean@597
  1734
                        }
Dean@597
  1735
                        catch { }
Dean@597
  1736
                    }
Dean@597
  1737
Dean@597
  1738
                    if (folders != null)
Dean@597
  1739
                    {
vb@1516
  1740
                        // Marshal.ReleaseComObject(folders);
Dean@597
  1741
                        folders = null;
Dean@597
  1742
                    }
Dean@596
  1743
Dean@608
  1744
                    // Move any contact folders/contacts to the deleted folder
Dean@608
  1745
                    contacts = (Outlook.Folder)store.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);
Dean@608
  1746
                    contactsFolders = contacts.Folders;
Dean@608
  1747
Dean@608
  1748
                    for (int i = contactsFolders.Count; i > 0; i--)
Dean@608
  1749
                    {
Dean@608
  1750
                        try
Dean@608
  1751
                        {
Dean@608
  1752
                            contactsFolders[i].Delete();
Dean@608
  1753
                        }
Dean@608
  1754
                        catch { }
Dean@608
  1755
                    }
Dean@608
  1756
Dean@596
  1757
                    // Delete items from deleted folder
Dean@597
  1758
                    deletedFolder = (Outlook.Folder)store.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderDeletedItems);
Dean@605
  1759
Dean@597
  1760
                    // Permanently delete items
Dean@597
  1761
                    items = deletedFolder.Items;
Dean@596
  1762
                    for (int i = items.Count; i > 0; i--)
Dean@596
  1763
                    {
Dean@597
  1764
                        try
Dean@597
  1765
                        {
Dean@597
  1766
                            items[i].Delete();
Dean@597
  1767
                        }
Dean@597
  1768
                        catch { }
Dean@596
  1769
                    }
Dean@596
  1770
Thomas@2328
  1771
                    items = null;
Dean@597
  1772
Dean@597
  1773
                    // Permanently delete folders
Dean@597
  1774
                    folders = deletedFolder.Folders;
Dean@596
  1775
                    for (int i = folders.Count; i > 0; i--)
Dean@596
  1776
                    {
Dean@597
  1777
                        try
Dean@597
  1778
                        {
Dean@597
  1779
                            folders[i].Delete();
Dean@597
  1780
                        }
Dean@597
  1781
                        catch { }
Dean@597
  1782
                    }
Dean@597
  1783
Thomas@2328
  1784
                    folders = null;
Dean@596
  1785
                }
Dean@596
  1786
            }
Thomas@2328
  1787
            catch (Exception ex)
Thomas@2328
  1788
            {
Thomas@2328
  1789
                Log.Error("ResetPEPStore: Error occured. " + ex.ToString());
Thomas@2328
  1790
            }
Dean@596
  1791
            finally
Dean@596
  1792
            {
Thomas@2328
  1793
                contacts = null;
Thomas@2328
  1794
                contactsFolders = null;
Thomas@2328
  1795
                deletedFolder = null;
Thomas@2328
  1796
                folders = null;
Thomas@2328
  1797
                items = null;
Thomas@2328
  1798
                store = null;
Dean@596
  1799
            }
Dean@596
  1800
        }
Dean@596
  1801
Dean@596
  1802
        /// <summary>
Dean@1262
  1803
        /// Sets the visibility of the pEp data store in the navigation pane.
Dean@1262
  1804
        /// This works by carefully releasing and maintaining references outside of Outlook.
Dean@815
  1805
        /// </summary>
Dean@1262
  1806
        /// <param name="visible">True if the pEp folder should be visible, otherwise false.</param>
Dean@1262
  1807
        private void SetPEPStoreRootFolderVisibility(bool visible)
Dean@815
  1808
        {
Dean@815
  1809
            Outlook.Folder folder = null;
Dean@919
  1810
            Outlook.NameSpace ns = null;
Dean@815
  1811
            Outlook.Store store = null;
Dean@815
  1812
Dean@815
  1813
            try
Dean@815
  1814
            {
Thomas@2137
  1815
                // If the pEp store hasn't been opened already, try to open it
Thomas@2137
  1816
                if (this._PEPStoreRootFolder == null)
Thomas@2137
  1817
                {
Thomas@2137
  1818
                    this.OpenPEPStoreRootFolder();
Thomas@2137
  1819
                }
Thomas@2137
  1820
Thomas@2137
  1821
                // Check again if the store has been found
Dean@1262
  1822
                if (this._PEPStoreRootFolder != null)
Dean@815
  1823
                {
Thomas@2137
  1824
                    ns = this.Application.Session;
Dean@1262
  1825
                    store = this._PEPStoreRootFolder.Store;
Dean@815
  1826
Dean@815
  1827
                    // Never show the default 'system' folders
Dean@815
  1828
                    foreach (Outlook.OlDefaultFolders defaultFolder in Enum.GetValues(typeof(Outlook.OlDefaultFolders)))
Dean@815
  1829
                    {
Dean@815
  1830
                        // Allow deleted items
Dean@815
  1831
                        if (defaultFolder != Outlook.OlDefaultFolders.olFolderDeletedItems)
Dean@815
  1832
                        {
Dean@815
  1833
                            try
Dean@815
  1834
                            {
Dean@815
  1835
                                folder = (Outlook.Folder)store.GetDefaultFolder(defaultFolder);
Dean@1350
  1836
                                MapiHelper.SetProperty(folder, MapiProperty.PidTagAttributeHidden, true);
Dean@815
  1837
                            }
Dean@815
  1838
                            catch { }
Dean@815
  1839
                            finally
Dean@815
  1840
                            {
Dean@815
  1841
                                if (folder != null)
Dean@815
  1842
                                {
vb@1516
  1843
                                    // Marshal.ReleaseComObject(folder);
Dean@815
  1844
                                    folder = null;
Dean@815
  1845
                                }
Dean@815
  1846
                            }
Dean@815
  1847
                        }
Dean@815
  1848
                    }
Dean@815
  1849
Dean@1501
  1850
                    // Attempt to add/remove the store from the session which sets visibility
Dean@1262
  1851
                    if (visible)
Dean@815
  1852
                    {
Dean@1262
  1853
                        try
Dean@815
  1854
                        {
Dean@815
  1855
                            // Release the temp folder before attempting an open/re-open
vb@1507
  1856
                            //Marshal.ReleaseComObject(this._PEPStoreRootFolder);
Dean@1262
  1857
                            this._PEPStoreRootFolder = null;
Dean@1262
  1858
Dean@1262
  1859
                            // After opening it will always be visible
Dean@1262
  1860
                            this.OpenPEPStoreRootFolder();
Dean@815
  1861
                        }
Thomas@1936
  1862
                        catch (Exception ex)
Dean@815
  1863
                        {
Thomas@1936
  1864
                            Log.Warning("SetPEPStoreRootFolderVisibility: Failed to make pEp root folder visible. " + ex.ToString());
Dean@1252
  1865
                        }
Dean@1252
  1866
                    }
Dean@1262
  1867
                    else
Dean@1252
  1868
                    {
Dean@1262
  1869
                        /* Remove the store from the session which will also hide it in the navigation pane.
Dean@1262
  1870
                         * Importantly, the pEp store's root folder reference is not released.
Dean@1262
  1871
                         * This allows the application to continue to use the store.
Dean@1262
  1872
                         * 
Dean@1262
  1873
                         * Also note that this call to remove the store will fail if the store is already removed.
Dean@1262
  1874
                         * This can happen when the visibility is set to false more than once.
Dean@1262
  1875
                         * Therefore, just try to remove it although don't log any errors.
Dean@1262
  1876
                         */
Dean@1262
  1877
                        try
Dean@1262
  1878
                        {
Dean@1262
  1879
                            ns.RemoveStore(this._PEPStoreRootFolder);
Dean@1262
  1880
                        }
Dean@1262
  1881
                        catch { }
Dean@815
  1882
                    }
Dean@815
  1883
                }
Thomas@2137
  1884
                else
Thomas@2137
  1885
                {
Thomas@2137
  1886
                    Log.Error("SetPEPStoreRootFolderVisibility: Couldn't set visibility. Folder is null.");
Thomas@2137
  1887
                }
Dean@815
  1888
            }
Dean@815
  1889
            catch (Exception ex)
Dean@815
  1890
            {
Dean@1262
  1891
                Log.Error("SetPEPStoreRootFolderVisibility: Failed, " + ex.ToString());
Dean@815
  1892
            }
Dean@815
  1893
            finally
Dean@815
  1894
            {
Dean@815
  1895
                // Release objects
Thomas@2137
  1896
                folder = null;
Thomas@2137
  1897
                ns = null;
Thomas@2137
  1898
                store = null;
Dean@815
  1899
            }
Thomas@2328
  1900
        }
Thomas@2328
  1901
Thomas@2328
  1902
        /// <summary>
Thomas@2432
  1903
        /// Sets pEp rules and view filters for a given account.
Thomas@2328
  1904
        /// <param name="account">The Outlook account for which to set rules and view
Thomas@2432
  1905
        /// <param name="enable">Whether to enable or disable rules and view filters.</param>
Thomas@2328
  1906
        /// filters.</param>
Thomas@2328
  1907
        /// </summary>
Thomas@2432
  1908
        internal void SetRulesAndViewFilters(Outlook.Account account,
Thomas@2432
  1909
                                             bool enable)
Thomas@2328
  1910
        {
Thomas@2432
  1911
            // If a failure occured, do not mark first startup as completed (run again next time).
Thomas@2432
  1912
            if ((this.SetRules(account, enable) == false) ||
Thomas@2432
  1913
                 (this.SetInboxViewFilters(account, enable) == false))
Thomas@2328
  1914
            {
Thomas@2432
  1915
                this.Settings.IsFirstStartupComplete = false;
Thomas@2328
  1916
            }
Thomas@2432
  1917
        }
Thomas@2432
  1918
Thomas@2432
  1919
        /// <summary>
Thomas@2432
  1920
        /// Sets pEp rules and view filters for all accounts.
Thomas@2432
  1921
        /// <param name="enable">Whether to enable or disable rules and view filters.</param>
Thomas@2432
  1922
        /// filters.</param>
Thomas@2432
  1923
        /// </summary>
Thomas@2432
  1924
        internal void SetRulesAndViewFilters(bool enable)
Thomas@2432
  1925
        {
Thomas@2432
  1926
            // If a failure occured, do not mark first startup as completed (run again next time).
Thomas@2432
  1927
            this.Settings.IsFirstStartupComplete = (this.SetRules(enable) && this.SetInboxViewFilters(enable));
Dean@815
  1928
        }
Dean@815
  1929
Dean@815
  1930
        /// <summary>
Thomas@1485
  1931
        /// Sets the rules to hide pEp internal category MailItems for the given account.
Thomas@1485
  1932
        /// </summary>
Thomas@1485
  1933
        /// <param name="account">The account to set the rules for.</param>
Thomas@2432
  1934
        /// <param name="enable">Whether to enable or disable the rules.</param>
Dean@1501
  1935
        /// <returns>True, if the rules were correctly set for this account. Otherwise false.</returns>
Thomas@2432
  1936
        internal bool SetRules(Outlook.Account account,
Thomas@2432
  1937
                               bool enable)
Thomas@1485
  1938
        {
Dean@1501
  1939
            bool success = false;
Thomas@1664
  1940
            bool categoriesSet = true;
Thomas@1485
  1941
            bool ruleExists = false;
Thomas@1485
  1942
            Outlook.AssignToCategoryRuleAction action = null;
Thomas@1485
  1943
            Outlook.Rules rules = null;
Thomas@1485
  1944
            Outlook.Rule rule = null;
Thomas@1485
  1945
            Outlook.Store deliveryStore = null;
Thomas@1485
  1946
            Outlook.TextRuleCondition condition = null;
Thomas@1485
  1947
Thomas@2328
  1948
            Log.Verbose("SetRules: Setting rules for single account.");
Thomas@1485
  1949
Thomas@1485
  1950
            try
Thomas@1485
  1951
            {
Thomas@1485
  1952
                // Getting delivery store can fail for new accounts when Outlook is not restarted
Thomas@1485
  1953
                try
Thomas@1485
  1954
                {
Thomas@1485
  1955
                    deliveryStore = account.DeliveryStore;
Thomas@1485
  1956
                }
Thomas@1485
  1957
                catch
Thomas@1485
  1958
                {
Thomas@1485
  1959
                    deliveryStore = null;
Thomas@1485
  1960
                    Log.Warning("SetRules: Failure getting DeliveryStore");
Thomas@1485
  1961
                }
Thomas@1485
  1962
Thomas@1485
  1963
                if (deliveryStore != null)
Thomas@1485
  1964
                {
Thomas@2328
  1965
                    // Get rules
Thomas@1485
  1966
                    try
Thomas@1485
  1967
                    {
Thomas@1485
  1968
                        rules = deliveryStore.GetRules();
Thomas@1485
  1969
                    }
Thomas@1485
  1970
                    catch
Thomas@1485
  1971
                    {
Thomas@2328
  1972
                        rules = null;
Thomas@1485
  1973
                        Log.Warning("SetRules: Failure getting rules");
Thomas@1485
  1974
                    }
Thomas@1485
  1975
Thomas@1485
  1976
                    // Adding rule to the rules collection
Thomas@1485
  1977
                    if (rules != null)
Thomas@1485
  1978
                    {
Thomas@1485
  1979
                        try
Thomas@1485
  1980
                        {
Thomas@2432
  1981
                            // Check if rule already was created, create new otherwise (if needed)
Thomas@1485
  1982
                            try
Thomas@1485
  1983
                            {
Thomas@1485
  1984
                                rule = rules[Globals.PEP_INTERNAL_CATEGORY_NAME];
Thomas@1485
  1985
                                ruleExists = true;
Dean@1501
  1986
                                success = true;
Thomas@1485
  1987
                            }
Thomas@1485
  1988
                            catch
Thomas@1485
  1989
                            {
Thomas@2432
  1990
                                if (enable)
Thomas@2432
  1991
                                {
Thomas@2432
  1992
                                    rule = rules.Create(Globals.PEP_INTERNAL_CATEGORY_NAME, Outlook.OlRuleType.olRuleReceive);
Thomas@2432
  1993
                                }
Thomas@1485
  1994
                            }
Thomas@1485
  1995
                        }
Thomas@2432
  1996
                        catch (Exception ex)
Thomas@1485
  1997
                        {
Thomas@2328
  1998
                            rule = null;
Thomas@2432
  1999
                            Log.Warning("SetRules: Failure creating rule. " + ex.ToString());
Thomas@1485
  2000
                        }
Thomas@1485
  2001
Thomas@2432
  2002
                        // Create or remove rule
Thomas@2432
  2003
                        if (enable)
Thomas@1485
  2004
                        {
Thomas@2432
  2005
                            // Define rule if it didn't exist previously
Thomas@2432
  2006
                            if ((rule != null) &&
Thomas@2432
  2007
                                (ruleExists == false))
Thomas@1485
  2008
                            {
Thomas@2432
  2009
                                // Condition: message header includes defined string
Thomas@1485
  2010
                                try
Thomas@1485
  2011
                                {
Thomas@2432
  2012
                                    condition = rule.Conditions?.MessageHeader;
Thomas@2432
  2013
                                    condition.Text = new string[] { PEPMessage.PR_PEP_AUTO_CONSUME_NAME.ToLower() };
Thomas@2432
  2014
                                    condition.Enabled = true;
Thomas@2432
  2015
                                }
Thomas@2432
  2016
                                catch (Exception ex)
Thomas@2432
  2017
                                {
Thomas@2432
  2018
                                    condition = null;
Thomas@2432
  2019
                                    Log.Warning("SetRules: Failure setting condition. " + ex.ToString());
Thomas@2432
  2020
                                }
Thomas@2432
  2021
Thomas@2432
  2022
                                if (condition != null)
Thomas@2432
  2023
                                {
Thomas@2432
  2024
                                    // Action: assign "pEp internal" category
Thomas@2432
  2025
                                    try
Thomas@1664
  2026
                                    {
Thomas@2501
  2027
                                        if (this.CreatePEPCategories() == false)
Thomas@2432
  2028
                                        {
Thomas@2432
  2029
                                            categoriesSet = false;
Thomas@2432
  2030
                                        }
Thomas@2432
  2031
Thomas@2432
  2032
                                        action = rule.Actions.AssignToCategory;
Thomas@2432
  2033
                                        action.Categories = new string[] { Globals.PEP_INTERNAL_CATEGORY_NAME };
Thomas@2432
  2034
                                        action.Enabled = true;
Thomas@1664
  2035
                                    }
Thomas@2432
  2036
                                    catch (Exception ex)
Thomas@2432
  2037
                                    {
Thomas@2432
  2038
                                        action = null;
Thomas@2432
  2039
                                        Log.Warning("SetRules: Failure adding category. " + ex.ToString());
Thomas@2432
  2040
                                    }
Thomas@2432
  2041
Thomas@2432
  2042
                                    if ((condition != null) &&
Thomas@2432
  2043
                                        (action != null))
Thomas@2432
  2044
                                    {
Thomas@2432
  2045
                                        rules.Save();
Thomas@2434
  2046
                                        rule.Execute();
Thomas@2432
  2047
                                        success = categoriesSet;
Thomas@2432
  2048
                                    }
Thomas@1485
  2049
                                }
Thomas@2432
  2050
                            }
Thomas@2432
  2051
                        }
Thomas@2432
  2052
                        else
Thomas@2432
  2053
                        {
Thomas@2432
  2054
                            if (ruleExists)
Thomas@2432
  2055
                            {
Thomas@2432
  2056
                                rules.Remove(Globals.PEP_INTERNAL_CATEGORY_NAME);
Thomas@2432
  2057
                                rules.Save();
Thomas@1485
  2058
                            }
Thomas@2479
  2059
Thomas@2479
  2060
                            success = true;
Thomas@1485
  2061
                        }
Thomas@1485
  2062
                    }
Thomas@1485
  2063
                }
Thomas@2328
  2064
Thomas@2328
  2065
                Log.Verbose("SetRules: {0} processed {1}.", account?.SmtpAddress ?? "NULL", success ? "successfully" : "unsuccessfully");
Thomas@1485
  2066
            }
Thomas@1485
  2067
            catch (Exception ex)
Thomas@1485
  2068
            {
Thomas@1485
  2069
                Log.Error("SetRules: Failure occured, " + ex.ToString());
Thomas@1485
  2070
            }
Thomas@1485
  2071
            finally
Thomas@1485
  2072
            {
Thomas@2328
  2073
                action = null;
Thomas@2328
  2074
                condition = null;
Thomas@2328
  2075
                deliveryStore = null;
Thomas@2328
  2076
                rule = null;
Thomas@2328
  2077
                rules = null;
Thomas@1485
  2078
            }
Thomas@1485
  2079
Dean@1501
  2080
            return success;
Thomas@1485
  2081
        }
Thomas@1485
  2082
Thomas@1485
  2083
        /// <summary>
Thomas@1485
  2084
        /// Sets the rules for all accounts to hide pEp internal category MailItems.
Thomas@1485
  2085
        /// </summary>
Thomas@2432
  2086
        /// <param name="enable">Whether to enable or disable the rules.</param>
Dean@1501
  2087
        /// <returns>True, if the rules were correctly set. Otherwise false.</returns>
Thomas@2432
  2088
        internal bool SetRules(bool enable)
Thomas@1485
  2089
        {
Dean@1501
  2090
            bool success = true;
Thomas@1485
  2091
            Outlook.Account account = null;
Thomas@1485
  2092
            Outlook.Accounts accounts = null;
Thomas@1485
  2093
            Outlook.NameSpace ns = null;
Thomas@1485
  2094
Thomas@1485
  2095
            Log.Verbose("SetRules: Setting rules for all accounts");
Thomas@1485
  2096
Thomas@1485
  2097
            try
Thomas@1485
  2098
            {
Thomas@1485
  2099
                ns = this.Application.Session;
Thomas@1485
  2100
                accounts = ns.Accounts;
Thomas@1485
  2101
Thomas@1485
  2102
                for (int i = 1; i <= accounts.Count; i++)
Thomas@1485
  2103
                {
Thomas@1485
  2104
                    account = accounts[i];
Thomas@1485
  2105
Thomas@1485
  2106
                    if (account != null)
Thomas@1485
  2107
                    {
Thomas@2432
  2108
                        if (this.SetRules(account, enable) == false)
Dean@1501
  2109
                        {
Dean@1501
  2110
                            success = false;
Dean@1501
  2111
                        }
Thomas@1485
  2112
Thomas@1485
  2113
                        account = null;
Thomas@1485
  2114
                    }
Thomas@1485
  2115
                }
Thomas@1485
  2116
            }
Thomas@1485
  2117
            catch (Exception ex)
Thomas@1485
  2118
            {
Dean@1501
  2119
                success = false;
Thomas@1485
  2120
                Log.Error("SetRules: Failure occured, " + ex.ToString());
Thomas@1485
  2121
            }
Thomas@1485
  2122
            finally
Thomas@1485
  2123
            {
Thomas@2328
  2124
                account = null;
Thomas@2328
  2125
                accounts = null;
Thomas@2328
  2126
                ns = null;
Thomas@1485
  2127
            }
Thomas@1485
  2128
Dean@1501
  2129
            return success;
Thomas@1485
  2130
        }
Thomas@1485
  2131
Thomas@1485
  2132
        /// <summary>
Dean@1442
  2133
        /// Sets the view filter settings of the inbox folder to hide pEp internal category MailItems for the given account.
Dean@1442
  2134
        /// </summary>
Dean@1442
  2135
        /// <param name="account">The account to set the inbox view filter for.</param>
Thomas@2432
  2136
        /// <param name="enable">Whether to enable or disable the view filters.</param>
Dean@1501
  2137
        /// <returns>True, if the filters were correctly set for this account. Otherwise false.</returns>
Thomas@2432
  2138
        internal bool SetInboxViewFilters(Outlook.Account account,
Thomas@2432
  2139
                                          bool enable)
Dean@1442
  2140
        {
Dean@1501
  2141
            bool success = false;
Dean@1442
  2142
            string currentViewName = null;
Dean@1442
  2143
            Outlook.Store deliveryStore = null;
Dean@1442
  2144
            Outlook.Folder folder = null;
Dean@1442
  2145
            Outlook.View view = null;
Dean@1442
  2146
            Outlook.Views views = null;
Dean@1442
  2147
Dean@1442
  2148
            Log.Verbose("SetInboxViewFilters: Setting inbox view filter for single account");
Dean@1442
  2149
Dean@1442
  2150
            try
Dean@1442
  2151
            {
Dean@1442
  2152
                // Getting delivery store can fail for new accounts when Outlook is not restarted
Dean@1442
  2153
                try
Dean@1442
  2154
                {
Dean@1442
  2155
                    deliveryStore = account.DeliveryStore;
Dean@1442
  2156
                }
Dean@1442
  2157
                catch
Dean@1442
  2158
                {
Dean@1442
  2159
                    deliveryStore = null;
Dean@1442
  2160
                    Log.Warning("SetInboxViewFilters: Failure getting DeliveryStore");
Dean@1442
  2161
                }
Dean@1442
  2162
Dean@1442
  2163
                if (deliveryStore != null)
Dean@1442
  2164
                {
Dean@1442
  2165
                    // Get the inbox
Dean@1442
  2166
                    try
Dean@1442
  2167
                    {
Dean@1442
  2168
                        folder = (Outlook.Folder)deliveryStore.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
Dean@1442
  2169
                    }
Dean@1442
  2170
                    catch
Dean@1442
  2171
                    {
Thomas@2328
  2172
                        folder = null;
Dean@1442
  2173
                        Log.Warning("SetInboxViewFilters: Failure getting inbox folder");
Dean@1442
  2174
                    }
Dean@1442
  2175
Dean@1442
  2176
                    // Change the filter for all views in the inbox
Dean@1442
  2177
                    if (folder != null)
Dean@1442
  2178
                    {
Dean@1442
  2179
                        views = folder.Views;
Dean@1442
  2180
                        currentViewName = folder.CurrentView?.Name;
Dean@1442
  2181
Dean@1442
  2182
                        for (int j = 1; j <= views.Count; j++)
Dean@1442
  2183
                        {
Dean@1442
  2184
                            view = views[j];
Dean@1442
  2185
Dean@1442
  2186
                            try
Dean@1442
  2187
                            {
Dean@1442
  2188
                                // Only set the filter on standard views, if the user creates their own don't modify it
Dean@1442
  2189
                                if (view.Standard)
Dean@1442
  2190
                                {
Dean@1442
  2191
                                    // Clear existing filter -- seems to work better
Dean@1442
  2192
                                    view.Filter = null;
Dean@1442
  2193
                                    view.Save();
Dean@1442
  2194
Dean@1442
  2195
                                    if ((currentViewName != null) &&
Dean@1442
  2196
                                        (string.Equals(view.Name, currentViewName, StringComparison.OrdinalIgnoreCase)))
Dean@1442
  2197
                                    {
Dean@1442
  2198
                                        view.Apply();
Dean@1442
  2199
                                    }
Dean@1442
  2200
Thomas@2432
  2201
                                    if (enable)
Dean@1442
  2202
                                    {
Thomas@2432
  2203
                                        // Set the filter
Thomas@2432
  2204
                                        if (account.AccountType == Outlook.OlAccountType.olImap)
Thomas@2432
  2205
                                        {
Thomas@2432
  2206
                                            // (1) Hide any deleted IMAP items http://schemas.microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/85700003 = 0
Thomas@2501
  2207
                                            // (2) Hide 'pEp internal' and "pEp processing' category items
Thomas@2432
  2208
                                            view.Filter = "(\"" + MapiProperty.PidLidImapMarkedForDeletion.DaslName + "\" = 0" +
Thomas@2432
  2209
                                                          " AND " +
Thomas@2501
  2210
                                                          "\"urn:schemas-microsoft-com:office:office#Keywords\" <> '" + Globals.PEP_INTERNAL_CATEGORY_NAME + "'" +
Thomas@2501
  2211
                                                          " AND " +
Thomas@2501
  2212
                                                          "\"urn:schemas-microsoft-com:office:office#Keywords\" <> '" + Globals.PEP_PROCESSING_CATEGORY_NAME + "')";
Thomas@2432
  2213
                                        }
Thomas@2432
  2214
                                        else
Thomas@2432
  2215
                                        {
Thomas@2501
  2216
                                            // Hide 'pEp internal' and "pEp processing' category items
Thomas@2501
  2217
                                            view.Filter = "(\"urn:schemas-microsoft-com:office:office#Keywords\" <> '" + Globals.PEP_INTERNAL_CATEGORY_NAME + "'" +
Thomas@2501
  2218
                                                          " AND " +
Thomas@2501
  2219
                                                          "\"urn:schemas-microsoft-com:office:office#Keywords\" <> '" + Globals.PEP_PROCESSING_CATEGORY_NAME + "')";
Thomas@2432
  2220
                                        }
Thomas@2432
  2221
Thomas@2432
  2222
                                        if ((currentViewName != null) &&
Thomas@2432
  2223
                                            (string.Equals(view.Name, currentViewName, StringComparison.OrdinalIgnoreCase)))
Thomas@2432
  2224
                                        {
Thomas@2432
  2225
                                            view.Save();
Thomas@2432
  2226
                                            view.Apply();
Thomas@2432
  2227
                                        }
Thomas@2432
  2228
                                        else
Thomas@2432
  2229
                                        {
Thomas@2432
  2230
                                            view.Save();
Thomas@2432
  2231
                                        }
Dean@1442
  2232
                                    }
Dean@1442
  2233
                                }
Dean@1501
  2234
Dean@1501
  2235
                                success = true;
Dean@1442
  2236
                            }
Thomas@2432
  2237
                            catch (Exception ex)
Dean@1442
  2238
                            {
Thomas@2432
  2239
                                Log.Warning("SetInboxViewFilters: Failed to set view. " + ex.ToString());
Dean@1442
  2240
                            }
Dean@1442
  2241
Thomas@2328
  2242
                            view = null;
Dean@1442
  2243
                        }
Dean@1442
  2244
                    }
Dean@1442
  2245
                }
Dean@1442
  2246
            }
Dean@1442
  2247
            catch (Exception ex)
Dean@1442
  2248
            {
Dean@1442
  2249
                Log.Error("SetInboxViewFilters: Failure occured, " + ex.ToString());
Dean@1442
  2250
            }
Dean@1442
  2251
            finally
Dean@1442
  2252
            {
Thomas@2328
  2253
                deliveryStore = null;
Thomas@2328
  2254
                folder = null;
Thomas@2328
  2255
                view = null;
Thomas@2328
  2256
                views = null;
Dean@1442
  2257
            }
Dean@1442
  2258
Dean@1501
  2259
            return success;
Dean@1442
  2260
        }
Dean@1442
  2261
Dean@1442
  2262
        /// <summary>
Dean@1442
  2263
        /// Sets the view filter settings of all account's inbox folders to hide pEp internal category MailItems.
Dean@1437
  2264
        /// </summary>
Thomas@2432
  2265
        /// <param name="enable">Whether to enable or disable the view filters.</param>
Dean@1501
  2266
        /// <returns>True, if the filters were correctly set. Otherwise false.</returns>
Thomas@2432
  2267
        internal bool SetInboxViewFilters(bool enable)
Dean@1437
  2268
        {
Dean@1501
  2269
            bool success = true;
Dean@1437
  2270
            Outlook.Account account = null;
Dean@1437
  2271
            Outlook.Accounts accounts = null;
Dean@1437
  2272
            Outlook.NameSpace ns = null;
Dean@1442
  2273
Dean@1442
  2274
            Log.Verbose("SetInboxViewFilters: Setting inbox view filter for all accounts");
Dean@1437
  2275
Dean@1437
  2276
            try
Dean@1437
  2277
            {
Dean@1437
  2278
                ns = this.Application.Session;
Dean@1437
  2279
                accounts = ns.Accounts;
Dean@1437
  2280
Dean@1437
  2281
                for (int i = 1; i <= accounts.Count; i++)
Dean@1437
  2282
                {
Dean@1437
  2283
                    account = accounts[i];
Dean@1437
  2284
Dean@1437
  2285
                    if (account != null)
Dean@1437
  2286
                    {
Thomas@2432
  2287
                        if (this.SetInboxViewFilters(account, enable) == false)
Dean@1501
  2288
                        {
Dean@1501
  2289
                            success = false;
Dean@1501
  2290
                        }
Dean@1442
  2291
Dean@1437
  2292
                        account = null;
Dean@1437
  2293
                    }
Dean@1437
  2294
                }
Dean@1437
  2295
            }
Dean@1437
  2296
            catch (Exception ex)
Dean@1437
  2297
            {
Dean@1501
  2298
                success = false;
Dean@1437
  2299
                Log.Error("SetInboxViewFilters: Failure occured, " + ex.ToString());
Dean@1437
  2300
            }
Dean@1437
  2301
            finally
Dean@1437
  2302
            {
Thomas@2328
  2303
                account = null;
Thomas@2328
  2304
                accounts = null;
Thomas@2328
  2305
                ns = null;
Dean@1437
  2306
            }
Dean@1437
  2307
Dean@1501
  2308
            return success;
Dean@1437
  2309
        }
Dean@1437
  2310
Dean@1437
  2311
        /// <summary>
Thomas@1545
  2312
        /// Retrieves the pEp drafts folder and creates it if necessary.
Thomas@1545
  2313
        /// </summary>
Thomas@1545
  2314
        /// <returns>The pEp drafts folder or null if an error occurs.</returns>
Thomas@1545
  2315
        internal Outlook.Folder GetPEPStoreDraftsFolder()
Thomas@1545
  2316
        {
Thomas@1545
  2317
            Outlook.Folder pEpDraftsFolder = null;
Thomas@1545
  2318
            Outlook.Folders folders = null;
Thomas@1545
  2319
Thomas@1545
  2320
            try
Thomas@1545
  2321
            {
Thomas@1545
  2322
                folders = PEPStoreRootFolder?.Folders;
Thomas@1545
  2323
Thomas@1545
  2324
                try
Thomas@1545
  2325
                {
Thomas@1545
  2326
                    pEpDraftsFolder = folders?[Globals.PEP_DRAFTS_FOLDER_NAME] as Outlook.Folder;
Thomas@1545
  2327
                }
Thomas@1549
  2328
                catch
Thomas@1545
  2329
                {
Thomas@1545
  2330
                    pEpDraftsFolder = null;
Thomas@1545
  2331
                }
Thomas@1545
  2332
Thomas@1545
  2333
                if (pEpDraftsFolder == null)
Thomas@1545
  2334
                {
Thomas@1545
  2335
                    pEpDraftsFolder = folders?.Add(Globals.PEP_DRAFTS_FOLDER_NAME, Outlook.OlDefaultFolders.olFolderDrafts) as Outlook.Folder;
Thomas@1545
  2336
                }
Thomas@1545
  2337
            }
Thomas@1936
  2338
            catch (Exception ex)
Thomas@1545
  2339
            {
Thomas@1545
  2340
                pEpDraftsFolder = null;
Thomas@1936
  2341
                Log.Error("Cannot create pEp drafts folder. " + ex.ToString());
Thomas@1545
  2342
            }
Thomas@1545
  2343
            finally
Thomas@1545
  2344
            {
Thomas@1545
  2345
                folders = null;
Thomas@1545
  2346
            }
Thomas@1545
  2347
Thomas@1545
  2348
            return pEpDraftsFolder;
Thomas@1545
  2349
        }
Thomas@1545
  2350
Thomas@1545
  2351
        /// <summary>
Thomas@1664
  2352
        /// Creates the pEp internal category for the specified account's store unless it already exists.
Dean@1437
  2353
        /// </summary>
Thomas@2501
  2354
        internal bool CreatePEPCategories(Outlook.Store deliveryStore)
Dean@1437
  2355
        {
Thomas@2501
  2356
            bool pEpInternalExists = false;
Thomas@2501
  2357
            bool pEpProcessingExists = false;
Dean@1437
  2358
            Outlook.Category category = null;
Dean@1437
  2359
            Outlook.Categories categories = null;
Thomas@1664
  2360
Thomas@1664
  2361
            if (deliveryStore != null)
Thomas@1664
  2362
            {
Thomas@1664
  2363
                try
Thomas@1664
  2364
                {
Thomas@1664
  2365
                    categories = deliveryStore.Categories;
Thomas@1664
  2366
Thomas@2501
  2367
                    // Check if the categories already exists
Thomas@1664
  2368
                    for (int i = 1; i <= categories?.Count; i++)
Thomas@1664
  2369
                    {
Thomas@1664
  2370
                        category = categories[i];
Thomas@1664
  2371
Thomas@2501
  2372
                        if (category?.Name?.Equals(Globals.PEP_INTERNAL_CATEGORY_NAME, StringComparison.OrdinalIgnoreCase) == true)
Thomas@1664
  2373
                        {
Thomas@2501
  2374
                            pEpInternalExists = true;
Thomas@2501
  2375
                        }
Thomas@2501
  2376
                        else if (category?.Name?.Equals(Globals.PEP_PROCESSING_CATEGORY_NAME, StringComparison.OrdinalIgnoreCase) == true)
Thomas@2501
  2377
                        {
Thomas@2501
  2378
                            pEpProcessingExists = true;
Thomas@2501
  2379
                        }
Thomas@2501
  2380
Thomas@2501
  2381
                        category = null;
Thomas@2501
  2382
Thomas@2501
  2383
                        if (pEpInternalExists &&
Thomas@2501
  2384
                            pEpProcessingExists)
Thomas@2501
  2385
                        {
Thomas@1664
  2386
                            break;
Thomas@1664
  2387
                        }
Thomas@1664
  2388
                    }
Thomas@1664
  2389
                }
Thomas@1936
  2390
                catch (Exception ex)
Thomas@1664
  2391
                {
Thomas@2501
  2392
                    Log.Error("CreatePEPCategories: Error checking if category exists. " + ex.ToString());
Thomas@1664
  2393
Thomas@1664
  2394
                    // Just try to create it anyway, this will throw an exception if it already exists
Thomas@2501
  2395
                    pEpInternalExists = false;
Thomas@2501
  2396
                    pEpProcessingExists = false;
Thomas@1664
  2397
                }
Thomas@1664
  2398
                finally
Thomas@1664
  2399
                {
Thomas@1664
  2400
                    category = null;
Thomas@1664
  2401
                    categories = null;
Thomas@1664
  2402
                }
Thomas@1664
  2403
Thomas@2501
  2404
                // If a category was not found, create and add it to account master list
Thomas@2501
  2405
                if (pEpInternalExists == false)
Thomas@1664
  2406
                {
Thomas@1664
  2407
                    try
Thomas@1664
  2408
                    {
Thomas@1664
  2409
                        // Add category
Thomas@1664
  2410
                        categories = deliveryStore.Categories;
Thomas@1664
  2411
                        categories?.Add(Globals.PEP_INTERNAL_CATEGORY_NAME, Outlook.OlCategoryColor.olCategoryColorDarkGreen);
Thomas@2501
  2412
                        pEpInternalExists = true;
Thomas@1664
  2413
                    }
Thomas@1936
  2414
                    catch (Exception ex)
Thomas@1664
  2415
                    {
Thomas@2501
  2416
                        Log.Error("CreatePEPCategories: Error setting pEp Internal category. " + ex.ToString());
Thomas@1664
  2417
                    }
Thomas@1664
  2418
                    finally
Thomas@1664
  2419
                    {
Thomas@1664
  2420
                        categories = null;
Thomas@1664
  2421
                    }
Thomas@2501
  2422
                }
Thomas@2501
  2423
Thomas@2501
  2424
                if (pEpProcessingExists == false)
Thomas@2501
  2425
                {
Thomas@2501
  2426
                    try
Thomas@2501
  2427
                    {
Thomas@2501
  2428
                        // Add category
Thomas@2501
  2429
                        categories = deliveryStore.Categories;
Thomas@2501
  2430
                        categories?.Add(Globals.PEP_PROCESSING_CATEGORY_NAME, Outlook.OlCategoryColor.olCategoryColorDarkGreen);
Thomas@2501
  2431
                        pEpProcessingExists = true;
Thomas@2501
  2432
                    }
Thomas@2501
  2433
                    catch (Exception ex)
Thomas@2501
  2434
                    {
Thomas@2501
  2435
                        Log.Error("CreatePEPCategories: Error settising pEp Processing. " + ex.ToString());
Thomas@2501
  2436
                    }
Thomas@2501
  2437
                    finally
Thomas@2501
  2438
                    {
Thomas@2501
  2439
                        categories = null;
Thomas@2501
  2440
                    }
Thomas@1664
  2441
                }
Thomas@1664
  2442
            }
Thomas@1664
  2443
Thomas@2501
  2444
            return (pEpInternalExists && pEpProcessingExists);
Thomas@1664
  2445
        }
Thomas@1664
  2446
Thomas@1664
  2447
        /// <summary>
Thomas@1664
  2448
        /// Creates the pEp internal category in Outlook for all accounts.
Thomas@1664
  2449
        /// </summary>
Thomas@2501
  2450
        internal bool CreatePEPCategories()
Thomas@1664
  2451
        {
Thomas@1664
  2452
            bool success = true;
Thomas@1664
  2453
            Outlook.Account account = null;
Thomas@1664
  2454
            Outlook.Accounts accounts = null;
Dean@1437
  2455
            Outlook.NameSpace ns = null;
Thomas@1664
  2456
            Outlook.Store deliveryStore = null;
Dean@1437
  2457
Dean@1437
  2458
            try
Dean@1437
  2459
            {
Dean@1437
  2460
                ns = this.Application.Session;
Thomas@1664
  2461
                accounts = ns?.Accounts;
Thomas@1664
  2462
Thomas@1664
  2463
                // Set the pEp internal category for all accounts
Thomas@1664
  2464
                for (int i = 1; i <= accounts?.Count; i++)
Dean@1437
  2465
                {
Thomas@1664
  2466
                    try
Dean@1437
  2467
                    {
Thomas@1664
  2468
                        account = accounts[i];