public void TestCrossingWritePositionExample ()
		{
			// http://msdn.microsoft.com/en-us/library/ee158471(v=exchg.80).aspx
			var compressedRtfData = new byte[] {
				// header
				0x1a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x4c, 0x5a, 0x46, 0x75, 0xe2, 0xd4, 0x4b, 0x51,

				// data
				0x41, 0x00, 0x04, 0x20, 0x57, 0x58, 0x59, 0x5a, 0x0d, 0x6e, 0x7d, 0x01, 0x0e, 0xb0
			};
			var expected = "{\\rtf1 WXYZWXYZWXYZWXYZWXYZ}";

			var converter = new RtfCompressedToRtf ();
			int outputLength, outputIndex;

			var decompressed = converter.Flush (compressedRtfData, 0, compressedRtfData.Length, out outputIndex, out outputLength);
			var text = Encoding.UTF8.GetString (decompressed, outputIndex, outputLength);

			Assert.AreEqual (expected, text, "Decompressed RTF data does not match.");
			Assert.IsTrue (converter.IsValidCrc32, "Invalid CRC32 checksum.");
		}
		public void TestSimpleCompressedRtfExample ()
		{
			// http://msdn.microsoft.com/en-us/library/ee217938(v=exchg.80).aspx
			var compressedRtfData = new byte[] {
				// header
				0x2d, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x4c, 0x5a, 0x46, 0x75, 0xf1, 0xc5, 0xc7, 0xa7,

				// data
				0x03, 0x00, 0x0a, 0x00, 0x72, 0x63, 0x70, 0x67, 0x31, 0x32, 0x35, 0x42, 0x32, 0x0a, 0xf3, 0x20,
				0x68, 0x65, 0x6c, 0x09, 0x00, 0x20, 0x62, 0x77, 0x05, 0xb0, 0x6c, 0x64, 0x7d, 0x0a, 0x80, 0x0f,
				0xa0
			};
			var expected = "{\\rtf1\\ansi\\ansicpg1252\\pard hello world}\r\n";

			var converter = new RtfCompressedToRtf ();
			int outputLength, outputIndex;

			var decompressed = converter.Flush (compressedRtfData, 0, compressedRtfData.Length, out outputIndex, out outputLength);
			var text = Encoding.UTF8.GetString (decompressed, outputIndex, outputLength);

			Assert.AreEqual (expected, text, "Decompressed RTF data does not match.");
			Assert.IsTrue (converter.IsValidCrc32, "Invalid CRC32 checksum.");
		}
