Example #1
0
        private bool PostAttachments(Account account, EcsConfiguration configuration,
            string encryptKey, string recips, ref List<string> pointers)
        {
            var source = CLASS_NAME + "PostAttachments";
            try
            {
                //get the bytes for the placeholder text
                var placeholder = Encoding.UTF8.GetBytes(Resources.placeholder_text);
                SafeMailItem safMail;
                try
                {
                    safMail = RedemptionLoader.new_SafeMailItem();
                }
                catch (Exception ex)
                {
                    Logger.Error("", String.Format(
                        "unable to work with attachments for {0}, failed to instantiate SafeMailItem: {1}",
                        MailItem.Subject, ex.Message));
                    return false;
                }
                //need to save the item first before we can work with the SafeMailItem
                MailItem.Save();
                safMail.Item = MailItem;
                var colAttach = safMail.Attachments;
                /* Outlook will move any embedded images to the head of the attachments table
                * if that's the case then we need to remove and re-add the other attachments
                * so that the pointer list will match the finished order
                */
                var hidden = false;
                string contentId;
                var savedAttach = new Dictionary<int, byte[]>();
                //do we have any embedded images?
                foreach (Redemption.Attachment rdoAttach in colAttach)
                {
                    Utils.GetAttachProps(rdoAttach, out contentId, out hidden);
                    if (hidden) break;
                }
                if (hidden)
                {
                    //walk through in reverse order
                    //delete and reattach each non-hidden attachment
                    for (var i = colAttach.Count; i > 0; i--)
                    {
                        Redemption.Attachment rdoAttach = colAttach[i];
                        Utils.GetAttachProps(rdoAttach, out contentId, out hidden);
                        if (hidden) continue;
                        if (rdoAttach.Type.Equals(5)) //embedded
                        {
                            var msg = rdoAttach.EmbeddedMsg;
                            rdoAttach.Delete();
                            colAttach.Add(msg, 5);
                        }
                        else
                        {
                            var path = Path.Combine(Path.GetTempPath(), "ChiaraMail", rdoAttach.FileName);
                            var displayName = rdoAttach.DisplayName;
                            if (File.Exists(path)) File.Delete(path);
                            rdoAttach.SaveAsFile(path);
                            rdoAttach.Delete();
                            rdoAttach = colAttach.Add(path, 1, Type.Missing, displayName);
                            //get the bytes and drop those in the dictionary, linked to the current index
                            savedAttach.Add(rdoAttach.Index, File.ReadAllBytes(path));
                            File.Delete(path);
                        }
                    }
                }

                //now loop through and collect the content (except for embedded messages)
                var attachList = new List<Attachment>();
                bool showForm = false;
                foreach (Redemption.Attachment rdoAttach in colAttach)
                {
                    var attach = new Attachment { Type = rdoAttach.Type };
                    switch (rdoAttach.Type)
                    {
                        case (int)OlAttachmentType.olEmbeddeditem:
                            //is this an ECS attachment?
                            var msg = rdoAttach.EmbeddedMsg;
                            if (Utils.HasChiaraHeader(msg))
                            {
                                ForwardEmbeddedECS(msg, recips, account);
                            }
                            //always add
                            attachList.Add(attach);
                            break;
                        case (int)OlAttachmentType.olByReference:
                        case (int)OlAttachmentType.olOLE:
                            attachList.Add(attach);
                            break;
                        case (int)OlAttachmentType.olByValue:
                            showForm = true;
                            //we may have already gotten the bytes
                            if (savedAttach.Count > 0 && savedAttach.ContainsKey(rdoAttach.Index))
                            {
                                attach.Content = savedAttach[rdoAttach.Index];
                            }
                            if (attach.Content == null || attach.Content.Length == 0)
                            {
                                //try just read the bytes from the binary property
                                //this could fail if the attachment is too big
                                try
                                {
                                    attach.Content = rdoAttach.AsArray != null
                                        ? rdoAttach.AsArray as byte[]
                                        : null;//.Fields[ThisAddIn.PR_ATTACH_DATA_BIN]);
                                }
                                catch
                                {
                                    attach.Content = null;
                                }
                            }
                            if (attach.Content == null)
                            {
                                //save to disk then get the bytes
                                var path = Path.Combine(Path.GetTempPath(), "ChiaraMail", rdoAttach.FileName);
                                if (File.Exists(path)) File.Delete(path);
                                rdoAttach.SaveAsFile(path);
                                attach.Content = File.ReadAllBytes(path);
                                File.Delete(path);
                            }
                            if (attach.Content != null)
                            {
                                attach.Index = rdoAttach.Index;
                                attach.Name = rdoAttach.DisplayName;
                                attachList.Add(attach);
                            }
                            else
                            {
                                Logger.Warning(source,
                                               "aborting: failed to retrieve content for " + rdoAttach.DisplayName);
                                MessageBox.Show(String.Format(
                                    "Unable to retrieve original content from {0}",
                                    rdoAttach.DisplayName), Resources.product_name,
                                                MessageBoxButtons.OK,
                                                MessageBoxIcon.Error);
                                return false;
                            }
                            break;
                    }
                }
                if (!showForm)
                {
                    pointers.AddRange(attachList.Select(attach => attach.Pointer));
                    return true;
                }
                //use the WaitForm to upload the attachments
                var win = new OutlookWin32Window(Inspector, Inspector.IsWordMail());
                var form = new WaitForm
                               {
                                   Attachments = attachList,
                                   Account = account,
                                   Configuration = configuration,
                                   Recips = recips,
                                   EncryptKey2 = encryptKey
                               };
                //use encryptKey2 for new post
                if (form.ShowDialog(win) == DialogResult.OK)
                {
                    //post succeeded for all attachments
                    //get the pointers
                    pointers.AddRange(form.Attachments.Select(attach => attach.Pointer));
                    //don't replace attachment bytes if we are sending content
                    if (NoPlaceholder) return true;
                    //loop back through to replace the original content with the placeholder bytes
                    foreach (Redemption.Attachment rdoAttach in colAttach)
                    {
                        if (rdoAttach.Type.Equals(1)) //OlAttachmentType.olByValue)
                        {
                            rdoAttach.Fields[ThisAddIn.PR_ATTACH_DATA_BIN] = placeholder;
                        }
                    }
                    return true;
                }
                //get the pointer list anyway so we can delete the items that got posted
                pointers.AddRange(form.Attachments
                                      .TakeWhile(attach => !String.IsNullOrEmpty(attach.Pointer))
                                      .Select(attach => attach.Pointer));
            }
            catch (Exception ex)
            {
                Logger.Error(source, ex.ToString());
            }
            return false;
        }
