/// <summary> /// Extracts a Outlook File Attachment object from the given <paramref name="stream"/> /// </summary> /// <param name="stream"></param> /// <param name="outputFolder">The output folder</param> internal static string ExtractOutlookAttachmentObject(Stream stream, string outputFolder) { // Outlook attachments embedded in RTF are firstly embedded in an OLE v1.0 object var ole10 = new Ole10(stream); // After that it is wrapped in a compound document using (var internalStream = new MemoryStream(ole10.NativeData)) using (var compoundFile = new CompoundFile(internalStream)) { string fileName = null; var attachDescStream = compoundFile.RootStorage.TryGetStream("AttachDesc"); if (attachDescStream != null) { fileName = GetFileNameFromAttachDescStream(attachDescStream); } if (string.IsNullOrEmpty(fileName)) { fileName = Extraction.DefaultEmbeddedObjectName; } fileName = FileManager.RemoveInvalidFileNameChars(fileName); fileName = Path.Combine(outputFolder, fileName); fileName = FileManager.FileExistsMakeNew(fileName); var attachContentsStream = compoundFile.RootStorage.TryGetStream("AttachContents"); if (attachContentsStream != null) { return(Extraction.SaveByteArrayToFile(attachContentsStream.GetData(), fileName)); } var mapiMessageStorage = compoundFile.RootStorage.TryGetStorage("MAPIMessage"); if (mapiMessageStorage != null) { fileName = Path.Combine(outputFolder, fileName); return(Extraction.SaveStorageTreeToCompoundFile(mapiMessageStorage, fileName)); } return(null); } }
/// <summary> /// Extracts a OLE v1.0 object from the given <paramref name="stream"/> /// </summary> /// <param name="stream"></param> /// <param name="outputFolder">The output folder</param> internal string ExtractOle10(Stream stream, string outputFolder) { var ole10 = new Ole10(stream); if (ole10.Format != OleFormat.File) { return(null); } switch (ole10.ClassName) { case "Package": var package = new Package(ole10.NativeData); if (package.Format == OleFormat.Link) { return(null); } var fileName = Path.GetFileName(package.FileName); if (string.IsNullOrWhiteSpace(fileName)) { fileName = Extraction.DefaultEmbeddedObjectName; } fileName = Path.Combine(outputFolder, fileName); return(Extraction.SaveByteArrayToFile(package.Data, fileName)); case "PBrush": // Ignore return(null); default: if (Extraction.IsCompoundFile(ole10.NativeData)) { return(Extraction.SaveFromStorageNode(ole10.NativeData, outputFolder, ole10.ItemName)); } throw new OEObjectTypeNotSupported("Unsupported OleNative ClassName '" + ole10.ClassName + "' found"); } }