PEPMessage.cs
author Dean Looyengoed
Fri, 08 Apr 2016 19:47:37 +0200
changeset 795 afef14b08666
parent 790 3c818a1fad95
child 808 ac5dbfafb662
permissions -rw-r--r--
When applying a PEPMessage to OMI, add a fallback to add recipients by username.
This is needed for cases such as distribution lists where no address is given.
Also explicitly check for empty strings instead of just null (which was causing some other issues)
Dean@384
     1
´╗┐using Microsoft.Win32;
Dean@384
     2
using pEpCOMServerAdapterLib;
Dean@384
     3
using System;
Dean@384
     4
using System.Collections.Generic;
Dean@384
     5
using System.IO;
Dean@384
     6
using System.Runtime.InteropServices;
Dean@384
     7
using Outlook = Microsoft.Office.Interop.Outlook;
Dean@384
     8
Dean@384
     9
namespace pEp
Dean@384
    10
{
Dean@384
    11
    /// <summary>
Dean@389
    12
    /// Class for a completely in-memory message based on the pEp engine text_message.
Dean@384
    13
    /// </summary>
Dean@389
    14
    public class PEPMessage : Interfaces.ICopy<PEPMessage>
Dean@384
    15
    {
Dean@572
    16
        // pEp properties
Dean@586
    17
        public const string PR_OPT_FIELD     = "http://schemas.microsoft.com/mapi/string/{00020386-0000-0000-C000-000000000046}/";
Dean@572
    18
        public const string PR_X_ENC_STATUS  = "http://schemas.microsoft.com/mapi/string/{00020386-0000-0000-C000-000000000046}/X-EncStatus";
Dean@572
    19
        public const string PR_X_KEY_LIST    = "http://schemas.microsoft.com/mapi/string/{00020386-0000-0000-C000-000000000046}/X-KeyList";
Dean@572
    20
        public const string PR_X_PEP_VERSION = "http://schemas.microsoft.com/mapi/string/{00020386-0000-0000-C000-000000000046}/X-pEp-Version";
Dean@572
    21
Dean@586
    22
        public const string PR_X_ENC_STATUS_NAME  = "X-EncStatus";
Dean@586
    23
        public const string PR_X_KEY_LIST_NAME    = "X-KeyList";
Dean@586
    24
        public const string PR_X_PEP_VERSION_NAME = "X-pEp-Version";
Dean@780
    25
Dean@384
    26
        private List<PEPAttachment> _Attachments;
Dean@384
    27
        private List<PEPIdentity>   _BCC;
Dean@384
    28
        private List<PEPIdentity>   _CC;
Dean@384
    29
        private _pEp_msg_direction  _Direction;
Dean@384
    30
        private PEPIdentity         _From;
Dean@384
    31
        private string              _ID;
Dean@384
    32
        private List<string>        _Keywords;
Dean@384
    33
        private string              _LongMsg;
Dean@697
    34
        private string              _LongMsgFormattedHTML;
Dean@697
    35
        private string              _LongMsgFormattedRTF;
Dean@572
    36
        private List<opt_field>     _OptionalProperties;
Dean@721
    37
        private DateTime?           _ReceivedOn;
Dean@721
    38
        private DateTime?           _SentOn;
Dean@384
    39
        private string              _ShortMsg;
Dean@384
    40
        private List<PEPIdentity>   _To;
Dean@384
    41
Dean@384
    42
        /**************************************************************
Dean@384
    43
         * 
Dean@384
    44
         * Constructors
Dean@384
    45
         * 
Dean@384
    46
         *************************************************************/
Dean@384
    47
Dean@384
    48
        /// <summary>
Dean@384
    49
        /// Default constructor.
Dean@384
    50
        /// </summary>
Dean@384
    51
        public PEPMessage()
Dean@384
    52
        {
Dean@384
    53
            this._Attachments = new List<PEPAttachment>();
Dean@384
    54
            this._BCC = new List<PEPIdentity>();
Dean@384
    55
            this._CC = new List<PEPIdentity>();
Dean@384
    56
            this._Direction = _pEp_msg_direction.pEp_dir_incoming;
Dean@384
    57
            this._From = null;
Dean@384
    58
            this._ID = null;
Dean@384
    59
            this._Keywords = new List<string>();
Dean@384
    60
            this._LongMsg = null;
Dean@697
    61
            this._LongMsgFormattedHTML = null;
Dean@697
    62
            this._LongMsgFormattedRTF = null;
Dean@572
    63
            this._OptionalProperties = new List<opt_field>();
Dean@721
    64
            this._ReceivedOn = null;
Dean@721
    65
            this._SentOn = null;
Dean@384
    66
            this._ShortMsg = null;
Dean@384
    67
            this._To = new List<PEPIdentity>();
Dean@384
    68
        }
Dean@384
    69
Dean@384
    70
        /// <summary>
Dean@384
    71
        /// Constructs a new message from the given pEp engine text_message.
Dean@384
    72
        /// </summary>
Dean@384
    73
        /// <param name="msg">The text_message to construct from.</param>
Dean@384
    74
        public PEPMessage(text_message msg)
Dean@384
    75
        {
Dean@384
    76
            // Attachments
Dean@384
    77
            this._Attachments = new List<PEPAttachment>();
Dean@384
    78
            if (msg.attachments != null)
Dean@384
    79
            {
Dean@384
    80
                for (int i = 0; i < msg.attachments.Length; i++)
Dean@384
    81
                {
Dean@384
    82
                    this._Attachments.Add(new PEPAttachment((blob)msg.attachments.GetValue(i)));
Dean@384
    83
                }
Dean@384
    84
            }
Dean@384
    85
Dean@384
    86
            // BCC
Dean@384
    87
            this._BCC = new List<PEPIdentity>();
Dean@384
    88
            if (msg.bcc != null)
Dean@384
    89
            {
Dean@384
    90
                for (int i = 0; i < msg.bcc.Length; i++)
Dean@384
    91
                {
Dean@384
    92
                    this._BCC.Add(new PEPIdentity((pEp_identity_s)msg.bcc.GetValue(i)));
Dean@384
    93
                }
Dean@384
    94
            }
Dean@384
    95
Dean@384
    96
            // CC
Dean@384
    97
            this._CC = new List<PEPIdentity>();
Dean@384
    98
            if (msg.cc != null)
Dean@384
    99
            {
Dean@384
   100
                for (int i = 0; i < msg.cc.Length; i++)
Dean@384
   101
                {
Dean@384
   102
                    this._CC.Add(new PEPIdentity((pEp_identity_s)msg.cc.GetValue(i)));
Dean@384
   103
                }
Dean@384
   104
            }
Dean@384
   105
Dean@384
   106
            this._Direction = msg.dir;
Dean@384
   107
            this._From = new PEPIdentity(msg.from);
Dean@384
   108
            this._ID = msg.id;
Dean@384
   109
Dean@384
   110
            // Keywords
Dean@384
   111
            this._Keywords = new List<string>();
Dean@384
   112
            if (msg.keywords != null)
Dean@384
   113
            {
Dean@384
   114
                for (int i = 0; i < msg.keywords.Length; i++)
Dean@384
   115
                {
Dean@384
   116
                    this._Keywords.Add((string)msg.keywords.GetValue(i));
Dean@384
   117
                }
Dean@384
   118
            }
Dean@384
   119
Dean@384
   120
            this._LongMsg = msg.longmsg;
Dean@697
   121
            this._LongMsgFormattedHTML = msg.longmsg_formatted;
Dean@697
   122
            this._LongMsgFormattedRTF = null;
Dean@384
   123
Dean@572
   124
            // Optional properties
Dean@572
   125
            this._OptionalProperties = new List<opt_field>();
Dean@384
   126
            if (msg.opt_fields != null)
Dean@384
   127
            {
Dean@384
   128
                for (int i = 0; i < msg.opt_fields.Length; i++)
Dean@384
   129
                {
Dean@572
   130
                    this._OptionalProperties.Add((opt_field)msg.opt_fields.GetValue(i));
Dean@384
   131
                }
Dean@384
   132
            }
Dean@384
   133
Dean@721
   134
            // ReceivedOn
Dean@721
   135
            if (msg.recv > 0)
Dean@721
   136
            {
Dean@721
   137
                this._ReceivedOn = new DateTime(1970, 1, 1).AddSeconds(msg.recv);
Dean@721
   138
            }
Dean@721
   139
            else
Dean@721
   140
            {
Dean@721
   141
                this._ReceivedOn = null;
Dean@721
   142
            }
Dean@721
   143
Dean@721
   144
            // SentOn
Dean@721
   145
            if (msg.sent > 0)
Dean@721
   146
            {
Dean@721
   147
                this._SentOn = new DateTime(1970, 1, 1).AddSeconds(msg.sent);
Dean@721
   148
            }
Dean@721
   149
            else
Dean@721
   150
            {
Dean@721
   151
                this._SentOn = null;
Dean@721
   152
            }
Dean@721
   153
Dean@384
   154
            this._ShortMsg = msg.shortmsg;
Dean@384
   155
Dean@384
   156
            // To
Dean@384
   157
            this._To = new List<PEPIdentity>();
Dean@384
   158
            if (msg.to != null)
Dean@384
   159
            {
Dean@384
   160
                for (int i = 0; i < msg.to.Length; i++)
Dean@384
   161
                {
Dean@384
   162
                    this._To.Add(new PEPIdentity((pEp_identity_s)msg.to.GetValue(i)));
Dean@384
   163
                }
Dean@384
   164
            }
Dean@384
   165
        }
Dean@384
   166
Dean@384
   167
        /// <summary>
Dean@384
   168
        /// Contructs a new message from the given outlook mail item.
Dean@384
   169
        /// </summary>
Dean@384
   170
        /// <param name="omi">The outlook mail item to create the message from.</param>
Dean@586
   171
        /// <param name="createWithoutContent">Whether to include content such as text body, attachments 
Dean@586
   172
        /// and optional properties.</param>
Dean@384
   173
        public PEPMessage(Outlook.MailItem omi,
Dean@384
   174
                          bool createWithoutContent = false)
Dean@384
   175
        {
Dean@698
   176
            byte[] rtfBody;
Dean@384
   177
            string delim;
Dean@384
   178
            string bodyLong = null;
Dean@697
   179
            string bodyLongFormattedHTML = null;
Dean@697
   180
            string bodyLongFormattedRTF = null;
Dean@586
   181
            object propertyValue;
Dean@586
   182
            opt_field newProp;
Dean@721
   183
            DateTime? receivedOn = null;
Dean@721
   184
            DateTime? sentOn = null;
Dean@384
   185
            List<string> keywordList = new List<string>();
Dean@384
   186
            List<PEPIdentity> toList = new List<PEPIdentity>();
Dean@384
   187
            List<PEPIdentity> ccList = new List<PEPIdentity>();
Dean@384
   188
            List<PEPIdentity> bccList = new List<PEPIdentity>();
Dean@384
   189
            List<PEPAttachment> attachmentList = new List<PEPAttachment>();
Dean@586
   190
            List<opt_field> optionalPropertyList = new List<opt_field>();
Dean@384
   191
            Outlook.Account acct = null;
Dean@551
   192
            Outlook.Attachment currAttachment = null;
Dean@551
   193
            Outlook.Attachments attachments = null;
Dean@551
   194
            Outlook.Recipient currRecipient = null;
Dean@551
   195
            Outlook.Recipients recipients = null;
Dean@499
   196
Dean@759
   197
            Global.LogVerbose("PEPMessage: Creating new PEPMessage started, calculating recipients.");
Dean@740
   198
Dean@384
   199
            // Calculate recipients
Dean@551
   200
            recipients = omi.Recipients;
Dean@551
   201
            for (int i = 1; i <= recipients.Count; i++)
Dean@384
   202
            {
Dean@551
   203
                currRecipient = recipients[i];
Dean@551
   204
Dean@551
   205
                switch ((Outlook.OlMailRecipientType)currRecipient.Type)
Dean@384
   206
                {
Dean@384
   207
                    case Outlook.OlMailRecipientType.olTo:
Dean@551
   208
                        toList.Add(PEPIdentity.ToIdentity(currRecipient));
Dean@384
   209
                        break;
Dean@384
   210
                    case Outlook.OlMailRecipientType.olCC:
Dean@551
   211
                        ccList.Add(PEPIdentity.ToIdentity(currRecipient));
Dean@384
   212
                        break;
Dean@384
   213
                    case Outlook.OlMailRecipientType.olBCC:
Dean@551
   214
                        bccList.Add(PEPIdentity.ToIdentity(currRecipient));
Dean@384
   215
                        break;
Dean@384
   216
                }
Dean@551
   217
Dean@551
   218
                Marshal.ReleaseComObject(currRecipient);
Dean@551
   219
                currRecipient = null;
Dean@384
   220
            }
Dean@384
   221
Dean@759
   222
            Global.LogVerbose("PEPMessage: Recipients calculated, calculating date & times.");
Dean@740
   223
Dean@721
   224
            /* Date & Times
Dean@721
   225
             * 
Dean@721
   226
             * Note: The mail item date can be invalid:
Dean@703
   227
             * For incoming this commonly occurs when creating a mirror -- it's created without a received time.
Dean@703
   228
             * For outgoing this commonly occurs for unsent mail.
Dean@703
   229
             * In these cases, the invalid date and time will be returned as 1/1/4501 at 12:00AM
Dean@703
   230
             * This situation is filtered here and the date is set as null.
Dean@703
   231
             */
Dean@721
   232
            receivedOn = omi.ReceivedTime;
Dean@721
   233
            if ((receivedOn != null) &&
Dean@721
   234
                (((DateTime)receivedOn).Year > 4000)) // ~2000 years from now, no issue
Dean@703
   235
            {
Dean@721
   236
                receivedOn = null;
Dean@721
   237
            }
Dean@721
   238
Dean@721
   239
            sentOn = omi.SentOn;
Dean@721
   240
            if ((sentOn != null) &&
Dean@721
   241
                (((DateTime)sentOn).Year > 4000)) // ~2000 years from now, no issue
Dean@721
   242
            {
Dean@721
   243
                sentOn = null;
Dean@691
   244
            }
Dean@691
   245
Dean@759
   246
            Global.LogVerbose("PEPMessage: Date & times calculated, calculating body and attachments.");
Dean@740
   247
Dean@384
   248
            // Calculate text body and attachments
Dean@384
   249
            if (createWithoutContent == false)
Dean@384
   250
            {
Dean@384
   251
                // Body
Dean@384
   252
                if (omi.Body != null)
Dean@384
   253
                {
Dean@384
   254
                    bodyLong = omi.Body.Replace("\r\n", "\n");
Dean@384
   255
Dean@697
   256
                    // Save as RTF
Dean@722
   257
                    try
Dean@722
   258
                    {
Dean@722
   259
                        rtfBody = omi.RTFBody;
Dean@722
   260
                        bodyLongFormattedRTF = System.Text.Encoding.ASCII.GetString(rtfBody, 0, rtfBody.Length);
Dean@722
   261
                    }
Dean@722
   262
                    catch
Dean@722
   263
                    {
Dean@759
   264
                        Global.Log("PEPMessage: Unable to read RTF body in MailItem.");
Dean@722
   265
                    }
Dean@697
   266
Dean@384
   267
                    // Force rich text into HTML
Dean@384
   268
                    if (omi.BodyFormat == Outlook.OlBodyFormat.olFormatRichText)
Dean@384
   269
                    {
Dean@384
   270
                        omi.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
Dean@384
   271
                    }
Dean@384
   272
Dean@384
   273
                    if (omi.BodyFormat == Outlook.OlBodyFormat.olFormatHTML)
Dean@384
   274
                    {
Dean@697
   275
                        bodyLongFormattedHTML = omi.HTMLBody;
Dean@384
   276
                    }
Dean@384
   277
                }
Dean@384
   278
Dean@384
   279
                // Attachments
Dean@551
   280
                attachments = omi.Attachments;
Dean@551
   281
                for (int i = 1; i <= attachments.Count; i++)
Dean@384
   282
                {
Dean@551
   283
                    currAttachment = attachments[i];
Dean@551
   284
Dean@384
   285
                    try
Dean@384
   286
                    {
Dean@551
   287
                        attachmentList.Add(new PEPAttachment(currAttachment));
Dean@384
   288
                    }
Dean@384
   289
                    catch { }
Dean@551
   290
Dean@551
   291
                    Marshal.ReleaseComObject(currAttachment);
Dean@551
   292
                    currAttachment = null;
Dean@384
   293
                }
Dean@384
   294
Dean@384
   295
                // Keywords
Dean@384
   296
                if (omi.Categories != null)
Dean@384
   297
                {
Dean@384
   298
                    using (RegistryKey key1 = Registry.CurrentUser.OpenSubKey("Control Panel\\International"))
Dean@384
   299
                    {
Dean@384
   300
                        delim = key1.GetValue("sList").ToString();
Dean@384
   301
                        keywordList = new List<string>(omi.Categories.Split(delim.ToCharArray()));
Dean@384
   302
                    }
Dean@384
   303
                }
Dean@572
   304
Dean@586
   305
                // Optional properties
Dean@586
   306
                propertyValue = MAPIHelper.GetProperty(omi, PEPMessage.PR_X_ENC_STATUS);
Dean@586
   307
                if (propertyValue != null)
Dean@586
   308
                {
Dean@586
   309
                    newProp = new opt_field();
Dean@586
   310
                    newProp.name = PEPMessage.PR_X_ENC_STATUS_NAME;
Dean@586
   311
                    newProp.value = propertyValue.ToString();
Dean@586
   312
Dean@586
   313
                    optionalPropertyList.Add(newProp);
Dean@586
   314
                }
Dean@586
   315
Dean@586
   316
                propertyValue = MAPIHelper.GetProperty(omi, PEPMessage.PR_X_KEY_LIST);
Dean@586
   317
                if (propertyValue != null)
Dean@586
   318
                {
Dean@586
   319
                    newProp = new opt_field();
Dean@586
   320
                    newProp.name = PEPMessage.PR_X_KEY_LIST_NAME;
Dean@586
   321
                    newProp.value = propertyValue.ToString();
Dean@586
   322
Dean@586
   323
                    optionalPropertyList.Add(newProp);
Dean@586
   324
                }
Dean@586
   325
Dean@586
   326
                propertyValue = MAPIHelper.GetProperty(omi, PEPMessage.PR_X_PEP_VERSION);
Dean@586
   327
                if (propertyValue != null)
Dean@586
   328
                {
Dean@586
   329
                    newProp = new opt_field();
Dean@586
   330
                    newProp.name = PEPMessage.PR_X_PEP_VERSION_NAME;
Dean@586
   331
                    newProp.value = propertyValue.ToString();
Dean@586
   332
Dean@586
   333
                    optionalPropertyList.Add(newProp);
Dean@586
   334
                }
Dean@384
   335
            }
Dean@384
   336
Dean@384
   337
            // Set properties
Dean@384
   338
            this._Attachments = attachmentList;
Dean@384
   339
            this._BCC = bccList;
Dean@384
   340
            this._CC = ccList;
Dean@384
   341
            this._Direction = CryptableMailItem.GetIsIncoming(omi) ? _pEp_msg_direction.pEp_dir_incoming : _pEp_msg_direction.pEp_dir_outgoing;
Dean@643
   342
            this._From = PEPIdentity.GetFromIdentity(omi);
Dean@384
   343
            this._ID = CryptableMailItem.GetMessageID(omi);
Dean@384
   344
            this._Keywords = keywordList;
Dean@384
   345
            this._LongMsg = bodyLong;
Dean@697
   346
            this._LongMsgFormattedHTML = bodyLongFormattedHTML;
Dean@697
   347
            this._LongMsgFormattedRTF = bodyLongFormattedRTF;
Dean@586
   348
            this._OptionalProperties = optionalPropertyList;
Dean@721
   349
            this._ReceivedOn = receivedOn;
Dean@721
   350
            this._SentOn = sentOn;
Dean@384
   351
            this._ShortMsg = omi.Subject;
Dean@384
   352
            this._To = toList;
Dean@384
   353
Dean@384
   354
            // Free resources
Dean@384
   355
            if (acct != null)
Dean@384
   356
            {
Dean@384
   357
                Marshal.ReleaseComObject(acct);
Dean@384
   358
                acct = null;
Dean@384
   359
            }
Dean@384
   360
Dean@551
   361
            if (currAttachment != null)
Dean@551
   362
            {
Dean@551
   363
                Marshal.ReleaseComObject(currAttachment);
Dean@551
   364
                currAttachment = null;
Dean@551
   365
            }
Dean@551
   366
Dean@551
   367
            if (attachments != null)
Dean@551
   368
            {
Dean@551
   369
                Marshal.ReleaseComObject(attachments);
Dean@551
   370
                attachments = null;
Dean@551
   371
            }
Dean@551
   372
Dean@551
   373
            if (currRecipient != null)
Dean@551
   374
            {
Dean@551
   375
                Marshal.ReleaseComObject(currRecipient);
Dean@551
   376
                currRecipient = null;
Dean@551
   377
            }
Dean@551
   378
Dean@551
   379
            if (recipients != null)
Dean@551
   380
            {
Dean@551
   381
                Marshal.ReleaseComObject(recipients);
Dean@551
   382
                recipients = null;
Dean@551
   383
            }
Dean@551
   384
Dean@759
   385
            Global.LogVerbose("PEPMessage: New PEPMessage created.");
Dean@740
   386
Dean@384
   387
            return;
Dean@384
   388
        }
Dean@384
   389
Dean@384
   390
        /**************************************************************
Dean@384
   391
         * 
Dean@384
   392
         * Property Accessors
Dean@384
   393
         * 
Dean@384
   394
         *************************************************************/
Dean@384
   395
Dean@384
   396
        /// <summary>
Dean@384
   397
        /// Gets the list of attachements for this message.
Dean@384
   398
        /// </summary>
Dean@384
   399
        public List<PEPAttachment> Attachments
Dean@384
   400
        {
Dean@384
   401
            get { return (this._Attachments); }
Dean@384
   402
        }
Dean@384
   403
Dean@384
   404
        /// <summary>
Dean@387
   405
        /// Gets the list of identities to be blind carbon copied on the message.
Dean@384
   406
        /// </summary>
Dean@384
   407
        public List<PEPIdentity> BCC
Dean@384
   408
        {
Dean@384
   409
            get { return (this._BCC); }
Dean@384
   410
        }
Dean@384
   411
Dean@384
   412
        /// <summary>
Dean@384
   413
        /// Gets the list of identities to be carbon copied on the message.
Dean@384
   414
        /// </summary>
Dean@384
   415
        public List<PEPIdentity> CC
Dean@384
   416
        {
Dean@384
   417
            get { return (this._CC); }
Dean@384
   418
        }
Dean@384
   419
Dean@384
   420
        /// <summary>
Dean@721
   421
        /// Gets the date and time when the message was either sent or received.
Dean@721
   422
        /// This corresponds with the SentOn and ReceivedOn properties.
Dean@691
   423
        /// </summary>
Dean@691
   424
        public DateTime? DateTimeSentOrReceived
Dean@691
   425
        {
Dean@721
   426
            get
Dean@721
   427
            {
Dean@721
   428
                if (this._Direction == _pEp_msg_direction.pEp_dir_incoming)
Dean@721
   429
                {
Dean@721
   430
                    return (this._ReceivedOn);
Dean@721
   431
                }
Dean@721
   432
                else
Dean@721
   433
                {
Dean@721
   434
                    return (this._SentOn);
Dean@721
   435
                }
Dean@721
   436
            }
Dean@691
   437
        }
Dean@691
   438
Dean@691
   439
        /// <summary>
Dean@384
   440
        /// Gets or sets the direction (incoming or outgoing) of the message.
Dean@384
   441
        /// </summary>
Dean@384
   442
        public _pEp_msg_direction Direction
Dean@384
   443
        {
Dean@384
   444
            get { return (this._Direction); }
Dean@384
   445
            set { this._Direction = value; }
Dean@384
   446
        }
Dean@384
   447
Dean@384
   448
        /// <summary>
Dean@384
   449
        /// Gets or sets the from identity of the message.
Dean@384
   450
        /// Warning: this value can be null.
Dean@384
   451
        /// </summary>
Dean@384
   452
        public PEPIdentity From
Dean@384
   453
        {
Dean@384
   454
            get { return (this._From); }
Dean@384
   455
            set { this._From = value; }
Dean@384
   456
        }
Dean@384
   457
Dean@384
   458
        /// <summary>
Dean@384
   459
        /// Gets or sets the ID of the message.
Dean@384
   460
        /// Warning: this value can be null.
Dean@384
   461
        /// </summary>
Dean@384
   462
        public string ID
Dean@384
   463
        {
Dean@384
   464
            get { return (this._ID); }
Dean@384
   465
            set { this._ID = value; }
Dean@384
   466
        }
Dean@384
   467
Dean@384
   468
        /// <summary>
Dean@384
   469
        /// Gets the list of keywords associated with the message.
Dean@384
   470
        /// </summary>
Dean@384
   471
        public List<string> Keywords
Dean@384
   472
        {
Dean@384
   473
            get { return (this._Keywords); }
Dean@384
   474
        }
Dean@384
   475
Dean@384
   476
        /// <summary>
Dean@384
   477
        /// Gets or sets the long-form (body) of the message.
Dean@384
   478
        /// This should be plain text.
Dean@384
   479
        /// Warning: this value can be null.
Dean@384
   480
        /// </summary>
Dean@384
   481
        public string LongMsg
Dean@384
   482
        {
Dean@384
   483
            get { return (this._LongMsg); }
Dean@384
   484
            set { this._LongMsg = value; }
Dean@384
   485
        }
Dean@384
   486
Dean@384
   487
        /// <summary>
Dean@697
   488
        /// Gets or sets the HTML formatted long-form (body) of the message.
Dean@384
   489
        /// Warning: this value can be null.
Dean@384
   490
        /// </summary>
Dean@697
   491
        public string LongMsgFormattedHTML
Dean@384
   492
        {
Dean@697
   493
            get { return (this._LongMsgFormattedHTML); }
Dean@697
   494
            set { this._LongMsgFormattedHTML = value; }
Dean@697
   495
        }
Dean@697
   496
Dean@697
   497
        /// <summary>
Dean@697
   498
        /// Gets or sets the RTF formatted long-form (body) of the message.
Dean@697
   499
        /// Warning: this value can be null.
Dean@697
   500
        /// </summary>
Dean@697
   501
        public string LongMsgFormattedRTF
Dean@697
   502
        {
Dean@697
   503
            get { return (this._LongMsgFormattedRTF); }
Dean@697
   504
            set { this._LongMsgFormattedRTF = value; }
Dean@384
   505
        }
Dean@384
   506
Dean@384
   507
        /// <summary>
Dean@572
   508
        /// Gets the list of optional properties associated with the message.
Dean@384
   509
        /// </summary>
Dean@572
   510
        public List<opt_field> OptionalProperties
Dean@384
   511
        {
Dean@572
   512
            get { return (this._OptionalProperties); }
Dean@384
   513
        }
Dean@384
   514
Dean@384
   515
        /// <summary>
Dean@721
   516
        /// Gets or sets the date and time when the message was received.
Dean@721
   517
        /// </summary>
Dean@721
   518
        public DateTime? ReceivedOn
Dean@721
   519
        {
Dean@721
   520
            get { return (this._ReceivedOn); }
Dean@721
   521
            set { this._ReceivedOn = value; }
Dean@721
   522
        }
Dean@721
   523
Dean@721
   524
        /// <summary>
Dean@721
   525
        /// Gets or sets the date and time when the message was sent.
Dean@721
   526
        /// </summary>
Dean@721
   527
        public DateTime? SentOn
Dean@721
   528
        {
Dean@721
   529
            get { return (this._SentOn); }
Dean@721
   530
            set { this._SentOn = value; }
Dean@721
   531
        }
Dean@721
   532
Dean@721
   533
        /// <summary>
Dean@384
   534
        /// Gets or sets the short-form (subject) of the message.
Dean@384
   535
        /// Warning: this value can be null.
Dean@384
   536
        /// </summary>
Dean@384
   537
        public string ShortMsg
Dean@384
   538
        {
Dean@384
   539
            get { return (this._ShortMsg); }
Dean@384
   540
            set { this._ShortMsg = value; }
Dean@384
   541
        }
Dean@384
   542
Dean@384
   543
        /// <summary>
Dean@384
   544
        /// Gets the list of identities to receive the message.
Dean@384
   545
        /// </summary>
Dean@384
   546
        public List<PEPIdentity> To
Dean@384
   547
        {
Dean@384
   548
            get { return (this._To); }
Dean@384
   549
        }
Dean@384
   550
Dean@625
   551
        /// <summary>
Dean@625
   552
        /// Gets the total number of all recipients in the message (BCC, CC &amp; To).
Dean@625
   553
        /// </summary>
Dean@625
   554
        public int RecipientCount
Dean@625
   555
        {
Dean@625
   556
            get { return (this._BCC.Count + this._CC.Count + this._To.Count); }
Dean@625
   557
        }
Dean@625
   558
Dean@625
   559
        /// <summary>
Dean@625
   560
        /// Gets a list of all recipients in the message (BCC, CC &amp; To).
Dean@625
   561
        /// Each recipient in the returned list is a copy.
Dean@625
   562
        /// </summary>
Dean@625
   563
        public PEPIdentity[] Recipients
Dean@625
   564
        {
Dean@625
   565
            get
Dean@625
   566
            {
Dean@625
   567
                List<PEPIdentity> recipients = new List<PEPIdentity>();
Dean@625
   568
Dean@625
   569
                // BCC
Dean@625
   570
                for (int i = 0; i < this._BCC.Count; i++)
Dean@625
   571
                {
Dean@625
   572
                    recipients.Add(this._BCC[i].Copy());
Dean@625
   573
                }
Dean@625
   574
Dean@625
   575
                // CC
Dean@625
   576
                for (int i = 0; i < this._CC.Count; i++)
Dean@625
   577
                {
Dean@625
   578
                    recipients.Add(this._CC[i].Copy());
Dean@625
   579
                }
Dean@625
   580
Dean@625
   581
                // To
Dean@625
   582
                for (int i = 0; i < this._To.Count; i++)
Dean@625
   583
                {
Dean@625
   584
                    recipients.Add(this._To[i].Copy());
Dean@625
   585
                }
Dean@625
   586
Dean@625
   587
                return (recipients.ToArray());
Dean@625
   588
            }
Dean@625
   589
        }
Dean@625
   590
Dean@384
   591
        /**************************************************************
Dean@384
   592
         * 
Dean@384
   593
         * Methods
Dean@384
   594
         * 
Dean@384
   595
         *************************************************************/
Dean@384
   596
Dean@384
   597
        /// <summary>
Dean@384
   598
        /// Returns this pEp message as a new pEp engine text_message.
Dean@384
   599
        /// </summary>
Dean@384
   600
        /// <returns>A pEp engine identity.</returns>
Dean@384
   601
        public text_message ToCOMType()
Dean@384
   602
        {
Dean@384
   603
            List<blob> attachments = new List<blob>();
Dean@384
   604
            List<pEp_identity_s> bcc = new List<pEp_identity_s>();
Dean@384
   605
            List<pEp_identity_s> cc = new List<pEp_identity_s>();
Dean@384
   606
            List<pEp_identity_s> to = new List<pEp_identity_s>();
Dean@384
   607
            text_message result = new text_message();
Dean@384
   608
Dean@388
   609
            // Convert attachments
Dean@384
   610
            for (int i = 0; i < this._Attachments.Count; i++)
Dean@384
   611
            {
Dean@384
   612
                attachments.Add(this._Attachments[i].ToCOMType());
Dean@384
   613
            }
Dean@398
   614
Dean@388
   615
            // Convert BCC
Dean@384
   616
            for (int i = 0; i < this._BCC.Count; i++)
Dean@384
   617
            {
Dean@384
   618
                bcc.Add(this._BCC[i].ToCOMType());
Dean@384
   619
            }
Dean@398
   620
Dean@388
   621
            // Convert CC
Dean@384
   622
            for (int i = 0; i < this._CC.Count; i++)
Dean@384
   623
            {
Dean@384
   624
                cc.Add(this._CC[i].ToCOMType());
Dean@384
   625
            }
Dean@398
   626
Dean@388
   627
            // Convert To
Dean@388
   628
            for (int i = 0; i < this._To.Count; i++)
Dean@388
   629
            {
Dean@388
   630
                to.Add(this._To[i].ToCOMType());
Dean@388
   631
            }
Dean@388
   632
Dean@697
   633
            /* Set properties
Dean@697
   634
             * 
Dean@697
   635
             * Note: Skip DateTimeSentOrReceived and LongMsgFormattedRTF which
Dean@697
   636
             * are not supported in the pEp engine.
Dean@697
   637
             */
Dean@388
   638
            result.attachments = attachments.ToArray();
Dean@388
   639
            result.bcc = bcc.ToArray();
Dean@384
   640
            result.cc = cc.ToArray();
Dean@384
   641
            result.dir = this._Direction;
Dean@384
   642
            result.from = (this._From == null ? new pEp_identity_s() : this._From.ToCOMType());
Dean@384
   643
            result.id = this._ID;
Dean@384
   644
            result.keywords = this._Keywords.ToArray();
Dean@384
   645
            result.longmsg = this._LongMsg;
Dean@697
   646
            result.longmsg_formatted = this._LongMsgFormattedHTML;
Dean@572
   647
            result.opt_fields = this._OptionalProperties.ToArray();
Dean@384
   648
            result.shortmsg = this._ShortMsg;
Dean@384
   649
            result.to = to.ToArray();
Dean@384
   650
Dean@384
   651
            return (result);
Dean@384
   652
        }
Dean@384
   653
Dean@384
   654
        /// <summary>
Dean@389
   655
        /// Gets a deep copy of the object and all it's data.
Dean@389
   656
        /// </summary>
Dean@389
   657
        /// <returns>The deep copy of the object.</returns>
Dean@389
   658
        public PEPMessage Copy()
Dean@389
   659
        {
Dean@390
   660
            return (this.Copy(false));
Dean@390
   661
        }
Dean@390
   662
Dean@390
   663
        /// <summary>
Dean@390
   664
        /// Gets a copy of the PEPMessage with or without data.
Dean@390
   665
        /// </summary>
Dean@586
   666
        /// <param name="createWithoutContent">Whether to include content such as text body, attachments 
Dean@586
   667
        /// and optional properties.</param>
Dean@390
   668
        /// <returns>The copy of the PEPMessage.</returns>
Dean@390
   669
        public PEPMessage Copy(bool createWithoutContent = false)
Dean@390
   670
        {
Dean@389
   671
            PEPMessage copy = new PEPMessage();
Dean@389
   672
Dean@389
   673
            // Attachments
Dean@389
   674
            copy.Attachments.Clear();
Dean@390
   675
            if (createWithoutContent == false)
Dean@389
   676
            {
Dean@390
   677
                for (int i = 0; i < this._Attachments.Count; i++)
Dean@390
   678
                {
Dean@390
   679
                    copy.Attachments.Add(this._Attachments[i].Copy());
Dean@390
   680
                }
Dean@389
   681
            }
Dean@389
   682
Dean@389
   683
            // BCC
Dean@389
   684
            copy.BCC.Clear();
Dean@389
   685
            for (int i = 0; i < this._BCC.Count; i++)
Dean@389
   686
            {
Dean@389
   687
                copy.BCC.Add(this._BCC[i].Copy());
Dean@389
   688
            }
Dean@389
   689
Dean@389
   690
            // CC
Dean@389
   691
            copy.CC.Clear();
Dean@389
   692
            for (int i = 0; i < this._CC.Count; i++)
Dean@389
   693
            {
Dean@389
   694
                copy.CC.Add(this._CC[i].Copy());
Dean@389
   695
            }
Dean@389
   696
Dean@389
   697
            copy.Direction = this._Direction;
Dean@389
   698
            copy.From = (this._From == null ? null : this._From.Copy());
Dean@389
   699
            copy.ID = this._ID;
Dean@389
   700
Dean@389
   701
            // Keywords
Dean@389
   702
            copy.Keywords.Clear();
Dean@389
   703
            for (int i = 0; i < this._Keywords.Count; i++)
Dean@389
   704
            {
Dean@389
   705
                copy.Keywords.Add(this._Keywords[i]);
Dean@389
   706
            }
Dean@398
   707
Dean@390
   708
            // Body
Dean@390
   709
            if (createWithoutContent == false)
Dean@390
   710
            {
Dean@390
   711
                copy.LongMsg = this._LongMsg;
Dean@697
   712
                copy.LongMsgFormattedHTML = this._LongMsgFormattedHTML;
Dean@697
   713
                copy.LongMsgFormattedRTF = this._LongMsgFormattedRTF;
Dean@390
   714
            }
Dean@390
   715
            else
Dean@390
   716
            {
Dean@390
   717
                copy.LongMsg = null;
Dean@697
   718
                copy.LongMsgFormattedHTML = null;
Dean@697
   719
                copy.LongMsgFormattedRTF = null;
Dean@390
   720
            }
Dean@389
   721
Dean@389
   722
            // OptionalFields
Dean@572
   723
            copy.OptionalProperties.Clear();
Dean@586
   724
            if (createWithoutContent == false)
Dean@389
   725
            {
Dean@586
   726
                for (int i = 0; i < this._OptionalProperties.Count; i++)
Dean@586
   727
                {
Dean@586
   728
                    copy.OptionalProperties.Add(this._OptionalProperties[i]);
Dean@586
   729
                }
Dean@389
   730
            }
Dean@604
   731
Dean@721
   732
            // ReceivedOn
Dean@721
   733
            if (this._ReceivedOn != null)
Dean@721
   734
            {
Dean@721
   735
                copy.ReceivedOn = new DateTime(((DateTime)this._ReceivedOn).Ticks);
Dean@721
   736
            }
Dean@721
   737
            else
Dean@721
   738
            {
Dean@721
   739
                copy.ReceivedOn = null;
Dean@721
   740
            }
Dean@721
   741
Dean@721
   742
            // SentOn
Dean@721
   743
            if (this._SentOn != null)
Dean@721
   744
            {
Dean@721
   745
                copy.SentOn = new DateTime(((DateTime)this._SentOn).Ticks);
Dean@721
   746
            }
Dean@721
   747
            else
Dean@721
   748
            {
Dean@721
   749
                copy.SentOn = null;
Dean@721
   750
            }
Dean@721
   751
Dean@389
   752
            copy.ShortMsg = this._ShortMsg;
Dean@389
   753
Dean@389
   754
            // To
Dean@389
   755
            copy.To.Clear();
Dean@389
   756
            for (int i = 0; i < this._To.Count; i++)
Dean@389
   757
            {
Dean@389
   758
                copy.To.Add(this._To[i].Copy());
Dean@389
   759
            }
Dean@389
   760
Dean@389
   761
            return (copy);
Dean@389
   762
        }
Dean@389
   763
Dean@389
   764
        /// <summary>
Dean@384
   765
        /// Applies this pEp message's data to the given Outlook item.
Dean@384
   766
        /// </summary>
Dean@384
   767
        /// <param name="omi">The Outlook mail item to apply this pEp message's data to.</param>
Dean@586
   768
        /// <param name="includeOptionalProperties">Whether to include optional properites such as 
Dean@586
   769
        /// color rating, pEp version etc...</param>
Dean@586
   770
        public void ApplyTo(Outlook.MailItem omi,
Dean@586
   771
                            bool includeOptionalProperties = false)
Dean@384
   772
        {
Dean@384
   773
            string tempDir;
Dean@384
   774
            string tempFile;
Dean@543
   775
            Outlook.Attachment newAttachment = null;
Dean@543
   776
            Outlook.Attachments attachments = null;
Dean@543
   777
            Outlook.Recipient newRecipient = null;
Dean@543
   778
            Outlook.Recipients recipients = null;
Dean@543
   779
            Outlook.Account currAccount = null;
Dean@543
   780
            Outlook.Account sendUsingAccount = null;
Dean@543
   781
            Outlook.Accounts accounts = null;
Dean@408
   782
Dean@543
   783
            try
Dean@408
   784
            {
Dean@543
   785
                // Remove all recipients
Dean@543
   786
                recipients = omi.Recipients;
Dean@543
   787
                while (recipients.Count > 0)
Dean@543
   788
                {
Dean@543
   789
                    recipients.Remove(1);
Dean@543
   790
                }
Dean@543
   791
Dean@543
   792
                // Set recipients
Dean@543
   793
                for (int i = 0; i < this._BCC.Count; i++)
Dean@543
   794
                {
Dean@795
   795
                    if (string.IsNullOrWhiteSpace(this._BCC[i].Address) == false)
Dean@543
   796
                    {
Dean@795
   797
                        // Add by address
Dean@543
   798
                        newRecipient = recipients.Add(this._BCC[i].Address);
Dean@543
   799
                        newRecipient.Type = (int)Outlook.OlMailRecipientType.olBCC;
Dean@543
   800
Dean@543
   801
                        Marshal.ReleaseComObject(newRecipient);
Dean@543
   802
                        newRecipient = null;
Dean@543
   803
                    }
Dean@795
   804
                    else if (string.IsNullOrWhiteSpace(this._BCC[i].Username) == false)
Dean@795
   805
                    {
Dean@795
   806
                        // Add by username (required for distribution lists)
Dean@795
   807
                        newRecipient = recipients.Add(this._BCC[i].Username);
Dean@795
   808
                        newRecipient.Type = (int)Outlook.OlMailRecipientType.olBCC;
Dean@795
   809
Dean@795
   810
                        Marshal.ReleaseComObject(newRecipient);
Dean@795
   811
                        newRecipient = null;
Dean@795
   812
                    }
Dean@543
   813
                }
Dean@543
   814
Dean@543
   815
                for (int i = 0; i < this._CC.Count; i++)
Dean@543
   816
                {
Dean@795
   817
                    if (string.IsNullOrWhiteSpace(this._CC[i].Address) == false)
Dean@543
   818
                    {
Dean@795
   819
                        // Add by address
Dean@543
   820
                        newRecipient = recipients.Add(this._CC[i].Address);
Dean@543
   821
                        newRecipient.Type = (int)Outlook.OlMailRecipientType.olCC;
Dean@543
   822
Dean@543
   823
                        Marshal.ReleaseComObject(newRecipient);
Dean@543
   824
                        newRecipient = null;
Dean@543
   825
                    }
Dean@795
   826
                    else if (string.IsNullOrWhiteSpace(this._CC[i].Username) == false)
Dean@795
   827
                    {
Dean@795
   828
                        // Add by username (required for distribution lists)
Dean@795
   829
                        newRecipient = recipients.Add(this._CC[i].Username);
Dean@795
   830
                        newRecipient.Type = (int)Outlook.OlMailRecipientType.olCC;
Dean@795
   831
Dean@795
   832
                        Marshal.ReleaseComObject(newRecipient);
Dean@795
   833
                        newRecipient = null;
Dean@795
   834
                    }
Dean@543
   835
                }
Dean@543
   836
Dean@543
   837
                for (int i = 0; i < this._To.Count; i++)
Dean@543
   838
                {
Dean@795
   839
                    if (string.IsNullOrWhiteSpace(this._To[i].Address) == false)
Dean@543
   840
                    {
Dean@795
   841
                        // Add by address
Dean@543
   842
                        newRecipient = recipients.Add(this._To[i].Address);
Dean@543
   843
                        newRecipient.Type = (int)Outlook.OlMailRecipientType.olTo;
Dean@543
   844
Dean@543
   845
                        Marshal.ReleaseComObject(newRecipient);
Dean@543
   846
                        newRecipient = null;
Dean@543
   847
                    }
Dean@795
   848
                    else if (string.IsNullOrWhiteSpace(this._To[i].Username) == false)
Dean@795
   849
                    {
Dean@795
   850
                        // Add by username (required for distribution lists)
Dean@795
   851
                        newRecipient = recipients.Add(this._To[i].Username);
Dean@795
   852
                        newRecipient.Type = (int)Outlook.OlMailRecipientType.olTo;
Dean@795
   853
Dean@795
   854
                        Marshal.ReleaseComObject(newRecipient);
Dean@795
   855
                        newRecipient = null;
Dean@795
   856
                    }
Dean@543
   857
                }
Dean@543
   858
Dean@543
   859
                recipients.ResolveAll();
Dean@543
   860
Dean@543
   861
                /* Set sender
Dean@543
   862
                 * Note that if fails, will be empty which eventually will use the default send account
Dean@543
   863
                 * If the send using account is already populated, this cannot be re-set.
Dean@543
   864
                 * So far this doesn't appear to be an issue as it occurs when applying unencrypted data to a mirror.
Dean@543
   865
                 * However, the mirror SendUsingAccount is already correct at this point and doesn't need to be set.
Dean@543
   866
                 */
Dean@543
   867
                sendUsingAccount = omi.SendUsingAccount;
Dean@543
   868
Dean@543
   869
                if ((this._From != null) &&
Dean@543
   870
                    (this._From.Address != null) &&
Dean@543
   871
                    (sendUsingAccount == null))
Dean@543
   872
                {
Dean@543
   873
                    accounts = Globals.ThisAddIn.Application.Session.Accounts;
Dean@543
   874
Dean@543
   875
                    // Note: Index starts at 1
Dean@543
   876
                    for (int i = 1; i <= accounts.Count; i++)
Dean@543
   877
                    {
Dean@543
   878
                        currAccount = accounts[i];
Dean@543
   879
Dean@543
   880
                        if ((currAccount.SmtpAddress != null) &&
Dean@543
   881
                            (currAccount.SmtpAddress.ToUpper() == this._From.Address.ToUpper()))
Dean@543
   882
                        {
Dean@543
   883
                            /* Try to set the SendUsingAccount
Dean@543
   884
                             * This will fail if the mail item is already marked as sent or the SendUsingAccount is not null, etc...
Dean@564
   885
                             * If it fails, Outlook will in the end just use the default account.
Dean@564
   886
                             * This property should ideally be set before a mail item is saved.
Dean@543
   887
                             */
Dean@543
   888
                            try
Dean@543
   889
                            {
Dean@564
   890
                                omi.SendUsingAccount = currAccount;
Dean@543
   891
                            }
Dean@543
   892
                            catch { }
Dean@543
   893
Dean@543
   894
                            Marshal.ReleaseComObject(currAccount);
Dean@543
   895
                            currAccount = null;
Dean@543
   896
Dean@543
   897
                            break;
Dean@543
   898
                        }
Dean@543
   899
Dean@543
   900
                        Marshal.ReleaseComObject(currAccount);
Dean@543
   901
                        currAccount = null;
Dean@543
   902
                    }
Dean@543
   903
                }
Dean@543
   904
Dean@543
   905
                // Set the subject
Dean@543
   906
                omi.Subject = this._ShortMsg;
Dean@543
   907
Dean@697
   908
                // Set the body (skip RTF format, only use HTML which is what the engine uses)
Dean@697
   909
                if (string.IsNullOrWhiteSpace(this._LongMsgFormattedHTML))
Dean@543
   910
                {
Dean@543
   911
                    omi.BodyFormat = Outlook.OlBodyFormat.olFormatPlain;
Dean@543
   912
                    omi.Body = this._LongMsg;
Dean@543
   913
                }
Dean@543
   914
                else
Dean@543
   915
                {
Dean@543
   916
                    omi.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
Dean@697
   917
                    omi.HTMLBody = this._LongMsgFormattedHTML;
Dean@543
   918
                }
Dean@543
   919
Dean@754
   920
                /* Set the encoding to UTF-8
Dean@754
   921
                 * See: https://msdn.microsoft.com/en-us/library/office/ff860730.aspx
Dean@754
   922
                 * All PEPMessages should be UTF even those coming from the engine.
Dean@754
   923
                 */
Dean@754
   924
                try
Dean@754
   925
                {
Dean@790
   926
                    MAPIHelper.SetProperty(omi, MAPIProperty.PidTagInternetCodepage, 65001);
Dean@790
   927
                    MAPIHelper.SetProperty(omi, MAPIProperty.PidTagMessageCodepage, 65001);
Dean@754
   928
                }
Dean@754
   929
                catch
Dean@754
   930
                {
Dean@759
   931
                    Global.Log("PEPMessage.ApplyTo: Failed to set UTF-8 encoding.");
Dean@754
   932
                }
Dean@754
   933
Dean@543
   934
                // Remove any previous attachments
Dean@543
   935
                attachments = omi.Attachments;
Dean@543
   936
                while (attachments.Count > 0)
Dean@543
   937
                {
Dean@543
   938
                    attachments.Remove(1);
Dean@543
   939
                }
Dean@543
   940
Dean@543
   941
                // Create temp directory for attachments
Dean@543
   942
                tempDir = Path.GetTempFileName() + ".dir";
Dean@543
   943
                Directory.CreateDirectory(tempDir);
Dean@543
   944
Dean@543
   945
                // Add new attachments
Dean@543
   946
                for (int i = 0; i < this._Attachments.Count; i++)
Dean@543
   947
                {
Dean@543
   948
                    // Write current attachment to disk
Dean@543
   949
                    tempFile = tempDir + "\\";
Dean@543
   950
                    if (string.IsNullOrWhiteSpace(this._Attachments[i].FileName))
Dean@543
   951
                    {
Dean@543
   952
                        tempFile += "attachment" + i.ToString();
Dean@543
   953
                    }
Dean@543
   954
                    else
Dean@543
   955
                    {
Dean@543
   956
                        tempFile += this._Attachments[i].FileName;
Dean@543
   957
                    }
Dean@543
   958
                    File.WriteAllBytes(tempFile, this._Attachments[i].Data);
Dean@543
   959
Dean@543
   960
                    // Create a new attachment from the file on disk
Dean@543
   961
                    newAttachment = attachments.Add(tempFile);
Dean@543
   962
Dean@543
   963
                    if (string.IsNullOrWhiteSpace(this._Attachments[i].MIMEType))
Dean@543
   964
                    {
Dean@543
   965
                        // Undefined
Dean@790
   966
                        MAPIHelper.SetProperty(newAttachment, MAPIProperty.PidTagAttachMimeTag, "application/octet-stream");
Dean@543
   967
                    }
Dean@543
   968
                    else
Dean@543
   969
                    {
Dean@790
   970
                        MAPIHelper.SetProperty(newAttachment, MAPIProperty.PidTagAttachMimeTag, this._Attachments[i].MIMEType);
Dean@543
   971
                    }
Dean@543
   972
Dean@543
   973
                    Marshal.ReleaseComObject(newAttachment);
Dean@543
   974
                    newAttachment = null;
Dean@543
   975
                }
Dean@543
   976
Dean@543
   977
                // Delete temp directory for attachments
Dean@543
   978
                Directory.Delete(tempDir, true);
Dean@543
   979
Dean@572
   980
                // Optional properties
Dean@586
   981
                if (includeOptionalProperties)
Dean@543
   982
                {
Dean@586
   983
                    for (int i = 0; i < this._OptionalProperties.Count; i++)
Dean@586
   984
                    {
Dean@586
   985
                        MAPIHelper.SetProperty(omi,
Dean@586
   986
                                               PEPMessage.PR_OPT_FIELD + this._OptionalProperties[i].name,
Dean@586
   987
                                               this._OptionalProperties[i].value);
Dean@586
   988
                    }
Dean@543
   989
                }
Dean@408
   990
            }
Dean@545
   991
            catch (Exception ex)
Dean@545
   992
            {
Dean@660
   993
                Global.StopAndSendCrashReport(ex);
Dean@545
   994
            }
Dean@543
   995
            finally
Dean@543
   996
            {
Dean@543
   997
                if (newAttachment != null)
Dean@543
   998
                {
Dean@543
   999
                    Marshal.ReleaseComObject(newAttachment);
Dean@543
  1000
                    newAttachment = null;
Dean@543
  1001
                }
Dean@408
  1002
Dean@543
  1003
                if (attachments != null)
Dean@466
  1004
                {
Dean@543
  1005
                    Marshal.ReleaseComObject(attachments);
Dean@543
  1006
                    attachments = null;
Dean@543
  1007
                }
Dean@408
  1008
Dean@543
  1009
                if (newRecipient != null)
Dean@543
  1010
                {
Dean@466
  1011
                    Marshal.ReleaseComObject(newRecipient);
Dean@543
  1012
                    newRecipient = null;
Dean@543
  1013
                }
Dean@543
  1014
Dean@543
  1015
                if (recipients != null)
Dean@543
  1016
                {
Dean@543
  1017
                    Marshal.ReleaseComObject(recipients);
Dean@543
  1018
                    recipients = null;
Dean@543
  1019
                }
Dean@543
  1020
Dean@543
  1021
                if (currAccount != null)
Dean@543
  1022
                {
Dean@543
  1023
                    Marshal.ReleaseComObject(currAccount);
Dean@543
  1024
                    currAccount = null;
Dean@543
  1025
                }
Dean@543
  1026
Dean@543
  1027
                if (sendUsingAccount != null)
Dean@543
  1028
                {
Dean@543
  1029
                    Marshal.ReleaseComObject(sendUsingAccount);
Dean@543
  1030
                    sendUsingAccount = null;
Dean@543
  1031
                }
Dean@543
  1032
Dean@543
  1033
                if (accounts != null)
Dean@543
  1034
                {
Dean@543
  1035
                    Marshal.ReleaseComObject(accounts);
Dean@543
  1036
                    accounts = null;
Dean@543
  1037
                }
Dean@408
  1038
            }
Dean@408
  1039
Dean@384
  1040
            return;
Dean@384
  1041
        }
Dean@384
  1042
Dean@398
  1043
        /// <summary>
Dean@398
  1044
        /// Recursivley converts all "BCC", "CC", and "To" identities into a 'flat' list of any members.
Dean@398
  1045
        /// This will remove groups (hierarchy) and convert a group into it's members.
Dean@398
  1046
        /// </summary>
Dean@398
  1047
        public void FlattenAllRecipientIdentities()
Dean@398
  1048
        {
Dean@398
  1049
            this._BCC = PEPIdentity.ToFlatList(this._BCC);
Dean@398
  1050
            this._CC = PEPIdentity.ToFlatList(this._CC);
Dean@398
  1051
            this._To = PEPIdentity.ToFlatList(this._To);
Dean@398
  1052
Dean@398
  1053
            return;
Dean@398
  1054
        }
Dean@413
  1055
Dean@384
  1056
    }
Dean@384
  1057
}