public static bool PostAttachments(Outlook.MailItem item, Account account, EcsConfiguration configuration, string encryptKey, string recips, ref List<string> pointers, OutlookWin32Window win, bool noPlaceholder) { const string 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(SOURCE, String.Format( "unable to work with attachments for {0}, failed to instantiate SafeMailItem: {1}", item.Subject, ex.Message)); return false; } //need to save the item first before we can work with the SafeMailItem item.Save(); safMail.Item = item; 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) { 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]; 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)Outlook.OlAttachmentType.olEmbeddeditem: //is this an ECS attachment? var msg = rdoAttach.EmbeddedMsg; if (HasChiaraHeader(msg)) { ForwardEmbeddedECS(msg, recips, account); } //always add attachList.Add(attach); break; case (int)Outlook.OlAttachmentType.olByReference: case (int)Outlook.OlAttachmentType.olOLE: attachList.Add(attach); break; case (int)Outlook.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 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; }
private List<Attachment> FetchParentAttachContent(MailItem parent, IList<string> pointers, string key, Account account, EcsConfiguration configuration, string senderAddress, string serverName, string serverPort, string encryptKey, string encryptKey2) { const string SOURCE = CLASS_NAME + "FetchParentAttachContent"; var attachList = new List<Attachment>(); try { var attachments = parent.Attachments; if (pointers.Count > 1 && attachments.Count > 0) { //we need the dynamic content for each attachment var parentPath = Path.Combine(Path.GetTempPath(), "ChiaraMail", key); MAPIUtils mapiUtils; try { mapiUtils = RedemptionLoader.new_MAPIUtils(); } catch (Exception ex) { Logger.Warning(SOURCE, string.Format( "unable to fetch ECS-enabled content for attachments on {0} - error loading MAPIUtils: {1}", parent.Subject, ex.Message)); return null; } for (var i = 1; i < attachments.Count + 1; i++) { var attach = attachments[i]; var cmAttach = new Attachment { Index = i, Pointer = pointers[i], Name = attach.DisplayName, Type = (int)attach.Type }; //only check ByValue - embedded message isn't stored on server if (attach.Type == OlAttachmentType.olByValue) { //check for content-id on hidden attachment var contentId = string.Empty; try { var prop = mapiUtils.HrGetOneProp(attach, (int) MAPITags.PR_ATTACHMENT_HIDDEN); if (prop != null && Convert.ToBoolean(prop)) { prop = mapiUtils.HrGetOneProp(attach, PR_ATTACH_CONTENT_ID); if (prop != null) contentId = Convert.ToString(prop); } } catch { contentId = ""; } string attachPath; if (!string.IsNullOrEmpty(contentId)) { attachPath = Path.Combine(parentPath, contentId); cmAttach.ContentId = contentId; } else { attachPath = Path.Combine(parentPath, Convert.ToString(i), attach.DisplayName); } if (File.Exists(attachPath)) { //load the bytes cmAttach.Content = File.ReadAllBytes(attachPath); } else { //fetch it string error; string content; ContentHandler.FetchContent(account.SMTPAddress, configuration, senderAddress, pointers[i], serverName, serverPort, true, out content, out error); if (!string.IsNullOrEmpty(error) && !error.Equals("Success",StringComparison.CurrentCultureIgnoreCase)) { Logger.Warning(SOURCE, string.Format( "failed to retrieve content for attachment {0} on item from sender {1}", i, senderAddress)); continue; } cmAttach.Content = ContentHandler.GetAttachBytes( content, encryptKey, encryptKey2); } } attachList.Add(cmAttach); } } } catch (Exception ex) { Logger.Error(SOURCE, ex.ToString()); } return attachList; }
internal static void LoadAttachments(Outlook.MailItem item, string[] pointers,string baseUrl, Account account, string senderAddress, string serverName, string serverPort, string encryptKey, string encryptKey2, List<string> EmbeddedFileNames, ref Dictionary<string,Attachment> attachList, ref Dictionary<string, Redemption.Attachment> embedded, ref Panel panelAttach, ref int upperWidth, ref int upperHeight) { const string SOURCE = CLASS_NAME + "LoadAttachments"; SafeMailItem safMail; try { safMail = RedemptionLoader.new_SafeMailItem(); } catch (Exception ex) { Logger.Warning(SOURCE,string.Format( "unable to load attachments for {0}, error instantiating SafeMailItem: {1}", item.Subject,ex.Message)); return; } safMail.Item = item; var safAttachments = safMail.Attachments; var index = 0; foreach (Redemption.Attachment safAttach in safAttachments) { index++; var attach = new Attachment { Index = index, Name = safAttach.DisplayName }; if (EmbeddedFileNames.Contains(safAttach.DisplayName)) continue; var btn = new AttachPanel { Caption = safAttach.DisplayName }; switch (safAttach.Type) { case 1: //byvalue if (string.IsNullOrEmpty(pointers[index])) continue; //is it hidden or have contentId string contentId; bool hidden; GetAttachProps(safAttach, out contentId, out hidden); if (hidden) { continue; } attach.Pointer = pointers[index]; //get the image var container = ShellIcons.GetIconForFile( attach.Name, true, false); btn.Picture = container.Icon.ToBitmap(); btn.Pointer = attach.Pointer; attachList.Add(attach.Pointer, attach); break; case 5: //embedded - will have null/0 pointer btn.Pointer = "embedded:" + index.ToString(CultureInfo.InvariantCulture); embedded.Add(btn.Pointer, safAttach); //use default envelope picture for button break; } panelAttach.Controls.Add(btn); if (btn.Width > upperWidth) upperWidth = btn.Width; if (btn.Height > upperHeight) upperHeight = btn.Height; } }