Beispiel #3
0
        static void ExtractMapiProperties(TnefReader reader, MimeMessage message, BodyBuilder builder)
        {
            var            prop              = reader.TnefPropertyReader;
            var            recipient         = new EmailAddress();
            var            sender            = new EmailAddress();
            string         normalizedSubject = null;
            string         subjectPrefix     = null;
            MailboxAddress mailbox;
            var            msgid = false;

            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();
                        msgid             = true;
                    }
                    break;

                case TnefPropertyId.TnefCorrelationKey:
                    // According to MSDN, PidTagTnefCorrelationKey is a unique key that is
                    // meant to be used to tie the TNEF attachment to the encapsulating
                    // message. It can be a string or a binary blob. It seems that most
                    // implementations use the Message-Id string, so if this property
                    // value looks like a Message-Id, then us it as one (unless we get a
                    // InternetMessageId property, in which case we use that instead.
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        if (!msgid)
                        {
                            var value = prop.ReadValueAsString();

                            if (value.Length > 5 && value[0] == '<' && value[value.Length - 1] == '>' && value.IndexOf('@') != -1)
                            {
                                message.MessageId = value;
                            }
                        }
                    }
                    break;

                case TnefPropertyId.Subject:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        message.Subject = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.SubjectPrefix:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        subjectPrefix = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.NormalizedSubject:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        normalizedSubject = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.SenderName:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        sender.Name = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.SenderEmailAddress:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        sender.Addr = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.SenderSearchKey:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        sender.SearchKey = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.SenderAddrtype:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        sender.AddrType = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.ReceivedByName:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        recipient.Name = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.ReceivedByEmailAddress:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        recipient.Addr = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.ReceivedBySearchKey:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        recipient.SearchKey = prop.ReadValueAsString();
                    }
                    break;

                case TnefPropertyId.ReceivedByAddrtype:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        recipient.AddrType = prop.ReadValueAsString();
                    }
                    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");

                        var converter = new RtfCompressedToRtf();
                        var content   = new MemoryBlockStream();

                        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);
                    }
                    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");
                        Encoding encoding;

                        if (prop.PropertyTag.ValueTnefType != TnefPropertyType.Unicode)
                        {
                            encoding = Encoding.GetEncoding(reader.MessageCodepage);
                        }
                        else
                        {
                            encoding = CharsetUtils.UTF8;
                        }

                        html.SetText(encoding, prop.ReadValueAsString());

                        builder.Attachments.Add(html);
                    }
                    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");
                        Encoding encoding;

                        if (prop.PropertyTag.ValueTnefType != TnefPropertyType.Unicode)
                        {
                            encoding = Encoding.GetEncoding(reader.MessageCodepage);
                        }
                        else
                        {
                            encoding = CharsetUtils.UTF8;
                        }

                        plain.SetText(encoding, prop.ReadValueAsString());

                        builder.Attachments.Add(plain);
                    }
                    break;

                case TnefPropertyId.Importance:
                    // https://msdn.microsoft.com/en-us/library/ee237166(v=exchg.80).aspx
                    switch (prop.ReadValueAsInt32())
                    {
                    case 2: message.Importance = MessageImportance.High; break;

                    case 1: message.Importance = MessageImportance.Normal; break;

                    case 0: message.Importance = MessageImportance.Low; break;
                    }
                    break;

                case TnefPropertyId.Priority:
                    // https://msdn.microsoft.com/en-us/library/ee159473(v=exchg.80).aspx
                    switch (prop.ReadValueAsInt32())
                    {
                    case  1: message.Priority = MessagePriority.Urgent; break;

                    case  0: message.Priority = MessagePriority.Normal; break;

                    case -1: message.Priority = MessagePriority.NonUrgent; break;
                    }
                    break;

                case TnefPropertyId.Sensitivity:
                    // https://msdn.microsoft.com/en-us/library/ee217353(v=exchg.80).aspx
                    // https://tools.ietf.org/html/rfc2156#section-5.3.4
                    switch (prop.ReadValueAsInt32())
                    {
                    case 1: message.Headers[HeaderId.Sensitivity] = "Personal"; break;

                    case 2: message.Headers[HeaderId.Sensitivity] = "Private"; break;

                    case 3: message.Headers[HeaderId.Sensitivity] = "Company-Confidential"; break;

                    case 0: message.Headers.Remove(HeaderId.Sensitivity); break;
                    }
                    break;
                }
            }

            if (string.IsNullOrEmpty(message.Subject) && !string.IsNullOrEmpty(normalizedSubject))
            {
                if (!string.IsNullOrEmpty(subjectPrefix))
                {
                    message.Subject = subjectPrefix + normalizedSubject;
                }
                else
                {
                    message.Subject = normalizedSubject;
                }
            }

            if (sender.TryGetMailboxAddress(out mailbox))
            {
                message.From.Add(mailbox);
            }

            if (recipient.TryGetMailboxAddress(out mailbox))
            {
                message.To.Add(mailbox);
            }
        }
Beispiel #4
0
        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();
                    }
                    break;

                case TnefPropertyId.Subject:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        message.Subject = prop.ReadValueAsString();
                    }
                    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");

                        var converter = new RtfCompressedToRtf();
                        var content   = new MemoryBlockStream();

                        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);
                    }
                    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");
                        Encoding encoding;

                        if (prop.PropertyTag.ValueTnefType != TnefPropertyType.Unicode)
                        {
                            encoding = Encoding.GetEncoding(reader.MessageCodepage);
                        }
                        else
                        {
                            encoding = CharsetUtils.UTF8;
                        }

                        html.SetText(encoding, prop.ReadValueAsString());

                        builder.Attachments.Add(html);
                    }
                    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");
                        Encoding encoding;

                        if (prop.PropertyTag.ValueTnefType != TnefPropertyType.Unicode)
                        {
                            encoding = Encoding.GetEncoding(reader.MessageCodepage);
                        }
                        else
                        {
                            encoding = CharsetUtils.UTF8;
                        }

                        plain.SetText(encoding, prop.ReadValueAsString());

                        builder.Attachments.Add(plain);
                    }
                    break;

                case TnefPropertyId.Importance:
                    switch (prop.ReadValueAsInt32())
                    {
                    case 2: message.Importance = MessageImportance.High; break;

                    case 0: message.Importance = MessageImportance.Low; break;
                    }
                    break;

                case TnefPropertyId.Priority:
                    switch (prop.ReadValueAsInt32())
                    {
                    case 2: message.Priority = MessagePriority.Urgent; break;

                    case 0: message.Priority = MessagePriority.NonUrgent; break;
                    }
                    break;
                }
            }
        }
