public CustomQueryInterfaceResult GetInterface(ref Guid iid, out IntPtr pInterface)
        {
            if (iid == typeof(IEnumVARIANT).GUID)
            {
                if ((Target is HostObject) || (Target is IHostVariable) || (Target is IByRefArg))
                {
                    pInterface = IntPtr.Zero;
                    return(BindSpecialTarget(Collateral.TargetEnumerator) ? CustomQueryInterfaceResult.NotHandled : CustomQueryInterfaceResult.Failed);
                }
            }
            else if (iid == typeof(IDispatchEx).GUID)
            {
                if (EnableVTablePatching && !bypassVTablePatching)
                {
                    var pUnknown = Marshal.GetIUnknownForObject(this);

                    bypassVTablePatching = true;
                    pInterface           = UnknownHelpers.QueryInterfaceNoThrow <IDispatchEx>(pUnknown);
                    bypassVTablePatching = false;

                    Marshal.Release(pUnknown);

                    if (pInterface != IntPtr.Zero)
                    {
                        VTablePatcher.GetInstance().PatchDispatchEx(pInterface);
                        return(CustomQueryInterfaceResult.Handled);
                    }
                }
            }

            pInterface = IntPtr.Zero;
            return(CustomQueryInterfaceResult.NotHandled);
        }
        public override void Close()
        {
            debugStackFrameSniffer       = null;
            activeScriptGarbageCollector = null;
            activeScriptDebug            = null;
            activeScriptParse            = null;

            UnknownHelpers.ReleaseAndEmpty(ref pDebugStackFrameSniffer);
            UnknownHelpers.ReleaseAndEmpty(ref pActiveScriptGarbageCollector);
            UnknownHelpers.ReleaseAndEmpty(ref pActiveScriptDebug);
            UnknownHelpers.ReleaseAndEmpty(ref pActiveScriptParse);
            UnknownHelpers.ReleaseAndEmpty(ref pActiveScript);

            activeScript.Close();
            Marshal.FinalReleaseComObject(activeScript);
            activeScript = null;
        }
        public ActiveScriptWrapper64(string progID, WindowsScriptEngineFlags flags)
        {
            // ReSharper disable SuspiciousTypeConversion.Global

            pActiveScript                 = ActivationHelpers.CreateInstance <IActiveScript>(progID);
            pActiveScriptParse            = UnknownHelpers.QueryInterface <IActiveScriptParse64>(pActiveScript);
            pActiveScriptDebug            = UnknownHelpers.QueryInterface <IActiveScriptDebug64>(pActiveScript);
            pActiveScriptGarbageCollector = UnknownHelpers.QueryInterfaceNoThrow <IActiveScriptGarbageCollector>(pActiveScript);
            pDebugStackFrameSniffer       = UnknownHelpers.QueryInterfaceNoThrow <IDebugStackFrameSnifferEx64>(pActiveScript);

            activeScript                 = (IActiveScript)Marshal.GetObjectForIUnknown(pActiveScript);
            activeScriptParse            = (IActiveScriptParse64)activeScript;
            activeScriptDebug            = (IActiveScriptDebug64)activeScript;
            activeScriptGarbageCollector = activeScript as IActiveScriptGarbageCollector;
            debugStackFrameSniffer       = activeScript as IDebugStackFrameSnifferEx64;

            if (flags.HasFlag(WindowsScriptEngineFlags.EnableStandardsMode))
            {
                var activeScriptProperty = activeScript as IActiveScriptProperty;
                if (activeScriptProperty != null)
                {
                    object name;
                    activeScriptProperty.GetProperty(ScriptProp.Name, IntPtr.Zero, out name);
                    if (Equals(name, "JScript"))
                    {
                        object value = ScriptLanguageVersion.Standards;
                        activeScriptProperty.SetProperty(ScriptProp.InvokeVersioning, IntPtr.Zero, ref value);
                    }
                }

                if (!flags.HasFlag(WindowsScriptEngineFlags.DoNotEnableVTablePatching) && MiscHelpers.IsX86InstructionSet())
                {
                    HostItem.EnableVTablePatching = true;
                }
            }

            // ReSharper restore SuspiciousTypeConversion.Global
        }
