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