/// <summary> /// Initializes a new instance of the <see cref="Storage.Attachment" /> class. /// </summary> /// <param name="message"> The message. </param> /// <param name="storageName">The name of the <see cref="CFStorage"/> that contains this attachment</param> internal Attachment(Storage message, string storageName) : base(message._rootStorage) { StorageName = storageName; GC.SuppressFinalize(message); _propHeaderSize = MapiTags.PropertiesStreamHeaderAttachOrRecip; CreationTime = GetMapiPropertyDateTime(MapiTags.PR_CREATION_TIME); LastModificationTime = GetMapiPropertyDateTime(MapiTags.PR_LAST_MODIFICATION_TIME); ContentId = GetMapiPropertyString(MapiTags.PR_ATTACH_CONTENTID); IsInline = ContentId != null; var isContactPhoto = GetMapiPropertyBool(MapiTags.PR_ATTACHMENT_CONTACTPHOTO); if (isContactPhoto == null) { IsContactPhoto = false; } else { IsContactPhoto = (bool)isContactPhoto; } var renderingPosition = GetMapiPropertyInt32(MapiTags.PR_RENDERING_POSITION); if (renderingPosition == null) { RenderingPosition = -1; } else { RenderingPosition = (int)renderingPosition; } var fileName = GetMapiPropertyString(MapiTags.PR_ATTACH_LONG_FILENAME); if (string.IsNullOrEmpty(fileName)) { fileName = GetMapiPropertyString(MapiTags.PR_ATTACH_FILENAME); } if (string.IsNullOrEmpty(fileName)) { fileName = GetMapiPropertyString(MapiTags.PR_DISPLAY_NAME); } FileName = fileName != null ? FileManager.RemoveInvalidFileNameChars(fileName) : LanguageConsts.NameLessFileName; var attachmentMethod = GetMapiPropertyInt32(MapiTags.PR_ATTACH_METHOD); switch (attachmentMethod) { case MapiTags.ATTACH_BY_REFERENCE: case MapiTags.ATTACH_BY_REF_RESOLVE: case MapiTags.ATTACH_BY_REF_ONLY: ResolveAttachment(); break; case MapiTags.ATTACH_OLE: var storage = GetMapiProperty(MapiTags.PR_ATTACH_DATA_BIN) as CFStorage; var attachmentOle = new Attachment(new Storage(storage), null); _data = attachmentOle.GetStreamBytes("CONTENTS"); if (_data != null) { var fileTypeInfo = FileTypeSelector.GetFileTypeFileInfo(Data); if (string.IsNullOrEmpty(FileName)) { FileName = fileTypeInfo.Description; } FileName += "." + fileTypeInfo.Extension.ToLower(); } else { // http://www.devsuperpage.com/search/Articles.aspx?G=10&ArtID=142729 _data = attachmentOle.GetStreamBytes("\u0002OlePres000"); } if (_data != null) { try { SaveImageAsPng(40); } catch (ArgumentException) { SaveImageAsPng(0); } } else { throw new MRUnknownAttachmentFormat("Can not read the attachment"); } OleAttachment = true; IsInline = true; break; } }
/// <summary> /// Initializes a new instance of the <see cref="Storage.Attachment" /> class. /// </summary> /// <param name="message"> The message. </param> /// <param name="storageName">The name of the <see cref="Storage.NativeMethods.IStorage"/> stream that containts this attachment</param> internal Attachment(Storage message, string storageName) : base(message._storage) { StorageName = storageName; GC.SuppressFinalize(message); _propHeaderSize = MapiTags.PropertiesStreamHeaderAttachOrRecip; CreationTime = GetMapiPropertyDateTime(MapiTags.PR_CREATION_TIME); LastModificationTime = GetMapiPropertyDateTime(MapiTags.PR_LAST_MODIFICATION_TIME); ContentId = GetMapiPropertyString(MapiTags.PR_ATTACH_CONTENTID); IsInline = ContentId != null; var isContactPhoto = GetMapiPropertyBool(MapiTags.PR_ATTACHMENT_CONTACTPHOTO); if (isContactPhoto == null) { IsContactPhoto = false; } else { IsContactPhoto = (bool)isContactPhoto; } var renderingPosition = GetMapiPropertyInt32(MapiTags.PR_RENDERING_POSITION); if (renderingPosition == null) { RenderingPosition = -1; } else { RenderingPosition = (int)renderingPosition; } var fileName = GetMapiPropertyString(MapiTags.PR_ATTACH_LONG_FILENAME); if (string.IsNullOrEmpty(fileName)) { fileName = GetMapiPropertyString(MapiTags.PR_ATTACH_FILENAME); } if (string.IsNullOrEmpty(fileName)) { fileName = GetMapiPropertyString(MapiTags.PR_DISPLAY_NAME); } FileName = fileName != null ? FileManager.RemoveInvalidFileNameChars(fileName) : LanguageConsts.NameLessFileName; var attachmentMethod = GetMapiPropertyInt32(MapiTags.PR_ATTACH_METHOD); switch (attachmentMethod) { case MapiTags.ATTACH_BY_REFERENCE: case MapiTags.ATTACH_BY_REF_RESOLVE: case MapiTags.ATTACH_BY_REF_ONLY: ResolveAttachment(); break; case MapiTags.ATTACH_OLE: var storage = GetMapiProperty(MapiTags.PR_ATTACH_DATA_BIN) as NativeMethods.IStorage; var attachmentOle = new Attachment(new Storage(storage), null); _data = attachmentOle.GetStreamBytes("CONTENTS"); if (_data != null) { var fileTypeInfo = FileTypeSelector.GetFileTypeFileInfo(Data); if (string.IsNullOrEmpty(FileName)) { FileName = fileTypeInfo.Description; } FileName += "." + fileTypeInfo.Extension.ToLower(); } else { _data = attachmentOle.GetStreamBytes("\u0002OlePres000"); } if (_data != null) { var length = _data.Length - 40; var bytes = new byte[length]; Buffer.BlockCopy(_data, 40, bytes, 0, length); using (var inputStream = new MemoryStream(bytes)) using (var image = Image.FromStream(inputStream)) using (var outputStream = new MemoryStream()) { image.Save(outputStream, ImageFormat.Png); outputStream.Position = 0; _data = outputStream.ToByteArray(); FileName = "ole0.bmp"; } } else { throw new MRUnknownAttachmentFormat("Can not read the attachment"); } OleAttachment = true; IsInline = true; break; } }
/// <summary> /// Initializes a new instance of the <see cref="Storage.Attachment" /> class. /// </summary> /// <param name="message"> The message. </param> /// <param name="storageName">The name of the <see cref="Storage.NativeMethods.IStorage"/> stream that containts this attachment</param> internal Attachment(Storage message, string storageName) : base(message._storage) { StorageName = storageName; GC.SuppressFinalize(message); _propHeaderSize = MapiTags.PropertiesStreamHeaderAttachOrRecip; CreationTime = GetMapiPropertyDateTime(MapiTags.PR_CREATION_TIME); LastModificationTime = GetMapiPropertyDateTime(MapiTags.PR_LAST_MODIFICATION_TIME); ContentId = GetMapiPropertyString(MapiTags.PR_ATTACH_CONTENTID); IsInline = ContentId != null; var isContactPhoto = GetMapiPropertyBool(MapiTags.PR_ATTACHMENT_CONTACTPHOTO); if (isContactPhoto == null) { IsContactPhoto = false; } else { IsContactPhoto = (bool)isContactPhoto; } var renderingPosition = GetMapiPropertyInt32(MapiTags.PR_RENDERING_POSITION); if (renderingPosition == null) { RenderingPosition = -1; } else { RenderingPosition = (int)renderingPosition; } var fileName = GetMapiPropertyString(MapiTags.PR_ATTACH_LONG_FILENAME); if (string.IsNullOrEmpty(fileName)) { fileName = GetMapiPropertyString(MapiTags.PR_ATTACH_FILENAME); } if (string.IsNullOrEmpty(fileName)) { fileName = GetMapiPropertyString(MapiTags.PR_DISPLAY_NAME); } FileName = fileName != null ? FileManager.RemoveInvalidFileNameChars(fileName) : LanguageConsts.NameLessFileName; var attachmentMethod = GetMapiPropertyInt32(MapiTags.PR_ATTACH_METHOD); switch (attachmentMethod) { case MapiTags.ATTACH_BY_REFERENCE: case MapiTags.ATTACH_BY_REF_RESOLVE: case MapiTags.ATTACH_BY_REF_ONLY: ResolveAttachment(); break; case MapiTags.ATTACH_OLE: var storage = GetMapiProperty(MapiTags.PR_ATTACH_DATA_BIN) as NativeMethods.IStorage; var attachmentOle = new Attachment(new Storage(storage), null); _data = attachmentOle.GetStreamBytes("CONTENTS"); var fileTypeInfo = FileTypeSelector.GetFileTypeFileInfo(Data); if (string.IsNullOrEmpty(FileName)) { FileName = fileTypeInfo.Description; } FileName += "." + fileTypeInfo.Extension.ToLower(); IsInline = true; break; } }
/// <summary> /// Returns <c>true</c> when the given file in the <paramref name="fileStream" /> is password protected /// </summary> /// <param name="fileStream">The file stream</param> /// <param name="fileNameOrExtension"> /// The filename or extension for the file that is inside the stream. When set to <c>null</c> /// the method tries to autodetect the type of file that is inside the file stream /// </param> /// <param name="checkerResult"></param> /// <returns></returns> /// <exception cref="PPCFileIsCorrupt">Raised when the file is corrupt</exception> /// <exception cref="PPCInvalidFile">Raised when the program could not detect what kind of file the stream is</exception> private Result IsStreamProtected(Stream fileStream, string fileNameOrExtension, Result checkerResult) { string extension; if (string.IsNullOrWhiteSpace(fileNameOrExtension)) { if (fileStream.Length < 100) { throw new PPCStreamToShort(); } using (var memoryStream = new MemoryStream()) { fileStream.CopyTo(memoryStream); var fileTypeFileInfo = FileTypeSelector.GetFileTypeFileInfo(memoryStream.ToArray()); if (fileTypeFileInfo.MagicBytes == null) { throw new PPCInvalidFile( "Could not autodetect the file type, use the extension parameter to set the file type"); } extension = fileTypeFileInfo.Extension; } } else { extension = Path.GetExtension(fileNameOrExtension); } extension = extension?.ToUpperInvariant(); var root = false; if (checkerResult == null) { root = true; checkerResult = new Result(); checkerResult.AddParentFile( !string.IsNullOrEmpty(fileNameOrExtension) ? fileNameOrExtension : extension); } else { checkerResult.AddChildFile(!string.IsNullOrEmpty(fileNameOrExtension) ? fileNameOrExtension : extension); } switch (extension) { case ".DOC": case ".DOT": case ".DOCM": case ".DOCX": case ".DOTM": checkerResult.Protected = IsWordPasswordProtected(fileStream); break; case ".ODT": checkerResult.Protected = IsOpenDocumentFormatPasswordProtected(fileStream); break; case ".XLS": case ".XLT": case ".XLW": case ".XLSB": case ".XLSM": case ".XLSX": case ".XLTM": case ".XLTX": checkerResult.Protected = IsExcelPasswordProtected(fileStream); break; case ".ODS": checkerResult.Protected = IsOpenDocumentFormatPasswordProtected(fileStream); break; case ".POT": case ".PPT": case ".PPS": case ".POTM": case ".POTX": case ".PPSM": case ".PPSX": case ".PPTM": case ".PPTX": // checkerResult.Protected = IsPowerPointPasswordProtected(fileStream); break; case ".ODP": checkerResult.Protected = IsOpenDocumentFormatPasswordProtected(fileStream); break; case ".ZIP": if (!root) { var childCheckerResult = new Result { ParentResult = checkerResult }; childCheckerResult.AddParentFile( !string.IsNullOrEmpty(fileNameOrExtension) ? fileNameOrExtension : extension); checkerResult = childCheckerResult; } checkerResult = IsZipPasswordProtected(fileStream, checkerResult); break; case ".MSG": if (!root) { var childCheckerResult = new Result { ParentResult = checkerResult }; childCheckerResult.AddParentFile( !string.IsNullOrEmpty(fileNameOrExtension) ? fileNameOrExtension : extension); checkerResult = childCheckerResult; } checkerResult = IsMsgPasswordProtected(fileStream, checkerResult); break; case ".EML": if (!root) { var childCheckerResult = new Result { ParentResult = checkerResult }; childCheckerResult.AddParentFile( !string.IsNullOrEmpty(fileNameOrExtension) ? fileNameOrExtension : extension); checkerResult = childCheckerResult; } checkerResult = IsEmlPasswordProtected(fileStream, checkerResult); break; } return(checkerResult); }