public void TestInvalidOemCodepageLoose() { using (var stream = new MemoryStream()) { stream.Write(BitConverter.GetBytes(0x223e9f78), 0, 4); stream.WriteByte(0); stream.WriteByte(0); stream.WriteByte((byte)TnefAttributeLevel.Message); stream.Write(BitConverter.GetBytes((int)TnefAttributeTag.OemCodepage), 0, 4); stream.Write(BitConverter.GetBytes(4), 0, 4); stream.Write(BitConverter.GetBytes(1), 0, 4); stream.Position = 0; using (var reader = new TnefReader(stream, 0, TnefComplianceMode.Loose)) { Assert.IsTrue(reader.ReadNextAttribute(), "ReadNextAttribute"); Assert.AreEqual(TnefAttributeTag.OemCodepage, reader.AttributeTag, "AttributeTag"); Assert.AreEqual(TnefComplianceStatus.InvalidMessageCodepage, reader.ComplianceStatus); } } }
public void TestReadSingle() { using (var stream = new MemoryStream()) { var signature = BitConverter.GetBytes(0x223e9f78); stream.Write(signature, 0, signature.Length); stream.WriteByte(0); stream.WriteByte(0); var buffer = BitConverter.GetBytes((float)1024.1024); stream.Write(buffer, 0, buffer.Length); stream.Position = 0; using (var reader = new TnefReader(stream, 0, TnefComplianceMode.Loose)) { var value = reader.ReadSingle(); Assert.AreEqual((float)1024.1024, value); } } }
public void TestInvalidSignatureStrict() { using (var stream = new MemoryStream()) { var invalidSignature = BitConverter.GetBytes(0x223e9f79); TnefReader reader; stream.Write(invalidSignature, 0, invalidSignature.Length); stream.WriteByte(0); stream.WriteByte(0); stream.Position = 0; try { reader = new TnefReader(stream, 0, TnefComplianceMode.Strict); Assert.Fail("new TnefReader should have thrown TnefException"); } catch (TnefException ex) { Assert.AreEqual(TnefComplianceStatus.InvalidTnefSignature, ex.Error, "Error"); } catch (Exception ex) { Assert.Fail("new TnefReader should have thrown TnefException, not {0}", ex); } } }
public void TestSeekTruncatedLoose() { using (var stream = new MemoryStream()) { stream.Write(BitConverter.GetBytes(0x223e9f78), 0, 4); stream.WriteByte(0); stream.WriteByte(0); stream.WriteByte((byte)TnefAttributeLevel.Message); stream.Write(BitConverter.GetBytes((int)TnefAttributeTag.TnefVersion), 0, 4); stream.Write(BitConverter.GetBytes(4), 0, 4); stream.Write(BitConverter.GetBytes(65536), 0, 4); stream.WriteByte((byte)TnefAttributeLevel.Message); stream.Write(BitConverter.GetBytes((int)TnefAttributeTag.OemCodepage), 0, 4); stream.Write(BitConverter.GetBytes(4), 0, 4); stream.Write(BitConverter.GetBytes(28591), 0, 4); stream.Position = 0; using (var reader = new TnefReader(stream, 0, TnefComplianceMode.Loose)) { Assert.IsFalse(reader.Seek(64), "Seek"); Assert.AreEqual(TnefComplianceStatus.StreamTruncated, reader.ComplianceStatus); } } }
private void ConvertToItem(TnefReader reader, bool isSummaryTnef) { if (this.IsReplicationMessage) { PersistablePropertyBag persistablePropertyBag = CoreObject.GetPersistablePropertyBag(base.MessageWriter.CoreItem); if (persistablePropertyBag != null) { persistablePropertyBag.Context.IsValidationDisabled = true; } } this.reader = reader; this.isSummaryTnef = isSummaryTnef; this.isRecipientTablePromoted = false; while (this.reader.ReadNextAttribute()) { this.CheckTnefComplianceStatus(); this.ReadAttribute(); } this.ProcessEndTnef(); PropertyBagSaveFlags propertyBagSaveFlags = PropertyBagSaveFlags.IgnoreMapiComputedErrors | base.ConversionOptions.GetSaveFlags(base.IsTopLevelMessage); CoreObject.GetPersistablePropertyBag(base.CoreItem).SaveFlags |= propertyBagSaveFlags; }
public void TestNegativeAttributeRawValueLengthLoose() { using (var stream = new MemoryStream()) { stream.Write(BitConverter.GetBytes(0x223e9f78), 0, 4); stream.WriteByte(0); stream.WriteByte(0); stream.WriteByte((byte)TnefAttributeLevel.Message); stream.Write(BitConverter.GetBytes((int)TnefAttributeTag.TnefVersion), 0, 4); stream.Write(BitConverter.GetBytes(-4), 0, 4); stream.Write(BitConverter.GetBytes(65536), 0, 4); stream.WriteByte((byte)TnefAttributeLevel.Message); stream.Write(BitConverter.GetBytes((int)TnefAttributeTag.OemCodepage), 0, 4); stream.Write(BitConverter.GetBytes(4), 0, 4); stream.Write(BitConverter.GetBytes(28591), 0, 4); stream.Position = 0; using (var reader = new TnefReader(stream, 0, TnefComplianceMode.Loose)) { Assert.IsFalse(reader.ReadNextAttribute(), "ReadNextAttribute"); Assert.AreEqual(TnefAttributeTag.TnefVersion, reader.AttributeTag, "AttributeTag"); Assert.AreEqual(TnefComplianceStatus.InvalidAttributeLength, reader.ComplianceStatus); } } }
protected override void PromoteAttachDataObject() { if (this.PropertyReader.IsEmbeddedMessage) { using (TnefReader embeddedMessageReader = this.PropertyReader.GetEmbeddedMessageReader()) { using (InboundMessageWriter inboundMessageWriter = base.MessageWriter.OpenAttachedMessageWriter()) { if (this.IsReplicationMessage) { inboundMessageWriter.ForceParticipantResolution = this.ResolveParticipantsOnAttachments; } else { inboundMessageWriter.ForceParticipantResolution = base.ConversionOptions.ResolveRecipientsInAttachedMessages; } new InboundTnefConverter(inboundMessageWriter) { IsReplicationMessage = this.IsReplicationMessage }.ConvertToItem(embeddedMessageReader, this.isSummaryTnef); inboundMessageWriter.Commit(); } return; } } if (this.PropertyReader.ObjectIid == MimeConstants.IID_IStorage) { using (Stream rawValueReadStream = this.PropertyReader.GetRawValueReadStream()) { using (Stream stream = base.MessageWriter.OpenOleAttachmentDataStream()) { Util.StreamHandler.CopyStreamData(rawValueReadStream, stream, null, 0, 131072); } } } }
internal bool Load(TnefReader reader, DataStorage tnefStorage, long tnefStart, long tnefEnd, TnefAttributeLevel level, int embeddingDepth, Charset binaryCharset) { bool result; while ((result = reader.ReadNextAttribute()) && TnefAttributeTag.AttachRenderData != reader.AttributeTag && level == reader.AttributeLevel) { if (TnefAttributeTag.RecipientTable == reader.AttributeTag) { if (level == TnefAttributeLevel.Message && this.parentMessage != null && 0 < embeddingDepth) { this.parentMessage.LoadRecipients(reader.PropertyReader); } } else { TnefPropertyReader propertyReader = reader.PropertyReader; while (propertyReader.ReadNextProperty()) { this.LoadProperty(propertyReader, tnefStorage, tnefStart, tnefEnd, level, embeddingDepth, binaryCharset); } } } return(result); }
// Token: 0x0600092A RID: 2346 RVA: 0x000311A6 File Offset: 0x0002F3A6 public TnefReaderStreamWrapper(TnefReader reader) { this.Reader = reader; this.Reader.Child = this; }
static void ExtractRecipientTable(TnefReader reader, MimeMessage message) { var prop = reader.TnefPropertyReader; // Note: The RecipientTable uses rows of properties... while (prop.ReadNextRow()) { InternetAddressList list = null; string name = null, addr = null; while (prop.ReadNextProperty()) { switch (prop.PropertyTag.Id) { case TnefPropertyId.RecipientType: int recipientType = prop.ReadValueAsInt32(); switch (recipientType) { case 1: list = message.To; break; case 2: list = message.Cc; break; case 3: list = message.Bcc; break; default: Assert.Fail("Invalid recipient type."); break; } //Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, recipientType); break; case TnefPropertyId.TransmitableDisplayName: if (string.IsNullOrEmpty(name)) { name = prop.ReadValueAsString(); //Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, name); } else { //Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, prop.ReadValueAsString ()); } break; case TnefPropertyId.DisplayName: name = prop.ReadValueAsString(); //Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, name); break; case TnefPropertyId.EmailAddress: if (string.IsNullOrEmpty(addr)) { addr = prop.ReadValueAsString(); //Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, addr); } else { //Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, prop.ReadValueAsString ()); } break; case TnefPropertyId.SmtpAddress: // The SmtpAddress, if it exists, should take precedence over the EmailAddress // (since the SmtpAddress is meant to be used in the RCPT TO command). addr = prop.ReadValueAsString(); //Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, addr); break; default: //Console.WriteLine ("RecipientTable Property (unhandled): {0} = {1}", prop.PropertyTag.Id, prop.ReadValue ()); break; } } Assert.IsNotNull(list, "The recipient type was never specified."); Assert.IsNotNull(addr, "The address was never specified."); if (list != null) { list.Add(new MailboxAddress(name, addr)); } } }
static void ExtractMapiProperties(TnefReader reader, MimeMessage message, BodyBuilder builder) { var prop = reader.TnefPropertyReader; while (prop.ReadNextProperty()) { switch (prop.PropertyTag.Id) { case TnefPropertyId.InternetMessageId: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { message.MessageId = prop.ReadValueAsString(); //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, message.MessageId); } else { Assert.Fail("Unknown property type for Message-Id: {0}", prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.Subject: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { message.Subject = prop.ReadValueAsString(); //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, message.Subject); } else { Assert.Fail("Unknown property type for Subject: {0}", prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.RtfCompressed: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var rtf = new TextPart("rtf"); rtf.ContentType.Name = "body.rtf"; var converter = new RtfCompressedToRtf(); var content = new MemoryStream(); using (var filtered = new FilteredStream(content)) { filtered.Add(converter); using (var compressed = prop.GetRawValueReadStream()) { compressed.CopyTo(filtered, 4096); filtered.Flush(); } } rtf.ContentObject = new ContentObject(content); content.Position = 0; builder.Attachments.Add(rtf); //Console.WriteLine ("Message Property: {0} = <compressed rtf data>", prop.PropertyTag.Id); } else { Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.BodyHtml: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var html = new TextPart("html"); html.ContentType.Name = "body.html"; html.Text = prop.ReadValueAsString(); builder.Attachments.Add(html); //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, html.Text); } else { Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.Body: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var plain = new TextPart("plain"); plain.ContentType.Name = "body.txt"; plain.Text = prop.ReadValueAsString(); builder.Attachments.Add(plain); //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, plain.Text); } else { Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; default: object value; try { value = prop.ReadValue(); } catch (Exception ex) { Console.WriteLine("Error in prop.ReadValue(): {0}", ex); value = null; } //Console.WriteLine ("Message Property (unhandled): {0} = {1}", prop.PropertyTag.Id, value); break; } } }
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()); }
private void LoadProperty(TnefPropertyReader propertyReader, DataStorage tnefStorage, long tnefStart, long tnefEnd, TnefAttributeLevel level, int embeddingDepth, Charset binaryCharset) { TnefPropertyTag propertyTag = propertyReader.PropertyTag; if (propertyTag.IsMultiValued) { return; } if (TnefPropertyType.Null == propertyTag.ValueTnefType) { return; } if (propertyReader.IsNamedProperty) { TnefNameId propertyNameId = propertyReader.PropertyNameId; TnefNameTag key = new TnefNameTag(propertyNameId, propertyTag.ValueTnefType); if (this.supportedNamedProperties.ContainsKey(key)) { if (propertyReader.IsLargeValue) { return; } this[this.GetIndex(propertyNameId)] = propertyReader.ReadValue(); } return; } if (!this.supportedProperties.ContainsKey(propertyTag)) { return; } TnefPropertyId id = propertyTag.Id; int index = this.GetIndex(id); if (TnefPropertyId.Body == id || TnefPropertyId.RtfCompressed == id || TnefPropertyId.BodyHtml == id) { tnefStart += (long)propertyReader.RawValueStreamOffset; tnefEnd = tnefStart + (long)propertyReader.RawValueLength; this[index] = new StoragePropertyValue(propertyTag, tnefStorage, tnefStart, tnefEnd); return; } if (TnefPropertyId.AttachData == id) { tnefStart += (long)propertyReader.RawValueStreamOffset; tnefEnd = tnefStart + (long)propertyReader.RawValueLength; this[index] = new StoragePropertyValue(propertyTag, tnefStorage, tnefStart, tnefEnd); if (!propertyReader.IsEmbeddedMessage) { return; } if (++embeddingDepth > 100) { throw new MimeException(EmailMessageStrings.NestingTooDeep(embeddingDepth, 100)); } using (TnefReader embeddedMessageReader = propertyReader.GetEmbeddedMessageReader()) { PureTnefMessage pureTnefMessage = new PureTnefMessage(this.attachmentData, tnefStorage, tnefStart, tnefEnd); pureTnefMessage.Load(embeddedMessageReader, embeddingDepth, binaryCharset); EmailMessage embeddedMessage = new EmailMessage(pureTnefMessage); this.attachmentData.EmbeddedMessage = embeddedMessage; return; } } if (propertyReader.IsLargeValue) { return; } if (TnefPropertyId.InternetCPID == id) { if (TnefPropertyType.Long == propertyTag.TnefType) { int num = propertyReader.ReadValueAsInt32(); this[index] = num; return; } } else { this[index] = propertyReader.ReadValue(); } }
internal TnefPropertyReader(TnefReader reader) { this.Reader = reader; }
static void ExtractMapiProperties(TnefReader reader, MimeMessage message, BodyBuilder builder) { var prop = reader.TnefPropertyReader; var chars = new char[1024]; var buf = new byte[1024]; while (prop.ReadNextProperty()) { var type = prop.ValueType; object value; switch (prop.PropertyTag.Id) { case TnefPropertyId.InternetMessageId: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { message.MessageId = prop.ReadValueAsString(); //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, message.MessageId); } else { Assert.Fail("Unknown property type for Message-Id: {0}", prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.Subject: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { message.Subject = prop.ReadValueAsString(); //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, message.Subject); } else { Assert.Fail("Unknown property type for Subject: {0}", prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.RtfCompressed: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var rtf = new TextPart("rtf"); rtf.ContentType.Name = "body.rtf"; var converter = new RtfCompressedToRtf(); var content = new MemoryStream(); using (var filtered = new FilteredStream(content)) { filtered.Add(converter); using (var compressed = prop.GetRawValueReadStream()) { compressed.CopyTo(filtered, 4096); filtered.Flush(); } } rtf.Content = new MimeContent(content); content.Position = 0; builder.Attachments.Add(rtf); //Console.WriteLine ("Message Property: {0} = <compressed rtf data>", prop.PropertyTag.Id); } else { Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.BodyHtml: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var html = new TextPart("html"); html.ContentType.Name = "body.html"; html.Text = prop.ReadValueAsString(); builder.Attachments.Add(html); //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, html.Text); } else { Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.Body: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var plain = new TextPart("plain"); plain.ContentType.Name = "body.txt"; plain.Text = prop.ReadValueAsString(); builder.Attachments.Add(plain); //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, plain.Text); } else { Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.AlternateRecipientAllowed: Assert.AreEqual(typeof(bool), type); value = prop.ReadValueAsBoolean(); break; case TnefPropertyId.MessageClass: Assert.AreEqual(typeof(string), type); value = prop.ReadValueAsString(); break; case TnefPropertyId.Importance: Assert.AreEqual(typeof(int), type); value = prop.ReadValueAsInt16(); break; case TnefPropertyId.Priority: Assert.AreEqual(typeof(int), type); value = prop.ReadValueAsInt16(); break; case TnefPropertyId.Sensitivity: Assert.AreEqual(typeof(int), type); value = prop.ReadValueAsInt16(); break; case TnefPropertyId.ClientSubmitTime: Assert.AreEqual(typeof(DateTime), type); value = prop.ReadValueAsDateTime(); break; case TnefPropertyId.SubjectPrefix: Assert.AreEqual(typeof(string), type); value = prop.ReadValueAsString(); break; case TnefPropertyId.MessageSubmissionId: Assert.AreEqual(typeof(byte[]), type); value = prop.ReadValueAsString(); break; case TnefPropertyId.ConversationTopic: Assert.AreEqual(typeof(string), type); value = prop.ReadValueAsString(); break; case TnefPropertyId.ConversationIndex: Assert.AreEqual(typeof(byte[]), type); value = prop.ReadValueAsBytes(); break; case TnefPropertyId.SenderName: Assert.AreEqual(typeof(string), type); value = prop.ReadValueAsString(); break; case TnefPropertyId.NormalizedSubject: Assert.AreEqual(typeof(string), type); value = prop.ReadValueAsString(); break; case TnefPropertyId.CreationTime: Assert.AreEqual(typeof(DateTime), type); value = prop.ReadValueAsDateTime(); break; case TnefPropertyId.LastModificationTime: Assert.AreEqual(typeof(DateTime), type); value = prop.ReadValueAsDateTime(); break; case TnefPropertyId.InternetCPID: Assert.AreEqual(typeof(int), type); value = prop.ReadValueAsInt32(); break; case TnefPropertyId.MessageCodepage: Assert.AreEqual(typeof(int), type); value = prop.ReadValueAsInt32(); break; case TnefPropertyId.INetMailOverrideFormat: Assert.AreEqual(typeof(int), type); value = prop.ReadValueAsInt32(); break; case TnefPropertyId.ReadReceiptRequested: Assert.AreEqual(typeof(bool), type); value = prop.ReadValueAsBoolean(); break; case TnefPropertyId.OriginatorDeliveryReportRequested: Assert.AreEqual(typeof(bool), type); value = prop.ReadValueAsBoolean(); break; case TnefPropertyId.TnefCorrelationKey: Assert.AreEqual(typeof(byte[]), type); value = prop.ReadValueAsString(); break; case TnefPropertyId.SenderSearchKey: Assert.AreEqual(typeof(byte[]), type); value = prop.ReadValueAsString(); break; case TnefPropertyId.DeleteAfterSubmit: Assert.AreEqual(typeof(bool), type); value = prop.ReadValueAsBoolean(); break; case TnefPropertyId.MessageDeliveryTime: Assert.AreEqual(typeof(DateTime), type); value = prop.ReadValueAsDateTime(); break; case TnefPropertyId.SentmailEntryId: Assert.AreEqual(typeof(byte[]), type); value = prop.ReadValueAsString(); break; case TnefPropertyId.RtfInSync: Assert.AreEqual(typeof(bool), type); value = prop.ReadValueAsBoolean(); break; case TnefPropertyId.MappingSignature: Assert.AreEqual(typeof(byte[]), type); value = prop.ReadValueAsBytes(); break; case TnefPropertyId.StoreRecordKey: Assert.AreEqual(typeof(byte[]), type); value = prop.ReadValueAsBytes(); break; case TnefPropertyId.StoreEntryId: Assert.AreEqual(typeof(byte[]), type); value = prop.ReadValueAsBytes(); break; default: Assert.Throws <ArgumentNullException> (() => prop.ReadTextValue(null, 0, chars.Length)); Assert.Throws <ArgumentOutOfRangeException> (() => prop.ReadTextValue(chars, -1, chars.Length)); Assert.Throws <ArgumentOutOfRangeException> (() => prop.ReadTextValue(chars, 0, -1)); Assert.Throws <ArgumentNullException> (() => prop.ReadRawValue(null, 0, buf.Length)); Assert.Throws <ArgumentOutOfRangeException> (() => prop.ReadRawValue(buf, -1, buf.Length)); Assert.Throws <ArgumentOutOfRangeException> (() => prop.ReadRawValue(buf, 0, -1)); if (type == typeof(int) || type == typeof(long) || type == typeof(bool) || type == typeof(double) || type == typeof(float)) { Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsString()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsGuid()); } else if (type == typeof(string)) { Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsBoolean()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsDouble()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsFloat()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsInt16()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsInt32()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsInt64()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsGuid()); } try { value = prop.ReadValue(); } catch (Exception ex) { Console.WriteLine("Error in prop.ReadValue(): {0}", ex); value = null; } //Console.WriteLine ("Message Property (unhandled): {0} = {1}", prop.PropertyTag.Id, value); Assert.AreEqual(type, value.GetType(), "Unexpected value type for {0}: {1}", prop.PropertyTag, value.GetType().Name); break; } } }
public void Debug() { using (var reader = new TnefReader(new MemoryStream(this.RawBinary), 0, TnefComplianceMode.Loose)) { while (reader.ReadNextAttribute()) { if (reader.AttributeLevel == TnefAttributeLevel.Attachment) { break; } TnefPropertyReader prop = reader.TnefPropertyReader; switch (reader.AttributeTag) { case TnefAttributeTag.RecipientTable: while (prop.ReadNextRow()) { string name = null, addr = null; while (prop.ReadNextProperty()) { switch (prop.PropertyTag.Id) { case TnefPropertyId.RecipientType: int recipientType = prop.ReadValueAsInt32(); switch (recipientType) { case 1: Console.WriteLine("To:"); break; case 2: Console.WriteLine("Cc:"); break; case 3: Console.WriteLine("Bcc:"); break; } Console.WriteLine("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, recipientType); break; case TnefPropertyId.TransmitableDisplayName: if (string.IsNullOrEmpty(name)) { name = prop.ReadValueAsString(); Console.WriteLine("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, name); } else { Console.WriteLine("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, prop.ReadValueAsString()); } break; case TnefPropertyId.DisplayName: name = prop.ReadValueAsString(); Console.WriteLine("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, name); break; case TnefPropertyId.EmailAddress: if (string.IsNullOrEmpty(addr)) { addr = prop.ReadValueAsString(); Console.WriteLine("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, addr); } else { Console.WriteLine("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, prop.ReadValueAsString()); } break; case TnefPropertyId.SmtpAddress: // The SmtpAddress, if it exists, should take precedence over the EmailAddress // (since the SmtpAddress is meant to be used in the RCPT TO command). addr = prop.ReadValueAsString(); Console.WriteLine("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, addr); break; default: Console.WriteLine("RecipientTable Property (unhandled): {0} = {1}", prop.PropertyTag.Id, prop.ReadValue()); break; } } } break; case TnefAttributeTag.MapiProperties: while (prop.ReadNextProperty()) { switch (prop.PropertyTag.Id) { case TnefPropertyId.InternetMessageId: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { Console.WriteLine("Message Property (InternetMessageId): {0} = {1}", prop.PropertyTag.Id, prop.ReadValueAsString()); } else { Console.WriteLine("Unknown property type for Message-Id: {0}", prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.Subject: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { this.Subject = prop.ReadValueAsString(); Console.WriteLine("Message Property (Subject): {0} = {1}", prop.PropertyTag.Id, this.Subject); } else { Console.WriteLine("Unknown property type for Subject: {0}", prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.RtfCompressed: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { //var rtf = new TextPart("rtf"); //rtf.ContentType.Name = "body.rtf"; //var converter = new RtfCompressedToRtf(); //var content = new MemoryStream(); //using (var filtered = new FilteredStream(content)) //{ // filtered.Add(converter); // using (var compressed = prop.GetRawValueReadStream()) // { // compressed.CopyTo(filtered, 4096); // filtered.Flush(); // } //} //rtf.ContentObject = new ContentObject(content); //content.Position = 0; //builder.Attachments.Add(rtf); Console.WriteLine("Message Property (RtfCompressed): {0} = <compressed rtf data>", prop.PropertyTag.Id); } else { Console.WriteLine("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.BodyHtml: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { this.HtmlBody = prop.ReadValueAsString(); Console.WriteLine("Message Property (BodyHtml): {0} = {1}", prop.PropertyTag.Id, this.HtmlBody); } else { Console.WriteLine("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.Body: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { this.TextBody = prop.ReadValueAsString(); Console.WriteLine("Message Property (Body): {0} = {1}", prop.PropertyTag.Id, this.TextBody); } else { Console.WriteLine("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; default: object val; try { val = prop.ReadValue(); } catch { val = null; } String key = prop.PropertyTag.Id.ToString(); switch (key) { case "SenderName": if (this.Sender == null) { this.Sender = new TnefAddress(); } this.Sender.Display = val.ToString().Trim(); break; case "SenderEmailAddress": if (this.Sender == null) { this.Sender = new TnefAddress(); } this.Sender.Address = val.ToString().Trim(); break; } Console.WriteLine("Message Property (unhandled): {0} = {1}", prop.PropertyTag.Id, val); break; } } break; case TnefAttributeTag.DateSent: this.DateSent = prop.ReadValueAsDateTime(); Console.WriteLine("Message Attribute (DateSent): {0} = {1}", reader.AttributeTag, this.DateSent); break; case TnefAttributeTag.Body: Console.WriteLine("Message Attribute (Body): {0} = {1}", reader.AttributeTag, prop.ReadValueAsString()); break; case TnefAttributeTag.OemCodepage: int codepage = prop.ReadValueAsInt32(); try { var encoding = Encoding.GetEncoding(codepage); Console.WriteLine("Message Attribute: OemCodepage = {0}", encoding.HeaderName); } catch { Console.WriteLine("Message Attribute: OemCodepage = {0}", codepage); } break; } } if (reader.AttributeLevel == TnefAttributeLevel.Attachment) { Console.WriteLine("attachments found"); TnefPropertyReader prop = reader.TnefPropertyReader; TnefAttachMethod attachMethod = TnefAttachMethod.ByValue; TnefAttachFlags flags; TnefAttachment attachment = null; Console.WriteLine("Extracting attachments..."); do { if (reader.AttributeLevel != TnefAttributeLevel.Attachment) { Console.WriteLine("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 TnefAttachment(); 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 (AttachLongFilename): {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: Console.WriteLine("Attachment Property (AttachContentLocation): {0} = {1}", prop.PropertyTag.Id, prop.ReadValueAsString()); break; case TnefPropertyId.AttachContentBase: Console.WriteLine("Attachment Property (AttachContentBase): {0} = {1}", prop.PropertyTag.Id, prop.ReadValueAsString()); break; case TnefPropertyId.AttachContentId: Console.WriteLine("Attachment Property (AttachContentId): {0} = {1}", prop.PropertyTag.Id, prop.ReadValueAsString()); break; case TnefPropertyId.AttachDisposition: Console.WriteLine("Attachment Property (AttachDisposition): {0} = {1}", prop.PropertyTag.Id, prop.ReadValueAsString()); break; case TnefPropertyId.AttachMethod: attachMethod = (TnefAttachMethod)prop.ReadValueAsInt32(); Console.WriteLine("Attachment Property (AttachMethod): {0} = {1}", prop.PropertyTag.Id, attachMethod); break; case TnefPropertyId.AttachMimeTag: attachment.MimeType = prop.ReadValueAsString(); Console.WriteLine("Attachment Property (AttachMimeTag): {0} = {1}", prop.PropertyTag.Id, attachment.MimeType); break; case TnefPropertyId.AttachFlags: flags = (TnefAttachFlags)prop.ReadValueAsInt32(); Console.WriteLine("Attachment Property (AttachFlags): {0} = {1}", prop.PropertyTag.Id, flags); break; case TnefPropertyId.AttachData: Stream stream = prop.GetRawValueReadStream(); byte[] guid = new byte[16]; stream.Read(guid, 0, 16); Console.WriteLine("Attachment Property (AttachData): {0} has GUID {1}", prop.PropertyTag.Id, new Guid(guid)); break; case TnefPropertyId.DisplayName: Console.WriteLine("Attachment Property (DisplayName): {0} = {1}", prop.PropertyTag.Id, prop.ReadValueAsString()); break; case TnefPropertyId.AttachSize: Console.WriteLine("Attachment Property (AttachSize): {0} = {1}", prop.PropertyTag.Id, prop.ReadValueAsInt64()); break; default: Console.WriteLine("Attachment Property (unhandled): {0} = {1}", prop.PropertyTag.Id, prop.ReadValue()); break; } } break; case TnefAttributeTag.AttachData: if (attachment == null || attachMethod != TnefAttachMethod.ByValue) { break; } attachment.BinaryContent = prop.ReadValueAsBytes(); this.Attachments.Add(attachment); Console.WriteLine("Attachment Attribute (AttachData): {0}", reader.AttributeTag); break; case TnefAttributeTag.AttachCreateDate: Console.WriteLine("Attachment Attribute (AttachCreateDate): {0} = {1}", reader.AttributeTag, prop.ReadValueAsDateTime()); break; case TnefAttributeTag.AttachModifyDate: Console.WriteLine("Attachment Attribute (AttachModifyDate): {0} = {1}", reader.AttributeTag, prop.ReadValueAsDateTime()); break; case TnefAttributeTag.AttachTitle: Console.WriteLine("Attachment Attribute (AttachTitle): {0} = {1}", reader.AttributeTag, prop.ReadValueAsString()); break; default: Console.WriteLine("Attachment Attribute (unhandled): {0} = {1}", reader.AttributeTag, prop.ReadValue()); break; } }while (reader.ReadNextAttribute()); } else { Console.WriteLine("no attachments"); } } }
public void Parse() { using (var reader = new TnefReader(new MemoryStream(this.RawBinary), 0, TnefComplianceMode.Loose)) { while (reader.ReadNextAttribute()) { if (reader.AttributeLevel == TnefAttributeLevel.Attachment) { break; } TnefPropertyReader prop = reader.TnefPropertyReader; switch (reader.AttributeTag) { case TnefAttributeTag.RecipientTable: while (prop.ReadNextRow()) { string name = null, addr = null; while (prop.ReadNextProperty()) { switch (prop.PropertyTag.Id) { case TnefPropertyId.RecipientType: int recipientType = prop.ReadValueAsInt32(); switch (recipientType) { case 1: Console.WriteLine("To:"); break; case 2: Console.WriteLine("Cc:"); break; case 3: Console.WriteLine("Bcc:"); break; } break; case TnefPropertyId.TransmitableDisplayName: if (string.IsNullOrEmpty(name)) { name = prop.ReadValueAsString(); } else { } break; case TnefPropertyId.DisplayName: name = prop.ReadValueAsString(); break; case TnefPropertyId.EmailAddress: if (string.IsNullOrEmpty(addr)) { addr = prop.ReadValueAsString(); } else { } break; case TnefPropertyId.SmtpAddress: // The SmtpAddress, if it exists, should take precedence over the EmailAddress // (since the SmtpAddress is meant to be used in the RCPT TO command). addr = prop.ReadValueAsString(); break; default: break; } } } break; case TnefAttributeTag.MapiProperties: while (prop.ReadNextProperty()) { switch (prop.PropertyTag.Id) { case TnefPropertyId.InternetMessageId: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { } else { } break; case TnefPropertyId.Subject: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { this.Subject = prop.ReadValueAsString(); } else { } break; case TnefPropertyId.RtfCompressed: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { //var rtf = new TextPart("rtf"); //rtf.ContentType.Name = "body.rtf"; //var converter = new RtfCompressedToRtf(); //var content = new MemoryStream(); //using (var filtered = new FilteredStream(content)) //{ // filtered.Add(converter); // using (var compressed = prop.GetRawValueReadStream()) // { // compressed.CopyTo(filtered, 4096); // filtered.Flush(); // } //} //rtf.ContentObject = new ContentObject(content); //content.Position = 0; //builder.Attachments.Add(rtf); } else { } break; case TnefPropertyId.BodyHtml: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { this.HtmlBody = prop.ReadValueAsString(); } else { } break; case TnefPropertyId.Body: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { this.TextBody = prop.ReadValueAsString(); } else { } break; default: object val; try { val = prop.ReadValue(); } catch { val = null; } String key = prop.PropertyTag.Id.ToString(); switch (key) { case "SenderName": if (this.Sender == null) { this.Sender = new TnefAddress(); } this.Sender.Display = val.ToString().Trim(); break; case "SenderEmailAddress": if (this.Sender == null) { this.Sender = new TnefAddress(); } this.Sender.Address = val.ToString().Trim(); break; } break; } } break; case TnefAttributeTag.DateSent: this.DateSent = prop.ReadValueAsDateTime(); break; case TnefAttributeTag.Body: break; case TnefAttributeTag.OemCodepage: int codepage = prop.ReadValueAsInt32(); try { var encoding = Encoding.GetEncoding(codepage); } catch { } break; } } if (reader.AttributeLevel == TnefAttributeLevel.Attachment) { TnefPropertyReader propertyReader = reader.TnefPropertyReader; TnefAttachMethod attachMethod = TnefAttachMethod.ByValue; TnefAttachFlags attachFlags; TnefAttachment attachment = null; do { if (reader.AttributeLevel != TnefAttributeLevel.Attachment) { } switch (reader.AttributeTag) { case TnefAttributeTag.AttachRenderData: attachMethod = TnefAttachMethod.ByValue; attachment = new TnefAttachment(); break; case TnefAttributeTag.Attachment: if (attachment == null) { break; } while (propertyReader.ReadNextProperty()) { switch (propertyReader.PropertyTag.Id) { case TnefPropertyId.AttachLongFilename: attachment.FileName = propertyReader.ReadValueAsString(); break; case TnefPropertyId.AttachFilename: if (String.IsNullOrEmpty(attachment.FileName)) { attachment.FileName = propertyReader.ReadValueAsString(); } else { } break; case TnefPropertyId.AttachContentLocation: break; case TnefPropertyId.AttachContentBase: break; case TnefPropertyId.AttachContentId: break; case TnefPropertyId.AttachDisposition: break; case TnefPropertyId.AttachMethod: attachMethod = (TnefAttachMethod)propertyReader.ReadValueAsInt32(); break; case TnefPropertyId.AttachMimeTag: attachment.MimeType = propertyReader.ReadValueAsString(); break; case TnefPropertyId.AttachFlags: attachFlags = (TnefAttachFlags)propertyReader.ReadValueAsInt32(); break; case TnefPropertyId.AttachData: Stream stream = propertyReader.GetRawValueReadStream(); byte[] guid = new byte[16]; stream.Read(guid, 0, 16); break; case TnefPropertyId.DisplayName: break; case TnefPropertyId.AttachSize: break; default: break; } } break; case TnefAttributeTag.AttachData: if (attachment == null || attachMethod != TnefAttachMethod.ByValue) { break; } attachment.BinaryContent = propertyReader.ReadValueAsBytes(); this.Attachments.Add(attachment); break; case TnefAttributeTag.AttachCreateDate: break; case TnefAttributeTag.AttachModifyDate: break; case TnefAttributeTag.AttachTitle: break; default: break; } }while (reader.ReadNextAttribute()); } else { } } }
private bool WriteModifiedProperty(TnefWriter writer, TnefReader reader, TnefPropertyTag propertyTag, object value, bool forceUnicode, ref bool startAttribute, byte[] scratchBuffer) { TnefPropertyReader propertyReader = reader.PropertyReader; TnefAttributeTag attributeTag = reader.AttributeTag; TnefAttributeLevel attributeLevel = reader.AttributeLevel; StoragePropertyValue storagePropertyValue = value as StoragePropertyValue; if (storagePropertyValue != null) { if (this.attachmentData != null && this.attachmentData.EmbeddedMessage != null && propertyReader.IsEmbeddedMessage) { using (TnefReader embeddedMessageReader = propertyReader.GetEmbeddedMessageReader()) { TnefPropertyBag.StartAttributeIfNecessary(writer, attributeTag, attributeLevel, ref startAttribute); writer.StartProperty(propertyTag); EmailMessage embeddedMessage = this.attachmentData.EmbeddedMessage; PureTnefMessage pureTnefMessage = embeddedMessage.PureTnefMessage; Charset textCharset = pureTnefMessage.TextCharset; using (TnefWriter embeddedMessageWriter = writer.GetEmbeddedMessageWriter(textCharset.CodePage)) { pureTnefMessage.WriteMessage(embeddedMessageReader, embeddedMessageWriter, scratchBuffer); } return(true); } } using (Stream readStream = storagePropertyValue.GetReadStream()) { int num = readStream.Read(scratchBuffer, 0, scratchBuffer.Length); if (num > 0) { propertyTag = storagePropertyValue.PropertyTag; if (propertyTag.ValueTnefType == TnefPropertyType.Unicode && TnefPropertyBag.IsLegacyAttribute(attributeTag)) { return(false); } TnefPropertyBag.StartAttributeIfNecessary(writer, attributeTag, attributeLevel, ref startAttribute); writer.StartProperty(propertyTag); do { writer.WritePropertyRawValue(scratchBuffer, 0, num); num = readStream.Read(scratchBuffer, 0, scratchBuffer.Length); }while (num > 0); } return(true); } } if (propertyTag.ValueTnefType == TnefPropertyType.String8 && forceUnicode) { if (TnefPropertyBag.IsLegacyAttribute(attributeTag)) { return(false); } TnefPropertyBag.StartAttributeIfNecessary(writer, attributeTag, attributeLevel, ref startAttribute); writer.WriteProperty(propertyTag.ToUnicode(), value); } else { TnefPropertyBag.StartAttributeIfNecessary(writer, attributeTag, attributeLevel, ref startAttribute); writer.WriteProperty(propertyTag, value); } return(true); }
public void changeBodyOfTnef(MimePart tnefPart, SchedulingInfo schedulingInfo) { TnefReader tnefreader = new TnefReader(tnefPart.GetContentReadStream(), 0, TnefComplianceMode.Loose); while (tnefreader.ReadNextAttribute()) { if (tnefreader.AttributeTag != TnefAttributeTag.MapiProperties) continue; string dialingInfo = schedulingInfo.dialingInfo; TnefWriter writer = new TnefWriter( tnefPart.GetContentWriteStream(tnefPart.ContentTransferEncoding), tnefreader.AttachmentKey, 0, TnefWriterFlags.NoStandardAttributes); writer.StartAttribute(TnefAttributeTag.MapiProperties, TnefAttributeLevel.Message); writer.WriteAllProperties(tnefreader.PropertyReader); writer.StartProperty(TnefPropertyTag.RtfCompressed); if (null != dialingInfo) { dialingInfo = convertToUnicode(dialingInfo); } string body = null == dialingInfo ? schedulingInfo.emailMessage : schedulingInfo.emailMessage + "<br><br>" + dialingInfo; Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(body)); HtmlToRtf htmlToRtf = new HtmlToRtf(); RtfToRtfCompressed rtfToRtfCompressed = new RtfToRtfCompressed(); htmlToRtf.InputEncoding = System.Text.Encoding.UTF8;//GetEncoding("ISO-8859-1"); stream = new ConverterStream(stream, htmlToRtf, ConverterStreamAccess.Read); stream = new ConverterStream(stream, rtfToRtfCompressed, ConverterStreamAccess.Read); writer.WritePropertyValue(stream); if (null != writer) { writer.Close(); } } tnefreader.Close(); RvLogger.DebugWrite("ok**************************************"); }
public void parseTnefSimple(MailItem mailItem, SchedulingInfo schedulingInfo) { try { TnefReader tnefreader = new TnefReader(mailItem.Message.TnefPart.GetContentReadStream(), 0, TnefComplianceMode.Loose); EnvelopeRecipientCollection.Enumerator enumerator = mailItem.Recipients.GetEnumerator(); StringBuilder recipents = new StringBuilder(""); StringBuilder resources = new StringBuilder(""); ArrayList displayNames = new ArrayList(); while (enumerator.MoveNext()) { string emailAddress = enumerator.Current.Address.ToString(); int recipientP2Type = (int)enumerator.Current.Properties["Microsoft.Exchange.Transport.RecipientP2Type"]; String displayName = emailAddress; try { displayName = (string)enumerator.Current.Properties["Microsoft.Exchange.MapiDisplayName"]; } catch (Exception ex1) { RvLogger.DebugWrite("Error: " + ex1.Message); if(emailAddress != null ) { int lastIndex = emailAddress.LastIndexOf("@"); if (lastIndex != -1) { displayName = emailAddress.Substring(0, lastIndex); } } } displayNames.Add(displayName); if (recipientP2Type == 3) { resources.Append(emailAddress).Append(" "); } else if (recipientP2Type == 1 || recipientP2Type == 2) { recipents.Append(emailAddress).Append(" "); } } schedulingInfo.outlookResources = resources.ToString(); schedulingInfo.recipents = recipents.ToString(); displayNames.Sort(); StringBuilder displayNamesStrb = new StringBuilder(""); foreach (object displayName in displayNames) { displayNamesStrb.Append((string)displayName).Append("; "); } string displayNamesStr = displayNamesStrb.ToString().Trim(); schedulingInfo.displayNames = displayNamesStr.Substring(0, displayNamesStr.Length - 1); RvLogger.DebugWrite("Recipents emails are :" + schedulingInfo.recipents); RvLogger.DebugWrite("Resources emails are :" + schedulingInfo.outlookResources); RvLogger.DebugWrite("DisplayNames emails are :" + displayNamesStr); bool isRecurrence = false; bool isOcurrence = false; while (tnefreader.ReadNextAttribute()) { if (tnefreader.AttributeTag != TnefAttributeTag.MapiProperties) continue; while (tnefreader.PropertyReader.ReadNextProperty()) { try { TnefPropertyTag tag = tnefreader.PropertyReader.PropertyTag; //RvLogger.DebugWrite("PropertyTagID:" + tag.Id); //RvLogger.DebugWrite("PropertyTagToString:" + tag.ToString()); //RvLogger.DebugWrite("ValueType==:" + tnefreader.PropertyReader.ValueType); /*try { RvLogger.DebugWrite("PropertyID:" + tnefreader.PropertyReader.PropertyNameId.Id); RvLogger.DebugWrite("PropertyName:" + tnefreader.PropertyReader.PropertyNameId.Name); RvLogger.DebugWrite("PropertySetGUID:" + tnefreader.PropertyReader.PropertyNameId.PropertySetGuid); } catch (Exception) { RvLogger.DebugWrite("***********************************************0"); } */ if (tnefreader.PropertyReader.IsNamedProperty && tnefreader.PropertyReader.PropertyNameId.Id == 33302) { byte[] recurrencePatternByte = tnefreader.PropertyReader.ReadValueAsBytes(); RecurrencePattern recurrencePattern = RvMailParser.parseRecurrenceMeeting(recurrencePatternByte); schedulingInfo.recurrencePattern = recurrencePattern; } else if (tnefreader.PropertyReader.IsNamedProperty && tnefreader.PropertyReader.PropertyNameId.Id == 33374) { byte[] timezonebytes = tnefreader.PropertyReader.ReadValueAsBytes(); byte[] lengthOfZone = { timezonebytes[6], timezonebytes[7] }; int length = BitConverter.ToInt16(lengthOfZone, 0); byte[] timezonekeyNameBytes = new byte[length * 2]; Array.Copy(timezonebytes, 8, timezonekeyNameBytes, 0, length * 2 - 1); String timezonekeyName = Encoding.Unicode.GetString(timezonekeyNameBytes); schedulingInfo.timeZoneID = timezonekeyName; //RvLogger.DebugWrite("timezonekeyName:" + timezonekeyName); } if (!tnefreader.PropertyReader.ValueType.IsArray) { object propValue = tnefreader.PropertyReader.ReadValue(); //RvLogger.DebugWrite("PropertyValue:" + propValue); if (tnefreader.PropertyReader.IsNamedProperty && tnefreader.PropertyReader.PropertyNameId.Id == 33315) { if ((Boolean)propValue) isRecurrence = (Boolean)propValue; isOcurrence = !(Boolean)propValue; } else if (tnefreader.PropertyReader.IsNamedProperty && tnefreader.PropertyReader.PropertyNameId.Id == 33330) { schedulingInfo.recurrenceInfo = (string)propValue; } else if (tnefreader.PropertyReader.IsNamedProperty && tnefreader.PropertyReader.PropertyNameId.Id == 33332) { schedulingInfo.timeZoneDisplayName = (string)propValue; } else if (tnefreader.PropertyReader.IsNamedProperty && tnefreader.PropertyReader.PropertyNameId.Id == 33336) { schedulingInfo.displayNamesFromTnef = ((string)propValue).Trim(); } else if (tnefreader.PropertyReader.IsNamedProperty && tnefreader.PropertyReader.PropertyNameId.Id == 41) { schedulingInfo.preStartDate = (DateTime)propValue; RvLogger.DebugWrite("schedulingInfo.preStartDate===================" + ((DateTime)propValue)); schedulingInfo.hasPreStartDate = true; } else if (tnefreader.PropertyReader.IsNamedProperty && tnefreader.PropertyReader.PropertyNameId.Id == 4115) { RvLogger.DebugWrite("Parsed html body===================" + ((string)propValue)); } else if (tnefreader.PropertyReader.IsNamedProperty && tnefreader.PropertyReader.PropertyNameId.Id == 4118) { RvLogger.DebugWrite("Parsed native body===================" + ((string)propValue)); } else if (tnefreader.PropertyReader.IsNamedProperty && tnefreader.PropertyReader.PropertyNameId.Id == 4096) { RvLogger.DebugWrite("Parsed text body===================" + ((string)propValue)); } else if (tag.Id == TnefPropertyId.StartDate) { schedulingInfo.startDate = ((DateTime)propValue); RvLogger.DebugWrite("schedulingInfo.startDate===================" + ((DateTime)propValue)); } else if (tag.Id == TnefPropertyId.EndDate) { schedulingInfo.endDate = ((DateTime)propValue); } else if (tag.Id == TnefPropertyId.LastModificationTime) { RvLogger.DebugWrite("lastModifiedTime===================" + ((DateTime)propValue)); } else if (tag.Id == TnefPropertyId.CreationTime) { RvLogger.DebugWrite("CreationTime===================" + ((DateTime)propValue)); } else if (tag.Id == TnefPropertyId.SenderEmailAddress) { schedulingInfo.senderEmailAddr = (string)propValue; } else if (tag.Id == TnefPropertyId.SubjectPrefix) { if (null != propValue) schedulingInfo.subjectPrefix = ((string)propValue).Trim(); } else if (tag.Id == TnefPropertyId.StoreEntryId) { schedulingInfo.storeEntryId = (string)propValue; } else if (tag.Id == TnefPropertyId.INetMailOverrideCharset) { object a = propValue; } else if (tag.Id == TnefPropertyId.ConversationKey) { schedulingInfo.conversationKey = (string)propValue; } else if (tnefreader.PropertyReader.IsNamedProperty && tnefreader.PropertyReader.PropertyNameId.Id == 2) { schedulingInfo.location = (string)propValue; string meetingPin = RvScopiaMeeting.parseMeetingPin(schedulingInfo.location); if (!string.IsNullOrEmpty(meetingPin)) schedulingInfo.meetingPin = meetingPin; } else if (tnefreader.PropertyReader.IsNamedProperty && tnefreader.PropertyReader.PropertyNameId.Id == 33289) { string value = (string)propValue; RvLogger.DebugWrite("infomation======================================" + value); int firstIndex = value.IndexOf(":"); int lastIndex = value.LastIndexOf(":"); if (firstIndex != -1) { schedulingInfo.conferenceID = value.Substring(firstIndex + 1, lastIndex - firstIndex - 1); string hashString = value.Substring(lastIndex + 1); int indexHashSplit = hashString.IndexOf("$"); schedulingInfo.lastHashInfo = hashString.Substring(0, indexHashSplit); schedulingInfo.lastRecurrenceHashInfo = hashString.Substring(indexHashSplit + 1); if (value.StartsWith("#")) { isRecurrence = true; } } } } else { if (tag == TnefPropertyTag.RtfCompressed) { schedulingInfo.emailMessage = ""; Stream stream = tnefreader.PropertyReader.GetRawValueReadStream(); Stream decompressedRtfStream = new ConverterStream(stream, new RtfCompressedToRtf(), ConverterStreamAccess.Read); RtfToHtml rtfToHtml = new RtfToHtml(); rtfToHtml.OutputEncoding = System.Text.Encoding.UTF8; rtfToHtml.EnableHtmlDeencapsulation = true; Stream text = new ConverterStream(decompressedRtfStream, rtfToHtml, ConverterStreamAccess.Read); StreamReader sr = new StreamReader(text); schedulingInfo.emailMessage = sr.ReadToEnd(); //RvLogger.DebugWrite("schedulingInfo.emailMessage: " + schedulingInfo.emailMessage); int indexOfSystemInfoSign = schedulingInfo.emailMessage.IndexOf("*~*~*~*~*~*~*~*~*~*"); int startIndex = -1; int endIndex = -1; if (indexOfSystemInfoSign > -1) { startIndex = schedulingInfo.emailMessage.Substring(0, indexOfSystemInfoSign).LastIndexOf("<div>"); endIndex = schedulingInfo.emailMessage.IndexOf("</div>", indexOfSystemInfoSign) + 6; if (startIndex > -1 && endIndex > -1) schedulingInfo.emailMessage = schedulingInfo.emailMessage.Substring(0, startIndex) + schedulingInfo.emailMessage.Substring(endIndex); } schedulingInfo.emailMessage = schedulingInfo.emailMessage.Replace("<img src=\"objattph://\">", ""); sr.Close(); text.Close(); decompressedRtfStream.Close(); stream.Close(); } } } catch (Exception ex) { RvLogger.DebugWrite("ex.Message======================" + ex.Message); RvLogger.DebugWrite(ex.StackTrace); } } } if (isRecurrence && !isOcurrence) schedulingInfo.meetingType = MeetingType.Reccurence; else if (isRecurrence && isOcurrence) schedulingInfo.meetingType = MeetingType.Ocurrence; else schedulingInfo.meetingType = MeetingType.Normal; tnefreader.Close(); } catch (Exception e) { RvLogger.DebugWrite("Fail to parse mail-- " + e.Message); RvLogger.DebugWrite(e.StackTrace); } }
static void ExtractMapiProperties(TnefReader reader, MimeMessage message, BodyBuilder builder) { var prop = reader.TnefPropertyReader; while (prop.ReadNextProperty()) { switch (prop.PropertyTag.Id) { case TnefPropertyId.InternetMessageId: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { message.MessageId = prop.ReadValueAsString(); Console.WriteLine("Message Property: {0} = {1}", prop.PropertyTag.Id, message.MessageId); } else { Assert.Fail("Unknown property type for Message-Id: {0}", prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.Subject: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { message.Subject = prop.ReadValueAsString(); Console.WriteLine("Message Property: {0} = {1}", prop.PropertyTag.Id, message.Subject); } else { Assert.Fail("Unknown property type for Subject: {0}", prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.RtfCompressed: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var rtf = new TextPart("rtf"); rtf.ContentType.Name = "body.rtf"; rtf.Text = prop.ReadValueAsString(); builder.Attachments.Add(rtf); Console.WriteLine("Message Property: {0} = <compressed rtf data>", prop.PropertyTag.Id); } else { Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.BodyHtml: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var html = new TextPart("html"); html.ContentType.Name = "body.html"; html.Text = prop.ReadValueAsString(); builder.Attachments.Add(html); Console.WriteLine("Message Property: {0} = {1}", prop.PropertyTag.Id, html.Text); } else { Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.Body: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var plain = new TextPart("plain"); plain.ContentType.Name = "body.txt"; plain.Text = prop.ReadValueAsString(); builder.Attachments.Add(plain); Console.WriteLine("Message Property: {0} = {1}", prop.PropertyTag.Id, plain.Text); } else { Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; default: Console.WriteLine("Message Property (unhandled): {0} = {1}", prop.PropertyTag.Id, prop.ReadValue()); break; } } }
internal bool Write(TnefReader reader, TnefWriter writer, TnefAttributeLevel level, bool dropRecipientTable, bool forceUnicode, byte[] scratchBuffer) { IDictionary <TnefPropertyTag, object> dictionary = null; char[] array = null; bool result; for (;;) { TnefPropertyReader propertyReader = reader.PropertyReader; if (0 >= propertyReader.PropertyCount) { goto IL_37A; } TnefAttributeTag attributeTag = reader.AttributeTag; TnefAttributeLevel attributeLevel = reader.AttributeLevel; bool flag = true; while (propertyReader.ReadNextProperty()) { TnefPropertyTag propertyTag = propertyReader.PropertyTag; if (TnefPropertyType.Null != propertyTag.ValueTnefType) { if (propertyReader.IsNamedProperty) { TnefNameId propertyNameId = propertyReader.PropertyNameId; TnefNameTag key = new TnefNameTag(propertyNameId, propertyTag.ValueTnefType); int num; if (this.supportedNamedProperties.TryGetValue(key, out num) && this.properties[num].IsDirty) { object obj = this[propertyNameId]; if (obj != null) { TnefPropertyBag.StartAttributeIfNecessary(writer, attributeTag, attributeLevel, ref flag); writer.StartProperty(propertyTag, propertyNameId.PropertySetGuid, propertyNameId.Id); writer.WritePropertyValue(obj); continue; } continue; } } else { TnefPropertyId id = propertyTag.Id; int num2; if (this.supportedProperties.TryGetValue(propertyTag, out num2) && this.properties[num2].IsDirty && (this.attachmentData == null || this.attachmentData.EmbeddedMessage == null || TnefAttributeLevel.Attachment != level || TnefAttributeTag.AttachData != attributeTag || TnefPropertyId.AttachData != id)) { object obj = this[id]; if (obj == null) { continue; } if (!this.WriteModifiedProperty(writer, reader, propertyTag, obj, forceUnicode, ref flag, scratchBuffer)) { if (dictionary == null) { dictionary = new Dictionary <TnefPropertyTag, object>(TnefPropertyBag.PropertyTagComparer); } if (!dictionary.ContainsKey(propertyTag)) { dictionary.Add(propertyTag, obj); continue; } continue; } else { if (dictionary != null && dictionary.ContainsKey(propertyTag)) { dictionary.Remove(propertyTag); continue; } continue; } } } if (propertyTag.ValueTnefType == TnefPropertyType.String8 && forceUnicode) { if (!TnefPropertyBag.IsLegacyAttribute(attributeTag)) { TnefPropertyBag.StartAttributeIfNecessary(writer, attributeTag, attributeLevel, ref flag); TnefPropertyBag.WriteUnicodeProperty(writer, propertyReader, propertyTag.ToUnicode(), ref array); } } else if (propertyTag.IsTnefTypeValid) { TnefPropertyBag.StartAttributeIfNecessary(writer, attributeTag, attributeLevel, ref flag); writer.WriteProperty(propertyReader); } } } if ((TnefAttributeTag.MapiProperties == attributeTag && level == TnefAttributeLevel.Message) || (TnefAttributeTag.Attachment == attributeTag && level == TnefAttributeLevel.Attachment)) { if (this.newProperties != null) { foreach (KeyValuePair <TnefPropertyTag, object> keyValuePair in this.newProperties) { object obj = keyValuePair.Value; if (obj != null) { this.WriteModifiedProperty(writer, reader, keyValuePair.Key, obj, forceUnicode, ref flag, scratchBuffer); } } } if (dictionary != null) { foreach (KeyValuePair <TnefPropertyTag, object> keyValuePair2 in dictionary) { this.WriteModifiedProperty(writer, reader, keyValuePair2.Key, keyValuePair2.Value, forceUnicode, ref flag, scratchBuffer); } } if (this.newNamedProperties != null) { using (IEnumerator <KeyValuePair <TnefNameTag, object> > enumerator3 = this.newNamedProperties.GetEnumerator()) { while (enumerator3.MoveNext()) { KeyValuePair <TnefNameTag, object> keyValuePair3 = enumerator3.Current; object obj = keyValuePair3.Value; if (obj != null) { TnefPropertyTag tag = new TnefPropertyTag((TnefPropertyId)(-32768), keyValuePair3.Key.Type); if (forceUnicode) { tag = tag.ToUnicode(); } TnefPropertyBag.StartAttributeIfNecessary(writer, attributeTag, attributeLevel, ref flag); writer.StartProperty(tag, keyValuePair3.Key.Id.PropertySetGuid, keyValuePair3.Key.Id.Id); writer.WritePropertyValue(obj); } } goto IL_3AC; } goto IL_37A; } } IL_3AC: if (!(result = reader.ReadNextAttribute()) || level != reader.AttributeLevel || TnefAttributeTag.AttachRenderData == reader.AttributeTag) { break; } continue; IL_37A: if (level != TnefAttributeLevel.Message || TnefAttributeTag.RecipientTable != reader.AttributeTag) { writer.WriteAttribute(reader); goto IL_3AC; } if (!dropRecipientTable) { this.parentMessage.WriteRecipients(reader.PropertyReader, writer, ref array); goto IL_3AC; } goto IL_3AC; } return(result); }
static void ExtractRecipientTable(TnefReader reader, MimeMessage message) { var prop = reader.TnefPropertyReader; var chars = new char[1024]; var buf = new byte[1024]; // Note: The RecipientTable uses rows of properties... while (prop.ReadNextRow()) { InternetAddressList list = null; string name = null, addr = null; while (prop.ReadNextProperty()) { var type = prop.ValueType; object value; switch (prop.PropertyTag.Id) { case TnefPropertyId.RecipientType: int recipientType = prop.ReadValueAsInt32(); switch (recipientType) { case 1: list = message.To; break; case 2: list = message.Cc; break; case 3: list = message.Bcc; break; default: Assert.Fail("Invalid recipient type."); break; } //Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, recipientType); break; case TnefPropertyId.TransmitableDisplayName: if (string.IsNullOrEmpty(name)) { name = prop.ReadValueAsString(); //Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, name); } else { //Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, prop.ReadValueAsString ()); } break; case TnefPropertyId.DisplayName: name = prop.ReadValueAsString(); //Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, name); break; case TnefPropertyId.EmailAddress: if (string.IsNullOrEmpty(addr)) { addr = prop.ReadValueAsString(); //Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, addr); } else { //Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, prop.ReadValueAsString ()); } break; case TnefPropertyId.SmtpAddress: // The SmtpAddress, if it exists, should take precedence over the EmailAddress // (since the SmtpAddress is meant to be used in the RCPT TO command). addr = prop.ReadValueAsString(); //Console.WriteLine ("RecipientTable Property: {0} = {1}", prop.PropertyTag.Id, addr); break; case TnefPropertyId.Addrtype: Assert.AreEqual(typeof(string), type); value = prop.ReadValueAsString(); break; case TnefPropertyId.Rowid: Assert.AreEqual(typeof(int), type); value = prop.ReadValueAsInt64(); break; case TnefPropertyId.SearchKey: Assert.AreEqual(typeof(byte[]), type); value = prop.ReadValueAsBytes(); break; case TnefPropertyId.SendRichInfo: Assert.AreEqual(typeof(bool), type); value = prop.ReadValueAsBoolean(); break; case TnefPropertyId.DisplayType: Assert.AreEqual(typeof(int), type); value = prop.ReadValueAsInt16(); break; case TnefPropertyId.SendInternetEncoding: Assert.AreEqual(typeof(int), type); value = prop.ReadValueAsBoolean(); break; default: Assert.Throws <ArgumentNullException> (() => prop.ReadTextValue(null, 0, chars.Length)); Assert.Throws <ArgumentOutOfRangeException> (() => prop.ReadTextValue(chars, -1, chars.Length)); Assert.Throws <ArgumentOutOfRangeException> (() => prop.ReadTextValue(chars, 0, -1)); Assert.Throws <ArgumentNullException> (() => prop.ReadRawValue(null, 0, buf.Length)); Assert.Throws <ArgumentOutOfRangeException> (() => prop.ReadRawValue(buf, -1, buf.Length)); Assert.Throws <ArgumentOutOfRangeException> (() => prop.ReadRawValue(buf, 0, -1)); if (type == typeof(int) || type == typeof(long) || type == typeof(bool) || type == typeof(double) || type == typeof(float)) { Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsString()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsGuid()); } else if (type == typeof(string)) { Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsBoolean()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsDouble()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsFloat()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsInt16()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsInt32()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsInt64()); Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsGuid()); } value = prop.ReadValue(); //Console.WriteLine ("RecipientTable Property (unhandled): {0} = {1}", prop.PropertyTag.Id, value); Assert.AreEqual(type, value.GetType(), "Unexpected value type for {0}: {1}", prop.PropertyTag, value.GetType().Name); break; } } Assert.IsNotNull(list, "The recipient type was never specified."); Assert.IsNotNull(addr, "The address was never specified."); if (list != null) { list.Add(new MailboxAddress(name, addr)); } } }
static void ExtractAttachments(TnefReader reader, BodyBuilder builder) { var filter = new BestEncodingFilter(); var prop = reader.TnefPropertyReader; MimePart attachment = null; int outIndex, outLength; byte[] attachData; 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: attachment = new MimePart(); builder.Attachments.Add(attachment); break; case TnefAttributeTag.Attachment: 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.AttachData: if (prop.IsEmbeddedMessage) { Console.WriteLine("Attachment Property: {0} is an EmbeddedMessage", prop.PropertyTag.Id); var stream = prop.GetRawValueReadStream(); using (var tnef = new TnefReader(stream, reader.MessageCodepage, reader.ComplianceMode)) { var embedded = ExtractTnefMessage(tnef); Console.WriteLine("embedded attachments = {0}", embedded.BodyParts.Count()); foreach (var part in embedded.BodyParts) { builder.Attachments.Add(part); } } } else { Console.WriteLine("Attachment Property: {0} is not an EmbeddedMessage", prop.PropertyTag.Id); } break; default: Console.WriteLine("Attachment Property (unhandled): {0} = {1}", prop.PropertyTag.Id, prop.ReadValue()); break; } } break; case TnefAttributeTag.AttachData: if (attachment == null) { 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(); break; default: Console.WriteLine("Attachment Attribute (unhandled): {0} = {1}", reader.AttributeTag, prop.ReadValue()); break; } } while (reader.ReadNextAttribute()); }
static MimeMessage ExtractTnefMessage(TnefReader reader) { var builder = new BodyBuilder(); var message = new MimeMessage(); while (reader.ReadNextAttribute()) { if (reader.AttributeLevel == TnefAttributeLevel.Attachment) { break; } if (reader.AttributeLevel != TnefAttributeLevel.Message) { Assert.Fail("Unknown attribute level: {0}", reader.AttributeLevel); } var prop = reader.TnefPropertyReader; switch (reader.AttributeTag) { case TnefAttributeTag.RecipientTable: ExtractRecipientTable(reader, message); break; case TnefAttributeTag.MapiProperties: ExtractMapiProperties(reader, message, builder); break; case TnefAttributeTag.DateSent: message.Date = prop.ReadValueAsDateTime(); //Console.WriteLine ("Message Attribute: {0} = {1}", reader.AttributeTag, message.Date); break; case TnefAttributeTag.Body: builder.TextBody = prop.ReadValueAsString(); //Console.WriteLine ("Message Attribute: {0} = {1}", reader.AttributeTag, builder.TextBody); break; case TnefAttributeTag.TnefVersion: //Console.WriteLine ("Message Attribute: {0} = {1}", reader.AttributeTag, prop.ReadValueAsInt32 ()); break; case TnefAttributeTag.OemCodepage: int codepage = prop.ReadValueAsInt32(); try { var encoding = Encoding.GetEncoding(codepage); //Console.WriteLine ("Message Attribute: OemCodepage = {0}", encoding.HeaderName); } catch { //Console.WriteLine ("Message Attribute: OemCodepage = {0}", codepage); } break; default: //Console.WriteLine ("Message Attribute (unhandled): {0} = {1}", reader.AttributeTag, prop.ReadValue ()); break; } } if (reader.AttributeLevel == TnefAttributeLevel.Attachment) { ExtractAttachments(reader, builder); } else { //Console.WriteLine ("no attachments"); } message.Body = builder.ToMessageBody(); return(message); }
internal void ProcessMailItem(MailItem item) { bool isPropertySet = false; int tag; unchecked { tag = (int)0x8000000B; } try { MimePart tnefPart = item.Message.TnefPart; if (tnefPart != null) { TnefReader reader = new TnefReader(tnefPart.GetContentReadStream()); TnefWriter writer = new TnefWriter( tnefPart.GetContentWriteStream(tnefPart.ContentTransferEncoding), reader.AttachmentKey); while (reader.ReadNextAttribute()) { if (reader.AttributeTag == TnefAttributeTag.MapiProperties) { writer.StartAttribute(TnefAttributeTag.MapiProperties, TnefAttributeLevel.Message); while (reader.PropertyReader.ReadNextProperty()) { if (reader.PropertyReader.IsNamedProperty) { switch (reader.PropertyReader.PropertyNameId.Name) { case PropertyTagName: isPropertySet = true; writer.StartProperty(new TnefPropertyTag(tag), PsPublicStrings, PropertyTagName); writer.WritePropertyValue(true); break; default: writer.WriteProperty(reader.PropertyReader); break; } } else { writer.WriteProperty(reader.PropertyReader); } } if (!isPropertySet) { writer.StartProperty(new TnefPropertyTag(tag), PsPublicStrings, PropertyTagName); writer.WritePropertyValue(true); } } else { writer.WriteAttribute(reader); } } if (null != writer) { writer.Close(); } } else { WriteLog("Attempted to process item with null TnefPart. Subject: " + item.Message.Subject, EventLogEntryType.Warning, 2000, EventLogSource); } } catch (Exception ex) { WriteLog(ex.Message + ". Stack Trace: " + ex.StackTrace, EventLogEntryType.Error, 5000, EventLogSource); } }