/// <summary>
        /// Initializes a new instance of the <see cref="MimeKit.Tnef.TnefReader"/> class.
        /// </summary>
        /// <remarks>
        /// <para>When reading a TNEF stream using the <see cref="TnefComplianceMode.Strict"/> mode,
        /// a <see cref="TnefException"/> will be thrown immediately at the first sign of
        /// invalid or corrupted data.</para>
        /// <para>When reading a TNEF stream using the <see cref="TnefComplianceMode.Loose"/> mode,
        /// however, compliance issues are accumulated in the <see cref="ComplianceMode"/>
        /// property, but exceptions are not raised unless the stream is too corrupted to continue.</para>
        /// </remarks>
        /// <param name="inputStream">The input stream.</param>
        /// <param name="defaultMessageCodepage">The default message codepage.</param>
        /// <param name="complianceMode">The compliance mode.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <paramref name="inputStream"/> is <c>null</c>.
        /// </exception>
        /// <exception cref="System.ArgumentOutOfRangeException">
        /// <paramref name="defaultMessageCodepage"/> is not a valid codepage.
        /// </exception>
        /// <exception cref="System.NotSupportedException">
        /// <paramref name="defaultMessageCodepage"/> is not a supported codepage.
        /// </exception>
        /// <exception cref="TnefException">
        /// The TNEF stream is corrupted or invalid.
        /// </exception>
        public TnefReader(Stream inputStream, int defaultMessageCodepage, TnefComplianceMode complianceMode)
        {
            if (inputStream == null)
            {
                throw new ArgumentNullException("inputStream");
            }

            if (defaultMessageCodepage < 0)
            {
                throw new ArgumentOutOfRangeException("defaultMessageCodepage");
            }

            if (defaultMessageCodepage != 0)
            {
                // make sure that this codepage is valid...
                var encoding = Encoding.GetEncoding(defaultMessageCodepage);
                codepage = encoding.CodePage;
            }
            else
            {
                codepage = 1252;
            }

            TnefPropertyReader = new TnefPropertyReader(this);
            ComplianceMode     = complianceMode;
            InputStream        = inputStream;

            DecodeHeader();
        }
        private void ParseAttachmentProperties()
        {
            TnefPropertyReader propertyReader = this.reader.PropertyReader;

            while (propertyReader.ReadNextProperty())
            {
                this.ParseTnefProperty(propertyReader, false);
            }
        }
        private void ParseMapiProperties(bool forceTransmittable)
        {
            TnefPropertyReader propertyReader = this.reader.PropertyReader;

            while (propertyReader.ReadNextProperty())
            {
                this.CheckTnefComplianceStatus();
                this.ParseTnefProperty(propertyReader, forceTransmittable);
            }
        }
        private void ParseAttachRenderData()
        {
            TnefPropertyReader propertyReader = this.reader.PropertyReader;

            while (propertyReader.ReadNextProperty())
            {
                if (propertyReader.PropertyTag != TnefPropertyTag.AttachMethod)
                {
                    this.ParseTnefProperty(propertyReader, false);
                }
            }
        }
Exemple #5
0
        internal static void WriteUnicodePropertyValue(TnefWriter writer, TnefPropertyReader propertyReader, ref char[] buffer)
        {
            if (buffer == null)
            {
                buffer = new char[1024];
            }
            int count;

            while ((count = propertyReader.ReadTextValue(buffer, 0, buffer.Length)) != 0)
            {
                writer.WritePropertyTextValue(buffer, 0, count);
            }
        }
        private void ParseTnefProperty(TnefPropertyReader propertyReader, bool forceTransmittable)
        {
            this.CheckTnefComplianceStatus();
            TnefNameId?namedProperty = propertyReader.IsNamedProperty ? new TnefNameId?(propertyReader.PropertyNameId) : null;
            NativeStorePropertyDefinition nativeStorePropertyDefinition = base.CreatePropertyDefinition(propertyReader.PropertyTag, namedProperty);

            if (nativeStorePropertyDefinition == null)
            {
                return;
            }
            AbstractInboundConverter.IPromotionRule propertyPromotionRule = base.GetPropertyPromotionRule(nativeStorePropertyDefinition);
            if (propertyPromotionRule != null)
            {
                propertyPromotionRule.PromoteProperty(this, nativeStorePropertyDefinition);
            }
        }