Beispiel #5
0
        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();
                    }
                    break;

                case TnefPropertyId.Subject:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        message.Subject = prop.ReadValueAsString();
                    }
                    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 MemoryBlockStream();

                        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);
                    }
                    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);
                    }
                    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);
                    }
                    break;
                }
            }
        }
Beispiel #6
0
		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 ();
					}
					break;
				case TnefPropertyId.Subject:
					if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
						prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) {
						message.Subject = prop.ReadValueAsString ();
					}
					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);
					}
					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);
					}
					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);
					}
					break;
				}
			}
		}
Beispiel #7
0
        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:
                    Console.WriteLine ("Message Property (unhandled): {0} = {1}", prop.PropertyTag.Id, prop.ReadValue ());
                    break;
                }
            }
        }
        private void ExtractMapiProperties(TnefReader reader, MimeMessage message, BodyBuilder builder)
        {
            var tnefPropertyReader = reader.TnefPropertyReader;
            while (tnefPropertyReader.ReadNextProperty())
            {
                switch (tnefPropertyReader.PropertyTag.Id)
                {
                    case TnefPropertyId.RtfCompressed:
                        var memoryStream = new MemoryStream();
                        if (tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.String8 || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                        {
                            var textPart = new TextPart("rtf");
                            textPart.ContentType.Name = "body.rtf";
                            RtfCompressedToRtf rtfCompressedToRtf = new RtfCompressedToRtf();
                            //var memoryStream = new MemoryStream();
                            using (var filteredStream = new FilteredStream(memoryStream))
                            {
                                filteredStream.Add(rtfCompressedToRtf);
                                using (Stream rawValueReadStream = tnefPropertyReader.GetRawValueReadStream())
                                {
                                    rawValueReadStream.CopyTo(filteredStream, 4096);
                                    filteredStream.Flush();
                                }
                            }

                            textPart.ContentObject = new ContentObject(memoryStream, ContentEncoding.Default);
                            memoryStream.Position = 0L;
                            builder.Attachments.Add(textPart);
                            continue;
                        }

                        memoryStream.Dispose();
                        continue;
                    case TnefPropertyId.BodyHtml:
                        if (tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.String8 || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                        {
                            var textPart = new TextPart("html");
                            textPart.ContentType.Name = "body.html";
                            textPart.Text = tnefPropertyReader.ReadValueAsString();
                            builder.Attachments.Add(textPart);
                            continue;
                        }

                        continue;
                    case TnefPropertyId.InternetMessageId:
                        if (tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.String8 || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                        {
                            message.MessageId = tnefPropertyReader.ReadValueAsString();
                            continue;
                        }

                        continue;
                    case TnefPropertyId.Subject:
                        if (tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.String8 || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                        {
                            message.Subject = tnefPropertyReader.ReadValueAsString();
                            continue;
                        }

                        continue;
                    case TnefPropertyId.Body:
                        if (tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.String8 || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                        {
                            var textPart = new TextPart("plain");
                            textPart.ContentType.Name = "body.txt";
                            textPart.Text = tnefPropertyReader.ReadValueAsString();
                            builder.Attachments.Add(textPart);
                            continue;
                        }

                        continue;
                    case TnefPropertyId.ConversationTopic:
                        if (tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.String8 || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                        {
                            message.Subject = tnefPropertyReader.ReadValueAsString();
                            continue;
                        }

                        continue;
                    case TnefPropertyId.SenderName:
                        if (tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.String8 || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                        {
                            var sender = new MailboxAddress(string.Empty, tnefPropertyReader.ReadValueAsString());
                            message.Sender = sender;
                        }

                        continue;
                    case (TnefPropertyId)Mapi.ID.PR_PRIMARY_SEND_ACCOUNT:
                        if (tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.String8 || tnefPropertyReader.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                        {
                            var senderEmail = new MailboxAddress(string.Empty, tnefPropertyReader.ReadValueAsString());
                            message.Sender = senderEmail;
                        }

                        continue;
                    default:
                        try
                        {
                            tnefPropertyReader.ReadValue();
                            continue;
                        }
                        catch
                        {
                            continue;
                        }
                }
            }
        }