/// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> public void Dispose() { if (!disposed) { disposed = true; if (handle != null && !handle.IsClosed) { handle.Dispose(); handle = null; } } }
internal static extern IntPtr GetProcAddress(SafeLibraryHandle hModule, string lpProcName);
/// <summary> /// Loads the 8bf filters from the specified file. /// </summary> /// <param name="fileName">The plug-in file name.</param> /// <returns>An enumerable collection containing the filters within the plug-in.</returns> /// <exception cref="System.ArgumentNullException"><paramref name="fileName"/> is null.</exception> internal static IEnumerable <PluginData> LoadFiltersFromFile(string fileName) { if (fileName == null) { throw new ArgumentNullException(nameof(fileName)); } ProcessorArchitecture platform = PEFile.GetProcessorArchitecture(fileName); if (!DllProcessorArchtectureIsSupported(platform)) { // Ignore any DLLs that cannot be used on the current platform. return(System.Linq.Enumerable.Empty <PluginData>()); } List <PluginData> pluginData = new List <PluginData>(); // Use LOAD_LIBRARY_AS_DATAFILE to prevent a BadImageFormatException from being thrown if the file is a different processor architecture than the parent process. using (SafeLibraryHandle dll = UnsafeNativeMethods.LoadLibraryExW(fileName, IntPtr.Zero, NativeConstants.LOAD_LIBRARY_AS_DATAFILE)) { if (!dll.IsInvalid) { QueryFilter queryFilter = new QueryFilter(fileName, platform); GCHandle handle = GCHandle.Alloc(queryFilter, GCHandleType.Normal); try { IntPtr callback = GCHandle.ToIntPtr(handle); if (UnsafeNativeMethods.EnumResourceNamesW(dll, "PiPl", new UnsafeNativeMethods.EnumResNameDelegate(EnumPiPL), callback)) { queryFilter = (QueryFilter)GCHandle.FromIntPtr(callback).Target; pluginData.AddRange(queryFilter.plugins); } else if (UnsafeNativeMethods.EnumResourceNamesW(dll, "PiMI", new UnsafeNativeMethods.EnumResNameDelegate(EnumPiMI), callback)) { // If there are no PiPL resources scan for Photoshop 2.5's PiMI resources. queryFilter = (QueryFilter)GCHandle.FromIntPtr(callback).Target; pluginData.AddRange(queryFilter.plugins); } #if DEBUG else { DebugUtils.Ping(DebugFlags.PiPL, string.Format("EnumResourceNames(PiPL, PiMI) failed for {0}", fileName)); } #endif } finally { if (handle.IsAllocated) { handle.Free(); } } } } int count = pluginData.Count; if (count > 1) { // If the DLL contains more than one filter, add a list of all the entry points to each individual filter. // Per the SDK only one entry point in a module will display the about box the rest are dummy calls so we must call all of them. string[] entryPoints = new string[count]; for (int i = 0; i < count; i++) { entryPoints[i] = pluginData[i].EntryPoint; } for (int i = 0; i < count; i++) { pluginData[i].ModuleEntryPoints = new ReadOnlyCollection <string>(entryPoints); } } return(pluginData); }