Exemple #7
0
        /// <summary>
        /// Advances to the next attribute in the TNEF stream.
        /// </summary>
        /// <remarks>
        /// Advances to the next attribute in the TNEF stream.
        /// </remarks>
        /// <returns><c>true</c> if there is another attribute available to be read; otherwise <c>false</c>.</returns>
        /// <exception cref="TnefException">
        /// The TNEF stream is corrupted or invalid.
        /// </exception>
        public bool ReadNextAttribute()
        {
            CheckDisposed();

            if (AttributeRawValueStreamOffset != 0 && !SkipAttributeRawValue())
            {
                return(false);
            }

            try {
                AttributeLevel = (TnefAttributeLevel)ReadByte();
            } catch (EndOfStreamException) {
                return(false);
            }

            CheckAttributeLevel();

            try {
                AttributeTag                  = (TnefAttributeTag)ReadInt32();
                AttributeRawValueLength       = ReadInt32();
                AttributeRawValueStreamOffset = StreamOffset;
                checksum = 0;
            } catch (EndOfStreamException) {
                SetComplianceError(TnefComplianceStatus.StreamTruncated);
                return(false);
            }

            CheckAttributeTag();

            if (AttributeRawValueLength < 0)
            {
                SetComplianceError(TnefComplianceStatus.InvalidAttributeLength);
                return(false);
            }

            try {
                TnefPropertyReader.Load();
            } catch (EndOfStreamException) {
                SetComplianceError(TnefComplianceStatus.StreamTruncated);
                return(false);
            }

            return(true);
        }
        private void ParseRecipientTable()
        {
            string valueOrDefault = base.CoreItem.PropertyBag.GetValueOrDefault <string>(InternalSchema.ItemClass);

            if (base.ConversionOptions.IsSenderTrusted || !base.MessageWriter.IsTopLevelWriter || ObjectClass.IsNonSendableWithRecipients(valueOrDefault) || ObjectClass.IsDsn(valueOrDefault))
            {
                TnefPropertyReader propertyReader = this.reader.PropertyReader;
                while (propertyReader.ReadNextRow())
                {
                    this.NewRecipient();
                    while (propertyReader.ReadNextProperty())
                    {
                        this.ParseTnefProperty(propertyReader, false);
                    }
                    this.EndRecipient();
                    this.isRecipientTablePromoted = true;
                }
            }
        }
Exemple #9
0
 internal static void WriteUnicodeProperty(TnefWriter writer, TnefPropertyReader propertyReader, TnefPropertyTag tag, ref char[] buffer)
 {
     if (tag.IsNamed)
     {
         TnefNameId propertyNameId = propertyReader.PropertyNameId;
         writer.StartProperty(tag, propertyNameId.PropertySetGuid, propertyNameId.Id);
     }
     else
     {
         writer.StartProperty(tag);
     }
     if (tag.IsMultiValued)
     {
         while (propertyReader.ReadNextValue())
         {
             writer.StartPropertyValue();
             TnefPropertyBag.WriteUnicodePropertyValue(writer, propertyReader, ref buffer);
         }
         return;
     }
     TnefPropertyBag.WriteUnicodePropertyValue(writer, propertyReader, ref buffer);
 }
        private void StreamBody(StorePropertyDefinition property, TnefPropertyReader reader)
        {
            Charset charset = null;

            if (this.internetCpid != 0)
            {
                ConvertUtils.TryGetValidCharset(this.internetCpid, out charset);
            }
            string text = (charset != null) ? charset.Name : null;
            BodyWriteConfiguration bodyWriteConfiguration = null;

            if (property == InternalSchema.TextBody)
            {
                bodyWriteConfiguration = new BodyWriteConfiguration(BodyFormat.TextPlain, ConvertUtils.UnicodeCharset.Name);
                bodyWriteConfiguration.SetTargetFormat(BodyFormat.TextPlain, text);
            }
            else if (property == InternalSchema.HtmlBody)
            {
                bodyWriteConfiguration = new BodyWriteConfiguration(BodyFormat.TextHtml, text);
                bodyWriteConfiguration.SetTargetFormat(BodyFormat.TextHtml, text);
            }
            else if (property == InternalSchema.RtfBody)
            {
                bodyWriteConfiguration = new BodyWriteConfiguration(BodyFormat.ApplicationRtf);
                bodyWriteConfiguration.SetTargetFormat(BodyFormat.ApplicationRtf, text);
            }
            int trailingNulls;

            using (Stream stream = this.OpenValueReadStream(out trailingNulls))
            {
                base.CoreItem.CharsetDetector.DetectionOptions = base.ConversionOptions.DetectionOptions;
                using (Stream stream2 = base.CoreItem.Body.InternalOpenWriteStream(bodyWriteConfiguration, null))
                {
                    Util.StreamHandler.CopyStreamData(stream, stream2, null, trailingNulls, 65536);
                }
            }
        }