Beispiel #4
0
            private void EnsurePatched()
            {
                using (var unknownScope = Scope.Create(() => Marshal.GetIUnknownForObject(this), pUnknown => Marshal.Release(pUnknown)))
                {
                    var pUnknown = unknownScope.Value;
                    using (var dispatchExScope = Scope.Create(() => UnknownHelpers.QueryInterface <IDispatchEx>(pUnknown), pDispatchEx => Marshal.Release(pDispatchEx)))
                    {
                        lock (VTablePatcher.PatchLock)
                        {
                            var pDispatchEx = dispatchExScope.Value;
                            var pVTable     = Marshal.ReadIntPtr(pDispatchEx);

                            if (!patchMap.ContainsKey(pVTable))
                            {
                                var entry = new PatchEntry();

                                var origGetDispID = VTableHelpers.GetMethodDelegate <RawGetDispID>(pDispatchEx, 7);
                                entry.AddDelegate(VTableHelpers.SetMethodDelegate(pDispatchEx, 7, new RawGetDispID((IntPtr pThis, string name, DispatchNameFlags nameFlags, out int dispid) =>
                                {
                                    try
                                    {
                                        return((Marshal.GetObjectForIUnknown(pThis) is DispatchExHostItem item) ? item.GetDispID(name, nameFlags, out dispid) : origGetDispID(pThis, name, nameFlags, out dispid));
                                    }
                                    catch (Exception exception)
                                    {
                                        dispid = SpecialDispIDs.Unknown;
                                        return(exception.HResult);
                                    }
                                })));

                                var origDeleteMemberByName = VTableHelpers.GetMethodDelegate <RawDeleteMemberByName>(pDispatchEx, 9);
                                entry.AddDelegate(VTableHelpers.SetMethodDelegate(pDispatchEx, 9, new RawDeleteMemberByName((pThis, name, nameFlags) =>
                                {
                                    try
                                    {
                                        return((Marshal.GetObjectForIUnknown(pThis) is DispatchExHostItem item) ? item.DeleteMemberByName(name, nameFlags) : origDeleteMemberByName(pThis, name, nameFlags));
                                    }
                                    catch (Exception exception)
                                    {
                                        return(exception.HResult);
                                    }
                                })));

                                var origDeleteMemberByDispID = VTableHelpers.GetMethodDelegate <RawDeleteMemberByDispID>(pDispatchEx, 10);
                                entry.AddDelegate(VTableHelpers.SetMethodDelegate(pDispatchEx, 10, new RawDeleteMemberByDispID((pThis, dispid) =>
                                {
                                    try
                                    {
                                        return((Marshal.GetObjectForIUnknown(pThis) is DispatchExHostItem item) ? item.DeleteMemberByDispID(dispid) : origDeleteMemberByDispID(pThis, dispid));
                                    }
                                    catch (Exception exception)
                                    {
                                        return(exception.HResult);
                                    }
                                })));

                                var origGetMemberProperties = VTableHelpers.GetMethodDelegate <RawGetMemberProperties>(pDispatchEx, 11);
                                entry.AddDelegate(VTableHelpers.SetMethodDelegate(pDispatchEx, 11, new RawGetMemberProperties((IntPtr pThis, int dispid, DispatchPropFlags fetchFlags, out DispatchPropFlags propFlags) =>
                                {
                                    try
                                    {
                                        var item = Marshal.GetObjectForIUnknown(pThis) as DispatchExHostItem;
                                        if (item == null)
                                        {
                                            return(origGetMemberProperties(pThis, dispid, fetchFlags, out propFlags));
                                        }

                                        var result = item.GetMemberProperties(dispid, fetchFlags, out propFlags);
                                        if (result == HResult.DISP_E_MEMBERNOTFOUND)
                                        {
                                            return(origGetMemberProperties(pThis, dispid, fetchFlags, out propFlags));
                                        }

                                        return(result);
                                    }
                                    catch (Exception exception)
                                    {
                                        propFlags = 0;
                                        return(exception.HResult);
                                    }
                                })));

                                var origGetMemberName = VTableHelpers.GetMethodDelegate <RawGetMemberName>(pDispatchEx, 12);
                                entry.AddDelegate(VTableHelpers.SetMethodDelegate(pDispatchEx, 12, new RawGetMemberName((IntPtr pThis, int dispid, out string name) =>
                                {
                                    try
                                    {
                                        return((Marshal.GetObjectForIUnknown(pThis) is DispatchExHostItem item) ? item.GetMemberName(dispid, out name) : origGetMemberName(pThis, dispid, out name));
                                    }
                                    catch (Exception exception)
                                    {
                                        name = null;
                                        return(exception.HResult);
                                    }
                                })));

                                var origGetNextDispID = VTableHelpers.GetMethodDelegate <RawGetNextDispID>(pDispatchEx, 13);
                                entry.AddDelegate(VTableHelpers.SetMethodDelegate(pDispatchEx, 13, new RawGetNextDispID((IntPtr pThis, DispatchEnumFlags enumFlags, int dispidCurrent, out int dispidNext) =>
                                {
                                    try
                                    {
                                        return((Marshal.GetObjectForIUnknown(pThis) is DispatchExHostItem item) ? item.GetNextDispID(dispidCurrent, out dispidNext) : origGetNextDispID(pThis, enumFlags, dispidCurrent, out dispidNext));
                                    }
                                    catch (Exception exception)
                                    {
                                        dispidNext = SpecialDispIDs.Unknown;
                                        return(exception.HResult);
                                    }
                                })));

                                patchMap.Add(pVTable, entry);
                                Debug.Assert(patchMap.Count < 16);
                            }
                        }
                    }
                }
            }