You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

422 lines
20 KiB

using System;
using System.IO;
using DocumentServices.Modules.Readers.MsgReader.Outlook;
using Microsoft.WindowsAPICodePack.Shell;
using Microsoft.WindowsAPICodePack.Shell.PropertySystem;
namespace MsgMapper
{
internal class Mapper
{
#region MapEmailPropertiesToExtendedFileAttributes
/// <summary>
/// Maps all the filled <see cref="Storage.Message"/> properties to the corresponding extended file attributes
/// </summary>
/// <param name="message">The <see cref="Storage.Message"/> object</param>
/// <param name="propertyWriter">The <see cref="ShellPropertyWriter"/> object</param>
private void MapEmailPropertiesToExtendedFileAttributes(Storage.Message message, ShellPropertyWriter propertyWriter)
{
// From
propertyWriter.WriteProperty(SystemProperties.System.Message.FromAddress, message.Sender.Email);
propertyWriter.WriteProperty(SystemProperties.System.Message.FromName, message.Sender.DisplayName);
// Sent on
propertyWriter.WriteProperty(SystemProperties.System.Message.DateSent, message.SentOn);
// To
propertyWriter.WriteProperty(SystemProperties.System.Message.ToAddress,
GetEmailRecipients(message, Storage.Recipient.RecipientType.To, false, false));
// CC
propertyWriter.WriteProperty(SystemProperties.System.Message.CcAddress,
GetEmailRecipients(message, Storage.Recipient.RecipientType.Cc, false, false));
// BCC
propertyWriter.WriteProperty(SystemProperties.System.Message.BccAddress,
GetEmailRecipients(message, Storage.Recipient.RecipientType.Bcc, false, false));
// Subject
propertyWriter.WriteProperty(SystemProperties.System.Subject, message.Subject);
// Urgent
propertyWriter.WriteProperty(SystemProperties.System.Importance, message.Importance);
propertyWriter.WriteProperty(SystemProperties.System.ImportanceText, message.ImportanceText);
// Attachments
var attachments = GetAttachmentNames(message);
if (string.IsNullOrEmpty(attachments))
{
propertyWriter.WriteProperty(SystemProperties.System.Message.HasAttachments, false);
propertyWriter.WriteProperty(SystemProperties.System.Message.AttachmentNames, null);
}
else
{
propertyWriter.WriteProperty(SystemProperties.System.Message.HasAttachments, true);
propertyWriter.WriteProperty(SystemProperties.System.Message.AttachmentNames, attachments);
}
// Clear properties
propertyWriter.WriteProperty(SystemProperties.System.StartDate, null);
propertyWriter.WriteProperty(SystemProperties.System.DueDate, null);
propertyWriter.WriteProperty(SystemProperties.System.DateCompleted, null);
propertyWriter.WriteProperty(SystemProperties.System.IsFlaggedComplete, null);
propertyWriter.WriteProperty(SystemProperties.System.FlagStatusText, null);
// Follow up
if (message.Flag != null)
{
propertyWriter.WriteProperty(SystemProperties.System.IsFlagged, true);
propertyWriter.WriteProperty(SystemProperties.System.FlagStatusText, message.Flag.Request);
// Flag status text
propertyWriter.WriteProperty(SystemProperties.System.FlagStatusText, message.Task.StatusText);
// When complete
if (message.Task.Complete != null && (bool)message.Task.Complete)
{
// Flagged complete
propertyWriter.WriteProperty(SystemProperties.System.IsFlaggedComplete, true);
// Task completed date
if (message.Task.CompleteTime != null)
propertyWriter.WriteProperty(SystemProperties.System.DateCompleted, (DateTime)message.Task.CompleteTime);
}
else
{
// Flagged not complete
propertyWriter.WriteProperty(SystemProperties.System.IsFlaggedComplete, false);
propertyWriter.WriteProperty(SystemProperties.System.DateCompleted, null);
// Task startdate
if (message.Task.StartDate != null)
propertyWriter.WriteProperty(SystemProperties.System.StartDate, (DateTime)message.Task.StartDate);
// Task duedate
if (message.Task.DueDate != null)
propertyWriter.WriteProperty(SystemProperties.System.DueDate, (DateTime)message.Task.DueDate);
}
}
// Categories
var categories = message.Categories;
if (categories != null)
propertyWriter.WriteProperty(SystemProperties.System.Category, String.Join("; ", String.Join("; ", categories)));
}
#endregion
#region MapAppointmentPropertiesToExtendedFileAttributes
/// <summary>
/// Maps all the filled <see cref="Storage.Appointment"/> properties to the corresponding extended file attributes
/// </summary>
/// <param name="message">The <see cref="Storage.Message"/> object</param>
/// <param name="propertyWriter">The <see cref="ShellPropertyWriter"/> object</param>
private void MapAppointmentPropertiesToExtendedFileAttributes(Storage.Message message, ShellPropertyWriter propertyWriter)
{
// From
propertyWriter.WriteProperty(SystemProperties.System.Message.FromAddress, message.Sender.Email);
propertyWriter.WriteProperty(SystemProperties.System.Message.FromName, message.Sender.DisplayName);
// Sent on
if (message.SentOn != null)
propertyWriter.WriteProperty(SystemProperties.System.Message.DateSent, message.SentOn);
// Subject
propertyWriter.WriteProperty(SystemProperties.System.Subject, message.Subject);
// Location
propertyWriter.WriteProperty(SystemProperties.System.Calendar.Location, message.Appointment.Location);
// Start
propertyWriter.WriteProperty(SystemProperties.System.StartDate, message.Appointment.Start);
// End
propertyWriter.WriteProperty(SystemProperties.System.StartDate, message.Appointment.End);
// Recurrence type
propertyWriter.WriteProperty(SystemProperties.System.Calendar.IsRecurring,
message.Appointment.ReccurrenceType != Storage.Appointment.AppointmentRecurrenceType.None);
// Status
propertyWriter.WriteProperty(SystemProperties.System.Status, message.Appointment.ClientIntentText);
// Appointment organizer (FROM)
propertyWriter.WriteProperty(SystemProperties.System.Calendar.OrganizerAddress, message.Sender.Email);
propertyWriter.WriteProperty(SystemProperties.System.Calendar.OrganizerName, message.Sender.DisplayName);
// Mandatory participants (TO)
propertyWriter.WriteProperty(SystemProperties.System.Calendar.RequiredAttendeeNames, message.Appointment.ToAttendees);
// Optional participants (CC)
propertyWriter.WriteProperty(SystemProperties.System.Calendar.OptionalAttendeeNames, message.Appointment.CclAttendees);
// Categories
var categories = message.Categories;
if (categories != null)
propertyWriter.WriteProperty(SystemProperties.System.Category, String.Join("; ", String.Join("; ", categories)));
// Urgent
propertyWriter.WriteProperty(SystemProperties.System.Importance, message.Importance);
propertyWriter.WriteProperty(SystemProperties.System.ImportanceText, message.ImportanceText);
// Attachments
var attachments = GetAttachmentNames(message);
if (string.IsNullOrEmpty(attachments))
{
propertyWriter.WriteProperty(SystemProperties.System.Message.HasAttachments, false);
propertyWriter.WriteProperty(SystemProperties.System.Message.AttachmentNames, null);
}
else
{
propertyWriter.WriteProperty(SystemProperties.System.Message.HasAttachments, true);
propertyWriter.WriteProperty(SystemProperties.System.Message.AttachmentNames, attachments);
}
}
#endregion
#region MapTaskPropertiesToExtendedFileAttributes
/// <summary>
/// Maps all the filled <see cref="Storage.Task"/> properties to the corresponding extended file attributes
/// </summary>
/// <param name="message">The <see cref="Storage.Message"/> object</param>
/// <param name="propertyWriter">The <see cref="ShellPropertyWriter"/> object</param>
private void MapTaskPropertiesToExtendedFileAttributes(Storage.Message message, ShellPropertyWriter propertyWriter)
{
// From
propertyWriter.WriteProperty(SystemProperties.System.Message.FromAddress, message.Sender.Email);
propertyWriter.WriteProperty(SystemProperties.System.Message.FromName, message.Sender.DisplayName);
// Sent on
propertyWriter.WriteProperty(SystemProperties.System.Message.DateSent, message.SentOn);
// Subject
propertyWriter.WriteProperty(SystemProperties.System.Subject, message.Subject);
// Task startdate
propertyWriter.WriteProperty(SystemProperties.System.StartDate, message.Task.StartDate);
// Task duedate
propertyWriter.WriteProperty(SystemProperties.System.DueDate, message.Task.DueDate);
// Urgent
propertyWriter.WriteProperty(SystemProperties.System.Importance, message.Importance);
propertyWriter.WriteProperty(SystemProperties.System.ImportanceText, message.ImportanceText);
// Status
propertyWriter.WriteProperty(SystemProperties.System.Status, message.Task.StatusText);
// Percentage complete
propertyWriter.WriteProperty(SystemProperties.System.Task.CompletionStatus, message.Task.PercentageComplete);
// Owner
propertyWriter.WriteProperty(SystemProperties.System.Task.Owner, message.Task.Owner);
// Categories
propertyWriter.WriteProperty(SystemProperties.System.Category,
message.Categories != null ? String.Join("; ", message.Categories) : null);
// Companies
propertyWriter.WriteProperty(SystemProperties.System.Company,
message.Task.Companies != null ? String.Join("; ", message.Task.Companies) : null);
// Billing information
propertyWriter.WriteProperty(SystemProperties.System.Task.BillingInformation, message.Task.BillingInformation);
// Mileage
propertyWriter.WriteProperty(SystemProperties.System.MileageInformation, message.Task.Mileage);
// Attachments
var attachments = GetAttachmentNames(message);
if (string.IsNullOrEmpty(attachments))
{
propertyWriter.WriteProperty(SystemProperties.System.Message.HasAttachments, false);
propertyWriter.WriteProperty(SystemProperties.System.Message.AttachmentNames, null);
}
else
{
propertyWriter.WriteProperty(SystemProperties.System.Message.HasAttachments, true);
propertyWriter.WriteProperty(SystemProperties.System.Message.AttachmentNames, attachments);
}
}
#endregion
#region MapContactPropertiesToExtendedFileAttributes
/// <summary>
/// Maps all the filled <see cref="Storage.Task"/> properties to the corresponding extended file attributes
/// </summary>
/// <param name="message">The <see cref="Storage.Message"/> object</param>
/// <param name="propertyWriter">The <see cref="ShellPropertyWriter"/> object</param>
private void MapContactPropertiesToExtendedFileAttributes(Storage.Message message, ShellPropertyWriter propertyWriter)
{
// From
propertyWriter.WriteProperty(SystemProperties.System.Message.FromAddress, message.Sender.Email);
propertyWriter.WriteProperty(SystemProperties.System.Message.FromName, message.Sender.DisplayName);
// Sent on
propertyWriter.WriteProperty(SystemProperties.System.Message.DateSent, message.SentOn);
// Full name
propertyWriter.WriteProperty(SystemProperties.System.Contact.FullName, message.Contact.DisplayName);
// Last name
propertyWriter.WriteProperty(SystemProperties.System.Contact.LastName, message.Contact.SurName);
// First name
propertyWriter.WriteProperty(SystemProperties.System.Contact.FirstName, message.Contact.GivenName);
// Job title
propertyWriter.WriteProperty(SystemProperties.System.Contact.JobTitle, message.Contact.Function);
// Department
propertyWriter.WriteProperty(SystemProperties.System.Contact.Department, message.Contact.Department);
// Company
propertyWriter.WriteProperty(SystemProperties.System.Company, message.Contact.Company);
// Business address
propertyWriter.WriteProperty(SystemProperties.System.Contact.BusinessAddress, message.Contact.WorkAddress);
// Home address
propertyWriter.WriteProperty(SystemProperties.System.Contact.HomeAddress, message.Contact.HomeAddress);
// Other address
propertyWriter.WriteProperty(SystemProperties.System.Contact.OtherAddress, message.Contact.OtherAddress);
// Instant messaging
propertyWriter.WriteProperty(SystemProperties.System.Contact.IMAddress, message.Contact.InstantMessagingAddress);
// Business telephone number
propertyWriter.WriteProperty(SystemProperties.System.Contact.BusinessTelephone, message.Contact.BusinessTelephoneNumber);
// Assistant's telephone number
propertyWriter.WriteProperty(SystemProperties.System.Contact.AssistantTelephone, message.Contact.AssistantTelephoneNumber);
// Company main phone
propertyWriter.WriteProperty(SystemProperties.System.Contact.CompanyMainTelephone, message.Contact.CompanyMainTelephoneNumber);
// Home telephone number
propertyWriter.WriteProperty(SystemProperties.System.Contact.HomeTelephone, message.Contact.HomeTelephoneNumber);
// Mobile phone
propertyWriter.WriteProperty(SystemProperties.System.Contact.MobileTelephone, message.Contact.CellularTelephoneNumber);
// Car phone
propertyWriter.WriteProperty(SystemProperties.System.Contact.CarTelephone, message.Contact.CarTelephoneNumber);
// Callback
propertyWriter.WriteProperty(SystemProperties.System.Contact.CallbackTelephone, message.Contact.CallbackTelephoneNumber);
// Primary telephone number
propertyWriter.WriteProperty(SystemProperties.System.Contact.PrimaryTelephone, message.Contact.PrimaryTelephoneNumber);
// Telex
propertyWriter.WriteProperty(SystemProperties.System.Contact.TelexNumber, message.Contact.TelexNumber);
// TTY/TDD phone
propertyWriter.WriteProperty(SystemProperties.System.Contact.TTYTDDTelephone, message.Contact.TextTelephone);
// Business fax
propertyWriter.WriteProperty(SystemProperties.System.Contact.BusinessFaxNumber, message.Contact.BusinessFaxNumber);
// Home fax
propertyWriter.WriteProperty(SystemProperties.System.Contact.HomeFaxNumber, message.Contact.HomeFaxNumber);
// E-mail
propertyWriter.WriteProperty(SystemProperties.System.Contact.EmailAddress, message.Contact.Email1EmailAddress);
propertyWriter.WriteProperty(SystemProperties.System.Contact.EmailName, message.Contact.Email1DisplayName);
// E-mail 2
propertyWriter.WriteProperty(SystemProperties.System.Contact.EmailAddress2, message.Contact.Email2EmailAddress);
// E-mail 3
propertyWriter.WriteProperty(SystemProperties.System.Contact.EmailAddress3, message.Contact.Email3EmailAddress);
// Birthday
propertyWriter.WriteProperty(SystemProperties.System.Contact.Birthday, message.Contact.Birthday);
// Anniversary
propertyWriter.WriteProperty(SystemProperties.System.Contact.Anniversary, message.Contact.WeddingAnniversary);
// Spouse/Partner
propertyWriter.WriteProperty(SystemProperties.System.Contact.SpouseName, message.Contact.SpouseName);
// Profession
propertyWriter.WriteProperty(SystemProperties.System.Contact.Profession, message.Contact.Profession);
// Assistant
propertyWriter.WriteProperty(SystemProperties.System.Contact.AssistantName, message.Contact.AssistantName);
// Web page
propertyWriter.WriteProperty(SystemProperties.System.Contact.Webpage, message.Contact.Html);
// Categories
var categories = message.Categories;
if (categories != null)
propertyWriter.WriteProperty(SystemProperties.System.Category, String.Join("; ", String.Join("; ", categories)));
}
#endregion
#region SetExtendedFileAttributesWithMsgProperties
/// <summary>
/// This function will read all the properties of an <see cref="Storage.Message"/> file and maps
/// all the properties that are filled to the extended file attributes.
/// </summary>
/// <param name="inputFile">The msg file</param>
public void SetExtendedFileAttributesWithMsgProperties(string inputFile)
{
MemoryStream memoryStream = null;
try
{
// We need to read the msg file into memory because we otherwise can't set the extended filesystem
// properties because the files is locked
memoryStream = new MemoryStream();
using (var fileStream = File.OpenRead(inputFile))
fileStream.CopyTo(memoryStream);
memoryStream.Position = 0;
using (var shellFile = ShellFile.FromFilePath(inputFile))
{
using (var propertyWriter = shellFile.Properties.GetPropertyWriter())
{
using (var message = new Storage.Message(memoryStream))
{
switch (message.Type)
{
case Storage.Message.MessageType.Email:
MapEmailPropertiesToExtendedFileAttributes(message, propertyWriter);
break;
case Storage.Message.MessageType.AppointmentRequest:
case Storage.Message.MessageType.Appointment:
case Storage.Message.MessageType.AppointmentResponse:
MapAppointmentPropertiesToExtendedFileAttributes(message, propertyWriter);
break;
case Storage.Message.MessageType.Task:
case Storage.Message.MessageType.TaskRequestAccept:
MapTaskPropertiesToExtendedFileAttributes(message, propertyWriter);
break;
case Storage.Message.MessageType.Contact:
MapContactPropertiesToExtendedFileAttributes(message, propertyWriter);
break;
case Storage.Message.MessageType.Unknown:
throw new NotSupportedException("Unsupported message type");
}
}
}
}
}
finally
{
if (memoryStream != null)
memoryStream.Dispose();
}
}
#endregion
}
}