Exemple #11
0
        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);
        }
        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");
                }
            }
        }
Exemple #13
0
        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();
            }
        }
Exemple #14
0
        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);
        }
Exemple #15
0
        static string GetHtmlBody(TnefPropertyReader prop, int codepage, out Encoding encoding)
        {
            var rawValue  = prop.ReadValueAsBytes();
            int rawLength = rawValue.Length;

            while (rawLength > 0 && rawValue[rawLength - 1] == 0)
            {
                rawLength--;
            }

            // Try and extract the charset from the HTML meta Content-Type value.
            using (var stream = new MemoryStream(rawValue, 0, rawLength)) {
                // It should be safe to assume ISO-8859-1 for this purpose. We don't want to risk using UTF-8 (or any other charset) and having it throw an exception...
                using (var reader = new StreamReader(stream, CharsetUtils.Latin1, true)) {
                    var       tokenizer = new HtmlTokenizer(reader);
                    HtmlToken token;

                    while (tokenizer.ReadNextToken(out token))
                    {
                        if (token.Kind != HtmlTokenKind.Tag)
                        {
                            continue;
                        }

                        var tag = (HtmlTagToken)token;

                        if (tag.Id == HtmlTagId.Body || (tag.Id == HtmlTagId.Head && tag.IsEndTag))
                        {
                            break;
                        }

                        if (tag.Id != HtmlTagId.Meta || tag.IsEndTag)
                        {
                            continue;
                        }

                        string httpEquiv = null;
                        string content   = null;

                        for (int i = 0; i < tag.Attributes.Count; i++)
                        {
                            switch (tag.Attributes[i].Id)
                            {
                            case HtmlAttributeId.HttpEquiv: httpEquiv = httpEquiv ?? tag.Attributes[i].Value; break;

                            case HtmlAttributeId.Content: content = content ?? tag.Attributes[i].Value; break;
                            }
                        }

                        if (httpEquiv == null || !httpEquiv.Equals("Content-Type", StringComparison.OrdinalIgnoreCase))
                        {
                            continue;
                        }

                        if (!ContentType.TryParse(content, out var contentType) || string.IsNullOrEmpty(contentType.Charset))
                        {
                            break;
                        }

                        try {
                            encoding = Encoding.GetEncoding(contentType.Charset, EncoderFallback.ExceptionFallback, DecoderFallback.ExceptionFallback);

                            // If this converts cleanly, then we're golden.
                            return(encoding.GetString(rawValue, 0, rawLength));
                        } catch {
                            // Otherwise, fall back to assuming the TNEF message codepage.
                            break;
                        }
                    }

                    encoding = Encoding.GetEncoding(codepage);

                    return(encoding.GetString(rawValue, 0, rawLength));
                }
            }
        }
        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
                {
                }
            }
        }
Exemple #17
0
        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);
        }