static TnefPart PromoteToTnefPart(MimePart part) { var tnef = new TnefPart (); foreach (var param in part.ContentType.Parameters) tnef.ContentType.Parameters[param.Name] = param.Value; if (part.ContentDisposition != null) tnef.ContentDisposition = part.ContentDisposition; tnef.ContentTransferEncoding = part.ContentTransferEncoding; return tnef; }
/// <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()); }
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; string text; do { if (reader.AttributeLevel != TnefAttributeLevel.Attachment) { break; } switch (reader.AttributeTag) { case TnefAttributeTag.AttachRenderData: attachMethod = TnefAttachMethod.ByValue; attachment = new MimePart(); break; case TnefAttributeTag.Attachment: if (attachment == null) { break; } while (prop.ReadNextProperty()) { switch (prop.PropertyTag.Id) { case TnefPropertyId.AttachLongFilename: attachment.FileName = prop.ReadValueAsString(); break; case TnefPropertyId.AttachFilename: if (attachment.FileName == null) { attachment.FileName = 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); } break; case TnefPropertyId.AttachContentBase: text = prop.ReadValueAsString(); attachment.ContentBase = new Uri(text, UriKind.Absolute); break; case TnefPropertyId.AttachContentId: attachment.ContentId = prop.ReadValueAsString(); break; case TnefPropertyId.AttachDisposition: text = prop.ReadValueAsString(); if (attachment.ContentDisposition == null) { attachment.ContentDisposition = new ContentDisposition(text); } else { attachment.ContentDisposition.Disposition = text; } 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; } // read the GUID stream.Read(guid, 0, 16); // the rest is content using (var filtered = new FilteredStream(content)) { filtered.Add(filter); stream.CopyTo(filtered, 4096); filtered.Flush(); } content.Position = 0; attachment.ContentTransferEncoding = filter.GetBestEncoding(EncodingConstraint.SevenBit); attachment.Content = new MimeContent(content); filter.Reset(); builder.Attachments.Add(attachment); break; case TnefPropertyId.AttachMethod: attachMethod = (TnefAttachMethod)prop.ReadValueAsInt32(); break; case TnefPropertyId.AttachMimeTag: mimeType = prop.ReadValueAsString().Split('/'); if (mimeType.Length == 2) { attachment.ContentType.MediaType = mimeType[0].Trim(); attachment.ContentType.MediaSubtype = mimeType[1].Trim(); } 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; } } break; case TnefPropertyId.AttachSize: if (attachment.ContentDisposition == null) { attachment.ContentDisposition = new ContentDisposition(); } attachment.ContentDisposition.Size = prop.ReadValueAsInt64(); break; case TnefPropertyId.DisplayName: attachment.ContentType.Name = prop.ReadValueAsString(); break; } } break; case TnefAttributeTag.AttachCreateDate: if (attachment != null) { if (attachment.ContentDisposition == null) { attachment.ContentDisposition = new ContentDisposition(); } attachment.ContentDisposition.CreationDate = prop.ReadValueAsDateTime(); } break; case TnefAttributeTag.AttachModifyDate: if (attachment != null) { if (attachment.ContentDisposition == null) { attachment.ContentDisposition = new ContentDisposition(); } attachment.ContentDisposition.ModificationDate = prop.ReadValueAsDateTime(); } break; case TnefAttributeTag.AttachTitle: if (attachment != null && string.IsNullOrEmpty(attachment.FileName)) { attachment.FileName = prop.ReadValueAsString(); } break; case TnefAttributeTag.AttachMetaFile: if (attachment == null) { break; } // TODO: what to do with the meta data? break; case TnefAttributeTag.AttachData: 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.EightBit); attachment.Content = new MimeContent(new MemoryStream(attachData, false)); filter.Reset(); builder.Attachments.Add(attachment); break; } } while (reader.ReadNextAttribute()); }
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; string text; do { if (reader.AttributeLevel != TnefAttributeLevel.Attachment) { break; } switch (reader.AttributeTag) { case TnefAttributeTag.AttachRenderData: attachMethod = TnefAttachMethod.ByValue; attachment = new MimePart(); break; case TnefAttributeTag.Attachment: if (attachment == null) { break; } while (prop.ReadNextProperty()) { switch (prop.PropertyTag.Id) { case TnefPropertyId.AttachLongFilename: attachment.FileName = prop.ReadValueAsString(); break; case TnefPropertyId.AttachFilename: if (attachment.FileName == null) { attachment.FileName = prop.ReadValueAsString(); } break; case TnefPropertyId.AttachContentLocation: attachment.ContentLocation = prop.ReadValueAsUri(); break; case TnefPropertyId.AttachContentBase: attachment.ContentBase = prop.ReadValueAsUri(); break; case TnefPropertyId.AttachContentId: text = prop.ReadValueAsString(); var buffer = CharsetUtils.UTF8.GetBytes(text); int index = 0; if (ParseUtils.TryParseMsgId(buffer, ref index, buffer.Length, false, false, out string msgid)) { attachment.ContentId = msgid; } break; case TnefPropertyId.AttachDisposition: text = prop.ReadValueAsString(); if (ContentDisposition.TryParse(text, out ContentDisposition disposition)) { attachment.ContentDisposition = disposition; } break; case TnefPropertyId.AttachData: 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; } 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 TnefPropertyId.AttachMethod: attachMethod = (TnefAttachMethod)prop.ReadValueAsInt32(); break; case TnefPropertyId.AttachMimeTag: mimeType = prop.ReadValueAsString().Split('/'); if (mimeType.Length == 2) { attachment.ContentType.MediaType = mimeType[0].Trim(); attachment.ContentType.MediaSubtype = mimeType[1].Trim(); } 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; } } break; case TnefPropertyId.AttachSize: if (attachment.ContentDisposition == null) { attachment.ContentDisposition = new ContentDisposition(); } attachment.ContentDisposition.Size = prop.ReadValueAsInt64(); break; case TnefPropertyId.DisplayName: attachment.ContentType.Name = prop.ReadValueAsString(); break; } } break; case TnefAttributeTag.AttachCreateDate: if (attachment != null) { if (attachment.ContentDisposition == null) { attachment.ContentDisposition = new ContentDisposition(); } attachment.ContentDisposition.CreationDate = prop.ReadValueAsDateTime(); } break; case TnefAttributeTag.AttachModifyDate: if (attachment != null) { if (attachment.ContentDisposition == null) { attachment.ContentDisposition = new ContentDisposition(); } attachment.ContentDisposition.ModificationDate = prop.ReadValueAsDateTime(); } break; case TnefAttributeTag.AttachTitle: if (attachment != null && string.IsNullOrEmpty(attachment.FileName)) { attachment.FileName = prop.ReadValueAsString(); } break; case TnefAttributeTag.AttachMetaFile: if (attachment == null) { break; } // TODO: what to do with the meta data? break; case TnefAttributeTag.AttachData: 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; } } while (reader.ReadNextAttribute()); }
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 { ContentObject = new ContentObject (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.ContentObject = new ContentObject (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.ContentObject = new ContentObject (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; default: Console.WriteLine ("Attachment Attribute (unhandled): {0} = {1}", reader.AttributeTag, prop.ReadValue ()); break; } } while (reader.ReadNextAttribute ()); }
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; string text; do { if (reader.AttributeLevel != TnefAttributeLevel.Attachment) break; switch (reader.AttributeTag) { case TnefAttributeTag.AttachRenderData: attachMethod = TnefAttachMethod.ByValue; attachment = new MimePart (); break; case TnefAttributeTag.Attachment: if (attachment == null) break; while (prop.ReadNextProperty ()) { switch (prop.PropertyTag.Id) { case TnefPropertyId.AttachLongFilename: attachment.FileName = prop.ReadValueAsString (); break; case TnefPropertyId.AttachFilename: if (attachment.FileName == null) attachment.FileName = 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); break; case TnefPropertyId.AttachContentBase: text = prop.ReadValueAsString (); attachment.ContentBase = new Uri (text, UriKind.Absolute); break; case TnefPropertyId.AttachContentId: attachment.ContentId = prop.ReadValueAsString (); break; case TnefPropertyId.AttachDisposition: text = prop.ReadValueAsString (); if (attachment.ContentDisposition == null) attachment.ContentDisposition = new ContentDisposition (text); else attachment.ContentDisposition.Disposition = text; 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; } // read the GUID stream.Read (guid, 0, 16); // the rest is content using (var filtered = new FilteredStream (content)) { filtered.Add (filter); stream.CopyTo (filtered, 4096); filtered.Flush (); } content.Position = 0; attachment.ContentTransferEncoding = filter.GetBestEncoding (EncodingConstraint.SevenBit); attachment.ContentObject = new ContentObject (content); filter.Reset (); builder.Attachments.Add (attachment); break; case TnefPropertyId.AttachMethod: attachMethod = (TnefAttachMethod) prop.ReadValueAsInt32 (); break; case TnefPropertyId.AttachMimeTag: mimeType = prop.ReadValueAsString ().Split ('/'); if (mimeType.Length == 2) { attachment.ContentType.MediaType = mimeType[0].Trim (); attachment.ContentType.MediaSubtype = mimeType[1].Trim (); } 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; } break; case TnefPropertyId.AttachSize: if (attachment.ContentDisposition == null) attachment.ContentDisposition = new ContentDisposition (); attachment.ContentDisposition.Size = prop.ReadValueAsInt64 (); break; case TnefPropertyId.DisplayName: attachment.ContentType.Name = prop.ReadValueAsString (); break; } } break; case TnefAttributeTag.AttachCreateDate: if (attachment != null) { if (attachment.ContentDisposition == null) attachment.ContentDisposition = new ContentDisposition (); attachment.ContentDisposition.CreationDate = prop.ReadValueAsDateTime (); } break; case TnefAttributeTag.AttachModifyDate: if (attachment != null) { if (attachment.ContentDisposition == null) attachment.ContentDisposition = new ContentDisposition (); attachment.ContentDisposition.ModificationDate = prop.ReadValueAsDateTime (); } break; case TnefAttributeTag.AttachTitle: if (attachment != null && string.IsNullOrEmpty (attachment.FileName)) attachment.FileName = prop.ReadValueAsString (); break; case TnefAttributeTag.AttachMetaFile: if (attachment == null) break; // TODO: what to do with the meta data? break; case TnefAttributeTag.AttachData: 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.EightBit); attachment.ContentObject = new ContentObject (new MemoryStream (attachData, false)); filter.Reset (); builder.Attachments.Add (attachment); break; } } while (reader.ReadNextAttribute ()); }
private void ExtractAttachments(TnefReader reader, BodyBuilder builder) { var tnefAttachMethod = TnefAttachMethod.ByValue; var bestEncodingFilter = new BestEncodingFilter(); var tnefPropertyReader = reader.TnefPropertyReader; MimePart mimePart = null; do { int outputIndex; int outputLength; switch (reader.AttributeTag) { case TnefAttributeTag.AttachData: if (mimePart != null && tnefAttachMethod == TnefAttachMethod.ByValue) { byte[] numArray = tnefPropertyReader.ReadValueAsBytes(); bestEncodingFilter.Flush(numArray, 0, numArray.Length, out outputIndex, out outputLength); mimePart.ContentTransferEncoding = bestEncodingFilter.GetBestEncoding(EncodingConstraint.SevenBit, 78); mimePart.ContentObject = new ContentObject(new MemoryStream(numArray, false), ContentEncoding.Default); bestEncodingFilter.Reset(); builder.Attachments.Add(mimePart); break; } break; case TnefAttributeTag.AttachRenderData: tnefAttachMethod = TnefAttachMethod.ByValue; mimePart = new MimePart(); break; case TnefAttributeTag.Attachment: if (mimePart != null) { while (tnefPropertyReader.ReadNextProperty()) { switch (tnefPropertyReader.PropertyTag.Id) { case TnefPropertyId.AttachData: using (var rawValueReadStream = tnefPropertyReader.GetRawValueReadStream()) { using (var memoryStream = new MemoryStream()) { byte[] buffer = new byte[16]; if (tnefAttachMethod == TnefAttachMethod.EmbeddedMessage) { TnefPart tnefPart = new TnefPart(); foreach (Parameter parameter in mimePart.ContentType.Parameters) { tnefPart.ContentType.Parameters[parameter.Name] = parameter.Value; } if (mimePart.ContentDisposition != null) { tnefPart.ContentDisposition = mimePart.ContentDisposition; } mimePart = tnefPart; } rawValueReadStream.Read(buffer, 0, 16); rawValueReadStream.CopyTo(memoryStream, 4096); byte[] input = memoryStream.ToArray(); bestEncodingFilter.Flush(input, 0, (int)memoryStream.Length, out outputIndex, out outputLength); mimePart.ContentTransferEncoding = bestEncodingFilter.GetBestEncoding(EncodingConstraint.SevenBit, 78); mimePart.ContentObject = new ContentObject(memoryStream, ContentEncoding.Default); bestEncodingFilter.Reset(); builder.Attachments.Add(mimePart); } } continue; case TnefPropertyId.AttachFilename: if (String.IsNullOrEmpty(mimePart.FileName)) { mimePart.FileName = tnefPropertyReader.ReadValueAsString(); continue; } continue; case TnefPropertyId.AttachMethod: tnefAttachMethod = (TnefAttachMethod)tnefPropertyReader.ReadValueAsInt32(); continue; case TnefPropertyId.AttachLongFilename: mimePart.FileName = tnefPropertyReader.ReadValueAsString(); continue; case TnefPropertyId.AttachMimeTag: string[] strArray = tnefPropertyReader.ReadValueAsString().Split('/'); if (strArray.Length == 2) { mimePart.ContentType.MediaType = strArray[0].Trim(); mimePart.ContentType.MediaSubtype = strArray[1].Trim(); continue; } continue; case TnefPropertyId.AttachContentBase: var uriString = tnefPropertyReader.ReadValueAsString(); mimePart.ContentBase = new Uri(uriString, UriKind.Absolute); continue; case TnefPropertyId.AttachContentId: mimePart.ContentId = tnefPropertyReader.ReadValueAsString(); continue; case TnefPropertyId.AttachContentLocation: var uriString2 = tnefPropertyReader.ReadValueAsString(); if (Uri.IsWellFormedUriString(uriString2, UriKind.Absolute)) { mimePart.ContentLocation = new Uri(uriString2, UriKind.Absolute); continue; } if (Uri.IsWellFormedUriString(uriString2, UriKind.Relative)) { mimePart.ContentLocation = new Uri(uriString2, UriKind.Relative); continue; } continue; case TnefPropertyId.AttachFlags: if ((tnefPropertyReader.ReadValueAsInt32() & 4) != 0) { if (mimePart.ContentDisposition == null) { mimePart.ContentDisposition = new ContentDisposition("inline"); continue; } mimePart.ContentDisposition.Disposition = "inline"; continue; } continue; case TnefPropertyId.AttachDisposition: var disposition = tnefPropertyReader.ReadValueAsString(); if (mimePart.ContentDisposition == null) { mimePart.ContentDisposition = new ContentDisposition(disposition); continue; } mimePart.ContentDisposition.Disposition = disposition; continue; case TnefPropertyId.AttachSize: if (mimePart.ContentDisposition == null) { mimePart.ContentDisposition = new ContentDisposition(); } mimePart.ContentDisposition.Size = new long?(tnefPropertyReader.ReadValueAsInt64()); continue; case TnefPropertyId.DisplayName: mimePart.ContentType.Name = tnefPropertyReader.ReadValueAsString(); continue; default: continue; } } break; } break; case TnefAttributeTag.AttachTitle: var name = tnefPropertyReader.ReadValueAsString(); if (mimePart != null && String.IsNullOrEmpty(mimePart.FileName)) { mimePart.FileName = name; break; } break; case TnefAttributeTag.AttachCreateDate: var creationDateTime = tnefPropertyReader.ReadValueAsDateTime(); if (mimePart != null) { if (mimePart.ContentDisposition == null) { mimePart.ContentDisposition = new ContentDisposition(); } mimePart.ContentDisposition.CreationDate = new DateTimeOffset(creationDateTime); break; } break; case TnefAttributeTag.AttachModifyDate: var modifyDateTime = tnefPropertyReader.ReadValueAsDateTime(); if (mimePart != null) { if (mimePart.ContentDisposition == null) { mimePart.ContentDisposition = new ContentDisposition(); } mimePart.ContentDisposition.ModificationDate = new DateTimeOffset(modifyDateTime); break; } break; } } while (reader.ReadNextAttribute()); }
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; byte[] attachData; string text; do { if (reader.AttributeLevel != TnefAttributeLevel.Attachment) { break; } switch (reader.AttributeTag) { case TnefAttributeTag.AttachRenderData: attachMethod = TnefAttachMethod.ByValue; attachment = new MimePart(); break; case TnefAttributeTag.Attachment: if (attachment == null) { break; } while (prop.ReadNextProperty()) { switch (prop.PropertyTag.Id) { case TnefPropertyId.AttachLongFilename: attachment.FileName = prop.ReadValueAsString(); break; case TnefPropertyId.AttachFilename: if (attachment.FileName == null) { attachment.FileName = 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); } break; case TnefPropertyId.AttachContentBase: text = prop.ReadValueAsString(); attachment.ContentBase = new Uri(text, UriKind.Absolute); break; case TnefPropertyId.AttachContentId: attachment.ContentId = prop.ReadValueAsString(); break; case TnefPropertyId.AttachDisposition: text = prop.ReadValueAsString(); if (attachment.ContentDisposition == null) { attachment.ContentDisposition = new ContentDisposition(text); } else { attachment.ContentDisposition.Disposition = text; } 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.Add(param.Name, param.Value); } if (attachment.ContentDisposition != null) { tnef.ContentDisposition = attachment.ContentDisposition; } attachment = tnef; } // read the GUID stream.Read(guid, 0, 16); // the rest is content stream.CopyTo(content, 4096); #if !PORTABLE var buffer = content.GetBuffer(); #else var buffer = content.ToArray(); #endif filter.Flush(buffer, 0, (int)content.Length, out outIndex, out outLength); attachment.ContentTransferEncoding = filter.GetBestEncoding(EncodingConstraint.SevenBit); attachment.ContentObject = new ContentObject(content); filter.Reset(); builder.Attachments.Add(attachment); break; case TnefPropertyId.AttachMethod: attachMethod = (TnefAttachMethod)prop.ReadValueAsInt32(); break; case TnefPropertyId.AttachSize: if (attachment.ContentDisposition == null) { attachment.ContentDisposition = new ContentDisposition(); } attachment.ContentDisposition.Size = prop.ReadValueAsInt64(); break; case TnefPropertyId.DisplayName: attachment.ContentType.Name = prop.ReadValueAsString(); break; } } break; case TnefAttributeTag.AttachCreateDate: if (attachment != null) { if (attachment.ContentDisposition == null) { attachment.ContentDisposition = new ContentDisposition(); } attachment.ContentDisposition.CreationDate = prop.ReadValueAsDateTime(); } break; case TnefAttributeTag.AttachModifyDate: if (attachment != null) { if (attachment.ContentDisposition == null) { attachment.ContentDisposition = new ContentDisposition(); } attachment.ContentDisposition.ModificationDate = prop.ReadValueAsDateTime(); } break; case TnefAttributeTag.AttachTitle: if (attachment != null && string.IsNullOrEmpty(attachment.FileName)) { attachment.FileName = prop.ReadValueAsString(); } break; case TnefAttributeTag.AttachMetaFile: if (attachment == null) { break; } // TODO: what to do with the meta data? break; case TnefAttributeTag.AttachData: 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.EightBit); attachment.ContentObject = new ContentObject(new MemoryStream(attachData, false)); filter.Reset(); builder.Attachments.Add(attachment); break; } } while (reader.ReadNextAttribute()); }