/// <summary> /// Returns an IFilter for the given <paramref name="stream"/> /// when there is no filter available /// </summary> /// <param name="stream">An <see cref="Stream"/></param> /// <param name="extension">The file extension</param> /// <param name="disableEmbeddedContent">When set to <c>true</c> embedded content is NOT read</param> /// <param name="fileName">The name of the file</param> /// <param name="readIntoMemory">When set to <c>true</c> the <paramref name="stream"/> is completely read /// into memory first before the iFilters starts to read chunks, when set to <c>false</c> the iFilter reads /// directly from the <paramref name="stream"/> and advances reading when the chunks are returned. /// Default set to <c>false</c></param> /// <returns><see cref="NativeMethods.IFilter"/> or null when no IFilter DLL is</returns> public static NativeMethods.IFilter LoadAndInitIFilter(Stream stream, string extension, bool disableEmbeddedContent, string fileName = "", bool readIntoMemory = false) { // Find the dll and ClassID GetFilterDllAndClass(extension, out var dllName, out var filterPersistClass); var iFilter = LoadFilterFromDll(dllName, filterPersistClass); if (iFilter == null) { return(null); } var iflags = NativeMethods.IFILTER_INIT.CANON_HYPHENS | NativeMethods.IFILTER_INIT.CANON_PARAGRAPHS | NativeMethods.IFILTER_INIT.CANON_SPACES | NativeMethods.IFILTER_INIT.APPLY_INDEX_ATTRIBUTES | NativeMethods.IFILTER_INIT.APPLY_CRAWL_ATTRIBUTES | NativeMethods.IFILTER_INIT.APPLY_OTHER_ATTRIBUTES | NativeMethods.IFILTER_INIT.HARD_LINE_BREAKS | NativeMethods.IFILTER_INIT.FILTER_OWNED_VALUE_OK | NativeMethods.IFILTER_INIT.EMIT_FORMATTING; if (disableEmbeddedContent) { iflags = iflags | NativeMethods.IFILTER_INIT.DISABLE_EMBEDDED; } // ReSharper disable once SuspiciousTypeConversion.Global var iPersistStream = iFilter as NativeMethods.IPersistStream; // IPersistStream is asumed on 64 bits systems if (iPersistStream != null) { // Create a COM stream IStream comStream; if (readIntoMemory) { // Copy the content to global memory var buffer = new byte[stream.Length]; stream.Read(buffer, 0, buffer.Length); var nativePtr = Marshal.AllocHGlobal(buffer.Length); Marshal.Copy(buffer, 0, nativePtr, buffer.Length); NativeMethods.CreateStreamOnHGlobal(nativePtr, true, out comStream); } else { comStream = new IStreamWrapper(stream); } try { iPersistStream.Load(comStream); if (iFilter.Init(iflags, 0, IntPtr.Zero, out _) == NativeMethods.IFilterReturnCode.S_OK) { return(iFilter); } } catch (Exception exception) { if (string.IsNullOrWhiteSpace(fileName)) { throw new IFOldFilterFormat("An error occured while trying to load a stream with the IPersistStream interface", exception); } } } if (string.IsNullOrWhiteSpace(fileName)) { throw new IFOldFilterFormat("The IFilter does not support the IPersistStream interface, supply a filename to use the IFilter"); } // If we get here we probably are using an old IFilter so try to load it the old way // ReSharper disable once SuspiciousTypeConversion.Global if (iFilter is IPersistFile persistFile) { persistFile.Load(fileName, 0); if (iFilter.Init(iflags, 0, IntPtr.Zero, out _) == NativeMethods.IFilterReturnCode.S_OK) { return(iFilter); } } // If we failed to retreive an IPersistStream or IPersistFile interface or to initialize // the filter, we release it and return null. Marshal.ReleaseComObject(iFilter); return(null); }
/// <summary> /// Returns an IFilter for the given <paramref name="stream"/> /// when there is no filter available /// </summary> /// <param name="stream">An <see cref="Stream"/></param> /// <param name="extension">The file extension</param> /// <param name="disableEmbeddedContent">When set to <c>true</c> embedded content is NOT read</param> /// <param name="fileName">The name of the file</param> /// <param name="readIntoMemory">When set to <c>true</c> the <paramref name="stream"/> is completely read /// into memory first before the iFilters starts to read chunks, when set to <c>false</c> the iFilter reads /// directly from the <paramref name="stream"/> and advances reading when the chunks are returned. /// Default set to <c>false</c></param> /// <returns><see cref="NativeMethods.IFilter"/> or null when no IFilter DLL is</returns> public static NativeMethods.IFilter LoadAndInitIFilter(Stream stream, string extension, bool disableEmbeddedContent, string fileName = "", bool readIntoMemory = false) { string dllName, filterPersistClass; // Find the dll and ClassID GetFilterDllAndClass(extension, out dllName, out filterPersistClass); var iFilter = LoadFilterFromDll(dllName, filterPersistClass); if (iFilter == null) return null; var iflags = NativeMethods.IFILTER_INIT.CANON_HYPHENS | NativeMethods.IFILTER_INIT.CANON_PARAGRAPHS | NativeMethods.IFILTER_INIT.CANON_SPACES | NativeMethods.IFILTER_INIT.APPLY_INDEX_ATTRIBUTES | NativeMethods.IFILTER_INIT.APPLY_CRAWL_ATTRIBUTES | NativeMethods.IFILTER_INIT.APPLY_OTHER_ATTRIBUTES | NativeMethods.IFILTER_INIT.HARD_LINE_BREAKS | NativeMethods.IFILTER_INIT.FILTER_OWNED_VALUE_OK | NativeMethods.IFILTER_INIT.EMIT_FORMATTING; if (disableEmbeddedContent) iflags = iflags | NativeMethods.IFILTER_INIT.DISABLE_EMBEDDED; // ReSharper disable once SuspiciousTypeConversion.Global var iPersistStream = iFilter as NativeMethods.IPersistStream; // IPersistStream is asumed on 64 bits systems if (iPersistStream != null) { // Create a COM stream IStream comStream; if (readIntoMemory) { // Copy the content to global memory var buffer = new byte[stream.Length]; stream.Read(buffer, 0, buffer.Length); var nativePtr = Marshal.AllocHGlobal(buffer.Length); Marshal.Copy(buffer, 0, nativePtr, buffer.Length); NativeMethods.CreateStreamOnHGlobal(nativePtr, true, out comStream); } else comStream = new IStreamWrapper(stream); iPersistStream.Load(comStream); NativeMethods.IFILTER_FLAGS flags; if (iFilter.Init(iflags, 0, IntPtr.Zero, out flags) == NativeMethods.IFilterReturnCode.S_OK) return iFilter; } if (string.IsNullOrWhiteSpace(fileName)) throw new IFOldFilterFormat("The IFilter does not support the IPersistStream interface, supply a filename to use the IFilter"); // If we get here we probably are using an old IFilter so try to load it the old way // ReSharper disable once SuspiciousTypeConversion.Global var persistFile = iFilter as IPersistFile; if (persistFile != null) { persistFile.Load(fileName, 0); NativeMethods.IFILTER_FLAGS flags; if (iFilter.Init(iflags, 0, IntPtr.Zero, out flags) == NativeMethods.IFilterReturnCode.S_OK) return iFilter; } // If we failed to retreive an IPersistStream or IPersistFile interface or to initialize // the filter, we release it and return null. Marshal.ReleaseComObject(iFilter); return null; }