예제 #1
0
        /// <summary>
        ///     Creates this object and sets all it's properties
        /// </summary>
        internal Message()
        {
            CompoundFile = new CompoundFile();

            // In the preceding figure, the "__nameid_version1.0" named property mapping storage contains the
            // three streams  used to provide a mapping from property ID to property name
            // ("__substg1.0_00020102", "__substg1.0_00030102", and "__substg1.0_00040102") and various other
            // streams that provide a mapping from property names to property IDs.
            if (!CompoundFile.RootStorage.TryGetStorage(PropertyTags.NameIdStorage, out var nameIdStorage))
            {
                nameIdStorage = CompoundFile.RootStorage.AddStorage(PropertyTags.NameIdStorage);
            }

            var entryStream = nameIdStorage.AddStream(PropertyTags.EntryStream);

            entryStream.SetData(new byte[0]);
            var stringStream = nameIdStorage.AddStream(PropertyTags.StringStream);

            stringStream.SetData(new byte[0]);
            var guidStream = nameIdStorage.AddStream(PropertyTags.GuidStream);

            guidStream.SetData(new byte[0]);

            TopLevelProperties = new TopLevelProperties();
            NamedProperties    = new NamedProperties(TopLevelProperties);
        }
예제 #2
0
 /// <summary>
 ///     Writes all <see cref="Property">properties</see> either as a <see cref="CFStream"/> or as a collection in
 ///     a <see cref="PropertyTags.PropertiesStreamName"/> stream, this depends on the <see cref="PropertyType"/>
 /// </summary>
 /// <remarks>
 ///     See the <see cref="Properties"/> class it's <see cref="Properties.WriteProperties"/> method for the logic
 ///     that is used to determine this
 /// </remarks>
 /// <param name="propertiesStream">The <see cref="TopLevelProperties"/></param>
 internal void WriteProperties(TopLevelProperties propertiesStream)
 {
     propertiesStream.AddProperty(PropertyTags.PR_RECEIVED_BY_EMAIL_ADDRESS_W, Email);
     propertiesStream.AddProperty(PropertyTags.PR_RECEIVED_BY_NAME_W, DisplayName);
     propertiesStream.AddProperty(PropertyTags.PR_RcvdBySimpleDispName_W, DisplayName);
     propertiesStream.AddProperty(PropertyTags.PR_RECEIVED_BY_ADDRTYPE_W, AddressTypeString);
 }
예제 #3
0
        /// <summary>
        ///     Writes all <see cref="Property">properties</see> either as a <see cref="CFStream"/> or as a collection in
        ///     a <see cref="PropertyTags.PropertiesStreamName"/> stream, this depends on the <see cref="PropertyType"/>
        /// </summary>
        /// <remarks>
        ///     See the <see cref="Properties"/> class it's <see cref="Properties.WriteProperties"/> method for the logic
        ///     that is used to determine this
        /// </remarks>
        /// <param name="propertiesStream">The <see cref="TopLevelProperties"/></param>
        internal void WriteProperties(TopLevelProperties propertiesStream)
        {
            propertiesStream.AddProperty(PropertyTags.PR_RCVD_REPRESENTING_EMAIL_ADDRESS_W, Email);
            propertiesStream.AddProperty(PropertyTags.PR_RCVD_REPRESENTING_NAME_W, DisplayName);
            propertiesStream.AddProperty(PropertyTags.PR_RcvdRepresentingSimpleDispName_W, DisplayName);
            propertiesStream.AddProperty(PropertyTags.PR_RCVD_REPRESENTING_ADDRTYPE_W, AddressTypeString);

            var entryId = new OneOffEntryId(Email,
                                            DisplayName,
                                            AddressType,
                                            MessageFormat.TextAndHtml,
                                            false);

            propertiesStream.AddProperty(PropertyTags.PR_RCVD_REPRESENTING_ENTRYID, entryId.ToByteArray());
        }
