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