private void QueryInterface(IntPtr punk, Guid iid, Dictionary <IntPtr, string> module_names, HashSet <COMInterfaceInstance> list) { if (punk != IntPtr.Zero) { IntPtr ppout; if (Marshal.QueryInterface(punk, ref iid, out ppout) == 0) { IntPtr vtable = Marshal.ReadIntPtr(ppout, 0); COMInterfaceInstance intf; using (SafeLibraryHandle module = COMUtilities.SafeGetModuleHandle(vtable)) { if (_clsctx == CLSCTX.INPROC_SERVER && module != null) { if (!module_names.ContainsKey(module.DangerousGetHandle())) { module_names[module.DangerousGetHandle()] = module.GetModuleFileName(); } intf = new COMInterfaceInstance(iid, module_names[module.DangerousGetHandle()], vtable.ToInt64() - module.DangerousGetHandle().ToInt64()); } else { intf = new COMInterfaceInstance(iid); } } list.Add(intf); Marshal.Release(ppout); } } }
private static IntPtr FindProxyDllInfo(SafeLibraryHandle lib, Guid clsid) { try { GetProxyDllInfo get_proxy_dllinfo = lib.GetFunctionPointer <GetProxyDllInfo>(); IntPtr pInfo; IntPtr pId; get_proxy_dllinfo(out pInfo, out pId); return(pInfo); } catch (Win32Exception) { } IntPtr psfactory = IntPtr.Zero; try { DllGetClassObject dll_get_class_object = lib.GetFunctionPointer <DllGetClassObject>(); Guid IID_IPSFactoryBuffer = COMInterfaceEntry.IID_IPSFactoryBuffer; int hr = dll_get_class_object(ref clsid, ref IID_IPSFactoryBuffer, out psfactory); if (hr != 0) { throw new Win32Exception(hr); } // The PSFactoryBuffer object seems to be structured like on Win10 at least. // VTABLE* // Reference Count // ProxyFileInfo* IntPtr pInfo = Marshal.ReadIntPtr(psfactory, 2 * IntPtr.Size); // TODO: Should add better checks here, // for example VTable should be in COMBASE and the pointer should be in the // server DLL's rdata section. But this is probably good enough for now. using (SafeLibraryHandle module = COMUtilities.SafeGetModuleHandle(pInfo)) { if (module == null || lib.DangerousGetHandle() != module.DangerousGetHandle()) { return(IntPtr.Zero); } } return(pInfo); } catch (Win32Exception) { return(IntPtr.Zero); } finally { if (psfactory != IntPtr.Zero) { Marshal.Release(psfactory); } } }
private static bool LoadBinFile(String fileName, out FilterData data) { if (String.IsNullOrEmpty(fileName)) { throw new ArgumentException("fileName is null or empty.", nameof(fileName)); } data = null; bool result = false; using (SafeLibraryHandle hm = UnsafeNativeMethods.LoadLibraryEx(fileName, IntPtr.Zero, LOAD_LIBRARY_AS_DATAFILE)) { if (!hm.IsInvalid) { byte[] ffdata = null; GCHandle gch = GCHandle.Alloc(ffdata); bool needsRelease = false; try { hm.DangerousAddRef(ref needsRelease); IntPtr hMod = hm.DangerousGetHandle(); if (!UnsafeNativeMethods.EnumResourceNames(hMod, "PARM", new EnumResNameDelegate(EnumRes), GCHandle.ToIntPtr(gch))) { ffdata = (byte[])gch.Target; if (ffdata != null) { data = GetFilterDataFromParmBytes(ffdata); result = true; } } } finally { gch.Free(); if (needsRelease) { hm.DangerousRelease(); } } } } return(result); }
internal static IEnumerable <PluginData> LoadPluginsFromFile(string path) { List <PluginData> pluginData = new List <PluginData>(); using (SafeLibraryHandle dll = UnsafeNativeMethods.LoadLibraryExW(path, IntPtr.Zero, NativeConstants.LOAD_LIBRARY_AS_DATAFILE)) { if (!dll.IsInvalid) { QueryPlugin query = new QueryPlugin(path); GCHandle handle = GCHandle.Alloc(query, GCHandleType.Normal); bool needsRelease = false; System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions(); try { dll.DangerousAddRef(ref needsRelease); IntPtr callback = GCHandle.ToIntPtr(handle); if (UnsafeNativeMethods.EnumResourceNamesW(dll.DangerousGetHandle(), "PIPl", EnumPIPL, callback)) { query = (QueryPlugin)GCHandle.FromIntPtr(callback).Target; pluginData.AddRange(query.plugins); } } finally { if (handle.IsAllocated) { handle.Free(); } if (needsRelease) { dll.DangerousRelease(); } } } } return(pluginData); }
/// <summary> /// Loads the 8bf filters from the specified file. /// </summary> /// <param name="path">The path of the plug-in.</param> /// <returns> /// An enumerable collection containing the filters within the specified file. /// </returns> internal static IEnumerable <PluginData> LoadFiltersFromFile(string path) { if (path == null) { throw new ArgumentNullException(nameof(path)); } if (!PEFile.CheckProcessorArchitecture(path)) { return(System.Linq.Enumerable.Empty <PluginData>()); } List <PluginData> pluginData = new List <PluginData>(); #if DEBUG DebugUtils.GlobalDebugFlags |= DebugFlags.PiPL; #endif SafeLibraryHandle dll = UnsafeNativeMethods.LoadLibraryExW(path, IntPtr.Zero, NativeConstants.LOAD_LIBRARY_AS_DATAFILE); try { if (!dll.IsInvalid) { QueryFilter queryFilter = new QueryFilter(path); GCHandle handle = GCHandle.Alloc(queryFilter, GCHandleType.Normal); bool needsRelease = false; System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions(); try { dll.DangerousAddRef(ref needsRelease); IntPtr callback = GCHandle.ToIntPtr(handle); if (UnsafeNativeMethods.EnumResourceNamesW(dll.DangerousGetHandle(), "PiPl", new UnsafeNativeMethods.EnumResNameDelegate(EnumPiPL), callback)) { queryFilter = (QueryFilter)GCHandle.FromIntPtr(callback).Target; pluginData.AddRange(queryFilter.plugins); } else if (UnsafeNativeMethods.EnumResourceNamesW(dll.DangerousGetHandle(), "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.Error, string.Format("EnumResourceNames(PiPL, PiMI) failed for {0}", path)); } #endif } finally { if (handle.IsAllocated) { handle.Free(); } if (needsRelease) { dll.DangerousRelease(); } } } #if DEBUG else { System.Diagnostics.Debug.WriteLine(string.Format("LoadLibrary() returned 0x{0:X8}", Marshal.GetLastWin32Error())); } #endif } finally { if (!dll.IsClosed) { dll.Dispose(); dll = null; } } if (pluginData.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[pluginData.Count]; for (int i = 0; i < entryPoints.Length; i++) { entryPoints[i] = pluginData[i].EntryPoint; } for (int i = 0; i < entryPoints.Length; i++) { pluginData[i].ModuleEntryPoints = entryPoints; } } return(pluginData); }