예제 #4
0
파일: Sender.cs 프로젝트: steveoc64/MsgKit
        /// <summary>
        ///     Writes all <see cref="Property">properties</see> either as a <see cref="CFStream"/> or as a collection in
        ///     a <see cref="PropertyTags.PropertiesStreamName"/> stream, this depends on the <see cref="PropertyType"/>
        /// </summary>
        /// <remarks>
        ///     See the <see cref="Properties"/> class it's <see cref="Properties.WriteProperties"/> method for the logic
        ///     that is used to determine this
        /// </remarks>
        /// <param name="propertiesStream">The <see cref="TopLevelProperties"/></param>
        internal void WriteProperties(TopLevelProperties propertiesStream)
        {
            if (_senderIsCreator)
            {
                propertiesStream.AddProperty(PropertyTags.PR_CreatorEmailAddr_W, Email);
                propertiesStream.AddProperty(PropertyTags.PR_CreatorSimpleDispName_W, DisplayName);
                propertiesStream.AddProperty(PropertyTags.PR_CreatorAddrType_W, AddressTypeString);
            }

            var senderEntryId = new OneOffEntryId(Email,
                                                  DisplayName,
                                                  AddressType,
                                                  _messageFormat,
                                                  _canLookupEmailAddress);

            propertiesStream.AddProperty(PropertyTags.PR_SENDER_ENTRYID, senderEntryId.ToByteArray());

            propertiesStream.AddProperty(PropertyTags.PR_SENDER_EMAIL_ADDRESS_W, Email);
            propertiesStream.AddProperty(PropertyTags.PR_SENDER_NAME_W, DisplayName);
            propertiesStream.AddProperty(PropertyTags.PR_SENDER_ADDRTYPE_W, AddressTypeString);
        }
