private void EnsurePatched()

in ClearScript/HostItem.NetCore.cs [176:292]


            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);
                            }
                        }
                    }
                }
            }