MegaBites-AI/Windows-powershell
0372
1// Licensed to the .NET Foundation under one or more agreements.2// The .NET Foundation licenses this file to you under the MIT license.3 4using System.Collections.Generic;5 6using System.Management.Automation.ComInterop;7 8namespace System.Management.Automation.InteropServices9{10 internal partial class ComEventsSink11 {12 private void Initialize(object rcw, Guid iid)13 {14 _iidSourceItf = iid;15 Advise(rcw);16 }17 18 public void AddHandler(int dispid, object func)19 {20 ComEventsMethod method = FindMethod(dispid);21 method ??= AddMethod(dispid);22 23 if (func is Delegate d)24 {25 method.AddDelegate(d);26 }27 else28 {29 method.AddDelegate(new SplatCallSite.InvokeDelegate(new SplatCallSite(func).Invoke), wrapArgs: true);30 }31 }32 33 public void RemoveHandler(int dispid, object func)34 {35 ComEventsMethod sinkEntry = FindMethod(dispid);36 if (sinkEntry == null)37 {38 return;39 }40 41 if (func is Delegate d)42 {43 sinkEntry.RemoveDelegate(d);44 }45 else46 {47 // Remove the delegate from multicast delegate chain.48 // We will need to find the delegate that corresponds49 // to the func handler we want to remove. This will be50 // easy since we Target property of the delegate object51 // is a ComEventCallContext object.52 sinkEntry.RemoveDelegates(d => d.Target is SplatCallSite callContext && callContext._callable.Equals(func));53 }54 55 // If the delegates chain is empty - we can remove56 // corresponding ComEvenSinkEntry57 if (sinkEntry.Empty)58 RemoveMethod(sinkEntry);59 60 if (_methods == null || _methods.Empty)61 {62 Unadvise();63 _iidSourceItf = Guid.Empty;64 }65 }66 67 public static ComEventsSink FromRuntimeCallableWrapper(object rcw, Guid sourceIid, bool createIfNotFound)68 {69 List<ComEventsSink> comEventSinks = ComEventSinksContainer.FromRuntimeCallableWrapper(rcw, createIfNotFound);70 if (comEventSinks == null)71 {72 return null;73 }74 75 ComEventsSink comEventSink = null;76 lock (comEventSinks)77 {78 foreach (ComEventsSink sink in comEventSinks)79 {80 if (sink._iidSourceItf == sourceIid)81 {82 comEventSink = sink;83 break;84 }85 86 if (sink._iidSourceItf == Guid.Empty)87 {88 // we found a ComEventSink object that89 // was previously disposed. Now we will reuse it.90 sink.Initialize(rcw, sourceIid);91 comEventSink = sink;92 }93 }94 95 if (comEventSink == null && createIfNotFound)96 {97 comEventSink = new ComEventsSink(rcw, sourceIid);98 comEventSinks.Add(comEventSink);99 }100 }101 102 return comEventSink;103 }104 }105}106 