// ==++== // // Copyright(c) Microsoft Corporation. All rights reserved. // // ==--== // [....] // 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 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 ret = new List(); 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 } }