protected override void VisitTnefPart(TnefPart entity) { // extract any attachments in the MS-TNEF part foreach (var attachment in entity.ExtractAttachments()) { handleAttachment(attachment, null); } }
static void TestTnefParser(string path, TnefComplianceStatus expected = TnefComplianceStatus.Compliant) { var message = ParseTnefMessage(path + ".tnef", expected); var names = File.ReadAllLines(path + ".list"); foreach (var name in names) { bool found = false; foreach (var part in message.BodyParts.OfType <MimePart> ()) { if (part.FileName == name) { found = true; break; } } if (!found) { Assert.Fail("Failed to locate attachment: {0}", name); } } // now use TnefPart to do the same thing using (var content = File.OpenRead(path + ".tnef")) { var tnef = new TnefPart { Content = new MimeContent(content) }; var attachments = tnef.ExtractAttachments().ToList(); foreach (var name in names) { bool found = false; foreach (var part in attachments.OfType <MimePart> ()) { if (part.FileName == name) { found = true; break; } } if (!found) { Assert.Fail("Failed to locate attachment in TnefPart: {0}", name); } } } }
static void ExtractAttachments(TnefReader reader, BodyBuilder builder) { var attachMethod = TnefAttachMethod.ByValue; var filter = new BestEncodingFilter(); var prop = reader.TnefPropertyReader; MimePart attachment = null; int outIndex, outLength; TnefAttachFlags flags; string[] mimeType; byte[] attachData; DateTime time; string text; //Console.WriteLine ("Extracting attachments..."); do { if (reader.AttributeLevel != TnefAttributeLevel.Attachment) { Assert.Fail("Expected attachment attribute level: {0}", reader.AttributeLevel); } switch (reader.AttributeTag) { case TnefAttributeTag.AttachRenderData: //Console.WriteLine ("Attachment Attribute: {0}", reader.AttributeTag); attachMethod = TnefAttachMethod.ByValue; attachment = new MimePart(); break; case TnefAttributeTag.Attachment: //Console.WriteLine ("Attachment Attribute: {0}", reader.AttributeTag); if (attachment == null) { break; } while (prop.ReadNextProperty()) { switch (prop.PropertyTag.Id) { case TnefPropertyId.AttachLongFilename: attachment.FileName = prop.ReadValueAsString(); //Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, attachment.FileName); break; case TnefPropertyId.AttachFilename: if (attachment.FileName == null) { attachment.FileName = prop.ReadValueAsString(); //Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, attachment.FileName); } else { //Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, prop.ReadValueAsString ()); } break; case TnefPropertyId.AttachContentLocation: text = prop.ReadValueAsString(); if (Uri.IsWellFormedUriString(text, UriKind.Absolute)) { attachment.ContentLocation = new Uri(text, UriKind.Absolute); } else if (Uri.IsWellFormedUriString(text, UriKind.Relative)) { attachment.ContentLocation = new Uri(text, UriKind.Relative); } //Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, text); break; case TnefPropertyId.AttachContentBase: text = prop.ReadValueAsString(); attachment.ContentBase = new Uri(text, UriKind.Absolute); //Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, text); break; case TnefPropertyId.AttachContentId: attachment.ContentId = prop.ReadValueAsString(); //Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, attachment.ContentId); break; case TnefPropertyId.AttachDisposition: text = prop.ReadValueAsString(); if (attachment.ContentDisposition == null) { attachment.ContentDisposition = new ContentDisposition(text); } else { attachment.ContentDisposition.Disposition = text; } //Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, text); break; case TnefPropertyId.AttachMethod: attachMethod = (TnefAttachMethod)prop.ReadValueAsInt32(); //Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, attachMethod); break; case TnefPropertyId.AttachMimeTag: text = prop.ReadValueAsString(); mimeType = text.Split('/'); if (mimeType.Length == 2) { attachment.ContentType.MediaType = mimeType[0].Trim(); attachment.ContentType.MediaSubtype = mimeType[1].Trim(); } //Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, text); break; case TnefPropertyId.AttachFlags: flags = (TnefAttachFlags)prop.ReadValueAsInt32(); if ((flags & TnefAttachFlags.RenderedInBody) != 0) { if (attachment.ContentDisposition == null) { attachment.ContentDisposition = new ContentDisposition(ContentDisposition.Inline); } else { attachment.ContentDisposition.Disposition = ContentDisposition.Inline; } } //Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, flags); break; case TnefPropertyId.AttachData: var stream = prop.GetRawValueReadStream(); var content = new MemoryStream(); var guid = new byte[16]; if (attachMethod == TnefAttachMethod.EmbeddedMessage) { var tnef = new TnefPart(); foreach (var param in attachment.ContentType.Parameters) { tnef.ContentType.Parameters[param.Name] = param.Value; } if (attachment.ContentDisposition != null) { tnef.ContentDisposition = attachment.ContentDisposition; } attachment = tnef; } stream.Read(guid, 0, 16); stream.CopyTo(content, 4096); var buffer = content.GetBuffer(); filter.Flush(buffer, 0, (int)content.Length, out outIndex, out outLength); attachment.ContentTransferEncoding = filter.GetBestEncoding(EncodingConstraint.SevenBit); attachment.Content = new MimeContent(content); filter.Reset(); //Console.WriteLine ("Attachment Property: {0} has GUID {1}", prop.PropertyTag.Id, new Guid (guid)); builder.Attachments.Add(attachment); break; case TnefPropertyId.DisplayName: attachment.ContentType.Name = prop.ReadValueAsString(); //Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, attachment.ContentType.Name); break; case TnefPropertyId.AttachSize: if (attachment.ContentDisposition == null) { attachment.ContentDisposition = new ContentDisposition(); } attachment.ContentDisposition.Size = prop.ReadValueAsInt64(); //Console.WriteLine ("Attachment Property: {0} = {1}", prop.PropertyTag.Id, attachment.ContentDisposition.Size.Value); break; default: //Console.WriteLine ("Attachment Property (unhandled): {0} = {1}", prop.PropertyTag.Id, prop.ReadValue ()); break; } } break; case TnefAttributeTag.AttachData: //Console.WriteLine ("Attachment Attribute: {0}", reader.AttributeTag); if (attachment == null || attachMethod != TnefAttachMethod.ByValue) { break; } attachData = prop.ReadValueAsBytes(); filter.Flush(attachData, 0, attachData.Length, out outIndex, out outLength); attachment.ContentTransferEncoding = filter.GetBestEncoding(EncodingConstraint.SevenBit); attachment.Content = new MimeContent(new MemoryStream(attachData, false)); filter.Reset(); builder.Attachments.Add(attachment); break; case TnefAttributeTag.AttachCreateDate: time = prop.ReadValueAsDateTime(); if (attachment != null) { if (attachment.ContentDisposition == null) { attachment.ContentDisposition = new ContentDisposition(); } attachment.ContentDisposition.CreationDate = time; } //Console.WriteLine ("Attachment Attribute: {0} = {1}", reader.AttributeTag, time); break; case TnefAttributeTag.AttachModifyDate: time = prop.ReadValueAsDateTime(); if (attachment != null) { if (attachment.ContentDisposition == null) { attachment.ContentDisposition = new ContentDisposition(); } attachment.ContentDisposition.ModificationDate = time; } //Console.WriteLine ("Attachment Attribute: {0} = {1}", reader.AttributeTag, time); break; case TnefAttributeTag.AttachTitle: text = prop.ReadValueAsString(); if (attachment != null && string.IsNullOrEmpty(attachment.FileName)) { attachment.FileName = text; } //Console.WriteLine ("Attachment Attribute: {0} = {1}", reader.AttributeTag, text); break; //case TnefAttributeTag.AttachMetaFile: // break; default: var type = prop.ValueType; var value = prop.ReadValue(); //Console.WriteLine ("Attachment Attribute (unhandled): {0} = {1}", reader.AttributeTag, value); Assert.AreEqual(type, value.GetType(), "Unexpected value type for {0}: {1}", reader.AttributeTag, value.GetType().Name); break; } } while (reader.ReadNextAttribute()); }
/// <summary> /// Visit the Microsoft TNEF MIME part entity. /// </summary> /// <remarks> /// Visits the Microsoft TNEF MIME part entity. /// </remarks> /// <example> /// <code language="c#" source="Examples\MimeVisitorExamples.cs" region="HtmlPreviewVisitor" /> /// </example> /// <param name="entity">The Microsoft TNEF MIME part entity.</param> protected internal virtual void VisitTnefPart(TnefPart entity) { VisitMimePart(entity); }
protected override void VisitTnefPart(TnefPart entity) { // extract any attachments in the MS-TNEF part attachments.AddRange(entity.ExtractAttachments()); }
protected internal override void VisitTnefPart(TnefPart entity) { TnefPart++; base.VisitTnefPart(entity); }
static void TestTnefParser(string path, TnefComplianceStatus expected = TnefComplianceStatus.Compliant) { var message = ParseTnefMessage(path + ".tnef", expected); var tnefName = Path.GetFileName(path + ".tnef"); var names = File.ReadAllLines(path + ".list"); foreach (var name in names) { bool found = false; foreach (var part in message.BodyParts.OfType <MimePart> ()) { if (part.FileName == name) { found = true; break; } } if (!found) { Assert.Fail("Failed to locate attachment: {0}", name); } } // now use TnefPart to do the same thing using (var content = File.OpenRead(path + ".tnef")) { var tnef = new TnefPart { Content = new MimeContent(content) }; var attachments = tnef.ExtractAttachments().ToList(); // Step 1: make sure we've extracted the body and all of the attachments foreach (var name in names) { bool found = false; foreach (var part in attachments.OfType <MimePart> ()) { if (part is TextPart && string.IsNullOrEmpty(part.FileName)) { var basename = Path.GetFileNameWithoutExtension(name); var extension = Path.GetExtension(name); string subtype; switch (extension) { case ".html": subtype = "html"; break; case ".rtf": subtype = "rtf"; break; default: subtype = "plain"; break; } if (basename == "body" && part.ContentType.IsMimeType("text", subtype)) { found = true; break; } } else if (part.FileName == name) { found = true; break; } } if (!found) { Assert.Fail("Failed to locate attachment in TnefPart: {0}", name); } } // Step 2: verify that the content of the extracted attachments matches up with the expected content int untitled = 1; foreach (var part in attachments.OfType <MimePart> ()) { var isText = false; string fileName; if (part is TextPart text && string.IsNullOrEmpty(part.FileName)) { if (text.IsHtml) { fileName = "message.html"; } else if (text.IsRichText) { fileName = "message.rtf"; } else { fileName = "message.txt"; } isText = true; }