Example #2
0
        private void MailItemSend(ref bool cancel)
        {
            const string SOURCE = CLASS_NAME + "InlineMailItemSend";
            //kill the timer
            if (_timer != null) _timer.Dispose();
            //get path for a temp folder
            var tempFolder = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            try
            {
                if (!Dynamic) return;
                Win32.SetCursor(Cursors.WaitCursor.Handle);
                Logger.Verbose(SOURCE, String.Format(
                    "assembling ECS content for {0}", MailItem.Subject));
                //assemble comma-delimited list of recipient addresses
                var recipients = MailItem.Recipients;
                var recipList = (from Recipient recip in recipients
                                 select recip.AddressEntry.GetPrimarySMTP()).ToList();
                //post the content first
                var contentPointer = "";
                string error;
                var recips = String.Join(",", recipList);
                var pointers = new List<string>();
                //just post the body, not the full HTML
                var originalHTML = MailItem.HTMLBody;
                var rawContent = Utils.GetBody(originalHTML);
                var originalContent = rawContent;
                //SendUsingAccount
                if(string.IsNullOrEmpty(_sendUsingAddress))
                    SetSendUsing();
                Logger.Verbose(SOURCE,"attempting to retrieve account using " + _sendUsingAddress);
                var account = ThisAddIn.Accounts[_sendUsingAddress];
                Logger.Verbose(SOURCE, "retrieveing default configuration for " + account.UserName);
                var config = account.Configurations[account.DefaultConfiguration];
                var encryptKey = Encrypted
                                     ? Cryptography.GenerateKey()
                                     : "";
                var replaced = new List<int>();
                if (MailItem.BodyFormat == OlBodyFormat.olFormatHTML)
                {
                    //are there embedded images?
                    Logger.Verbose(SOURCE, "checking for embedded images");
                    if (Utils.HasEmbeddedImages(MailItem) && !NoPlaceholder)
                    {
                        Logger.Verbose(SOURCE,"found embedded images");
                        var embedded = Utils.GetEmbeddedImages(MailItem);
                        //replace the src link with the base64-encoded content
                        foreach (var attachment in embedded)
                        {
                            //build the replacement path

                            var data = Convert.ToBase64String(attachment.Content);
                            var imageType = Regex.Match(attachment.Name, @"\.(\S{3,4})").Groups[1].Value;
                            var src = string.Format("data:image/{0};base64,{1}",
                                imageType, data);
                            //replace the src path
                            var cidPath = "cid:" + attachment.ContentId;
                            while (rawContent.Contains(cidPath))
                                rawContent = rawContent.Replace(cidPath, src);
                            replaced.Add(attachment.Index);
                        }
                    }
                }

                //encode it (use JS compatible method for encryption)
                var content = ContentHandler.EncodeContent(rawContent, "", encryptKey);
                Logger.Verbose(SOURCE, "invoking PostContent");
                ContentHandler.PostContent(account.SMTPAddress, config,
                    content, recips, ref contentPointer, out error);
                if (String.IsNullOrEmpty(contentPointer))
                {
                    Logger.Warning(SOURCE, String.Format(
                        "unable to post content for {0}: {1}",
                        MailItem.Subject, error));
                    //we've got a problem - raise alert
                    MessageBox.Show(string.Format(Resources.error_storing_content,
                            Environment.NewLine,
                            error),
                        Resources.product_name,
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
                    //cancel the send
                    cancel = true;
                    return;
                }
                pointers.Add(contentPointer);
                //post each attachment and replace with stub
                if (replaced.Count > 0)
                    Utils.DeleteReplaced(MailItem, replaced);
                var attachments = MailItem.Attachments;
                if (attachments.Count > 0)
                {
                    var win = new OutlookWin32Window(_explorer, false);
                    Logger.Verbose(SOURCE,"invoking PostAttachments");
                    if (!Utils.PostAttachments(MailItem, account, config, encryptKey, recips,
                        ref pointers, win, NoPlaceholder))
                    {
                        Logger.Warning(SOURCE, String.Format(
                            "unable to post attachments for {0}",
                            MailItem.Subject));
                        //delete any pointers that we got
                        Utils.DeletePointers(pointers, account, config);
                        //cancel the send
                        cancel = true;
                        return;
                    }
                }
                if (!NoPlaceholder)
                {
                    //swap in placeholder to replace original body
                    MailItem.HTMLBody = MailItem.HTMLBody.Replace(
                        originalContent, Resources.placeholder_html);
                }
                //assign the headers
                Logger.Verbose(SOURCE,"calling Assign Headers");
                Utils.AssignHeaders(MailItem, account, pointers, encryptKey, Encrypted);

                Utils.UpdateAccountStorage(account);

                //change message class
                _mailItem.MessageClass = Resources.message_class_CM;
                //save changes
                _mailItem.Save();
                //Outlook handles the Send from here
            }
            catch (Exception ex)
            {
                Logger.Error(SOURCE, ex.ToString());
            }
            finally
            {
                if (Directory.Exists(tempFolder))
                {
                    //clear out the temp directory and files if they exist
                    Directory.Delete(tempFolder, true);
                }
                Win32.SetCursor(Cursors.Default.Handle);
            }
        }