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);
                }
            }
        }
Exemple #3
0
        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);
        }
Exemple #5
0
        /// <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);
        }