Extensions/AccountExtensions.cs
author Thomas
Tue, 03 Apr 2018 10:17:13 +0200
branchOUT-369
changeset 2100 91f72cbed562
parent 2069 e7a29b63f826
child 2230 664d0aef77e2
permissions -rw-r--r--
Close branch OUT-369
Thomas@1949
     1
´╗┐using Microsoft.Win32;
Thomas@1949
     2
using System;
Thomas@1926
     3
using System.Net;
Dean@1438
     4
using Outlook = Microsoft.Office.Interop.Outlook;
Dean@1438
     5
Dean@1438
     6
namespace pEp
Dean@1438
     7
{
Dean@1438
     8
    /// <summary>
Dean@1438
     9
    /// Contains extensions for the Account as well as utility methods specific for pEp.
Dean@1438
    10
    /// </summary>
Dean@1438
    11
    internal static class AccountExtensions
Dean@1438
    12
    {
Dean@1438
    13
        /// <summary>
Thomas@2058
    14
        /// Creates the pEp account settings for the given Outlook account
Thomas@2058
    15
        /// and adds them to the account settings list.
Thomas@2058
    16
        /// </summary>
Thomas@2058
    17
        /// <param name="account">The Outlook account to process with</param>
Thomas@2058
    18
        /// <returns>The created pEp account settings or null if an error occured.</returns>
Thomas@2058
    19
        public static PEPSettings.PEPAccountSettings CreatePEPSettings(this Outlook.Account account)
Thomas@2058
    20
        {
Thomas@2058
    21
            PEPSettings.PEPAccountSettings acctSettings = new PEPSettings.PEPAccountSettings();
Thomas@2058
    22
Thomas@2058
    23
            try
Thomas@2058
    24
            {
Thomas@2058
    25
                acctSettings.SmtpAddress = account.SmtpAddress;
Thomas@2058
    26
                acctSettings.Type = account.AccountType.ToString();
Thomas@2058
    27
                acctSettings.UserName = account.UserName;
Thomas@2058
    28
Thomas@2058
    29
                // Qualify server trust if not ActiveSync (always trusted as mails don't get synced back to server)
Thomas@2063
    30
                if (account.AccountType == Outlook.OlAccountType.olEas)
Thomas@2063
    31
                {
Thomas@2063
    32
                    acctSettings.IsSecureStorageEnabled = false;
Thomas@2063
    33
                }
Thomas@2063
    34
                else
Thomas@2058
    35
                {
Thomas@2058
    36
                    acctSettings.IsSecureStorageEnabled = (account.GetIsInLocalDomain() == false);
Thomas@2058
    37
                }
Thomas@2058
    38
Thomas@2058
    39
                // Deactivate key sync for IMAP accounts or if global sync setting is disabled
Thomas@2058
    40
                if ((account.AccountType == Outlook.OlAccountType.olImap) ||
Thomas@2058
    41
                    (Globals.ThisAddIn.Settings.IsSyncEnabledForAllAccounts == false))
Thomas@2058
    42
                {
Thomas@2058
    43
                    acctSettings.IsSyncEnabled = false;
Thomas@2058
    44
                }
Thomas@2058
    45
Thomas@2058
    46
                // Add account settings
Thomas@2058
    47
                Globals.ThisAddIn.Settings.AccountSettingsList.Add(acctSettings);
Thomas@2058
    48
            }
Thomas@2058
    49
            catch (Exception ex)
Thomas@2058
    50
            {
Thomas@2058
    51
                acctSettings = null;
Thomas@2058
    52
                Log.Error("AddToSettings: error adding account to settings. " + ex.ToString());
Thomas@2058
    53
            }
Thomas@2058
    54
Thomas@2058
    55
            return acctSettings;
Thomas@2058
    56
        }
Thomas@2058
    57
Thomas@2058
    58
        /// <summary>
Thomas@2063
    59
        /// Gets the default account based on a specified folder type.
Thomas@2063
    60
        /// This method gets the global default folder and looks up the 
Thomas@2063
    61
        /// associated account.
Thomas@2063
    62
        /// Can return null
Thomas@2063
    63
        /// </summary>
Thomas@2063
    64
        /// <param name="folderType">The folder</param>
Thomas@2063
    65
        /// <returns>The default account or null if none was found.</returns>
Thomas@2063
    66
        public static Outlook.Account GetDefaultAccount(Outlook.OlDefaultFolders folderType)
Thomas@2063
    67
        {
Thomas@2063
    68
            Outlook.Account account = null;
Thomas@2063
    69
            Outlook.Accounts accounts = null;
Thomas@2063
    70
            Outlook.NameSpace ns = null;
Thomas@2063
    71
            Outlook.Folder defaultFolder = null;
Thomas@2063
    72
            Outlook.Store store = null;
Thomas@2063
    73
Thomas@2063
    74
            try
Thomas@2063
    75
            {
Thomas@2063
    76
                // Get default folder and the folder's store id
Thomas@2063
    77
                ns = Globals.ThisAddIn.Application.Session;
Thomas@2063
    78
                defaultFolder = ns?.GetDefaultFolder(folderType) as Outlook.Folder;
Thomas@2063
    79
                string storeId = defaultFolder?.StoreID;
Thomas@2063
    80
                accounts = ns?.Accounts;
Thomas@2063
    81
Thomas@2063
    82
                // Find account which matches the default folder store's id
Thomas@2063
    83
                for (int i = 1; i <= accounts?.Count; i++)
Thomas@2063
    84
                {
Thomas@2063
    85
                    account = accounts[i];
Thomas@2063
    86
                    store = account?.DeliveryStore;
Thomas@2063
    87
Thomas@2063
    88
                    if (store?.StoreID?.Equals(storeId) == true)
Thomas@2063
    89
                    {
Thomas@2063
    90
                        // If store is found, break
Thomas@2063
    91
                        break;
Thomas@2063
    92
                    }
Thomas@2063
    93
Thomas@2063
    94
                    account = null;
Thomas@2063
    95
                    store = null;
Thomas@2063
    96
                }
Thomas@2063
    97
            }
Thomas@2063
    98
            catch (Exception ex)
Thomas@2063
    99
            {
Thomas@2063
   100
                account = null;
Thomas@2063
   101
                Log.Error("GetDefaultAccount: Error getting default account. " + ex.ToString());
Thomas@2063
   102
            }
Thomas@2063
   103
            finally
Thomas@2063
   104
            {
Thomas@2063
   105
                accounts = null;
Thomas@2063
   106
                ns = null;
Thomas@2063
   107
                defaultFolder = null;
Thomas@2063
   108
                store = null;
Thomas@2063
   109
            }
Thomas@2063
   110
Thomas@2063
   111
            return account;
Thomas@2063
   112
        }
Thomas@2063
   113
Thomas@2063
   114
        /// <summary>
Thomas@1784
   115
        /// Determines if the given Outlook account should always be decrypted by comparing against the account settings.
Thomas@1784
   116
        /// </summary>
Thomas@1784
   117
        /// <param name="acct">The Outlook account to process with.</param>
Thomas@1784
   118
        /// <returns>True if the given Outlook account should always be decrypted, otherwise false.</returns>
Thomas@1784
   119
        public static bool GetIsDecryptAlwaysEnabled(this Outlook.Account acct)
Thomas@1784
   120
        {
Thomas@1784
   121
            bool isEnabled = PEPSettings.ACCOUNT_SETTING_IS_DECRYPT_ALWAYS_ENABLED_DEFAULT;
Thomas@1784
   122
            PEPSettings.PEPAccountSettings acctSettings;
Thomas@1784
   123
Thomas@1784
   124
            try
Thomas@1784
   125
            {
Thomas@1784
   126
                if (acct != null)
Thomas@1784
   127
                {
Thomas@1784
   128
                    acctSettings = Globals.ThisAddIn.Settings.GetAccountSettings(acct.SmtpAddress);
Thomas@1784
   129
                    if (acctSettings != null)
Thomas@1784
   130
                    {
Thomas@1784
   131
                        isEnabled = acctSettings.IsDecryptAlwaysEnabled;
Thomas@1784
   132
                    }
Thomas@1784
   133
                }
Thomas@1784
   134
                else
Thomas@1784
   135
                {
Thomas@1784
   136
                    isEnabled = PEPSettings.ACCOUNT_SETTING_IS_DECRYPT_ALWAYS_ENABLED_DEFAULT;
Thomas@1784
   137
                    Log.Warning("GetIsDecryptAlwaysEnabled: null account, returning default.");
Thomas@1784
   138
                }
Thomas@1784
   139
            }
Thomas@1784
   140
            catch (Exception ex)
Thomas@1784
   141
            {
Thomas@1784
   142
                isEnabled = PEPSettings.ACCOUNT_SETTING_IS_DECRYPT_ALWAYS_ENABLED_DEFAULT;
Thomas@1784
   143
                Log.Error("GetIsDecryptAlwaysEnabled: Failure occured, returning default. " + ex.ToString());
Thomas@1784
   144
            }
Thomas@1784
   145
Thomas@1784
   146
            return (isEnabled);
Thomas@1784
   147
        }
Thomas@1784
   148
Thomas@1784
   149
        /// <summary>
Dean@1438
   150
        /// Determines if the given Outlook account has pEp enabled by comparing against the account settings.
Dean@1438
   151
        /// </summary>
Dean@1438
   152
        /// <param name="acct">The Outlook account to process with.</param>
Dean@1438
   153
        /// <returns>True if the given Outlook account has pEp enabled, otherwise false.</returns>
Dean@1438
   154
        public static bool GetIsPEPEnabled(this Outlook.Account acct)
Dean@1438
   155
        {
Dean@1438
   156
            bool defaultResult = PEPSettings.ACCOUNT_SETTING_IS_PEP_ENABLED_DEFAULT;
Dean@1438
   157
            bool result = defaultResult;
Dean@1438
   158
            PEPSettings.PEPAccountSettings acctSettings;
Dean@1438
   159
Dean@1438
   160
            try
Dean@1438
   161
            {
Dean@1438
   162
                if (acct != null)
Dean@1438
   163
                {
Thomas@1522
   164
                    acctSettings = Globals.ThisAddIn.Settings.GetAccountSettings(acct.SmtpAddress);
Dean@1438
   165
                    if (acctSettings != null)
Dean@1438
   166
                    {
Dean@1438
   167
                        result = acctSettings.IsPEPEnabled;
Dean@1438
   168
                    }
Dean@1438
   169
                }
Dean@1438
   170
                else
Dean@1438
   171
                {
Dean@1438
   172
                    result = defaultResult;
Dean@1438
   173
                    Log.Warning("GetIsPEPEnabled: null account, returning default.");
Dean@1438
   174
                }
Dean@1438
   175
            }
Dean@1438
   176
            catch (Exception ex)
Dean@1438
   177
            {
Dean@1438
   178
                result = defaultResult;
Dean@1438
   179
                Log.Error("GetIsPEPEnabled: Failure occured, returning default. " + ex.ToString());
Dean@1438
   180
            }
Dean@1438
   181
Dean@1438
   182
            return (result);
Dean@1438
   183
        }
Thomas@1926
   184
Thomas@1926
   185
        /// <summary>
Thomas@1926
   186
        /// Determines whether an account is in a local domain. This follows the definitions
Thomas@1926
   187
        /// from RFC 1918 (https://tools.ietf.org/html/rfc1918) for IPv4 and RFC 4193 for
Thomas@1926
   188
        /// IPv6 (https://tools.ietf.org/html/rfc4193).
Thomas@1926
   189
        /// 
Thomas@1926
   190
        /// Private IPv6 addresses are defined as having a FC00::/7 prefix. This block is 
Thomas@1926
   191
        /// divided into the two blocks fc00::/8 and fd00::/8.
Thomas@1926
   192
        /// 
Thomas@1926
   193
        /// Private IPv4 addresses are the following:
Thomas@1926
   194
        /// 
Thomas@1926
   195
        /// The Internet Assigned Numbers Authority (IANA) has reserved the
Thomas@1926
   196
        /// following three blocks of the IP address space for private internets:
Thomas@1926
   197
        /// 
Thomas@1926
   198
        /// 10.0.0.0        -   10.255.255.255  (10/8 prefix)
Thomas@1926
   199
        /// 172.16.0.0      -   172.31.255.255  (172.16/12 prefix)
Thomas@1926
   200
        /// 192.168.0.0     -   192.168.255.255 (192.168/16 prefix)
Thomas@1926
   201
        /// </summary>
Thomas@1949
   202
        /// <param name="account">The Outlook account to process with.</param>
Thomas@1926
   203
        /// <returns>True if the account is in a local domain, otherwise false.</returns>
Thomas@1926
   204
        public static bool GetIsInLocalDomain(this Outlook.Account account)
Thomas@1926
   205
        {
Thomas@1926
   206
            bool isLocalDomain = false;
Thomas@1926
   207
Thomas@1926
   208
            try
Thomas@1926
   209
            {
Thomas@1949
   210
                // Get the server address of the account's address. If server address 
Thomas@1949
   211
                // couldn't be retrieved, use SMTP address for check.
Thomas@1949
   212
                string address = null;
Thomas@1949
   213
                if (account.TryGetMailServerAddressFromRegistry(out address) == false)
Thomas@1949
   214
                {
Thomas@1949
   215
                    address = account.SmtpAddress;
Thomas@1949
   216
                }
Thomas@1949
   217
Thomas@1949
   218
                // Resolve address
Thomas@1949
   219
                IPHostEntry ipHostEntry = Dns.GetHostEntry(address);
Thomas@1926
   220
Thomas@1926
   221
                // Only return true if all associated IP addresses are local
Thomas@1926
   222
                for (int i = 0; i < ipHostEntry.AddressList.Length; i++)
Thomas@1926
   223
                {
Thomas@1926
   224
                    IPAddress ipAddress = ipHostEntry.AddressList[i];
Thomas@1926
   225
Thomas@1926
   226
                    // If IPv6 address (RFC 4193)
Thomas@1926
   227
                    if (ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
Thomas@1926
   228
                    {
Thomas@1926
   229
                        // This property seems to check for deprecated addresses (fec0::/10)
Thomas@1926
   230
                        isLocalDomain = ipAddress.IsIPv6SiteLocal;
Thomas@1926
   231
Thomas@1926
   232
                        // Search manually if not found with the above property
Thomas@1926
   233
                        if (isLocalDomain == false)
Thomas@1926
   234
                        {
Thomas@1926
   235
                            string firstGroup = ipAddress.ToString().Split(new [] { ':' }, StringSplitOptions.RemoveEmptyEntries)[0];
Thomas@1949
   236
                            isLocalDomain = ((firstGroup.Length >= 4) &&
Thomas@1926
   237
                                             (firstGroup.StartsWith("fc", StringComparison.OrdinalIgnoreCase) || firstGroup.StartsWith("fd", StringComparison.OrdinalIgnoreCase)));
Thomas@1926
   238
                        }
Thomas@1926
   239
                    }
Thomas@1926
   240
                    // Assume IPv4 address (RFC 1918)
Thomas@1926
   241
                    else
Thomas@1926
   242
                    {
Thomas@1926
   243
                        // Get address bytes
Thomas@1926
   244
                        byte[] addressBytes = ipAddress.GetAddressBytes();
Thomas@1926
   245
Thomas@1926
   246
                        // Determine if local according to RFC 1918 (see summary)
Thomas@1926
   247
                        switch (addressBytes[0])
Thomas@1926
   248
                        {
Thomas@1926
   249
                            case 10:
Thomas@1926
   250
                                isLocalDomain = true;
Thomas@1926
   251
                                break;
Thomas@1926
   252
                            case 172:
Thomas@1926
   253
                                isLocalDomain = (addressBytes[1] >= 16 && addressBytes[1] < 32);
Thomas@1926
   254
                                break;
Thomas@1926
   255
                            case 192:
Thomas@1926
   256
                                isLocalDomain = (addressBytes[1] == 168);
Thomas@1926
   257
                                break;
Thomas@1926
   258
                            default:
Thomas@1926
   259
                                isLocalDomain = false;
Thomas@1926
   260
                                break;
Thomas@1926
   261
                        }
Thomas@1926
   262
                    }
Thomas@1926
   263
Thomas@1926
   264
                    // If one associated address is not local, return false
Thomas@1926
   265
                    if (isLocalDomain == false)
Thomas@1926
   266
                    {
Thomas@1926
   267
                        break;
Thomas@1926
   268
                    }
Thomas@1926
   269
                }
Thomas@1926
   270
            }
Thomas@1926
   271
            catch (Exception ex)
Thomas@1926
   272
            {
Thomas@1926
   273
                isLocalDomain = false;
Thomas@1926
   274
                Log.Error("AccountExtensions.IsLocalDomain: Error determining if local domain, returning default. " + ex.ToString());
Thomas@1926
   275
            }
Thomas@1926
   276
Thomas@1926
   277
            Log.Verbose("AccountExtensions.IsLocalDomain: " + account?.SmtpAddress + (isLocalDomain ? " is in local domain." : " is not in local domain."));
Thomas@1926
   278
Thomas@1926
   279
            return isLocalDomain;
Thomas@1926
   280
        }
Thomas@1949
   281
Thomas@1949
   282
        /// <summary>
Thomas@1949
   283
        /// Retrieves the mail server address of a given account from the Registry. Can return null if
Thomas@1949
   284
        /// the entry wasn't found.
Thomas@1949
   285
        /// </summary>
Thomas@1949
   286
        /// <param name="account">The Outlook account to process with.</param>
Thomas@1949
   287
        /// <param name="serverAddress">The mail server address.</param>
Thomas@1949
   288
        /// <returns>True if a server address could be retrieved, otherwise false.</returns>
Thomas@1949
   289
        public static bool TryGetMailServerAddressFromRegistry(this Outlook.Account account, out string serverAddress)
Thomas@1949
   290
        {
Thomas@1949
   291
            serverAddress = null;
Thomas@1950
   292
            Log.Verbose("TryGetMailServerAddressFromRegistry: Trying to get mail server address for " + account.SmtpAddress + " (" + Enum.GetName(typeof(Outlook.OlAccountType), account.AccountType) + ")");
Thomas@1949
   293
Thomas@1949
   294
            // Determine the current profile name
Thomas@1949
   295
            string currentProfileName = null;
Thomas@1949
   296
            Outlook.NameSpace session;
Thomas@1949
   297
            try
Thomas@1949
   298
            {
Thomas@1949
   299
                session = Globals.ThisAddIn.Application.Session;
Thomas@1949
   300
                currentProfileName = session.CurrentProfileName;
Thomas@1949
   301
            }
Thomas@1949
   302
            catch (Exception ex)
Thomas@1949
   303
            {
Thomas@1949
   304
                Log.Error("TryGetMailServerAddressFromRegistry: Error getting current Profile name. " + ex.ToString());
Thomas@1949
   305
            }
Thomas@1949
   306
            finally
Thomas@1949
   307
            {
Thomas@1949
   308
                session = null;
Thomas@1949
   309
            }
Thomas@1949
   310
Thomas@1949
   311
            /* For Outlook 2013 and newer, the account details are stored in
Thomas@1949
   312
             * HKCU\Software\Microsoft\Office\[version_no]\Outlook\Profiles\[profile_name]\9375CFF0413111d3B88A00104B2A6676.
Thomas@1949
   313
             * The code of this key is not officially documented, but referred to on multiple pages. 
Thomas@1949
   314
             * See e.g. http://www.outlookcode.com/threads.aspx?forumid=4&messageid=6885
Thomas@1949
   315
             * For Outlook 2010 and older, this information can be found in
Thomas@1949
   316
             * HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\[profile_name]\9375CFF0413111d3B88A00104B2A6676.
Thomas@1949
   317
             * All accounts can be indentified by the "Account Name" value
Thomas@1949
   318
             * For ActiveSync accounts, the server is stored in the "EAS Server URL" value.
Thomas@1949
   319
             * For IMAP accounts, the server is stored in the "SMTP Server" value.
Thomas@1949
   320
             */
Thomas@1950
   321
Thomas@1950
   322
            // Set registry path according to Outlook version
Thomas@1949
   323
            string registryPathAccounts = "Software\\Microsoft\\";
Thomas@1949
   324
            if (Globals.GetOutlookVersion() > Globals.Version.Outlook2010)
Thomas@1949
   325
            {
Thomas@1949
   326
                registryPathAccounts += "Office\\" + Globals.ThisAddIn.Application.Version.Substring(0, 2) +
Thomas@1949
   327
                                        ".0\\Outlook\\Profiles\\" + currentProfileName + "\\9375CFF0413111d3B88A00104B2A6676";
Thomas@1949
   328
            }
Thomas@1949
   329
            else
Thomas@1949
   330
            {
Thomas@1951
   331
                registryPathAccounts += "Windows NT\\CurrentVersion\\Windows Messaging Subsystem\\Profiles\\" +
Thomas@1949
   332
                                        currentProfileName + "\\9375CFF0413111d3B88A00104B2A6676";
Thomas@1949
   333
            }
Thomas@1949
   334
Thomas@1950
   335
            // Set registry value name according to account type
Thomas@1950
   336
            string valueName = string.Empty;
Thomas@1950
   337
            switch (account.AccountType)
Thomas@1950
   338
            {
Thomas@1950
   339
                case Outlook.OlAccountType.olImap:
Thomas@1950
   340
                    valueName = "SMTP Server";
Thomas@1950
   341
                    break;
Thomas@1950
   342
                case Outlook.OlAccountType.olEas:
Thomas@1950
   343
                    valueName = "EAS Server URL";
Thomas@1950
   344
                    break;
Thomas@1950
   345
                case Outlook.OlAccountType.olExchange:
Thomas@1950
   346
                case Outlook.OlAccountType.olPop3:
Thomas@1950
   347
                case Outlook.OlAccountType.olHttp:
Thomas@1950
   348
                case Outlook.OlAccountType.olOtherAccount:
Thomas@1950
   349
                default:
Thomas@1950
   350
                    break;
Thomas@1950
   351
            }
Thomas@1950
   352
Thomas@1949
   353
            // Get registry values
Thomas@1951
   354
            if (string.IsNullOrEmpty(valueName) == false)
Thomas@1949
   355
            {
Thomas@1951
   356
                try
Thomas@1949
   357
                {
Thomas@1951
   358
                    using (RegistryKey key = Registry.CurrentUser.OpenSubKey(registryPathAccounts))
Thomas@1949
   359
                    {
Thomas@1951
   360
                        // Search all sub keys
Thomas@1951
   361
                        string[] subKeys = key?.GetSubKeyNames();
Thomas@1951
   362
                        for (int i = 0; i < subKeys.Length; i++)
Thomas@1949
   363
                        {
Thomas@1951
   364
                            using (var subKey = key.OpenSubKey(subKeys[i]))
Thomas@1951
   365
                            {
Thomas@1951
   366
                                // Try to retrieve value
Thomas@1951
   367
                                object serverAddressValue = subKey.GetValue(valueName);
Thomas@1949
   368
Thomas@1951
   369
                                // If value was found, check if correct account and convert to string
Thomas@1951
   370
                                if (serverAddressValue != null)
Thomas@1951
   371
                                {
Thomas@1951
   372
                                    Log.Verbose("TryGetMailServerAddressFromRegistry: Value found. Checking if accounts match...");
Thomas@1950
   373
Thomas@1951
   374
                                    // Check if correct account
Thomas@1951
   375
                                    object accountNameValue = subKey.GetValue("Account Name");
Thomas@1951
   376
                                    RegistryValueKind accountNameValueKind = subKey.GetValueKind("Account Name");
Thomas@1950
   377
Thomas@1951
   378
                                    // Convert account name value and compare with given SMTP address.
Thomas@1951
   379
                                    // If addresses don't match, skip to next registry sub key.
Thomas@1951
   380
                                    switch (accountNameValueKind)
Thomas@1951
   381
                                    {
Thomas@1951
   382
                                        case RegistryValueKind.String:
Thomas@1949
   383
                                            {
Thomas@1951
   384
                                                if (accountNameValue?.ToString()?.Equals(account.SmtpAddress) != true)
Thomas@1951
   385
                                                {
Thomas@1951
   386
                                                    Log.Verbose("TryGetMailServerAddressFromRegistry: Accounts don't match. Found value: " + accountNameValue?.ToString() + ". Account name: " + account.SmtpAddress);
Thomas@1951
   387
                                                    continue;
Thomas@1951
   388
                                                }
Thomas@1949
   389
                                            }
Thomas@1951
   390
                                            break;
Thomas@1951
   391
                                        case RegistryValueKind.Binary:
Thomas@1949
   392
                                            {
Thomas@1951
   393
                                                string accountName = System.Text.Encoding.Unicode.GetString(accountNameValue as byte[]).Trim('\0');
Thomas@1951
   394
                                                if (accountName?.Equals(account.SmtpAddress) != true)
Thomas@1951
   395
                                                {
Thomas@1951
   396
                                                    Log.Verbose("TryGetMailServerAddressFromRegistry: Accounts don't match. Found value: " + accountName + ". Account name: " + account.SmtpAddress);
Thomas@1951
   397
                                                    continue;
Thomas@1951
   398
                                                }
Thomas@1949
   399
                                            }
Thomas@1951
   400
                                            break;
Thomas@1951
   401
                                        case RegistryValueKind.DWord:
Thomas@1951
   402
                                        case RegistryValueKind.MultiString:
Thomas@1951
   403
                                        case RegistryValueKind.QWord:
Thomas@1951
   404
                                        case RegistryValueKind.ExpandString:
Thomas@1951
   405
                                        case RegistryValueKind.Unknown:
Thomas@1951
   406
                                        case RegistryValueKind.None:
Thomas@1951
   407
                                        default:
Thomas@1951
   408
                                            break;
Thomas@1951
   409
                                    }
Thomas@1951
   410
Thomas@1951
   411
                                    // Convert to string depending on retrieved registry value kind
Thomas@1951
   412
                                    RegistryValueKind serverAddressValueKind = subKey.GetValueKind(valueName);
Thomas@1951
   413
                                    Log.Verbose("TryGetMailServerAddressFromRegistry: Value of type " + Enum.GetName(typeof(RegistryValueKind), serverAddressValueKind) + " found.");
Thomas@1951
   414
Thomas@1951
   415
                                    switch (serverAddressValueKind)
Thomas@1951
   416
                                    {
Thomas@1951
   417
                                        case RegistryValueKind.String:
Thomas@1951
   418
                                            {
Thomas@1951
   419
                                                serverAddress = serverAddressValue.ToString();
Thomas@1951
   420
                                            }
Thomas@1951
   421
                                            break;
Thomas@1951
   422
                                        case RegistryValueKind.Binary:
Thomas@1951
   423
                                            {
Thomas@1951
   424
                                                serverAddress = System.Text.Encoding.Unicode.GetString(serverAddressValue as byte[]).Trim('\0');
Thomas@1951
   425
                                            }
Thomas@1951
   426
                                            break;
Thomas@1951
   427
                                        case RegistryValueKind.DWord:
Thomas@1951
   428
                                        case RegistryValueKind.MultiString:
Thomas@1951
   429
                                        case RegistryValueKind.QWord:
Thomas@1951
   430
                                        case RegistryValueKind.ExpandString:
Thomas@1951
   431
                                        case RegistryValueKind.Unknown:
Thomas@1951
   432
                                        case RegistryValueKind.None:
Thomas@1951
   433
                                        default:
Thomas@1951
   434
                                            break;
Thomas@1951
   435
                                    }
Thomas@1951
   436
Thomas@1951
   437
                                    Log.Verbose("TryGetMailServerAddressFromRegistry: Server address found: " + serverAddress);
Thomas@1951
   438
                                    break;
Thomas@1950
   439
                                }
Thomas@1949
   440
                            }
Thomas@1949
   441
                        }
Thomas@1949
   442
                    }
Thomas@1949
   443
                }
Thomas@1951
   444
                catch (Exception ex)
Thomas@1951
   445
                {
Thomas@1951
   446
                    serverAddress = null;
Thomas@1951
   447
                    Log.Error("TryGetMailServerAddressFromRegistry: Error getting registry values. " + ex.ToString());
Thomas@1951
   448
                }
Thomas@1949
   449
            }
Thomas@1949
   450
Thomas@1949
   451
            return (string.IsNullOrEmpty(serverAddress) == false);
Thomas@1949
   452
        }
Dean@1438
   453
    }
Dean@1438
   454
}