예제 #5
0
파일: Email.cs 프로젝트: Xylon5/MsgKit
        /// <summary>
        ///     Writes all the properties that are part of the <see cref="Email"/> object either as <see cref="CFStorage"/>'s
        ///     or <see cref="CFStream"/>'s to the <see cref="CompoundFile.RootStorage"/>
        /// </summary>
        internal void WriteToStorage()
        {
            var rootStorage = CompoundFile.RootStorage;

            Class        = MessageClass.IPM_Note;
            MessageSize += Recipients.WriteToStorage(rootStorage);
            MessageSize += Attachments.WriteToStorage(rootStorage);

            var recipientCount  = Recipients.Count;
            var attachmentCount = Attachments.Count;

            TopLevelProperties.RecipientCount   = recipientCount;
            TopLevelProperties.AttachmentCount  = attachmentCount;
            TopLevelProperties.NextRecipientId  = recipientCount;
            TopLevelProperties.NextAttachmentId = attachmentCount;

            if (!string.IsNullOrEmpty(InternetMessageId))
            {
                TopLevelProperties.AddProperty(PropertyTags.PR_INTERNET_MESSAGE_ID_W, InternetMessageId);
            }

            TopLevelProperties.AddProperty(PropertyTags.PR_ENTRYID, Mapi.GenerateEntryId());
            TopLevelProperties.AddProperty(PropertyTags.PR_INSTANCE_KEY, Mapi.GenerateInstanceKey());
            TopLevelProperties.AddProperty(PropertyTags.PR_STORE_SUPPORT_MASK, StoreSupportMaskConst.StoreSupportMask, PropertyFlags.PROPATTR_READABLE);
            TopLevelProperties.AddProperty(PropertyTags.PR_STORE_UNICODE_MASK, StoreSupportMaskConst.StoreSupportMask, PropertyFlags.PROPATTR_READABLE);
            TopLevelProperties.AddProperty(PropertyTags.PR_ALTERNATE_RECIPIENT_ALLOWED, true, PropertyFlags.PROPATTR_READABLE);
            TopLevelProperties.AddProperty(PropertyTags.PR_HASATTACH, attachmentCount > 0);
            TopLevelProperties.AddProperty(PropertyTags.PR_TRANSPORT_MESSAGE_HEADERS_W, TransportMessageHeaders);

            var messageFlags = MessageFlags.MSGFLAG_UNMODIFIED;

            if (attachmentCount > 0)
            {
                messageFlags |= MessageFlags.MSGFLAG_HASATTACH;
            }

            TopLevelProperties.AddProperty(PropertyTags.PR_INTERNET_CPID, Encoding.UTF8.CodePage);

            TopLevelProperties.AddProperty(PropertyTags.PR_BODY_W, BodyText);
            if (!string.IsNullOrEmpty(BodyHtml))
            {
                TopLevelProperties.AddProperty(PropertyTags.PR_HTML, BodyHtml);
            }

            if (Draft)
            {
                messageFlags |= MessageFlags.MSGFLAG_UNSENT | MessageFlags.MSGFLAG_FROMME;
                IconIndex     = MessageIconIndex.UnsentMail;

                if (string.IsNullOrWhiteSpace(BodyRtf) && !string.IsNullOrWhiteSpace(BodyHtml))
                {
                    BodyRtf           = Strings.GetEscapedRtf(BodyHtml);
                    BodyRtfCompressed = true;
                }
            }

            if (!SentOn.HasValue)
            {
                SentOn = DateTime.UtcNow;
            }

            TopLevelProperties.AddProperty(PropertyTags.PR_CLIENT_SUBMIT_TIME, SentOn.Value.ToUniversalTime());
            TopLevelProperties.AddProperty(PropertyTags.PR_MESSAGE_FLAGS, messageFlags);
            TopLevelProperties.AddProperty(PropertyTags.PR_ACCESS, MapiAccess.MAPI_ACCESS_DELETE | MapiAccess.MAPI_ACCESS_MODIFY | MapiAccess.MAPI_ACCESS_READ);
            TopLevelProperties.AddProperty(PropertyTags.PR_ACCESS_LEVEL, MapiAccess.MAPI_ACCESS_MODIFY);
            TopLevelProperties.AddProperty(PropertyTags.PR_OBJECT_TYPE, MapiObjectType.MAPI_MESSAGE);

            SetSubject();
            TopLevelProperties.AddProperty(PropertyTags.PR_SUBJECT_W, Subject);
            TopLevelProperties.AddProperty(PropertyTags.PR_NORMALIZED_SUBJECT_W, SubjectNormalized);
            TopLevelProperties.AddProperty(PropertyTags.PR_SUBJECT_PREFIX_W, SubjectPrefix);
            TopLevelProperties.AddProperty(PropertyTags.PR_CONVERSATION_TOPIC_W, SubjectNormalized);

            // http://www.meridiandiscovery.com/how-to/e-mail-conversation-index-metadata-computer-forensics/
            // http://stackoverflow.com/questions/11860540/does-outlook-embed-a-messageid-or-equivalent-in-its-email-elements
            //propertiesStream.AddProperty(PropertyTags.PR_CONVERSATION_INDEX, Subject);

            // TODO: Change modification time when this message is opened and only modified
            var utcNow = DateTime.UtcNow;

            TopLevelProperties.AddProperty(PropertyTags.PR_CREATION_TIME, utcNow);
            TopLevelProperties.AddProperty(PropertyTags.PR_LAST_MODIFICATION_TIME, utcNow);
            TopLevelProperties.AddProperty(PropertyTags.PR_PRIORITY, Priority);
            TopLevelProperties.AddProperty(PropertyTags.PR_IMPORTANCE, Importance);
            TopLevelProperties.AddProperty(PropertyTags.PR_MESSAGE_LOCALE_ID, CultureInfo.CurrentCulture.LCID);
            TopLevelProperties.AddProperty(PropertyTags.PR_ICON_INDEX, IconIndex);

            if (Sender != null)
            {
                Sender.WriteProperties(TopLevelProperties);
            }
            if (Receiving != null)
            {
                Receiving.WriteProperties(TopLevelProperties);
            }
            if (Representing != null)
            {
                Representing.WriteProperties(TopLevelProperties);
            }
            if (ReceivingRepresenting != null)
            {
                ReceivingRepresenting.WriteProperties(TopLevelProperties);
            }

            if (recipientCount > 0)
            {
                var displayTo  = new List <string>();
                var displayCc  = new List <string>();
                var displayBcc = new List <string>();

                foreach (var recipient in Recipients)
                {
                    switch (recipient.RecipientType)
                    {
                    case RecipientType.To:
                        if (!string.IsNullOrWhiteSpace(recipient.DisplayName))
                        {
                            displayTo.Add(recipient.DisplayName);
                        }
                        else if (!string.IsNullOrWhiteSpace(recipient.Email))
                        {
                            displayTo.Add(recipient.Email);
                        }
                        break;

                    case RecipientType.Cc:
                        if (!string.IsNullOrWhiteSpace(recipient.DisplayName))
                        {
                            displayCc.Add(recipient.DisplayName);
                        }
                        else if (!string.IsNullOrWhiteSpace(recipient.Email))
                        {
                            displayCc.Add(recipient.Email);
                        }
                        break;

                    case RecipientType.Bcc:
                        if (!string.IsNullOrWhiteSpace(recipient.DisplayName))
                        {
                            displayBcc.Add(recipient.DisplayName);
                        }
                        else if (!string.IsNullOrWhiteSpace(recipient.Email))
                        {
                            displayBcc.Add(recipient.Email);
                        }
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }

                TopLevelProperties.AddProperty(PropertyTags.PR_DISPLAY_TO_W, string.Join(";", displayTo), PropertyFlags.PROPATTR_READABLE);
                TopLevelProperties.AddProperty(PropertyTags.PR_DISPLAY_CC_W, string.Join(";", displayCc), PropertyFlags.PROPATTR_READABLE);
                TopLevelProperties.AddProperty(PropertyTags.PR_DISPLAY_BCC_W, string.Join(";", displayBcc), PropertyFlags.PROPATTR_READABLE);
            }

            if (!string.IsNullOrEmpty(BodyRtf) && BodyRtfCompressed)
            {
                TopLevelProperties.AddProperty(PropertyTags.PR_RTF_COMPRESSED, RtfCompressor.Compress(Encoding.ASCII.GetBytes(BodyRtf)));
                TopLevelProperties.AddProperty(PropertyTags.PR_RTF_IN_SYNC, true);
            }
        }
예제 #6
0
 /// <summary>
 ///     Writes all <see cref="Property">properties</see> either as a <see cref="CFStream"/> or as a collection in
 ///     a <see cref="PropertyTags.PropertiesStreamName"/> stream, this depends on the <see cref="PropertyType"/>
 /// </summary>
 /// <remarks>
 ///     See the <see cref="Properties"/> class it's <see cref="Properties.WriteProperties"/> method for the logic
 ///     that is used to determine this
 /// </remarks>
 /// <param name="propertiesStream">The <see cref="TopLevelProperties"/></param>
 internal void WriteProperties(TopLevelProperties propertiesStream)
 {
     propertiesStream.AddProperty(PropertyTags.PR_SENT_REPRESENTING_EMAIL_ADDRESS_W, Email);
     propertiesStream.AddProperty(PropertyTags.PR_SENT_REPRESENTING_NAME_W, DisplayName);
     propertiesStream.AddProperty(PropertyTags.PR_SENT_REPRESENTING_ADDRTYPE_W, AddressTypeString);
 }
예제 #7
0
파일: Email.cs 프로젝트: Repstor/MsgKit
        /// <summary>
        ///     Writes all the properties that are part of the <see cref="Email"/> object either as <see cref="CFStorage"/>'s
        ///     or <see cref="CFStream"/>'s to the <see cref="CompoundFile.RootStorage"/>
        /// </summary>
        internal new void WriteToStorage()
        {
            base.WriteToStorage();
            TopLevelProperties.AddProperty(PropertyTags.PR_STORE_SUPPORT_MASK, StoreSupportMaskConst.StoreSupportMask, PropertyFlags.PROPATTR_READABLE);

            var rootStorage = CompoundFile.RootStorage;

            Class        = MessageClass.IPM_Note;
            MessageSize += Recipients.WriteToStorage(rootStorage);


            var recipientCount = Recipients.Count;

            TopLevelProperties.RecipientCount = recipientCount;

            TopLevelProperties.NextRecipientId = recipientCount;


            //TopLevelProperties.AddProperty(PropertyTags.PR_ENTRYID, Mapi.GenerateEntryId());
            //TopLevelProperties.AddProperty(PropertyTags.PR_INSTANCE_KEY, Mapi.GenerateInstanceKey());

            TopLevelProperties.AddProperty(PropertyTags.PR_STORE_UNICODE_MASK, StoreSupportMaskConst.StoreSupportMask, PropertyFlags.PROPATTR_READABLE);
            TopLevelProperties.AddProperty(PropertyTags.PR_ALTERNATE_RECIPIENT_ALLOWED, true, PropertyFlags.PROPATTR_READABLE);

            if (!string.IsNullOrWhiteSpace(InternetMessageId))
            {
                TopLevelProperties.AddOrReplaceProperty(PropertyTags.PR_INTERNET_MESSAGE_ID_W, InternetMessageId);
            }

            if (!string.IsNullOrWhiteSpace(InternetReferences))
            {
                TopLevelProperties.AddOrReplaceProperty(PropertyTags.PR_INTERNET_REFERENCES_W, InternetReferences);
            }

            if (!string.IsNullOrWhiteSpace(InReplyToId))
            {
                TopLevelProperties.AddOrReplaceProperty(PropertyTags.PR_IN_REPLY_TO_ID_W, InReplyToId);
            }

            _messageFlags = MessageFlags.MSGFLAG_UNMODIFIED;

            TopLevelProperties.AddProperty(PropertyTags.PR_INTERNET_CPID, Encoding.UTF8.CodePage);


            if (MessageEditorFormat != MessageEditorFormat.EDITOR_FORMAT_DONTKNOW)
            {
                TopLevelProperties.AddProperty(PropertyTags.PR_MSG_EDITOR_FORMAT, MessageEditorFormat);
            }

            if (ReceivedOn.HasValue)
            {
                TopLevelProperties.AddProperty(PropertyTags.PR_MESSAGE_DELIVERY_TIME, ReceivedOn.Value.ToUniversalTime());
                TopLevelProperties.AddProperty(PropertyTags.PR_DELIVER_TIME, ReceivedOn.Value.ToUniversalTime());
                TopLevelProperties.AddProperty(PropertyTags.PR_LATEST_DELIVERY_TIME, ReceivedOn.Value.ToUniversalTime());
                TopLevelProperties.AddProperty(PropertyTags.PR_RECEIPT_TIME, ReceivedOn.Value.ToUniversalTime());
            }

            TopLevelProperties.AddProperty(PropertyTags.PR_ACCESS, MapiAccess.MAPI_ACCESS_DELETE | MapiAccess.MAPI_ACCESS_MODIFY | MapiAccess.MAPI_ACCESS_READ);
            TopLevelProperties.AddProperty(PropertyTags.PR_ACCESS_LEVEL, MapiAccess.MAPI_ACCESS_MODIFY);
            TopLevelProperties.AddProperty(PropertyTags.PR_OBJECT_TYPE, MapiObjectType.MAPI_MESSAGE);

            // http://www.meridiandiscovery.com/how-to/e-mail-conversation-index-metadata-computer-forensics/
            // http://stackoverflow.com/questions/11860540/does-outlook-embed-a-messageid-or-equivalent-in-its-email-elements
            //propertiesStream.AddProperty(PropertyTags.PR_CONVERSATION_INDEX, Subject);

            // TODO: Change modification time when this message is opened and only modified
            var utcNow = DateTime.UtcNow;

            if (Draft)
            {
                _messageFlags |= MessageFlags.MSGFLAG_UNSENT;
                IconIndex      = MessageIconIndex.UnsentMail;
            }

            TopLevelProperties.AddProperty(PropertyTags.PR_MESSAGE_FLAGS, _messageFlags);

            Sender?.WriteProperties(TopLevelProperties);
            Receiving?.WriteProperties(TopLevelProperties);
            Representing?.WriteProperties(TopLevelProperties);
            ReceivingRepresenting?.WriteProperties(TopLevelProperties);

            if (recipientCount > 0)
            {
                var displayTo  = new List <string>();
                var displayCc  = new List <string>();
                var displayBcc = new List <string>();

                foreach (var recipient in Recipients)
                {
                    switch (recipient.RecipientType)
                    {
                    case RecipientType.To:
                        if (!string.IsNullOrWhiteSpace(recipient.DisplayName))
                        {
                            displayTo.Add(recipient.DisplayName);
                        }
                        else if (!string.IsNullOrWhiteSpace(recipient.Email))
                        {
                            displayTo.Add(recipient.Email);
                        }
                        break;

                    case RecipientType.Cc:
                        if (!string.IsNullOrWhiteSpace(recipient.DisplayName))
                        {
                            displayCc.Add(recipient.DisplayName);
                        }
                        else if (!string.IsNullOrWhiteSpace(recipient.Email))
                        {
                            displayCc.Add(recipient.Email);
                        }
                        break;

                    case RecipientType.Bcc:
                        if (!string.IsNullOrWhiteSpace(recipient.DisplayName))
                        {
                            displayBcc.Add(recipient.DisplayName);
                        }
                        else if (!string.IsNullOrWhiteSpace(recipient.Email))
                        {
                            displayBcc.Add(recipient.Email);
                        }
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }

                TopLevelProperties.AddProperty(PropertyTags.PR_DISPLAY_TO_W, string.Join(";", displayTo), PropertyFlags.PROPATTR_READABLE);
                TopLevelProperties.AddProperty(PropertyTags.PR_DISPLAY_CC_W, string.Join(";", displayCc), PropertyFlags.PROPATTR_READABLE);
                TopLevelProperties.AddProperty(PropertyTags.PR_DISPLAY_BCC_W, string.Join(";", displayBcc), PropertyFlags.PROPATTR_READABLE);

                AddExtendedProperties();
            }
        }
예제 #8
0
        /// <summary>
        ///     Writes all the properties that are part of the <see cref="Email"/> object either as <see cref="CFStorage"/>'s
        ///     or <see cref="CFStream"/>'s to the <see cref="CompoundFile.RootStorage"/>
        /// </summary>
        internal new void WriteToStorage()
        {
            var rootStorage = CompoundFile.RootStorage;

            Class = MessageClass.IPM_Post;

            base.WriteToStorage();

            var attachmentCount = Attachments.Count;

            TopLevelProperties.AttachmentCount  = attachmentCount;
            TopLevelProperties.NextAttachmentId = attachmentCount;

            //TopLevelProperties.AddProperty(PropertyTags.PR_ENTRYID, Mapi.GenerateEntryId());
            //TopLevelProperties.AddProperty(PropertyTags.PR_INSTANCE_KEY, Mapi.GenerateInstanceKey());
            TopLevelProperties.AddProperty(PropertyTags.PR_STORE_SUPPORT_MASK, StoreSupportMaskConst.StoreSupportMask, PropertyFlags.PROPATTR_READABLE);
            TopLevelProperties.AddProperty(PropertyTags.PR_STORE_UNICODE_MASK, StoreSupportMaskConst.StoreSupportMask, PropertyFlags.PROPATTR_READABLE);
            TopLevelProperties.AddProperty(PropertyTags.PR_ALTERNATE_RECIPIENT_ALLOWED, true, PropertyFlags.PROPATTR_READABLE);
            TopLevelProperties.AddProperty(PropertyTags.PR_HASATTACH, attachmentCount > 0);

            TopLevelProperties.AddProperty(PropertyTags.PR_PARENT_DISPLAY_W, PostedTo);


            if (!string.IsNullOrWhiteSpace(InternetMessageId))
            {
                TopLevelProperties.AddOrReplaceProperty(PropertyTags.PR_INTERNET_MESSAGE_ID_W, InternetMessageId);
            }

            if (!string.IsNullOrWhiteSpace(InternetReferences))
            {
                TopLevelProperties.AddOrReplaceProperty(PropertyTags.PR_INTERNET_REFERENCES_W, InternetReferences);
            }

            if (!string.IsNullOrWhiteSpace(InReplyToId))
            {
                TopLevelProperties.AddOrReplaceProperty(PropertyTags.PR_IN_REPLY_TO_ID_W, InReplyToId);
            }

            var messageFlags = MessageFlags.MSGFLAG_UNMODIFIED;

            if (attachmentCount > 0)
            {
                messageFlags |= MessageFlags.MSGFLAG_HASATTACH;
            }

            TopLevelProperties.AddProperty(PropertyTags.PR_INTERNET_CPID, Encoding.UTF8.CodePage);

            if (MessageEditorFormat != MessageEditorFormat.EDITOR_FORMAT_DONTKNOW)
            {
                TopLevelProperties.AddProperty(PropertyTags.PR_MSG_EDITOR_FORMAT, MessageEditorFormat);
            }

            if (!SentOn.HasValue)
            {
                SentOn = DateTime.UtcNow;
            }

            TopLevelProperties.AddProperty(PropertyTags.PR_ACCESS, MapiAccess.MAPI_ACCESS_DELETE | MapiAccess.MAPI_ACCESS_MODIFY | MapiAccess.MAPI_ACCESS_READ);
            TopLevelProperties.AddProperty(PropertyTags.PR_ACCESS_LEVEL, MapiAccess.MAPI_ACCESS_MODIFY);
            TopLevelProperties.AddProperty(PropertyTags.PR_OBJECT_TYPE, MapiObjectType.MAPI_MESSAGE);


            // http://www.meridiandiscovery.com/how-to/e-mail-conversation-index-metadata-computer-forensics/
            // http://stackoverflow.com/questions/11860540/does-outlook-embed-a-messageid-or-equivalent-in-its-email-elements
            //propertiesStream.AddProperty(PropertyTags.PR_CONVERSATION_INDEX, Subject);

            // TODO: Change modification time when this message is opened and only modified

            TopLevelProperties.AddProperty(PropertyTags.PR_PRIORITY, Priority);

            if (Draft)
            {
                messageFlags |= MessageFlags.MSGFLAG_UNSENT;
            }

            IconIndex = MessageIconIndex.Post;

            TopLevelProperties.AddProperty(PropertyTags.PR_MESSAGE_FLAGS, messageFlags);

            Sender?.WriteProperties(TopLevelProperties);
            Representing?.WriteProperties(TopLevelProperties);
        }
예제 #9
0
        /// <summary>
        ///     Writes all the properties that are part of the <see cref="Appointment"/> object either as <see cref="CFStorage"/>'s
        ///     or <see cref="CFStream"/>'s to the <see cref="CompoundFile.RootStorage"/>
        /// </summary>
        private void WriteToStorage()
        {
            var  rootStorage = CompoundFile.RootStorage;
            long messageSize = 0;

            messageSize += Recipients.WriteToStorage(rootStorage);
            messageSize += Attachments.WriteToStorage(rootStorage);

            var recipientCount   = Recipients.Count;
            var attachmentCount  = Attachments.Count;
            var propertiesStream = new TopLevelProperties(recipientCount,
                                                          attachmentCount,
                                                          recipientCount,
                                                          attachmentCount);

            if (!string.IsNullOrEmpty(InternetMessageId))
            {
                propertiesStream.AddProperty(PropertyTags.PR_INTERNET_MESSAGE_ID_W, InternetMessageId);
            }

            propertiesStream.AddProperty(PropertyTags.PR_ENTRYID, Mapi.GenerateEntryId());
            propertiesStream.AddProperty(PropertyTags.PR_INSTANCE_KEY, Mapi.GenerateInstanceKey());
            propertiesStream.AddProperty(PropertyTags.PR_STORE_SUPPORT_MASK, StoreSupportMaskConst.StoreSupportMask, PropertyFlags.PROPATTR_READABLE);
            propertiesStream.AddProperty(PropertyTags.PR_STORE_UNICODE_MASK, StoreSupportMaskConst.StoreSupportMask, PropertyFlags.PROPATTR_READABLE);
            propertiesStream.AddProperty(PropertyTags.PR_ALTERNATE_RECIPIENT_ALLOWED, true, PropertyFlags.PROPATTR_READABLE);
            propertiesStream.AddProperty(PropertyTags.PR_HASATTACH, attachmentCount > 0);

            var messageFlags = MessageFlags.MSGFLAG_UNMODIFIED;

            if (Draft)
            {
                messageFlags |= MessageFlags.MSGFLAG_UNSENT | MessageFlags.MSGFLAG_FROMME;
                IconIndex     = MessageIconIndex.UnsentMail;
            }

            if (attachmentCount > 0)
            {
                messageFlags |= MessageFlags.MSGFLAG_HASATTACH;
            }

            if (!SentOn.HasValue)
            {
                SentOn = DateTime.UtcNow;
            }

            propertiesStream.AddProperty(PropertyTags.PR_CLIENT_SUBMIT_TIME, SentOn);
            propertiesStream.AddProperty(PropertyTags.PR_MESSAGE_FLAGS, messageFlags);
            propertiesStream.AddProperty(PropertyTags.PR_ACCESS, MapiAccess.MAPI_ACCESS_DELETE | MapiAccess.MAPI_ACCESS_MODIFY | MapiAccess.MAPI_ACCESS_READ);
            propertiesStream.AddProperty(PropertyTags.PR_ACCESS_LEVEL, MapiAccess.MAPI_ACCESS_MODIFY);
            propertiesStream.AddProperty(PropertyTags.PR_OBJECT_TYPE, MapiObjectType.MAPI_MESSAGE);

            SetSubject();
            propertiesStream.AddProperty(PropertyTags.PR_SUBJECT_W, Subject);
            propertiesStream.AddProperty(PropertyTags.PR_NORMALIZED_SUBJECT_W, SubjectNormalized);
            propertiesStream.AddProperty(PropertyTags.PR_SUBJECT_PREFIX_W, SubjectPrefix);
            propertiesStream.AddProperty(PropertyTags.PR_CONVERSATION_TOPIC_W, SubjectNormalized);

            // http://www.meridiandiscovery.com/how-to/e-mail-conversation-index-metadata-computer-forensics/
            // http://stackoverflow.com/questions/11860540/does-outlook-embed-a-messageid-or-equivalent-in-its-email-elements
            //propertiesStream.AddProperty(PropertyTags.PR_CONVERSATION_INDEX, Subject);

            // TODO: Change modification time when this message is opened and only modified
            var utcNow = DateTime.UtcNow;

            propertiesStream.AddProperty(PropertyTags.PR_CREATION_TIME, utcNow);
            propertiesStream.AddProperty(PropertyTags.PR_LAST_MODIFICATION_TIME, utcNow);
            propertiesStream.AddProperty(PropertyTags.PR_MESSAGE_CLASS_W, "IPM.Appointment");
            propertiesStream.AddProperty(PropertyTags.PR_PRIORITY, Priority);
            propertiesStream.AddProperty(PropertyTags.PR_IMPORTANCE, Importance);
            propertiesStream.AddProperty(PropertyTags.PR_MESSAGE_LOCALE_ID, CultureInfo.CurrentCulture.LCID);
            propertiesStream.AddProperty(PropertyTags.PR_ICON_INDEX, IconIndex);

            if (Sender != null)
            {
                Sender.WriteProperties(propertiesStream);
            }
            if (Receiving != null)
            {
                Receiving.WriteProperties(propertiesStream);
            }
            if (Representing != null)
            {
                Representing.WriteProperties(propertiesStream);
            }
            if (ReceivingRepresenting != null)
            {
                ReceivingRepresenting.WriteProperties(propertiesStream);
            }

            if (recipientCount > 0)
            {
                var displayTo  = new List <string>();
                var displayCc  = new List <string>();
                var displayBcc = new List <string>();

                foreach (var recipient in Recipients)
                {
                    switch (recipient.RecipientType)
                    {
                    case RecipientType.To:
                        if (!string.IsNullOrWhiteSpace(recipient.DisplayName))
                        {
                            displayTo.Add(recipient.DisplayName);
                        }
                        else if (!string.IsNullOrWhiteSpace(recipient.Email))
                        {
                            displayTo.Add(recipient.Email);
                        }
                        break;

                    case RecipientType.Cc:
                        if (!string.IsNullOrWhiteSpace(recipient.DisplayName))
                        {
                            displayCc.Add(recipient.DisplayName);
                        }
                        else if (!string.IsNullOrWhiteSpace(recipient.Email))
                        {
                            displayCc.Add(recipient.Email);
                        }
                        break;

                    case RecipientType.Bcc:
                        if (!string.IsNullOrWhiteSpace(recipient.DisplayName))
                        {
                            displayBcc.Add(recipient.DisplayName);
                        }
                        else if (!string.IsNullOrWhiteSpace(recipient.Email))
                        {
                            displayBcc.Add(recipient.Email);
                        }
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }

                propertiesStream.AddProperty(PropertyTags.PR_DISPLAY_TO_W, string.Join(";", displayTo), PropertyFlags.PROPATTR_READABLE);
                propertiesStream.AddProperty(PropertyTags.PR_DISPLAY_CC_W, string.Join(";", displayCc), PropertyFlags.PROPATTR_READABLE);
                propertiesStream.AddProperty(PropertyTags.PR_DISPLAY_BCC_W, string.Join(";", displayBcc), PropertyFlags.PROPATTR_READABLE);
            }

            propertiesStream.AddProperty(PropertyTags.PR_INTERNET_CPID, Encoding.UTF8.CodePage);


            if (BodyRtfCompressed)
            {
                propertiesStream.AddProperty(PropertyTags.PR_RTF_COMPRESSED, RTFCompressor.Compress(Encoding.ASCII.GetBytes(BodyRtf)));
                propertiesStream.AddProperty(PropertyTags.PR_RTF_IN_SYNC, true);
            }

            var namedProperties = new NamedProperties(propertiesStream); //Uses the top level properties.

            namedProperties.AddProperty(NamedPropertyTags.PidLidLocation, Location);
            namedProperties.AddProperty(NamedPropertyTags.PidLidAppointmentStartWhole, MeetingStart);
            namedProperties.AddProperty(NamedPropertyTags.PidLidAppointmentEndWhole, MeetingEnd);
            namedProperties.AddProperty(NamedPropertyTags.PidLidMeetingType, MeetingType.mtgRequest);
            namedProperties.AddProperty(NamedPropertyTags.PidLidAppointmentSubType, AllDay);
            namedProperties.AddProperty(NamedPropertyTags.PidLidAppointmentStateFlags, AppointmentState.asfMeeting);

            namedProperties.WriteProperties(rootStorage);

            propertiesStream.WriteProperties(rootStorage, messageSize);
        }