コード例 #1
0
ファイル: PluginLoader.cs プロジェクト: simedcn/PSFilterHost
        private static unsafe bool EnumPiPL(IntPtr hModule, IntPtr lpszType, IntPtr lpszName, IntPtr lParam)
        {
            GCHandle    handle = GCHandle.FromIntPtr(lParam);
            QueryFilter query  = (QueryFilter)handle.Target;

            IntPtr hRes = UnsafeNativeMethods.FindResourceW(hModule, lpszName, lpszType);

            if (hRes == IntPtr.Zero)
            {
#if DEBUG
                System.Diagnostics.Debug.WriteLine(string.Format("FindResource failed for PiPL in {0}", query.fileName));
#endif
                return(true);
            }

            IntPtr loadRes = UnsafeNativeMethods.LoadResource(hModule, hRes);
            if (loadRes == IntPtr.Zero)
            {
#if DEBUG
                System.Diagnostics.Debug.WriteLine(string.Format("LoadResource failed for PiPL in {0}", query.fileName));
#endif
                return(true);
            }

            IntPtr lockRes = UnsafeNativeMethods.LockResource(loadRes);
            if (lockRes == IntPtr.Zero)
            {
#if DEBUG
                System.Diagnostics.Debug.WriteLine(string.Format("LockResource failed for PiPL in {0}", query.fileName));
#endif

                return(true);
            }

#if DEBUG
            short fb = Marshal.ReadInt16(lockRes);             // PiPL Resources always start with 1, this seems to be Photoshop's signature.
#endif
            int version = Marshal.ReadInt32(lockRes, 2);

            if (version != PSConstants.latestPIPLVersion)
            {
#if DEBUG
                System.Diagnostics.Debug.WriteLine(string.Format("Invalid PiPL version in {0}: {1}, Expected version {2}", query.fileName, version, PSConstants.latestPIPLVersion));
#endif
                return(true);
            }

            int count = Marshal.ReadInt32(lockRes, 6);

            byte *propPtr = (byte *)lockRes.ToPointer() + 10L;

            string           entryPoint     = null;
            string           category       = null;
            string           title          = null;
            FilterCaseInfo[] filterInfo     = null;
            PluginAETE       aete           = null;
            string           enableInfo     = null;
            ushort?          supportedModes = null;
            bool             hasAboutBox    = true;

            uint platformEntryPoint = IntPtr.Size == 8 ? PIPropertyID.PIWin64X86CodeProperty : PIPropertyID.PIWin32X86CodeProperty;

            for (int i = 0; i < count; i++)
            {
                PIProperty *pipp           = (PIProperty *)propPtr;
                uint        propKey        = pipp->propertyKey;
                int         propertyLength = pipp->propertyLength;

                byte *dataPtr = propPtr + PIProperty.SizeOf;
                if (propKey == PIPropertyID.PIKindProperty)
                {
                    if (*((uint *)dataPtr) != PSConstants.filterKind)
                    {
#if DEBUG
                        System.Diagnostics.Debug.WriteLine(string.Format("{0} is not a valid Photoshop filter.", query.fileName));
#endif
                        return(true);
                    }
                }
                else if (propKey == platformEntryPoint)
                {
                    entryPoint = Marshal.PtrToStringAnsi((IntPtr)dataPtr, propertyLength).TrimEnd('\0');
                }
                else if (propKey == PIPropertyID.PIVersionProperty)
                {
                    int packedVersion = *(int *)dataPtr;
                    int major         = (packedVersion >> 16);
                    int minor         = (packedVersion & 0xffff);

                    if (major > PSConstants.latestFilterVersion ||
                        major == PSConstants.latestFilterVersion && minor > PSConstants.latestFilterSubVersion)
                    {
#if DEBUG
                        System.Diagnostics.Debug.WriteLine(string.Format("{0} requires newer filter interface version {1}.{2} and only version {3}.{4} is supported",
                                                                         new object[] { query.fileName, major, minor, PSConstants.latestFilterVersion, PSConstants.latestFilterSubVersion }));
#endif
                        return(true);
                    }
                }
                else if (propKey == PIPropertyID.PIImageModesProperty)
                {
#if GDIPLUS
                    // All GDI+ images are converted to 8-bit RGB(A) for processing.
                    if ((dataPtr[0] & PSConstants.flagSupportsRGBColor) != PSConstants.flagSupportsRGBColor)
                    {
                        return(true);
                    }
#else
                    if ((dataPtr[0] & PSConstants.flagSupportsRGBColor) != PSConstants.flagSupportsRGBColor &&
                        (dataPtr[0] & PSConstants.flagSupportsGrayScale) != PSConstants.flagSupportsGrayScale)
                    {
#if DEBUG
                        System.Diagnostics.Debug.WriteLine(string.Format("{0} does not support the plugInModeRGBColor or plugInModeGrayScale image modes.", query.fileName));
#endif
                        return(true);
                    }
#endif
                    supportedModes = *(ushort *)dataPtr;
                }
                else if (propKey == PIPropertyID.PICategoryProperty)
                {
                    category = StringUtil.FromPascalString(dataPtr);
                }
                else if (propKey == PIPropertyID.PINameProperty)
                {
                    title = StringUtil.FromPascalString(dataPtr);
                }
                else if (propKey == PIPropertyID.PIFilterCaseInfoProperty)
                {
                    FilterCaseInfoResult result = FilterCaseInfoParser.Parse(dataPtr, propertyLength);

                    if (result != null)
                    {
                        filterInfo = result.filterCaseInfo;
                        // The actual property length may be longer than the header specifies
                        // if the FilterCaseInfo fields are incorrectly escaped.
                        if (propertyLength != result.propertyLength)
                        {
                            propertyLength = result.propertyLength;
                        }
                    }
                }
                else if (propKey == PIPropertyID.PIHasTerminologyProperty)
                {
                    PITerminology *term = (PITerminology *)dataPtr;
                    if (term->version == PSConstants.LatestTerminologyVersion)
                    {
#if DEBUG
                        string aeteName = Marshal.PtrToStringAnsi(new IntPtr(dataPtr + PITerminology.SizeOf)).TrimEnd('\0');
#endif
                        QueryAETE queryAETE = new QueryAETE(term->terminologyID);

                        GCHandle aeteHandle = GCHandle.Alloc(queryAETE, GCHandleType.Normal);
                        try
                        {
                            IntPtr callback = GCHandle.ToIntPtr(aeteHandle);
                            if (!UnsafeNativeMethods.EnumResourceNamesW(hModule, "AETE", new UnsafeNativeMethods.EnumResNameDelegate(EnumAETE), callback))
                            {
                                queryAETE = (QueryAETE)GCHandle.FromIntPtr(callback).Target;
                            }
                        }
                        finally
                        {
                            if (aeteHandle.IsAllocated)
                            {
                                aeteHandle.Free();
                            }
                        }

                        if (queryAETE.enumAETE != null)
                        {
                            aete = queryAETE.enumAETE;
                        }
                    }
                }
                else if (propKey == PIPropertyID.EnableInfo)
                {
                    enableInfo = Marshal.PtrToStringAnsi((IntPtr)dataPtr, propertyLength).TrimEnd('\0');
                }
                else if (propKey == PIPropertyID.PIRequiredHostProperty)
                {
                    uint host = *(uint *)dataPtr;
                    if (host != PSConstants.kPhotoshopSignature && host != PSConstants.AnyHostSignature)
                    {
#if DEBUG
                        System.Diagnostics.Debug.WriteLine(string.Format("{0} requires host '{1}'.", query.fileName, DebugUtils.PropToString(host)));
#endif
                        return(true);
                    }
                }
                else if (propKey == PIPropertyID.NoAboutBox)
                {
                    hasAboutBox = false;
                }
#if DEBUG
                else
                {
                    DebugUtils.Ping(DebugFlags.PiPL, string.Format("Unsupported property '{0}' in {1}", DebugUtils.PropToString(propKey), query.fileName));
                }
#endif

                // The property data is padded to a 4 byte boundary.
                int propertyDataPaddedLength = (propertyLength + 3) & ~3;
                propPtr += (PIProperty.SizeOf + propertyDataPaddedLength);
            }

            PluginData pluginData = new PluginData(query.fileName, entryPoint, category, title, filterInfo, aete, enableInfo, supportedModes, hasAboutBox);

            if (pluginData.IsValid())
            {
                query.plugins.Add(pluginData);
                handle.Target = query;
                lParam        = GCHandle.ToIntPtr(handle);
            }

            return(true);
        }
コード例 #2
0
ファイル: PluginLoader.cs プロジェクト: simedcn/PSFilterHost
 public QueryAETE(int terminologyID)
 {
     resourceID = new IntPtr(terminologyID);
     enumAETE   = null;
 }