464 lines
15 KiB
C#
464 lines
15 KiB
C#
// ==++==
|
|
//
|
|
// Copyright(c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
// ==--==
|
|
// <OWNER>[....]</OWNER>
|
|
//
|
|
|
|
namespace System.Reflection
|
|
{
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Diagnostics.Contracts;
|
|
using System.Diagnostics.Tracing;
|
|
using System.Runtime.InteropServices;
|
|
using System.Runtime.Serialization;
|
|
using System.Runtime.ConstrainedExecution;
|
|
using System.Security.Permissions;
|
|
using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
|
|
|
|
[Serializable]
|
|
[ClassInterface(ClassInterfaceType.None)]
|
|
[ComDefaultInterface(typeof(_EventInfo))]
|
|
#pragma warning disable 618
|
|
[PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")]
|
|
#pragma warning restore 618
|
|
[System.Runtime.InteropServices.ComVisible(true)]
|
|
public abstract class EventInfo : MemberInfo, _EventInfo
|
|
{
|
|
#region Constructor
|
|
protected EventInfo() { }
|
|
#endregion
|
|
|
|
#if !FEATURE_CORECLR
|
|
public static bool operator ==(EventInfo left, EventInfo right)
|
|
{
|
|
if (ReferenceEquals(left, right))
|
|
return true;
|
|
|
|
if ((object)left == null || (object)right == null ||
|
|
left is RuntimeEventInfo || right is RuntimeEventInfo)
|
|
{
|
|
return false;
|
|
}
|
|
return left.Equals(right);
|
|
}
|
|
|
|
public static bool operator !=(EventInfo left, EventInfo right)
|
|
{
|
|
return !(left == right);
|
|
}
|
|
#endif // !FEATURE_CORECLR
|
|
#if FEATURE_NETCORE || !FEATURE_CORECLR
|
|
public override bool Equals(object obj)
|
|
{
|
|
return base.Equals(obj);
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return base.GetHashCode();
|
|
}
|
|
#endif //FEATURE_NETCORE || !FEATURE_CORECLR
|
|
#region MemberInfo Overrides
|
|
public override MemberTypes MemberType { get { return MemberTypes.Event; } }
|
|
#endregion
|
|
|
|
#region Public Abstract\Virtual Members
|
|
public virtual MethodInfo[] GetOtherMethods(bool nonPublic)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public abstract MethodInfo GetAddMethod(bool nonPublic);
|
|
|
|
public abstract MethodInfo GetRemoveMethod(bool nonPublic);
|
|
|
|
public abstract MethodInfo GetRaiseMethod(bool nonPublic);
|
|
|
|
public abstract EventAttributes Attributes { get; }
|
|
#endregion
|
|
|
|
#region Public Members
|
|
public virtual MethodInfo AddMethod
|
|
{
|
|
get
|
|
{
|
|
return GetAddMethod(true);
|
|
}
|
|
}
|
|
|
|
public virtual MethodInfo RemoveMethod
|
|
{
|
|
get
|
|
{
|
|
return GetRemoveMethod(true);
|
|
}
|
|
}
|
|
|
|
public virtual MethodInfo RaiseMethod
|
|
{
|
|
get
|
|
{
|
|
return GetRaiseMethod(true);
|
|
}
|
|
}
|
|
|
|
public MethodInfo[] GetOtherMethods() { return GetOtherMethods(false); }
|
|
|
|
public MethodInfo GetAddMethod() { return GetAddMethod(false); }
|
|
|
|
public MethodInfo GetRemoveMethod() { return GetRemoveMethod(false); }
|
|
|
|
public MethodInfo GetRaiseMethod() { return GetRaiseMethod(false); }
|
|
|
|
[DebuggerStepThroughAttribute]
|
|
[Diagnostics.DebuggerHidden]
|
|
public virtual void AddEventHandler(Object target, Delegate handler)
|
|
{
|
|
MethodInfo addMethod = GetAddMethod();
|
|
|
|
if (addMethod == null)
|
|
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoPublicAddMethod"));
|
|
|
|
#if FEATURE_COMINTEROP
|
|
if (addMethod.ReturnType == typeof(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken))
|
|
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotSupportedOnWinRTEvent"));
|
|
|
|
// Must be a normal non-WinRT event
|
|
Contract.Assert(addMethod.ReturnType == typeof(void));
|
|
#endif // FEATURE_COMINTEROP
|
|
|
|
addMethod.Invoke(target, new object[] { handler });
|
|
}
|
|
|
|
[DebuggerStepThroughAttribute]
|
|
[Diagnostics.DebuggerHidden]
|
|
public virtual void RemoveEventHandler(Object target, Delegate handler)
|
|
{
|
|
MethodInfo removeMethod = GetRemoveMethod();
|
|
|
|
if (removeMethod == null)
|
|
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoPublicRemoveMethod"));
|
|
|
|
#if FEATURE_COMINTEROP
|
|
ParameterInfo[] parameters = removeMethod.GetParametersNoCopy();
|
|
Contract.Assert(parameters != null && parameters.Length == 1);
|
|
|
|
if (parameters[0].ParameterType == typeof(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken))
|
|
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotSupportedOnWinRTEvent"));
|
|
|
|
// Must be a normal non-WinRT event
|
|
Contract.Assert(parameters[0].ParameterType.BaseType == typeof(MulticastDelegate));
|
|
#endif // FEATURE_COMINTEROP
|
|
|
|
removeMethod.Invoke(target, new object[] { handler });
|
|
}
|
|
|
|
public virtual Type EventHandlerType
|
|
{
|
|
get
|
|
{
|
|
MethodInfo m = GetAddMethod(true);
|
|
|
|
ParameterInfo[] p = m.GetParametersNoCopy();
|
|
|
|
Type del = typeof(Delegate);
|
|
|
|
for (int i = 0; i < p.Length; i++)
|
|
{
|
|
Type c = p[i].ParameterType;
|
|
|
|
if (c.IsSubclassOf(del))
|
|
return c;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
public bool IsSpecialName
|
|
{
|
|
get
|
|
{
|
|
return(Attributes & EventAttributes.SpecialName) != 0;
|
|
}
|
|
}
|
|
|
|
public virtual bool IsMulticast
|
|
{
|
|
get
|
|
{
|
|
Type cl = EventHandlerType;
|
|
Type mc = typeof(MulticastDelegate);
|
|
return mc.IsAssignableFrom(cl);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
Type _EventInfo.GetType()
|
|
{
|
|
return base.GetType();
|
|
}
|
|
|
|
void _EventInfo.GetTypeInfoCount(out uint pcTInfo)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
void _EventInfo.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
void _EventInfo.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
// If you implement this method, make sure to include _EventInfo.Invoke in VM\DangerousAPIs.h and
|
|
// include _EventInfo in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp.
|
|
void _EventInfo.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
[Serializable]
|
|
internal unsafe sealed class RuntimeEventInfo : EventInfo, ISerializable
|
|
{
|
|
#region Private Data Members
|
|
private int m_token;
|
|
private EventAttributes m_flags;
|
|
private string m_name;
|
|
[System.Security.SecurityCritical]
|
|
private void* m_utf8name;
|
|
private RuntimeTypeCache m_reflectedTypeCache;
|
|
private RuntimeMethodInfo m_addMethod;
|
|
private RuntimeMethodInfo m_removeMethod;
|
|
private RuntimeMethodInfo m_raiseMethod;
|
|
private MethodInfo[] m_otherMethod;
|
|
private RuntimeType m_declaringType;
|
|
private BindingFlags m_bindingFlags;
|
|
#endregion
|
|
|
|
#region Constructor
|
|
internal RuntimeEventInfo()
|
|
{
|
|
// Used for dummy head node during population
|
|
}
|
|
[System.Security.SecurityCritical] // auto-generated
|
|
internal RuntimeEventInfo(int tkEvent, RuntimeType declaredType, RuntimeTypeCache reflectedTypeCache, out bool isPrivate)
|
|
{
|
|
Contract.Requires(declaredType != null);
|
|
Contract.Requires(reflectedTypeCache != null);
|
|
Contract.Assert(!reflectedTypeCache.IsGlobal);
|
|
|
|
MetadataImport scope = declaredType.GetRuntimeModule().MetadataImport;
|
|
|
|
m_token = tkEvent;
|
|
m_reflectedTypeCache = reflectedTypeCache;
|
|
m_declaringType = declaredType;
|
|
|
|
|
|
RuntimeType reflectedType = reflectedTypeCache.GetRuntimeType();
|
|
|
|
scope.GetEventProps(tkEvent, out m_utf8name, out m_flags);
|
|
|
|
RuntimeMethodInfo dummy;
|
|
Associates.AssignAssociates(scope, tkEvent, declaredType, reflectedType,
|
|
out m_addMethod, out m_removeMethod, out m_raiseMethod,
|
|
out dummy, out dummy, out m_otherMethod, out isPrivate, out m_bindingFlags);
|
|
}
|
|
#endregion
|
|
|
|
#region Internal Members
|
|
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
|
internal override bool CacheEquals(object o)
|
|
{
|
|
RuntimeEventInfo m = o as RuntimeEventInfo;
|
|
|
|
if ((object)m == null)
|
|
return false;
|
|
|
|
return m.m_token == m_token &&
|
|
RuntimeTypeHandle.GetModule(m_declaringType).Equals(
|
|
RuntimeTypeHandle.GetModule(m.m_declaringType));
|
|
}
|
|
|
|
internal BindingFlags BindingFlags { get { return m_bindingFlags; } }
|
|
#endregion
|
|
|
|
#region Object Overrides
|
|
public override String ToString()
|
|
{
|
|
if (m_addMethod == null || m_addMethod.GetParametersNoCopy().Length == 0)
|
|
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoPublicAddMethod"));
|
|
|
|
return m_addMethod.GetParametersNoCopy()[0].ParameterType.FormatTypeName() + " " + Name;
|
|
}
|
|
#endregion
|
|
|
|
#region ICustomAttributeProvider
|
|
public override Object[] GetCustomAttributes(bool inherit)
|
|
{
|
|
return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType);
|
|
}
|
|
|
|
public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
|
|
{
|
|
if (attributeType == null)
|
|
throw new ArgumentNullException("attributeType");
|
|
Contract.EndContractBlock();
|
|
|
|
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
|
|
|
|
if (attributeRuntimeType == null)
|
|
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
|
|
|
|
return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
|
|
}
|
|
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
public override bool IsDefined(Type attributeType, bool inherit)
|
|
{
|
|
if (attributeType == null)
|
|
throw new ArgumentNullException("attributeType");
|
|
Contract.EndContractBlock();
|
|
|
|
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
|
|
|
|
if (attributeRuntimeType == null)
|
|
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType");
|
|
|
|
return CustomAttribute.IsDefined(this, attributeRuntimeType);
|
|
}
|
|
|
|
public override IList<CustomAttributeData> GetCustomAttributesData()
|
|
{
|
|
return CustomAttributeData.GetCustomAttributesInternal(this);
|
|
}
|
|
#endregion
|
|
|
|
#region MemberInfo Overrides
|
|
public override MemberTypes MemberType { get { return MemberTypes.Event; } }
|
|
public override String Name
|
|
{
|
|
[System.Security.SecuritySafeCritical] // auto-generated
|
|
get
|
|
{
|
|
if (m_name == null)
|
|
m_name = new Utf8String(m_utf8name).ToString();
|
|
|
|
#if !FEATURE_CORECLR
|
|
if (FrameworkEventSource.IsInitialized && FrameworkEventSource.Log.IsEnabled(EventLevel.Informational, FrameworkEventSource.Keywords.DynamicTypeUsage))
|
|
{
|
|
FrameworkEventSource.Log.EventName(DeclaringType.GetFullNameForEtw(), GetFullNameForEtw());
|
|
}
|
|
#endif
|
|
return m_name;
|
|
}
|
|
}
|
|
|
|
[System.Security.SecuritySafeCritical]
|
|
internal override String GetFullNameForEtw()
|
|
{
|
|
if (m_name == null)
|
|
return new Utf8String(m_utf8name).ToString();
|
|
|
|
return m_name;
|
|
}
|
|
|
|
public override Type DeclaringType { get { return m_declaringType; } }
|
|
public override Type ReflectedType
|
|
{
|
|
get
|
|
{
|
|
return ReflectedTypeInternal;
|
|
}
|
|
}
|
|
|
|
private RuntimeType ReflectedTypeInternal
|
|
{
|
|
get
|
|
{
|
|
return m_reflectedTypeCache.GetRuntimeType();
|
|
}
|
|
}
|
|
|
|
public override int MetadataToken { get { return m_token; } }
|
|
public override Module Module { get { return GetRuntimeModule(); } }
|
|
internal RuntimeModule GetRuntimeModule() { return m_declaringType.GetRuntimeModule(); }
|
|
|
|
#endregion
|
|
|
|
#region ISerializable
|
|
[System.Security.SecurityCritical] // auto-generated_required
|
|
public void GetObjectData(SerializationInfo info, StreamingContext context)
|
|
{
|
|
if (info == null)
|
|
throw new ArgumentNullException("info");
|
|
Contract.EndContractBlock();
|
|
|
|
MemberInfoSerializationHolder.GetSerializationInfo(
|
|
info,
|
|
Name,
|
|
ReflectedTypeInternal,
|
|
null,
|
|
MemberTypes.Event);
|
|
}
|
|
#endregion
|
|
|
|
#region EventInfo Overrides
|
|
public override MethodInfo[] GetOtherMethods(bool nonPublic)
|
|
{
|
|
List<MethodInfo> ret = new List<MethodInfo>();
|
|
|
|
if ((object)m_otherMethod == null)
|
|
return new MethodInfo[0];
|
|
|
|
for(int i = 0; i < m_otherMethod.Length; i ++)
|
|
{
|
|
if (Associates.IncludeAccessor((MethodInfo)m_otherMethod[i], nonPublic))
|
|
ret.Add(m_otherMethod[i]);
|
|
}
|
|
|
|
return ret.ToArray();
|
|
}
|
|
|
|
public override MethodInfo GetAddMethod(bool nonPublic)
|
|
{
|
|
if (!Associates.IncludeAccessor(m_addMethod, nonPublic))
|
|
return null;
|
|
|
|
return m_addMethod;
|
|
}
|
|
|
|
public override MethodInfo GetRemoveMethod(bool nonPublic)
|
|
{
|
|
if (!Associates.IncludeAccessor(m_removeMethod, nonPublic))
|
|
return null;
|
|
|
|
return m_removeMethod;
|
|
}
|
|
|
|
public override MethodInfo GetRaiseMethod(bool nonPublic)
|
|
{
|
|
if (!Associates.IncludeAccessor(m_raiseMethod, nonPublic))
|
|
return null;
|
|
|
|
return m_raiseMethod;
|
|
}
|
|
|
|
public override EventAttributes Attributes
|
|
{
|
|
get
|
|
{
|
|
return m_flags;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
|
|
}
|