The Labs \ Source Viewer \ SSCLI \ System.Reflection \ CustomAttributeType

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. using System;
  16. using System.Runtime.CompilerServices;
  17. using System.Runtime.InteropServices;
  18. using System.Collections;
  19. using System.Collections.Generic;
  20. using System.Resources;
  21. using System.Diagnostics;
  22. using System.Globalization;
  23. using System.Security;
  24. using System.Security.Permissions;
  25. using System.Runtime.ConstrainedExecution;
  26. namespace System.Reflection
  27. {
  28.     [Serializable()]
  29.     [System.Runtime.InteropServices.ComVisible(true)]
  30.     public sealed class CustomAttributeData
  31.     {
  32.         #region Public Static Members
  33.         public static IList<CustomAttributeData> GetCustomAttributes(MemberInfo target)
  34.         {
  35.             if (target == null)
  36.                 throw new ArgumentNullException("target");
  37.            
  38.             IList<CustomAttributeData> cad = GetCustomAttributes(target.Module, target.MetadataToken);
  39.            
  40.             int pcaCount = 0;
  41.             Attribute[] a = null;
  42.             if (target is RuntimeType)
  43.                 a = PseudoCustomAttribute.GetCustomAttributes((RuntimeType)target, typeof(object), false, out pcaCount);
  44.             else if (target is RuntimeMethodInfo)
  45.                 a = PseudoCustomAttribute.GetCustomAttributes((RuntimeMethodInfo)target, typeof(object), false, out pcaCount);
  46.             else if (target is RuntimeFieldInfo)
  47.                 a = PseudoCustomAttribute.GetCustomAttributes((RuntimeFieldInfo)target, typeof(object), out pcaCount);
  48.            
  49.             if (pcaCount == 0)
  50.                 return cad;
  51.            
  52.             CustomAttributeData[] pca = new CustomAttributeData[cad.Count + pcaCount];
  53.             cad.CopyTo(pca, pcaCount);
  54.             for (int i = 0; i < pcaCount; i++) {
  55.                 if (PseudoCustomAttribute.IsSecurityAttribute(a[i].GetType()))
  56.                     continue;
  57.                
  58.                 pca[i] = new CustomAttributeData(a[i]);
  59.             }
  60.            
  61.             return Array.AsReadOnly(pca);
  62.         }
  63.        
  64.         public static IList<CustomAttributeData> GetCustomAttributes(Module target)
  65.         {
  66.             if (target == null)
  67.                 throw new ArgumentNullException("target");
  68.            
  69.             if (target.IsResourceInternal())
  70.                 return new List<CustomAttributeData>();
  71.            
  72.             return GetCustomAttributes(target, target.MetadataToken);
  73.         }
  74.        
  75.         public static IList<CustomAttributeData> GetCustomAttributes(Assembly target)
  76.         {
  77.             if (target == null)
  78.                 throw new ArgumentNullException("target");
  79.            
  80.             return GetCustomAttributes(target.ManifestModule, target.AssemblyHandle.GetToken());
  81.         }
  82.        
  83.         public static IList<CustomAttributeData> GetCustomAttributes(ParameterInfo target)
  84.         {
  85.             if (target == null)
  86.                 throw new ArgumentNullException("target");
  87.            
  88.             IList<CustomAttributeData> cad = GetCustomAttributes(target.Member.Module, target.MetadataToken);
  89.            
  90.             int pcaCount = 0;
  91.             Attribute[] a = PseudoCustomAttribute.GetCustomAttributes((ParameterInfo)target, typeof(object), out pcaCount);
  92.            
  93.             if (pcaCount == 0)
  94.                 return cad;
  95.            
  96.             CustomAttributeData[] pca = new CustomAttributeData[cad.Count + pcaCount];
  97.             cad.CopyTo(pca, pcaCount);
  98.             for (int i = 0; i < pcaCount; i++)
  99.                 pca[i] = new CustomAttributeData(a[i]);
  100.            
  101.             return Array.AsReadOnly(pca);
  102.         }
  103.         #endregion
  104.        
  105.         #region Private Static Methods
  106.         private static CustomAttributeEncoding TypeToCustomAttributeEncoding(Type type)
  107.         {
  108.             if (type == typeof(int))
  109.                 return CustomAttributeEncoding.Int32;
  110.            
  111.             if (type.IsEnum)
  112.                 return CustomAttributeEncoding.Enum;
  113.            
  114.             if (type == typeof(string))
  115.                 return CustomAttributeEncoding.String;
  116.            
  117.             if (type == typeof(Type))
  118.                 return CustomAttributeEncoding.Type;
  119.            
  120.             if (type == typeof(object))
  121.                 return CustomAttributeEncoding.Object;
  122.            
  123.             if (type.IsArray)
  124.                 return CustomAttributeEncoding.Array;
  125.            
  126.             if (type == typeof(char))
  127.                 return CustomAttributeEncoding.Char;
  128.            
  129.             if (type == typeof(bool))
  130.                 return CustomAttributeEncoding.Boolean;
  131.            
  132.             if (type == typeof(byte))
  133.                 return CustomAttributeEncoding.Byte;
  134.            
  135.             if (type == typeof(sbyte))
  136.                 return CustomAttributeEncoding.SByte;
  137.            
  138.             if (type == typeof(short))
  139.                 return CustomAttributeEncoding.Int16;
  140.            
  141.             if (type == typeof(ushort))
  142.                 return CustomAttributeEncoding.UInt16;
  143.            
  144.             if (type == typeof(uint))
  145.                 return CustomAttributeEncoding.UInt32;
  146.            
  147.             if (type == typeof(long))
  148.                 return CustomAttributeEncoding.Int64;
  149.            
  150.             if (type == typeof(ulong))
  151.                 return CustomAttributeEncoding.UInt64;
  152.            
  153.             if (type == typeof(float))
  154.                 return CustomAttributeEncoding.Float;
  155.            
  156.             if (type == typeof(double))
  157.                 return CustomAttributeEncoding.Double;
  158.            
  159.             if (type.IsClass)
  160.                 return CustomAttributeEncoding.Object;
  161.            
  162.             if (type.IsInterface)
  163.                 return CustomAttributeEncoding.Object;
  164.            
  165.             if (type.IsValueType)
  166.                 return CustomAttributeEncoding.Undefined;
  167.            
  168.             throw new ArgumentException(Environment.GetResourceString("Argument_InvalidKindOfTypeForCA"), "type");
  169.         }
  170.         private static CustomAttributeType InitCustomAttributeType(Type parameterType, Module scope)
  171.         {
  172.             CustomAttributeEncoding encodedType = CustomAttributeData.TypeToCustomAttributeEncoding(parameterType);
  173.             CustomAttributeEncoding encodedArrayType = CustomAttributeEncoding.Undefined;
  174.             CustomAttributeEncoding encodedEnumType = CustomAttributeEncoding.Undefined;
  175.             string enumName = null;
  176.            
  177.             if (encodedType == CustomAttributeEncoding.Array) {
  178.                 parameterType = parameterType.GetElementType();
  179.                 encodedArrayType = CustomAttributeData.TypeToCustomAttributeEncoding(parameterType);
  180.             }
  181.            
  182.             if (encodedType == CustomAttributeEncoding.Enum || encodedArrayType == CustomAttributeEncoding.Enum) {
  183.                 encodedEnumType = TypeToCustomAttributeEncoding(Enum.GetUnderlyingType(parameterType));
  184.                
  185.                 if (parameterType.Module == scope)
  186.                     enumName = parameterType.FullName;
  187.                 else
  188.                     enumName = parameterType.AssemblyQualifiedName;
  189.             }
  190.            
  191.             return new CustomAttributeType(encodedType, encodedArrayType, encodedEnumType, enumName);
  192.         }
  193.         private static IList<CustomAttributeData> GetCustomAttributes(Module module, int tkTarget)
  194.         {
  195.             CustomAttributeRecord[] records = GetCustomAttributeRecords(module, tkTarget);
  196.            
  197.             CustomAttributeData[] customAttributes = new CustomAttributeData[records.Length];
  198.             for (int i = 0; i < records.Length; i++)
  199.                 customAttributes[i] = new CustomAttributeData(module, records[i]);
  200.            
  201.             return Array.AsReadOnly(customAttributes);
  202.         }
  203.         #endregion
  204.        
  205.         #region Internal Static Members
  206.         unsafe static internal CustomAttributeRecord[] GetCustomAttributeRecords(Module module, int targetToken)
  207.         {
  208.             MetadataImport scope = module.MetadataImport;
  209.            
  210.             int cCustomAttributeTokens = scope.EnumCustomAttributesCount(targetToken);
  211.             int* tkCustomAttributeTokens = stackalloc int[cCustomAttributeTokens];
  212.             scope.EnumCustomAttributes(targetToken, tkCustomAttributeTokens, cCustomAttributeTokens);
  213.            
  214.             CustomAttributeRecord[] records = new CustomAttributeRecord[cCustomAttributeTokens];
  215.            
  216.             for (int i = 0; i < cCustomAttributeTokens; i++) {
  217.                 scope.GetCustomAttributeProps(tkCustomAttributeTokens[i], out records[i].tkCtor.Value, out records[i].blob);
  218.             }
  219.            
  220.             return records;
  221.         }
  222.        
  223.         static internal CustomAttributeTypedArgument Filter(IList<CustomAttributeData> attrs, Type caType, string name)
  224.         {
  225.             for (int i = 0; i < attrs.Count; i++) {
  226.                 if (attrs[i].Constructor.DeclaringType == caType) {
  227.                     IList<CustomAttributeNamedArgument> namedArguments = attrs[i].NamedArguments;
  228.                     for (int j = 0; j < namedArguments.Count; j++) {
  229.                         if (namedArguments[j].MemberInfo.Name.Equals(name))
  230.                             return namedArguments[j].TypedValue;
  231.                     }
  232.                 }
  233.             }
  234.            
  235.             return new CustomAttributeTypedArgument();
  236.         }
  237.        
  238.         static internal CustomAttributeTypedArgument Filter(IList<CustomAttributeData> attrs, Type caType, int parameter)
  239.         {
  240.             for (int i = 0; i < attrs.Count; i++) {
  241.                 if (attrs[i].Constructor.DeclaringType == caType) {
  242.                     return attrs[i].ConstructorArguments[parameter];
  243.                 }
  244.             }
  245.            
  246.             return new CustomAttributeTypedArgument();
  247.         }
  248.         #endregion
  249.        
  250.         #region Private Data Members
  251.         private ConstructorInfo m_ctor;
  252.         private Module m_scope;
  253.         private MemberInfo[] m_members;
  254.         private CustomAttributeCtorParameter[] m_ctorParams;
  255.         private CustomAttributeNamedParameter[] m_namedParams;
  256.         private IList<CustomAttributeTypedArgument> m_typedCtorArgs;
  257.         private IList<CustomAttributeNamedArgument> m_namedArgs;
  258.         #endregion
  259.        
  260.         #region Constructor
  261.         internal CustomAttributeData(Module scope, CustomAttributeRecord caRecord)
  262.         {
  263.             m_scope = scope;
  264.             m_ctor = (ConstructorInfo)RuntimeType.GetMethodBase(scope, caRecord.tkCtor);
  265.            
  266.             ParameterInfo[] parameters = m_ctor.GetParametersNoCopy();
  267.             m_ctorParams = new CustomAttributeCtorParameter[parameters.Length];
  268.             for (int i = 0; i < parameters.Length; i++)
  269.                 m_ctorParams[i] = new CustomAttributeCtorParameter(InitCustomAttributeType(parameters[i].ParameterType, scope));
  270.            
  271.             FieldInfo[] fields = m_ctor.DeclaringType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
  272.             PropertyInfo[] properties = m_ctor.DeclaringType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
  273.             m_namedParams = new CustomAttributeNamedParameter[properties.Length + fields.Length];
  274.             for (int i = 0; i < fields.Length; i++)
  275.                 m_namedParams[i] = new CustomAttributeNamedParameter(fields[i].Name, CustomAttributeEncoding.Field, InitCustomAttributeType(fields[i].FieldType, scope));
  276.             for (int i = 0; i < properties.Length; i++)
  277.                 m_namedParams[i + fields.Length] = new CustomAttributeNamedParameter(properties[i].Name, CustomAttributeEncoding.Property, InitCustomAttributeType(properties[i].PropertyType, scope));
  278.            
  279.             m_members = new MemberInfo[fields.Length + properties.Length];
  280.             fields.CopyTo(m_members, 0);
  281.             properties.CopyTo(m_members, fields.Length);
  282.            
  283.             CustomAttributeEncodedArgument.ParseAttributeArguments(caRecord.blob, ref m_ctorParams, ref m_namedParams, m_scope);
  284.         }
  285.         #endregion
  286.        
  287.         #region Pseudo Custom Attribute Constructor
  288.         internal CustomAttributeData(Attribute attribute)
  289.         {
  290.             if (attribute is DllImportAttribute)
  291.                 Init((DllImportAttribute)attribute);
  292.             else if (attribute is FieldOffsetAttribute)
  293.                 Init((FieldOffsetAttribute)attribute);
  294.             else if (attribute is MarshalAsAttribute)
  295.                 Init((MarshalAsAttribute)attribute);
  296.             else
  297.                 Init(attribute);
  298.         }
  299.         private void Init(DllImportAttribute dllImport)
  300.         {
  301.             Type type = typeof(DllImportAttribute);
  302.             m_ctor = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance)[0];
  303.             m_typedCtorArgs = Array.AsReadOnly(new CustomAttributeTypedArgument[] {new CustomAttributeTypedArgument(dllImport.Value)});
  304.            
  305.                
  306.             m_namedArgs = Array.AsReadOnly(new CustomAttributeNamedArgument[] {new CustomAttributeNamedArgument(type.GetField("EntryPoint"), dllImport.EntryPoint), new CustomAttributeNamedArgument(type.GetField("CharSet"), dllImport.CharSet), new CustomAttributeNamedArgument(type.GetField("ExactSpelling"), dllImport.ExactSpelling), new CustomAttributeNamedArgument(type.GetField("SetLastError"), dllImport.SetLastError), new CustomAttributeNamedArgument(type.GetField("PreserveSig"), dllImport.PreserveSig), new CustomAttributeNamedArgument(type.GetField("CallingConvention"), dllImport.CallingConvention), new CustomAttributeNamedArgument(type.GetField("BestFitMapping"), dllImport.BestFitMapping), new CustomAttributeNamedArgument(type.GetField("ThrowOnUnmappableChar"), dllImport.ThrowOnUnmappableChar)});
  307.         }
  308.         private void Init(FieldOffsetAttribute fieldOffset)
  309.         {
  310.             m_ctor = typeof(FieldOffsetAttribute).GetConstructors(BindingFlags.Public | BindingFlags.Instance)[0];
  311.             m_typedCtorArgs = Array.AsReadOnly(new CustomAttributeTypedArgument[] {new CustomAttributeTypedArgument(fieldOffset.Value)});
  312.             m_namedArgs = Array.AsReadOnly(new CustomAttributeNamedArgument[0]);
  313.         }
  314.         private void Init(MarshalAsAttribute marshalAs)
  315.         {
  316.             Type type = typeof(MarshalAsAttribute);
  317.             m_ctor = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance)[0];
  318.             m_typedCtorArgs = Array.AsReadOnly(new CustomAttributeTypedArgument[] {new CustomAttributeTypedArgument(marshalAs.Value)});
  319.            
  320.             int i = 3;
  321.             // ArraySubType, SizeParamIndex, SizeConst
  322.             if (marshalAs.MarshalType != null)
  323.                 i++;
  324.             if (marshalAs.MarshalTypeRef != null)
  325.                 i++;
  326.             if (marshalAs.MarshalCookie != null)
  327.                 i++;
  328.             CustomAttributeNamedArgument[] namedArgs = new CustomAttributeNamedArgument[i];
  329.            
  330.             i = 0;
  331.             namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("ArraySubType"), marshalAs.ArraySubType);
  332.             namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("SizeParamIndex"), marshalAs.SizeParamIndex);
  333.             namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("SizeConst"), marshalAs.SizeConst);
  334.             if (marshalAs.MarshalType != null)
  335.                 namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("MarshalType"), marshalAs.MarshalType);
  336.             if (marshalAs.MarshalTypeRef != null)
  337.                 namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("MarshalTypeRef"), marshalAs.MarshalTypeRef);
  338.             if (marshalAs.MarshalCookie != null)
  339.                 namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("MarshalCookie"), marshalAs.MarshalCookie);
  340.            
  341.             m_namedArgs = Array.AsReadOnly(namedArgs);
  342.         }
  343.         private void Init(object pca)
  344.         {
  345.             m_ctor = pca.GetType().GetConstructors(BindingFlags.Public | BindingFlags.Instance)[0];
  346.             m_typedCtorArgs = Array.AsReadOnly(new CustomAttributeTypedArgument[0]);
  347.             m_namedArgs = Array.AsReadOnly(new CustomAttributeNamedArgument[0]);
  348.         }
  349.         #endregion
  350.        
  351.         #region Object Override
  352.         public override string ToString()
  353.         {
  354.             string ctorArgs = "";
  355.             for (int i = 0; i < ConstructorArguments.Count; i++)
  356.                 ctorArgs += String.Format(CultureInfo.CurrentCulture, i == 0 ? "{0}" : ", {0}", ConstructorArguments[i]);
  357.            
  358.             string namedArgs = "";
  359.             for (int i = 0; i < NamedArguments.Count; i++)
  360.                 namedArgs += String.Format(CultureInfo.CurrentCulture, i == 0 && ctorArgs.Length == 0 ? "{0}" : ", {0}", NamedArguments[i]);
  361.            
  362.             return String.Format(CultureInfo.CurrentCulture, "[{0}({1}{2})]", Constructor.DeclaringType.FullName, ctorArgs, namedArgs);
  363.         }
  364.         public override int GetHashCode()
  365.         {
  366.             return base.GetHashCode();
  367.         }
  368.         public override bool Equals(object obj)
  369.         {
  370.             return obj == (object)this;
  371.         }
  372.         #endregion
  373.        
  374.         #region Public Members
  375.         [System.Runtime.InteropServices.ComVisible(true)]
  376.         public ConstructorInfo Constructor {
  377.             get { return m_ctor; }
  378.         }
  379.        
  380.         [System.Runtime.InteropServices.ComVisible(true)]
  381.         public IList<CustomAttributeTypedArgument> ConstructorArguments {
  382.             get {
  383.                 if (m_typedCtorArgs == null) {
  384.                     CustomAttributeTypedArgument[] typedCtorArgs = new CustomAttributeTypedArgument[m_ctorParams.Length];
  385.                    
  386.                     for (int i = 0; i < typedCtorArgs.Length; i++) {
  387.                         CustomAttributeEncodedArgument encodedArg = m_ctorParams[i].CustomAttributeEncodedArgument;
  388.                        
  389.                         typedCtorArgs[i] = new CustomAttributeTypedArgument(m_scope, m_ctorParams[i].CustomAttributeEncodedArgument);
  390.                     }
  391.                    
  392.                     m_typedCtorArgs = Array.AsReadOnly(typedCtorArgs);
  393.                 }
  394.                
  395.                 return m_typedCtorArgs;
  396.             }
  397.         }
  398.         public IList<CustomAttributeNamedArgument> NamedArguments {
  399.             get {
  400.                 if (m_namedArgs == null) {
  401.                    
  402.                     if (m_namedParams == null)
  403.                         return null;
  404.                    
  405.                     int cNamedArgs = 0;
  406.                     for (int i = 0; i < m_namedParams.Length; i++) {
  407.                         if (m_namedParams[i].EncodedArgument.CustomAttributeType.EncodedType != CustomAttributeEncoding.Undefined)
  408.                             cNamedArgs++;
  409.                     }
  410.                    
  411.                     CustomAttributeNamedArgument[] namedArgs = new CustomAttributeNamedArgument[cNamedArgs];
  412.                    
  413.                     for (int i = 0int j = 0; i < m_namedParams.Length; i++) {
  414.                         if (m_namedParams[i].EncodedArgument.CustomAttributeType.EncodedType != CustomAttributeEncoding.Undefined)
  415.                             namedArgs[j++] = new CustomAttributeNamedArgument(m_members[i], new CustomAttributeTypedArgument(m_scope, m_namedParams[i].EncodedArgument));
  416.                     }
  417.                    
  418.                     m_namedArgs = Array.AsReadOnly(namedArgs);
  419.                 }
  420.                
  421.                 return m_namedArgs;
  422.             }
  423.         }
  424.         #endregion
  425.     }
  426.    
  427.     [Serializable()]
  428.     [System.Runtime.InteropServices.ComVisible(true)]
  429.     public struct CustomAttributeNamedArgument
  430.     {
  431.         #region Public Static Members
  432.         public static bool operator ==(CustomAttributeNamedArgument left, CustomAttributeNamedArgument right)
  433.         {
  434.             return left.Equals(right);
  435.         }
  436.         public static bool operator !=(CustomAttributeNamedArgument left, CustomAttributeNamedArgument right)
  437.         {
  438.             return !left.Equals(right);
  439.         }
  440.         #endregion
  441.        
  442.         #region Private Data Members
  443.         private MemberInfo m_memberInfo;
  444.         private CustomAttributeTypedArgument m_value;
  445.         #endregion
  446.        
  447.         #region Constructor
  448.         internal CustomAttributeNamedArgument(MemberInfo memberInfo, object value)
  449.         {
  450.             m_memberInfo = memberInfo;
  451.             m_value = new CustomAttributeTypedArgument(value);
  452.         }
  453.         internal CustomAttributeNamedArgument(MemberInfo memberInfo, CustomAttributeTypedArgument value)
  454.         {
  455.             m_memberInfo = memberInfo;
  456.             m_value = value;
  457.         }
  458.         #endregion
  459.        
  460.         #region Object Override
  461.         public override string ToString()
  462.         {
  463.             return String.Format(CultureInfo.CurrentCulture, "{0} = {1}", MemberInfo.Name, TypedValue.ToString(ArgumentType != typeof(object)));
  464.         }
  465.         public override int GetHashCode()
  466.         {
  467.             return base.GetHashCode();
  468.         }
  469.         public override bool Equals(object obj)
  470.         {
  471.             return obj == (object)this;
  472.         }
  473.         #endregion
  474.        
  475.         #region Internal Members
  476.         internal Type ArgumentType {
  477.             get { return m_memberInfo is FieldInfo ? ((FieldInfo)m_memberInfo).FieldType : ((PropertyInfo)m_memberInfo).PropertyType; }
  478.         }
  479.         #endregion
  480.        
  481.         #region Public Members
  482.         public MemberInfo MemberInfo {
  483.             get { return m_memberInfo; }
  484.         }
  485.         public CustomAttributeTypedArgument TypedValue {
  486.             get { return m_value; }
  487.         }
  488.         #endregion
  489.     }
  490.    
  491.     [Serializable()]
  492.     [ComVisible(true)]
  493.     public struct CustomAttributeTypedArgument
  494.     {
  495.         #region Public Static Members
  496.         public static bool operator ==(CustomAttributeTypedArgument left, CustomAttributeTypedArgument right)
  497.         {
  498.             return left.Equals(right);
  499.         }
  500.         public static bool operator !=(CustomAttributeTypedArgument left, CustomAttributeTypedArgument right)
  501.         {
  502.             return !left.Equals(right);
  503.         }
  504.         #endregion
  505.        
  506.         #region Private Static Methods
  507.         private static Type CustomAttributeEncodingToType(CustomAttributeEncoding encodedType)
  508.         {
  509.             switch (encodedType) {
  510.                 case (CustomAttributeEncoding.Enum):
  511.                     return typeof(Enum);
  512.                 case (CustomAttributeEncoding.Int32):
  513.                    
  514.                     return typeof(int);
  515.                 case (CustomAttributeEncoding.String):
  516.                    
  517.                     return typeof(string);
  518.                 case (CustomAttributeEncoding.Type):
  519.                    
  520.                     return typeof(Type);
  521.                 case (CustomAttributeEncoding.Array):
  522.                    
  523.                     return typeof(Array);
  524.                 case (CustomAttributeEncoding.Char):
  525.                    
  526.                     return typeof(char);
  527.                 case (CustomAttributeEncoding.Boolean):
  528.                    
  529.                     return typeof(bool);
  530.                 case (CustomAttributeEncoding.SByte):
  531.                    
  532.                     return typeof(sbyte);
  533.                 case (CustomAttributeEncoding.Byte):
  534.                    
  535.                     return typeof(byte);
  536.                 case (CustomAttributeEncoding.Int16):
  537.                    
  538.                     return typeof(short);
  539.                 case (CustomAttributeEncoding.UInt16):
  540.                    
  541.                     return typeof(ushort);
  542.                 case (CustomAttributeEncoding.UInt32):
  543.                    
  544.                     return typeof(uint);
  545.                 case (CustomAttributeEncoding.Int64):
  546.                    
  547.                     return typeof(long);
  548.                 case (CustomAttributeEncoding.UInt64):
  549.                    
  550.                     return typeof(ulong);
  551.                 case (CustomAttributeEncoding.Float):
  552.                    
  553.                     return typeof(float);
  554.                 case (CustomAttributeEncoding.Double):
  555.                    
  556.                     return typeof(double);
  557.                 case (CustomAttributeEncoding.Object):
  558.                    
  559.                     return typeof(object);
  560.                 default:
  561.                    
  562.                     throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)encodedType), "encodedType");
  563.                     break;
  564.             }
  565.         }
  566.         private static object EncodedValueToRawValue(long val, CustomAttributeEncoding encodedType)
  567.         {
  568.             switch (encodedType) {
  569.                 case CustomAttributeEncoding.Boolean:
  570.                     return (byte)val != 0;
  571.                 case CustomAttributeEncoding.Char:
  572.                    
  573.                     return (char)val;
  574.                 case CustomAttributeEncoding.Byte:
  575.                    
  576.                     return (byte)val;
  577.                 case CustomAttributeEncoding.SByte:
  578.                    
  579.                     return (sbyte)val;
  580.                 case CustomAttributeEncoding.Int16:
  581.                    
  582.                     return (short)val;
  583.                 case CustomAttributeEncoding.UInt16:
  584.                    
  585.                     return (ushort)val;
  586.                 case CustomAttributeEncoding.Int32:
  587.                    
  588.                     return (int)val;
  589.                 case CustomAttributeEncoding.UInt32:
  590.                    
  591.                     return (uint)val;
  592.                 case CustomAttributeEncoding.Int64:
  593.                    
  594.                     return (long)val;
  595.                 case CustomAttributeEncoding.UInt64:
  596.                    
  597.                     return (ulong)val;
  598.                 case CustomAttributeEncoding.Float:
  599.                    
  600.                     unsafe {
  601.                         return *(float*)&val;
  602.                     }
  603.                     break;
  604.                 case CustomAttributeEncoding.Double:
  605.                    
  606.                     unsafe {
  607.                         return *(double*)&val;
  608.                     }
  609.                     break;
  610.                 default:
  611.                    
  612.                     throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)val), "val");
  613.                     break;
  614.             }
  615.         }
  616.         private static Type ResolveType(Module scope, string typeName)
  617.         {
  618.             Type type = RuntimeTypeHandle.GetTypeByNameUsingCARules(typeName, scope);
  619.            
  620.             if (type == null)
  621.                 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_CATypeResolutionFailed"), typeName));
  622.            
  623.             return type;
  624.         }
  625.         #endregion
  626.        
  627.         #region Private Data Members
  628.         private object m_value;
  629.         private Type m_argumentType;
  630.         #endregion
  631.        
  632.         #region Constructor
  633.         internal CustomAttributeTypedArgument(object value)
  634.         {
  635.             m_argumentType = value.GetType();
  636.             if (m_argumentType.IsEnum) {
  637.                 if (Enum.GetUnderlyingType(m_argumentType) == typeof(int))
  638.                     m_value = (int)value;
  639.                 else if (Enum.GetUnderlyingType(m_argumentType) == typeof(short))
  640.                     m_value = (short)value;
  641.                 else
  642.                     throw new ArgumentException(Environment.GetResourceString("Argument_EnumIsNotIntOrShort"), "value");
  643.             }
  644.             else {
  645.                 m_value = value;
  646.             }
  647.         }
  648.         internal CustomAttributeTypedArgument(Module scope, CustomAttributeEncodedArgument encodedArg)
  649.         {
  650.             CustomAttributeEncoding encodedType = encodedArg.CustomAttributeType.EncodedType;
  651.            
  652.             if (encodedType == CustomAttributeEncoding.Undefined)
  653.                 throw new ArgumentException("encodedArg");
  654.            
  655.             else if (encodedType == CustomAttributeEncoding.Enum) {
  656.                 m_argumentType = ResolveType(scope, encodedArg.CustomAttributeType.EnumName);
  657.                 m_value = EncodedValueToRawValue(encodedArg.PrimitiveValue, encodedArg.CustomAttributeType.EncodedEnumType);
  658.             }
  659.             else if (encodedType == CustomAttributeEncoding.String) {
  660.                 m_argumentType = typeof(string);
  661.                 m_value = encodedArg.StringValue;
  662.             }
  663.             else if (encodedType == CustomAttributeEncoding.Type) {
  664.                 m_argumentType = typeof(Type);
  665.                
  666.                 m_value = null;
  667.                
  668.                 if (encodedArg.StringValue != null)
  669.                     m_value = ResolveType(scope, encodedArg.StringValue);
  670.             }
  671.             else if (encodedType == CustomAttributeEncoding.Array) {
  672.                 encodedType = encodedArg.CustomAttributeType.EncodedArrayType;
  673.                 Type elementType;
  674.                
  675.                 if (encodedType == CustomAttributeEncoding.Enum) {
  676.                     elementType = ResolveType(scope, encodedArg.CustomAttributeType.EnumName);
  677.                 }
  678.                 else {
  679.                     elementType = CustomAttributeEncodingToType(encodedType);
  680.                 }
  681.                
  682.                 m_argumentType = elementType.MakeArrayType();
  683.                
  684.                 if (encodedArg.ArrayValue == null) {
  685.                     m_value = null;
  686.                 }
  687.                 else {
  688.                     CustomAttributeTypedArgument[] arrayValue = new CustomAttributeTypedArgument[encodedArg.ArrayValue.Length];
  689.                     for (int i = 0; i < arrayValue.Length; i++)
  690.                         arrayValue[i] = new CustomAttributeTypedArgument(scope, encodedArg.ArrayValue[i]);
  691.                    
  692.                     m_value = Array.AsReadOnly(arrayValue);
  693.                 }
  694.             }
  695.             else {
  696.                 m_argumentType = CustomAttributeEncodingToType(encodedType);
  697.                 m_value = EncodedValueToRawValue(encodedArg.PrimitiveValue, encodedType);
  698.             }
  699.         }
  700.         #endregion
  701.        
  702.         #region Object Overrides
  703.         public override string ToString()
  704.         {
  705.             return ToString(false);
  706.         }
  707.         internal string ToString(bool typed)
  708.         {
  709.             if (ArgumentType.IsEnum)
  710.                 return String.Format(CultureInfo.CurrentCulture, typed ? "{0}" : "({1}){0}", Value, ArgumentType.FullName);
  711.             else if (Value == null)
  712.                 return String.Format(CultureInfo.CurrentCulture, typed ? "null" : "({0})null", ArgumentType.Name);
  713.             else if (ArgumentType == typeof(string))
  714.                 return String.Format(CultureInfo.CurrentCulture, "\"{0}\"", Value);
  715.             else if (ArgumentType == typeof(char))
  716.                 return String.Format(CultureInfo.CurrentCulture, "'{0}'", Value);
  717.             else if (ArgumentType == typeof(Type))
  718.                 return String.Format(CultureInfo.CurrentCulture, "typeof({0})", ((Type)Value).FullName);
  719.            
  720.            
  721.            
  722.            
  723.            
  724.             else if (ArgumentType.IsArray) {
  725.                 string result = null;
  726.                 IList<CustomAttributeTypedArgument> array = Value as IList<CustomAttributeTypedArgument>;
  727.                
  728.                 Type elementType = ArgumentType.GetElementType();
  729.                 result = String.Format(CultureInfo.CurrentCulture, "new {0}[{1}] {{ ", elementType.IsEnum ? elementType.FullName : elementType.Name, array.Count);
  730.                
  731.                 for (int i = 0; i < array.Count; i++)
  732.                     result += String.Format(CultureInfo.CurrentCulture, i == 0 ? "{0}" : ", {0}", array[i].ToString(elementType != typeof(object)));
  733.                
  734.                 return result += " }";
  735.             }
  736.            
  737.             return String.Format(CultureInfo.CurrentCulture, typed ? "{0}" : "({1}){0}", Value, ArgumentType.Name);
  738.         }
  739.         public override int GetHashCode()
  740.         {
  741.             return base.GetHashCode();
  742.         }
  743.         public override bool Equals(object obj)
  744.         {
  745.             return obj == (object)this;
  746.         }
  747.         #endregion
  748.        
  749.         #region Public Members
  750.         public Type ArgumentType {
  751.             get { return m_argumentType; }
  752.         }
  753.         public object Value {
  754.             get { return m_value; }
  755.         }
  756.         #endregion
  757.     }
  758.    
  759.     [Serializable()]
  760.     internal struct CustomAttributeRecord
  761.     {
  762.         internal ConstArray blob;
  763.         internal MetadataToken tkCtor;
  764.     }
  765.    
  766.     [Serializable()]
  767.     internal enum CustomAttributeEncoding : int
  768.     {
  769.         Undefined = 0,
  770.         Boolean = CorElementType.Boolean,
  771.         Char = CorElementType.Char,
  772.         SByte = CorElementType.I1,
  773.         Byte = CorElementType.U1,
  774.         Int16 = CorElementType.I2,
  775.         UInt16 = CorElementType.U2,
  776.         Int32 = CorElementType.I4,
  777.         UInt32 = CorElementType.U4,
  778.         Int64 = CorElementType.I8,
  779.         UInt64 = CorElementType.U8,
  780.         Float = CorElementType.R4,
  781.         Double = CorElementType.R8,
  782.         String = CorElementType.String,
  783.         Array = CorElementType.SzArray,
  784.         Type = 80,
  785.         Object = 81,
  786.         Field = 83,
  787.         Property = 84,
  788.         Enum = 85
  789.     }
  790.    
  791.     [Serializable()]
  792.     [StructLayout(LayoutKind.Auto)]
  793.     internal struct CustomAttributeEncodedArgument
  794.     {
  795.         #region Parser
  796.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  797.         private static extern void ParseAttributeArguments(IntPtr pCa, int cCa, ref CustomAttributeCtorParameter[] CustomAttributeCtorParameters, ref CustomAttributeNamedParameter[] CustomAttributeTypedArgument, IntPtr assembly);
  798.        
  799.         static internal void ParseAttributeArguments(ConstArray attributeBlob, ref CustomAttributeCtorParameter[] customAttributeCtorParameters, ref CustomAttributeNamedParameter[] customAttributeNamedParameters, Module customAttributeModule)
  800.         {
  801.             if (customAttributeModule == null)
  802.                 throw new ArgumentNullException("customAttributeModule");
  803.            
  804.             if (customAttributeNamedParameters == null)
  805.                 customAttributeNamedParameters = new CustomAttributeNamedParameter[0];
  806.            
  807.             CustomAttributeCtorParameter[] _customAttributeCtorParameters = customAttributeCtorParameters;
  808.             CustomAttributeNamedParameter[] _customAttributeNamedParameters = customAttributeNamedParameters;
  809.            
  810.             unsafe {
  811.                 ParseAttributeArguments(attributeBlob.Signature, (int)attributeBlob.Length, ref _customAttributeCtorParameters, ref _customAttributeNamedParameters, (IntPtr)customAttributeModule.Assembly.AssemblyHandle.Value);
  812.             }
  813.            
  814.             customAttributeCtorParameters = _customAttributeCtorParameters;
  815.             customAttributeNamedParameters = _customAttributeNamedParameters;
  816.         }
  817.         #endregion
  818.        
  819.         #region Private Data Members
  820.         private long m_primitiveValue;
  821.         private CustomAttributeEncodedArgument[] m_arrayValue;
  822.         private string m_stringValue;
  823.         private CustomAttributeType m_type;
  824.         #endregion
  825.        
  826.         #region Public Members
  827.         public CustomAttributeType CustomAttributeType {
  828.             get { return m_type; }
  829.         }
  830.         public long PrimitiveValue {
  831.             get { return m_primitiveValue; }
  832.         }
  833.         public CustomAttributeEncodedArgument[] ArrayValue {
  834.             get { return m_arrayValue; }
  835.         }
  836.         public string StringValue {
  837.             get { return m_stringValue; }
  838.         }
  839.         #endregion
  840.     }
  841.    
  842.     [Serializable()]
  843.     [StructLayout(LayoutKind.Auto)]
  844.     internal struct CustomAttributeNamedParameter
  845.     {
  846.         #region Private Data Members
  847.         private string m_argumentName;
  848.         private CustomAttributeEncoding m_fieldOrProperty;
  849.         private CustomAttributeEncoding m_padding;
  850.         private CustomAttributeType m_type;
  851.         private CustomAttributeEncodedArgument m_encodedArgument;
  852.         #endregion
  853.        
  854.         #region Constructor
  855.         public CustomAttributeNamedParameter(string argumentName, CustomAttributeEncoding fieldOrProperty, CustomAttributeType type)
  856.         {
  857.             if (argumentName == null)
  858.                 throw new ArgumentNullException("argumentName");
  859.            
  860.             m_argumentName = argumentName;
  861.             m_fieldOrProperty = fieldOrProperty;
  862.             m_padding = fieldOrProperty;
  863.             m_type = type;
  864.             m_encodedArgument = new CustomAttributeEncodedArgument();
  865.         }
  866.         #endregion
  867.        
  868.         #region Public Members
  869.         public CustomAttributeEncodedArgument EncodedArgument {
  870.             get { return m_encodedArgument; }
  871.         }
  872.         #endregion
  873.     }
  874.    
  875.     [Serializable()]
  876.     [StructLayout(LayoutKind.Auto)]
  877.     internal struct CustomAttributeCtorParameter
  878.     {
  879.         #region Private Data Members
  880.         private CustomAttributeType m_type;
  881.         private CustomAttributeEncodedArgument m_encodedArgument;
  882.         #endregion
  883.        
  884.         #region Constructor
  885.         public CustomAttributeCtorParameter(CustomAttributeType type)
  886.         {
  887.             m_type = type;
  888.             m_encodedArgument = new CustomAttributeEncodedArgument();
  889.         }
  890.         #endregion
  891.        
  892.         #region Public Members
  893.         public CustomAttributeEncodedArgument CustomAttributeEncodedArgument {
  894.             get { return m_encodedArgument; }
  895.         }
  896.         #endregion
  897.     }
  898.    
  899.     // Note: This is a managed representation of a frame type defined in vm\frames.h; please ensure the layout remains
  900.     // synchronized.
  901.     [StructLayout(LayoutKind.Sequential)]
  902.     internal struct SecurityContextFrame
  903.     {
  904.         IntPtr m_GSCookie;
  905.         // This is actually at a negative offset in the real frame definition
  906.         IntPtr __VFN_table;
  907.         // This is the real start of the SecurityContextFrame
  908.         IntPtr m_Next;
  909.         IntPtr m_Assembly;
  910.        
  911.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  912.         public extern void Push(Assembly assembly);
  913.        
  914.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  915.         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  916.         public extern void Pop();
  917.     }
  918.    
  919.     [Serializable()]
  920.     [StructLayout(LayoutKind.Auto)]
  921.     internal struct CustomAttributeType
  922.     {
  923.         #region Private Data Members
  924.         /// The most complicated type is an enum[] in which case...
  925.         private string m_enumName;
  926.         // ...enum name
  927.         private CustomAttributeEncoding m_encodedType;
  928.         // ...array
  929.         private CustomAttributeEncoding m_encodedEnumType;
  930.         // ...enum
  931.         private CustomAttributeEncoding m_encodedArrayType;
  932.         // ...enum type
  933.         private CustomAttributeEncoding m_padding;
  934.         #endregion
  935.        
  936.         #region Constructor
  937.         public CustomAttributeType(CustomAttributeEncoding encodedType, CustomAttributeEncoding encodedArrayType, CustomAttributeEncoding encodedEnumType, string enumName)
  938.         {
  939.             m_encodedType = encodedType;
  940.             m_encodedArrayType = encodedArrayType;
  941.             m_encodedEnumType = encodedEnumType;
  942.             m_enumName = enumName;
  943.             m_padding = m_encodedType;
  944.         }
  945.         #endregion
  946.        
  947.         #region Public Members
  948.         public CustomAttributeEncoding EncodedType {
  949.             get { return m_encodedType; }
  950.         }
  951.         public CustomAttributeEncoding EncodedEnumType {
  952.             get { return m_encodedEnumType; }
  953.         }
  954.         public CustomAttributeEncoding EncodedArrayType {
  955.             get { return m_encodedArrayType; }
  956.         }
  957.         [System.Runtime.InteropServices.ComVisible(true)]
  958.         public string EnumName {
  959.             get { return m_enumName; }
  960.         }
  961.         #endregion
  962.     }
  963.    
  964.     unsafe static internal class CustomAttribute
  965.     {
  966.         #region Internal Static Members
  967.         static internal bool IsDefined(RuntimeType type, RuntimeType caType, bool inherit)
  968.         {
  969.             ASSERT.PRECONDITION(type != null);
  970.            
  971.             if (type.GetElementType() != null)
  972.                 return false;
  973.            
  974.             if (PseudoCustomAttribute.IsDefined(type, caType))
  975.                 return true;
  976.            
  977.             if (IsCustomAttributeDefined(type.Module, type.MetadataToken, caType))
  978.                 return true;
  979.            
  980.             if (!inherit)
  981.                 return false;
  982.            
  983.             type = type.BaseType as RuntimeType;
  984.            
  985.             while (type != null) {
  986.                 if (IsCustomAttributeDefined(type.Module, type.MetadataToken, caType, inherit))
  987.                     return true;
  988.                
  989.                 type = type.BaseType as RuntimeType;
  990.             }
  991.            
  992.             return false;
  993.         }
  994.        
  995.         static internal bool IsDefined(RuntimeMethodInfo method, RuntimeType caType, bool inherit)
  996.         {
  997.             ASSERT.PRECONDITION(method != null);
  998.            
  999.             if (PseudoCustomAttribute.IsDefined(method, caType))
  1000.                 return true;
  1001.            
  1002.             if (IsCustomAttributeDefined(method.Module, method.MetadataToken, caType))
  1003.                 return true;
  1004.            
  1005.             if (!inherit)
  1006.                 return false;
  1007.            
  1008.             method = method.GetParentDefinition() as RuntimeMethodInfo;
  1009.            
  1010.             while (method != null) {
  1011.                 if (IsCustomAttributeDefined(method.Module, method.MetadataToken, caType, inherit))
  1012.                     return true;
  1013.                
  1014.                 method = method.GetParentDefinition() as RuntimeMethodInfo;
  1015.             }
  1016.            
  1017.             return false;
  1018.         }
  1019.        
  1020.         static internal bool IsDefined(RuntimeConstructorInfo ctor, RuntimeType caType)
  1021.         {
  1022.             ASSERT.PRECONDITION(ctor != null);
  1023.            
  1024.             if (PseudoCustomAttribute.IsDefined(ctor, caType))
  1025.                 return true;
  1026.            
  1027.             return IsCustomAttributeDefined(ctor.Module, ctor.MetadataToken, caType);
  1028.         }
  1029.        
  1030.         static internal bool IsDefined(RuntimePropertyInfo property, RuntimeType caType)
  1031.         {
  1032.             ASSERT.PRECONDITION(property != null);
  1033.            
  1034.             if (PseudoCustomAttribute.IsDefined(property, caType))
  1035.                 return true;
  1036.            
  1037.             return IsCustomAttributeDefined(property.Module, property.MetadataToken, caType);
  1038.         }
  1039.        
  1040.         static internal bool IsDefined(RuntimeEventInfo e, RuntimeType caType)
  1041.         {
  1042.             ASSERT.PRECONDITION(e != null);
  1043.            
  1044.             if (PseudoCustomAttribute.IsDefined(e, caType))
  1045.                 return true;
  1046.            
  1047.             return IsCustomAttributeDefined(e.Module, e.MetadataToken, caType);
  1048.         }
  1049.        
  1050.         static internal bool IsDefined(RuntimeFieldInfo field, RuntimeType caType)
  1051.         {
  1052.             ASSERT.PRECONDITION(field != null);
  1053.            
  1054.             if (PseudoCustomAttribute.IsDefined(field, caType))
  1055.                 return true;
  1056.            
  1057.             return IsCustomAttributeDefined(field.Module, field.MetadataToken, caType);
  1058.         }
  1059.        
  1060.         static internal bool IsDefined(ParameterInfo parameter, RuntimeType caType)
  1061.         {
  1062.             if (PseudoCustomAttribute.IsDefined(parameter, caType))
  1063.                 return true;
  1064.            
  1065.             return IsCustomAttributeDefined(parameter.Member.Module, parameter.MetadataToken, caType);
  1066.         }
  1067.        
  1068.         static internal bool IsDefined(Assembly assembly, RuntimeType caType)
  1069.         {
  1070.             if (PseudoCustomAttribute.IsDefined(assembly, caType))
  1071.                 return true;
  1072.            
  1073.             return IsCustomAttributeDefined(assembly.ManifestModule, assembly.AssemblyHandle.GetToken(), caType);
  1074.         }
  1075.        
  1076.         static internal bool IsDefined(Module module, RuntimeType caType)
  1077.         {
  1078.             if (PseudoCustomAttribute.IsDefined(module, caType))
  1079.                 return true;
  1080.            
  1081.             return IsCustomAttributeDefined(module, module.MetadataToken, caType);
  1082.         }
  1083.        
  1084.         static internal object[] GetCustomAttributes(RuntimeType type, RuntimeType caType, bool inherit)
  1085.         {
  1086.             if (type.GetElementType() != null)
  1087.                 return (caType.IsValueType) ? new object[0] : (object[])Array.CreateInstance(caType, 0);
  1088.            
  1089.             if (type.IsGenericType && !type.IsGenericTypeDefinition)
  1090.                 type = type.GetGenericTypeDefinition() as RuntimeType;
  1091.            
  1092.             int pcaCount = 0;
  1093.             Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(type, caType, true, out pcaCount);
  1094.            
  1095.             // if we are asked to go up the hierarchy chain we have to do it now and regardless of the
  1096.             // attribute usage for the specific attribute because a derived attribute may override the usage...
  1097.             // ... however if the attribute is sealed we can rely on the attribute usage
  1098.             if (!inherit || (caType.IsSealed && !CustomAttribute.GetAttributeUsage(caType).Inherited)) {
  1099.                 object[] attributes = GetCustomAttributes(type.Module, type.MetadataToken, pcaCount, caType);
  1100.                 if (pcaCount > 0)
  1101.                     Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount);
  1102.                 return attributes;
  1103.             }
  1104.            
  1105.             List<object> result = new List<object>();
  1106.             bool mustBeInheritable = false;
  1107.             bool useObjectArray = (caType == null || caType.IsValueType || caType.ContainsGenericParameters);
  1108.             Type arrayType = useObjectArray ? typeof(object) : caType;
  1109.            
  1110.             while (pcaCount > 0)
  1111.                 result.Add(pca[--pcaCount]);
  1112.            
  1113.             while (type != typeof(object) && type != null) {
  1114.                 object[] attributes = GetCustomAttributes(type.Module, type.MetadataToken, 0, caType, mustBeInheritable, result);
  1115.                 mustBeInheritable = true;
  1116.                 for (int i = 0; i < attributes.Length; i++)
  1117.                     result.Add(attributes[i]);
  1118.                
  1119.                 type = type.BaseType as RuntimeType;
  1120.             }
  1121.            
  1122.             object[] typedResult = Array.CreateInstance(arrayType, result.Count) as object[];
  1123.             Array.Copy(result.ToArray(), 0, typedResult, 0, result.Count);
  1124.             return typedResult;
  1125.         }
  1126.        
  1127.         static internal object[] GetCustomAttributes(RuntimeMethodInfo method, RuntimeType caType, bool inherit)
  1128.         {
  1129.             if (method.IsGenericMethod && !method.IsGenericMethodDefinition)
  1130.                 method = method.GetGenericMethodDefinition() as RuntimeMethodInfo;
  1131.            
  1132.             int pcaCount = 0;
  1133.             Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(method, caType, true, out pcaCount);
  1134.            
  1135.             // if we are asked to go up the hierarchy chain we have to do it now and regardless of the
  1136.             // attribute usage for the specific attribute because a derived attribute may override the usage...
  1137.             // ... however if the attribute is sealed we can rely on the attribute usage
  1138.             if (!inherit || (caType.IsSealed && !CustomAttribute.GetAttributeUsage(caType).Inherited)) {
  1139.                 object[] attributes = GetCustomAttributes(method.Module, method.MetadataToken, pcaCount, caType);
  1140.                 if (pcaCount > 0)
  1141.                     Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount);
  1142.                 return attributes;
  1143.             }
  1144.            
  1145.             List<object> result = new List<object>();
  1146.             bool mustBeInheritable = false;
  1147.             bool useObjectArray = (caType == null || caType.IsValueType || caType.ContainsGenericParameters);
  1148.             Type arrayType = useObjectArray ? typeof(object) : caType;
  1149.            
  1150.             while (pcaCount > 0)
  1151.                 result.Add(pca[--pcaCount]);
  1152.            
  1153.             while (method != null) {
  1154.                 object[] attributes = GetCustomAttributes(method.Module, method.MetadataToken, 0, caType, mustBeInheritable, result);
  1155.                 mustBeInheritable = true;
  1156.                 for (int i = 0; i < attributes.Length; i++)
  1157.                     result.Add(attributes[i]);
  1158.                
  1159.                 method = method.GetParentDefinition() as RuntimeMethodInfo;
  1160.             }
  1161.            
  1162.             object[] typedResult = Array.CreateInstance(arrayType, result.Count) as object[];
  1163.             Array.Copy(result.ToArray(), 0, typedResult, 0, result.Count);
  1164.             return typedResult;
  1165.         }
  1166.        
  1167.         static internal object[] GetCustomAttributes(RuntimeConstructorInfo ctor, RuntimeType caType)
  1168.         {
  1169.             int pcaCount = 0;
  1170.             Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(ctor, caType, true, out pcaCount);
  1171.             object[] attributes = GetCustomAttributes(ctor.Module, ctor.MetadataToken, pcaCount, caType);
  1172.             if (pcaCount > 0)
  1173.                 Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount);
  1174.             return attributes;
  1175.         }
  1176.        
  1177.         static internal object[] GetCustomAttributes(RuntimePropertyInfo property, RuntimeType caType)
  1178.         {
  1179.             int pcaCount = 0;
  1180.             Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(property, caType, out pcaCount);
  1181.             object[] attributes = GetCustomAttributes(property.Module, property.MetadataToken, pcaCount, caType);
  1182.             if (pcaCount > 0)
  1183.                 Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount);
  1184.             return attributes;
  1185.         }
  1186.        
  1187.         static internal object[] GetCustomAttributes(RuntimeEventInfo e, RuntimeType caType)
  1188.         {
  1189.             int pcaCount = 0;
  1190.             Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(e, caType, out pcaCount);
  1191.             object[] attributes = GetCustomAttributes(e.Module, e.MetadataToken, pcaCount, caType);
  1192.             if (pcaCount > 0)
  1193.                 Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount);
  1194.             return attributes;
  1195.         }
  1196.        
  1197.         static internal object[] GetCustomAttributes(RuntimeFieldInfo field, RuntimeType caType)
  1198.         {
  1199.             int pcaCount = 0;
  1200.             Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(field, caType, out pcaCount);
  1201.             object[] attributes = GetCustomAttributes(field.Module, field.MetadataToken, pcaCount, caType);
  1202.             if (pcaCount > 0)
  1203.                 Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount);
  1204.             return attributes;
  1205.         }
  1206.        
  1207.         static internal object[] GetCustomAttributes(ParameterInfo parameter, RuntimeType caType)
  1208.         {
  1209.             int pcaCount = 0;
  1210.             Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(parameter, caType, out pcaCount);
  1211.             object[] attributes = GetCustomAttributes(parameter.Member.Module, parameter.MetadataToken, pcaCount, caType);
  1212.             if (pcaCount > 0)
  1213.                 Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount);
  1214.             return attributes;
  1215.         }
  1216.        
  1217.         static internal object[] GetCustomAttributes(Assembly assembly, RuntimeType caType)
  1218.         {
  1219.             int pcaCount = 0;
  1220.             Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(assembly, caType, out pcaCount);
  1221.             object[] attributes = GetCustomAttributes(assembly.ManifestModule, assembly.AssemblyHandle.GetToken(), pcaCount, caType);
  1222.             if (pcaCount > 0)
  1223.                 Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount);
  1224.             return attributes;
  1225.         }
  1226.        
  1227.         static internal object[] GetCustomAttributes(Module module, RuntimeType caType)
  1228.         {
  1229.             int pcaCount = 0;
  1230.             Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(module, caType, out pcaCount);
  1231.             object[] attributes = GetCustomAttributes(module, module.MetadataToken, pcaCount, caType);
  1232.             if (pcaCount > 0)
  1233.                 Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount);
  1234.             return attributes;
  1235.         }
  1236.        
  1237.         static internal bool IsCustomAttributeDefined(Module decoratedModule, int decoratedMetadataToken, RuntimeType attributeFilterType)
  1238.         {
  1239.             return IsCustomAttributeDefined(decoratedModule, decoratedMetadataToken, attributeFilterType, false);
  1240.         }
  1241.        
  1242.         static internal bool IsCustomAttributeDefined(Module decoratedModule, int decoratedMetadataToken, RuntimeType attributeFilterType, bool mustBeInheritable)
  1243.         {
  1244.             if (decoratedModule.Assembly.ReflectionOnly)
  1245.                 throw new InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyCA"));
  1246.            
  1247.             MetadataImport scope = decoratedModule.MetadataImport;
  1248.             CustomAttributeRecord[] car = CustomAttributeData.GetCustomAttributeRecords(decoratedModule, decoratedMetadataToken);
  1249.             RuntimeType attributeType;
  1250.             RuntimeMethodHandle ctor;
  1251.             bool ctorHasParameters;
  1252.             bool isVarArg;
  1253.            
  1254.             // Optimization for the case where attributes decorate entities in the same assembly in which case
  1255.             // we can cache the successful APTCA check between the decorated and the declared assembly.
  1256.             Assembly lastAptcaOkAssembly = null;
  1257.            
  1258.             for (int i = 0; i < car.Length; i++) {
  1259.                 CustomAttributeRecord caRecord = car[i];
  1260.                
  1261.                 if (FilterCustomAttributeRecord(caRecord, scope, ref lastAptcaOkAssembly, decoratedModule, decoratedMetadataToken, attributeFilterType, mustBeInheritable, null, null, out attributeType,
  1262.                 out ctor, out ctorHasParameters, out isVarArg))
  1263.                     return true;
  1264.             }
  1265.            
  1266.             return false;
  1267.         }
  1268.        
  1269.         unsafe static internal object[] GetCustomAttributes(Module decoratedModule, int decoratedMetadataToken, int pcaCount, RuntimeType attributeFilterType)
  1270.         {
  1271.             return GetCustomAttributes(decoratedModule, decoratedMetadataToken, pcaCount, attributeFilterType, false, null);
  1272.         }
  1273.        
  1274.         unsafe static internal object[] GetCustomAttributes(Module decoratedModule, int decoratedMetadataToken, int pcaCount, RuntimeType attributeFilterType, bool mustBeInheritable, IList derivedAttributes)
  1275.         {
  1276.             if (decoratedModule.Assembly.ReflectionOnly)
  1277.                 throw new InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyCA"));
  1278.            
  1279.             MetadataImport scope = decoratedModule.MetadataImport;
  1280.             CustomAttributeRecord[] car = CustomAttributeData.GetCustomAttributeRecords(decoratedModule, decoratedMetadataToken);
  1281.            
  1282.             bool useObjectArray = (attributeFilterType == null || attributeFilterType.IsValueType || attributeFilterType.ContainsGenericParameters);
  1283.             Type arrayType = useObjectArray ? typeof(object) : attributeFilterType;
  1284.            
  1285.             if (attributeFilterType == null && car.Length == 0)
  1286.                 return Array.CreateInstance(arrayType, 0) as object[];
  1287.            
  1288.             object[] attributes = Array.CreateInstance(arrayType, car.Length) as object[];
  1289.             int cAttributes = 0;
  1290.            
  1291.             // Custom attribute security checks are done with respect to the assembly *decorated* with the
  1292.             // custom attribute as opposed to the *caller of GetCustomAttributes*.
  1293.             // Since this assembly might not be on the stack and the attribute ctor or property setters we're about to invoke may
  1294.             // make security demands, we push a frame on the stack as a proxy for the decorated assembly (this frame will be picked
  1295.             // up an interpreted by the security stackwalker).
  1296.             // Once we push the frame it will be automatically popped in the event of an exception, so no need to use CERs or the
  1297.             // like.
  1298.             SecurityContextFrame frame = new SecurityContextFrame();
  1299.             frame.Push(decoratedModule.Assembly);
  1300.            
  1301.             // Optimization for the case where attributes decorate entities in the same assembly in which case
  1302.             // we can cache the successful APTCA check between the decorated and the declared assembly.
  1303.             Assembly lastAptcaOkAssembly = null;
  1304.            
  1305.             for (int i = 0; i < car.Length; i++) {
  1306.                 object attribute = null;
  1307.                 CustomAttributeRecord caRecord = car[i];
  1308.                
  1309.                 RuntimeMethodHandle ctor = new RuntimeMethodHandle();
  1310.                 RuntimeType attributeType = null;
  1311.                 bool ctorHasParameters;
  1312.                 bool isVarArg;
  1313.                 int cNamedArgs = 0;
  1314.                
  1315.                 IntPtr blobStart = caRecord.blob.Signature;
  1316.                 IntPtr blobEnd = (IntPtr)((byte*)blobStart + caRecord.blob.Length);
  1317.                
  1318.                 if (!FilterCustomAttributeRecord(caRecord, scope, ref lastAptcaOkAssembly, decoratedModule, decoratedMetadataToken, attributeFilterType, mustBeInheritable, attributes, derivedAttributes, out attributeType,
  1319.                 out ctor, out ctorHasParameters, out isVarArg))
  1320.                     continue;
  1321.                
  1322.                 if (!ctor.IsNullHandle()) {
  1323.                     // Linktime demand checks
  1324.                     // decoratedMetadataToken needed as it may be "transparent" in which case we do a full stack walk
  1325.                     ctor.CheckLinktimeDemands(decoratedModule, decoratedMetadataToken);
  1326.                 }
  1327.                 else {
  1328.                 }
  1329.                
  1330.                 // Leverage RuntimeConstructorInfo standard .ctor verfication
  1331.                 RuntimeConstructorInfo.CheckCanCreateInstance(attributeType, isVarArg);
  1332.                
  1333.                 // Create custom attribute object
  1334.                 if (ctorHasParameters) {
  1335.                     attribute = CreateCaObject(decoratedModule, ctor, ref blobStart, blobEnd, out cNamedArgs);
  1336.                 }
  1337.                 else {
  1338.                     attribute = attributeType.TypeHandle.CreateCaInstance(ctor);
  1339.                    
  1340.                     if (Marshal.ReadInt16(blobStart) != 1)
  1341.                         throw new CustomAttributeFormatException();
  1342.                     blobStart = (IntPtr)((byte*)blobStart + 2);
  1343.                     // skip 0x0001 prefix
  1344.                     cNamedArgs = Marshal.ReadInt16(blobStart);
  1345.                     blobStart = (IntPtr)((byte*)blobStart + 2);
  1346.                     // skip namedArgs count
  1347.                 }
  1348.                
  1349.                 for (int j = 0; j < cNamedArgs; j++) {
  1350.                     #region // Initialize named properties and fields
  1351.                     string name;
  1352.                     bool isProperty;
  1353.                     Type type;
  1354.                     object value;
  1355.                    
  1356.                     IntPtr blobItr = caRecord.blob.Signature;
  1357.                    
  1358.                     GetPropertyOrFieldData(decoratedModule, ref blobStart, blobEnd, out name, out isProperty, out type, out value);
  1359.                    
  1360.                     try {
  1361.                         if (isProperty) {
  1362.                             #region // Initialize property
  1363.                             if (type == null && value != null)
  1364.                                 type = (value.GetType() == typeof(RuntimeType)) ? typeof(Type) : value.GetType();
  1365.                            
  1366.                             RuntimePropertyInfo property = null;
  1367.                            
  1368.                             if (type == null)
  1369.                                 property = attributeType.GetProperty(name) as RuntimePropertyInfo;
  1370.                             else
  1371.                                 property = attributeType.GetProperty(name, type, Type.EmptyTypes) as RuntimePropertyInfo;
  1372.                            
  1373.                             RuntimeMethodInfo setMethod = property.GetSetMethod(true) as RuntimeMethodInfo;
  1374.                            
  1375.                             // Public properties may have non-public setter methods
  1376.                             if (!setMethod.IsPublic)
  1377.                                 continue;
  1378.                            
  1379.                             setMethod.MethodHandle.CheckLinktimeDemands(decoratedModule, decoratedMetadataToken);
  1380.                            
  1381.                             setMethod.Invoke(attribute, BindingFlags.Default, null, new object[] {value}, null, true);
  1382.                             #endregion
  1383.                         }
  1384.                         else {
  1385.                             RtFieldInfo field = attributeType.GetField(name) as RtFieldInfo;
  1386.                            
  1387.                             field.InternalSetValue(attribute, value, BindingFlags.Default, Type.DefaultBinder, null, false);
  1388.                         }
  1389.                     }
  1390.                     catch (Exception e) {
  1391.                         throw new CustomAttributeFormatException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString(isProperty ? "RFLCT.InvalidPropFail" : "RFLCT.InvalidFieldFail"), name), e);
  1392.                     }
  1393.                     #endregion
  1394.                 }
  1395.                
  1396.                 if (!blobStart.Equals(blobEnd))
  1397.                     throw new CustomAttributeFormatException();
  1398.                
  1399.                 attributes[cAttributes++] = attribute;
  1400.             }
  1401.            
  1402.             // The frame will be popped automatically if we take an exception any time after we pushed it. So no need of a catch or
  1403.             // finally or CERs here.
  1404.             frame.Pop();
  1405.            
  1406.             if (cAttributes == car.Length && pcaCount == 0)
  1407.                 return attributes;
  1408.            
  1409.             if (cAttributes == 0)
  1410.                 Array.CreateInstance(arrayType, 0);
  1411.            
  1412.             object[] result = Array.CreateInstance(arrayType, cAttributes + pcaCount) as object[];
  1413.             Array.Copy(attributes, 0, result, 0, cAttributes);
  1414.             return result;
  1415.         }
  1416.        
  1417.         unsafe static internal bool FilterCustomAttributeRecord(CustomAttributeRecord caRecord, MetadataImport scope, ref Assembly lastAptcaOkAssembly, Module decoratedModule, MetadataToken decoratedToken, RuntimeType attributeFilterType, bool mustBeInheritable, object[] attributes, IList derivedAttributes, out RuntimeType attributeType,
  1418.         out RuntimeMethodHandle ctor, out bool ctorHasParameters, out bool isVarArg)
  1419.         {
  1420.             ctor = new RuntimeMethodHandle();
  1421.             attributeType = null;
  1422.             ctorHasParameters = false;
  1423.             isVarArg = false;
  1424.            
  1425.             IntPtr blobStart = caRecord.blob.Signature;
  1426.             IntPtr blobEnd = (IntPtr)((byte*)blobStart + caRecord.blob.Length);
  1427.            
  1428.             // Resolve attribute type from ctor parent token found in decorated decoratedModule scope
  1429.             attributeType = decoratedModule.ResolveType(scope.GetParentToken(caRecord.tkCtor), null, null) as RuntimeType;
  1430.            
  1431.             // Test attribute type against user provided attribute type filter
  1432.             if (!(attributeFilterType.IsAssignableFrom(attributeType)))
  1433.                 return false;
  1434.            
  1435.             if (!AttributeUsageCheck(attributeType, mustBeInheritable, attributes, derivedAttributes))
  1436.                 return false;
  1437.            
  1438.             // APTCA checks
  1439.             if (attributeType.Assembly != lastAptcaOkAssembly && !attributeType.Assembly.AptcaCheck(decoratedModule.Assembly))
  1440.                 return false;
  1441.            
  1442.             // Cache last successful APTCA check (optimization)
  1443.             lastAptcaOkAssembly = decoratedModule.Assembly;
  1444.            
  1445.             // Resolve the attribute ctor
  1446.             ConstArray ctorSig = scope.GetMethodSignature(caRecord.tkCtor);
  1447.             isVarArg = (ctorSig[0] & 5) != 0;
  1448.             ctorHasParameters = ctorSig[1] != 0;
  1449.            
  1450.             if (ctorHasParameters) {
  1451.                 // Resolve method ctor token found in decorated decoratedModule scope
  1452.                 ctor = decoratedModule.ModuleHandle.ResolveMethodHandle(caRecord.tkCtor);
  1453.             }
  1454.             else {
  1455.                 // Resolve method ctor token from decorated decoratedModule scope
  1456.                 ctor = attributeType.GetTypeHandleInternal().GetDefaultConstructor();
  1457.                
  1458.                 if (ctor.IsNullHandle() && !attributeType.IsValueType)
  1459.                     throw new MissingMethodException(".ctor");
  1460.             }
  1461.            
  1462.             // Visibility checks
  1463.             if (ctor.IsNullHandle()) {
  1464.                 if (!attributeType.IsVisible && !attributeType.TypeHandle.IsVisibleFromModule(decoratedModule.ModuleHandle))
  1465.                     return false;
  1466.                
  1467.                 return true;
  1468.             }
  1469.            
  1470.             if (ctor.IsVisibleFromModule(decoratedModule))
  1471.                 return true;
  1472.            
  1473.             MetadataToken tkParent = new MetadataToken();
  1474.            
  1475.             if (decoratedToken.IsParamDef) {
  1476.                 tkParent = new MetadataToken(scope.GetParentToken(decoratedToken));
  1477.                 tkParent = new MetadataToken(scope.GetParentToken(tkParent));
  1478.             }
  1479.             else if (decoratedToken.IsMethodDef || decoratedToken.IsProperty || decoratedToken.IsEvent || decoratedToken.IsFieldDef) {
  1480.                 tkParent = new MetadataToken(scope.GetParentToken(decoratedToken));
  1481.             }
  1482.             else if (decoratedToken.IsTypeDef) {
  1483.                 tkParent = decoratedToken;
  1484.             }
  1485.            
  1486.             if (tkParent.IsTypeDef)
  1487.                 return ctor.IsVisibleFromType(decoratedModule.ModuleHandle.ResolveTypeHandle(tkParent));
  1488.            
  1489.             return false;
  1490.         }
  1491.         #endregion
  1492.        
  1493.         #region Private Static Methods
  1494.         private static bool AttributeUsageCheck(RuntimeType attributeType, bool mustBeInheritable, object[] attributes, IList derivedAttributes)
  1495.         {
  1496.             AttributeUsageAttribute attributeUsageAttribute = null;
  1497.            
  1498.             if (mustBeInheritable) {
  1499.                 attributeUsageAttribute = CustomAttribute.GetAttributeUsage(attributeType);
  1500.                
  1501.                 if (!attributeUsageAttribute.Inherited)
  1502.                     return false;
  1503.             }
  1504.            
  1505.             // Legacy: AllowMultiple ignored for none inheritable attributes
  1506.            
  1507.             if (derivedAttributes == null)
  1508.                 return true;
  1509.            
  1510.             for (int i = 0; i < derivedAttributes.Count; i++) {
  1511.                 if (derivedAttributes[i].GetType() == attributeType) {
  1512.                     if (attributeUsageAttribute == null)
  1513.                         attributeUsageAttribute = CustomAttribute.GetAttributeUsage(attributeType);
  1514.                    
  1515.                     return attributeUsageAttribute.AllowMultiple;
  1516.                 }
  1517.             }
  1518.            
  1519.             return true;
  1520.         }
  1521.        
  1522.         static internal AttributeUsageAttribute GetAttributeUsage(RuntimeType decoratedAttribute)
  1523.         {
  1524.             Module decoratedModule = decoratedAttribute.Module;
  1525.             MetadataImport scope = decoratedModule.MetadataImport;
  1526.             CustomAttributeRecord[] car = CustomAttributeData.GetCustomAttributeRecords(decoratedModule, decoratedAttribute.MetadataToken);
  1527.            
  1528.             AttributeUsageAttribute attributeUsageAttribute = null;
  1529.            
  1530.             for (int i = 0; i < car.Length; i++) {
  1531.                 CustomAttributeRecord caRecord = car[i];
  1532.                 RuntimeType attributeType = decoratedModule.ResolveType(scope.GetParentToken(caRecord.tkCtor), null, null) as RuntimeType;
  1533.                
  1534.                 if (attributeType != typeof(AttributeUsageAttribute))
  1535.                     continue;
  1536.                
  1537.                 if (attributeUsageAttribute != null)
  1538.                     throw new FormatException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Format_AttributeUsage"), attributeType));
  1539.                
  1540.                 AttributeTargets targets;
  1541.                 bool inherited;
  1542.                 bool allowMultiple;
  1543.                 ParseAttributeUsageAttribute(caRecord.blob, out targets, out inherited, out allowMultiple);
  1544.                 attributeUsageAttribute = new AttributeUsageAttribute(targets, allowMultiple, inherited);
  1545.             }
  1546.            
  1547.             if (attributeUsageAttribute == null)
  1548.                 return AttributeUsageAttribute.Default;
  1549.            
  1550.             return attributeUsageAttribute;
  1551.         }
  1552.         #endregion
  1553.        
  1554.         #region Private Static FCalls
  1555.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1556.         private static extern void _ParseAttributeUsageAttribute(IntPtr pCa, int cCa, out int targets, out bool inherited, out bool allowMultiple);
  1557.         private static void ParseAttributeUsageAttribute(ConstArray ca, out AttributeTargets targets, out bool inherited, out bool allowMultiple)
  1558.         {
  1559.             int _targets;
  1560.             _ParseAttributeUsageAttribute(ca.Signature, ca.Length, out _targets, out inherited, out allowMultiple);
  1561.             targets = (AttributeTargets)_targets;
  1562.         }
  1563.        
  1564.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1565.         unsafe private static extern object _CreateCaObject(void* pModule, void* pCtor, byte** ppBlob, byte* pEndBlob, int* pcNamedArgs);
  1566.         unsafe private static object CreateCaObject(Module module, RuntimeMethodHandle ctor, ref IntPtr blob, IntPtr blobEnd, out int namedArgs)
  1567.         {
  1568.             byte* pBlob = (byte*)blob;
  1569.             byte* pBlobEnd = (byte*)blobEnd;
  1570.             int cNamedArgs;
  1571.             object ca = _CreateCaObject((void*)module.ModuleHandle.Value, (void*)ctor.Value, &pBlob, pBlobEnd, &cNamedArgs);
  1572.             blob = (IntPtr)pBlob;
  1573.             namedArgs = cNamedArgs;
  1574.             return ca;
  1575.         }
  1576.        
  1577.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1578.         unsafe private static extern void _GetPropertyOrFieldData(IntPtr pModule, byte** ppBlobStart, byte* pBlobEnd, out string name, out bool bIsProperty, out Type type, out object value);
  1579.         unsafe private static void GetPropertyOrFieldData(Module module, ref IntPtr blobStart, IntPtr blobEnd, out string name, out bool isProperty, out Type type, out object value)
  1580.         {
  1581.             byte* pBlobStart = (byte*)blobStart;
  1582.             _GetPropertyOrFieldData((IntPtr)module.ModuleHandle.Value, &pBlobStart, (byte*)blobEnd, out name, out isProperty, out type, out value);
  1583.             blobStart = (IntPtr)pBlobStart;
  1584.         }
  1585.         #endregion
  1586.     }
  1587.    
  1588.     static internal class PseudoCustomAttribute
  1589.     {
  1590.         #region Private Static Data Members
  1591.         private static Hashtable s_pca;
  1592.         private static int s_pcasCount;
  1593.         #endregion
  1594.        
  1595.         #region FCalls
  1596.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  1597.         unsafe private static extern void _GetSecurityAttributes(void* module, int token, out object[] securityAttributes);
  1598.         unsafe static internal void GetSecurityAttributes(ModuleHandle module, int token, out object[] securityAttributes)
  1599.         {
  1600.             _GetSecurityAttributes(module.Value, token, out securityAttributes);
  1601.         }
  1602.         #endregion
  1603.        
  1604.         #region Static Constructor
  1605.         static PseudoCustomAttribute()
  1606.         {
  1607.             Type[] pcas = new Type[] {typeof(FieldOffsetAttribute), typeof(SerializableAttribute), typeof(MarshalAsAttribute), typeof(ComImportAttribute), typeof(NonSerializedAttribute), typeof(InAttribute), typeof(OutAttribute), typeof(OptionalAttribute), typeof(DllImportAttribute), typeof(PreserveSigAttribute)
  1608.                 // See //depot/DevDiv/private/Main/ndp/clr/src/MD/Compiler/CustAttr.cpp
  1609.                 // field
  1610.                 // class, struct, enum, delegate
  1611.                 // parameter, field, return-value
  1612.                 // class, interface
  1613.                 // field, inherited
  1614.                 // parameter
  1615.                 // parameter
  1616.                 // parameter
  1617.                 // method
  1618.                 // method
  1619.             };
  1620.            
  1621.             s_pcasCount = pcas.Length;
  1622.             s_pca = new Hashtable(s_pcasCount);
  1623.             for (int i = 0; i < s_pcasCount; i++) {
  1624.                 VerifyPseudoCustomAttribute(pcas[i]);
  1625.                 s_pca[pcas[i]] = pcas[i];
  1626.             }
  1627.         }
  1628.        
  1629.         [Conditional("_DEBUG")]
  1630.         private static void VerifyPseudoCustomAttribute(Type pca)
  1631.         {
  1632.             // If any of these are invariants are no longer true will have to
  1633.             // re-architect the PCA product logic and test cases -- you've been warned!
  1634.             BCLDebug.Assert(pca.BaseType == typeof(Attribute), "Pseudo CA Error");
  1635.             AttributeUsageAttribute usage = CustomAttribute.GetAttributeUsage(pca as RuntimeType);
  1636.             BCLDebug.Assert(usage.Inherited == false, "Pseudo CA Error");
  1637.             BCLDebug.Assert(usage.AllowMultiple == false, "Pseudo CA Error");
  1638.         }
  1639.         #endregion
  1640.        
  1641.         #region Internal Static
  1642.         static internal bool IsSecurityAttribute(Type type)
  1643.         {
  1644.             return type == typeof(SecurityAttribute) || type.IsSubclassOf(typeof(SecurityAttribute));
  1645.         }
  1646.        
  1647.         static internal Attribute[] GetCustomAttributes(RuntimeType type, Type caType, bool includeSecCa, out int count)
  1648.         {
  1649.             ASSERT.PRECONDITION(type != null);
  1650.             ASSERT.PRECONDITION(caType != null);
  1651.            
  1652.             count = 0;
  1653.            
  1654.             bool all = caType == typeof(object) || caType == typeof(Attribute);
  1655.             if (!all && s_pca[caType] == null && !IsSecurityAttribute(caType))
  1656.                 return new Attribute[0];
  1657.            
  1658.             List<Attribute> pcas = new List<Attribute>();
  1659.             Attribute pca = null;
  1660.            
  1661.             if (all || caType == typeof(SerializableAttribute)) {
  1662.                 pca = SerializableAttribute.GetCustomAttribute(type);
  1663.                 if (pca != null)
  1664.                     pcas.Add(pca);
  1665.             }
  1666.             if (all || caType == typeof(ComImportAttribute)) {
  1667.                 pca = ComImportAttribute.GetCustomAttribute(type);
  1668.                 if (pca != null)
  1669.                     pcas.Add(pca);
  1670.             }
  1671.             if (includeSecCa && (all || IsSecurityAttribute(caType))) {
  1672.                 if (!type.IsGenericParameter) {
  1673.                     if (type.IsGenericType)
  1674.                         type = (RuntimeType)type.GetGenericTypeDefinition();
  1675.                    
  1676.                     object[] securityAttributes;
  1677.                     GetSecurityAttributes(type.Module.ModuleHandle, type.MetadataToken, out securityAttributes);
  1678.                     if (securityAttributes != null)
  1679.                         foreach (object a in securityAttributes)
  1680.                             if (caType == a.GetType() || a.GetType().IsSubclassOf(caType))
  1681.                                 pcas.Add((Attribute)a);
  1682.                 }
  1683.             }
  1684.            
  1685.             count = pcas.Count;
  1686.             return pcas.ToArray();
  1687.         }
  1688.         static internal bool IsDefined(RuntimeType type, Type caType)
  1689.         {
  1690.             bool all = caType == typeof(object) || caType == typeof(Attribute);
  1691.             if (!all && s_pca[caType] == null && !IsSecurityAttribute(caType))
  1692.                 return false;
  1693.            
  1694.             if (all || caType == typeof(SerializableAttribute)) {
  1695.                 if (SerializableAttribute.IsDefined(type))
  1696.                     return true;
  1697.             }
  1698.             if (all || caType == typeof(ComImportAttribute)) {
  1699.                 if (ComImportAttribute.IsDefined(type))
  1700.                     return true;
  1701.             }
  1702.             if (all || IsSecurityAttribute(caType)) {
  1703.                 int count;
  1704.                 if (GetCustomAttributes(type, caType, true, out count).Length != 0)
  1705.                     return true;
  1706.             }
  1707.            
  1708.             return false;
  1709.         }
  1710.        
  1711.         static internal Attribute[] GetCustomAttributes(RuntimeMethodInfo method, Type caType, bool includeSecCa, out int count)
  1712.         {
  1713.             ASSERT.PRECONDITION(method != null);
  1714.             ASSERT.PRECONDITION(caType != null);
  1715.            
  1716.             count = 0;
  1717.            
  1718.             bool all = caType == typeof(object) || caType == typeof(Attribute);
  1719.             if (!all && s_pca[caType] == null && !IsSecurityAttribute(caType))
  1720.                 return new Attribute[0];
  1721.            
  1722.             List<Attribute> pcas = new List<Attribute>();
  1723.             Attribute pca = null;
  1724.            
  1725.             if (all || caType == typeof(DllImportAttribute)) {
  1726.                 pca = DllImportAttribute.GetCustomAttribute(method);
  1727.                 if (pca != null)
  1728.                     pcas.Add(pca);
  1729.             }
  1730.             if (all || caType == typeof(PreserveSigAttribute)) {
  1731.                 pca = PreserveSigAttribute.GetCustomAttribute(method);
  1732.                 if (pca != null)
  1733.                     pcas.Add(pca);
  1734.             }
  1735.             if (includeSecCa && (all || IsSecurityAttribute(caType))) {
  1736.                 object[] securityAttributes;
  1737.                
  1738.                 GetSecurityAttributes(method.Module.ModuleHandle, method.MetadataToken, out securityAttributes);
  1739.                 if (securityAttributes != null)
  1740.                     foreach (object a in securityAttributes)
  1741.                         if (caType == a.GetType() || a.GetType().IsSubclassOf(caType))
  1742.                             pcas.Add((Attribute)a);
  1743.             }
  1744.            
  1745.             count = pcas.Count;
  1746.             return pcas.ToArray();
  1747.         }
  1748.         static internal bool IsDefined(RuntimeMethodInfo method, Type caType)
  1749.         {
  1750.             bool all = caType == typeof(object) || caType == typeof(Attribute);
  1751.             if (!all && s_pca[caType] == null)
  1752.                 return false;
  1753.            
  1754.             if (all || caType == typeof(DllImportAttribute)) {
  1755.                 if (DllImportAttribute.IsDefined(method))
  1756.                     return true;
  1757.             }
  1758.             if (all || caType == typeof(PreserveSigAttribute)) {
  1759.                 if (PreserveSigAttribute.IsDefined(method))
  1760.                     return true;
  1761.             }
  1762.             if (all || IsSecurityAttribute(caType)) {
  1763.                 int count;
  1764.                
  1765.                 if (GetCustomAttributes(method, caType, true, out count).Length != 0)
  1766.                     return true;
  1767.             }
  1768.            
  1769.             return false;
  1770.         }
  1771.        
  1772.         static internal Attribute[] GetCustomAttributes(ParameterInfo parameter, Type caType, out int count)
  1773.         {
  1774.             ASSERT.PRECONDITION(parameter != null);
  1775.             ASSERT.PRECONDITION(caType != null);
  1776.            
  1777.             count = 0;
  1778.            
  1779.             bool all = caType == typeof(object) || caType == typeof(Attribute);
  1780.             if (!all && s_pca[caType] == null)
  1781.                 return null;
  1782.            
  1783.             Attribute[] pcas = new Attribute[s_pcasCount];
  1784.             Attribute pca = null;
  1785.            
  1786.             if (all || caType == typeof(InAttribute)) {
  1787.                 pca = InAttribute.GetCustomAttribute(parameter);
  1788.                 if (pca != null)
  1789.                     pcas[count++] = pca;
  1790.             }
  1791.             if (all || caType == typeof(OutAttribute)) {
  1792.                 pca = OutAttribute.GetCustomAttribute(parameter);
  1793.                 if (pca != null)
  1794.                     pcas[count++] = pca;
  1795.             }
  1796.             if (all || caType == typeof(OptionalAttribute)) {
  1797.                 pca = OptionalAttribute.GetCustomAttribute(parameter);
  1798.                 if (pca != null)
  1799.                     pcas[count++] = pca;
  1800.             }
  1801.             if (all || caType == typeof(MarshalAsAttribute)) {
  1802.                 pca = MarshalAsAttribute.GetCustomAttribute(parameter);
  1803.                 if (pca != null)
  1804.                     pcas[count++] = pca;
  1805.             }
  1806.             return pcas;
  1807.         }
  1808.         static internal bool IsDefined(ParameterInfo parameter, Type caType)
  1809.         {
  1810.             bool all = caType == typeof(object) || caType == typeof(Attribute);
  1811.             if (!all && s_pca[caType] == null)
  1812.                 return false;
  1813.            
  1814.            
  1815.             if (all || caType == typeof(InAttribute)) {
  1816.                 if (InAttribute.IsDefined(parameter))
  1817.                     return true;
  1818.             }
  1819.             if (all || caType == typeof(OutAttribute)) {
  1820.                 if (OutAttribute.IsDefined(parameter))
  1821.                     return true;
  1822.             }
  1823.             if (all || caType == typeof(OptionalAttribute)) {
  1824.                 if (OptionalAttribute.IsDefined(parameter))
  1825.                     return true;
  1826.             }
  1827.             if (all || caType == typeof(MarshalAsAttribute)) {
  1828.                 if (MarshalAsAttribute.IsDefined(parameter))
  1829.                     return true;
  1830.             }
  1831.            
  1832.             return false;
  1833.         }
  1834.        
  1835.         static internal Attribute[] GetCustomAttributes(Assembly assembly, Type caType, out int count)
  1836.         {
  1837.             count = 0;
  1838.            
  1839.             bool all = caType == typeof(object) || caType == typeof(Attribute);
  1840.            
  1841.             if (!all && s_pca[caType] == null && !IsSecurityAttribute(caType))
  1842.                 return new Attribute[0];
  1843.            
  1844.             List<Attribute> pcas = new List<Attribute>();
  1845.            
  1846.             if (all || IsSecurityAttribute(caType)) {
  1847.                 object[] securityAttributes;
  1848.                
  1849.                 GetSecurityAttributes(assembly.ManifestModule.ModuleHandle, assembly.AssemblyHandle.GetToken(), out securityAttributes);
  1850.                 if (securityAttributes != null)
  1851.                     foreach (object a in securityAttributes)
  1852.                         if (caType == a.GetType() || a.GetType().IsSubclassOf(caType))
  1853.                             pcas.Add((Attribute)a);
  1854.             }
  1855.            
  1856.             count = pcas.Count;
  1857.             return pcas.ToArray();
  1858.         }
  1859.         static internal bool IsDefined(Assembly assembly, Type caType)
  1860.         {
  1861.             int count;
  1862.             return GetCustomAttributes(assembly, caType, out count).Length > 0;
  1863.         }
  1864.        
  1865.         static internal Attribute[] GetCustomAttributes(Module module, Type caType, out int count)
  1866.         {
  1867.             count = 0;
  1868.             return null;
  1869.         }
  1870.         static internal bool IsDefined(Module module, Type caType)
  1871.         {
  1872.             return false;
  1873.         }
  1874.        
  1875.         static internal Attribute[] GetCustomAttributes(RuntimeFieldInfo field, Type caType, out int count)
  1876.         {
  1877.             ASSERT.PRECONDITION(field != null);
  1878.             ASSERT.PRECONDITION(caType != null);
  1879.            
  1880.             count = 0;
  1881.            
  1882.             bool all = caType == typeof(object) || caType == typeof(Attribute);
  1883.             if (!all && s_pca[caType] == null)
  1884.                 return null;
  1885.            
  1886.             Attribute[] pcas = new Attribute[s_pcasCount];
  1887.             Attribute pca = null;
  1888.            
  1889.             if (all || caType == typeof(MarshalAsAttribute)) {
  1890.                 pca = MarshalAsAttribute.GetCustomAttribute(field);
  1891.                 if (pca != null)
  1892.                     pcas[count++] = pca;
  1893.             }
  1894.             if (all || caType == typeof(FieldOffsetAttribute)) {
  1895.                 pca = FieldOffsetAttribute.GetCustomAttribute(field);
  1896.                 if (pca != null)
  1897.                     pcas[count++] = pca;
  1898.             }
  1899.             if (all || caType == typeof(NonSerializedAttribute)) {
  1900.                 pca = NonSerializedAttribute.GetCustomAttribute(field);
  1901.                 if (pca != null)
  1902.                     pcas[count++] = pca;
  1903.             }
  1904.             return pcas;
  1905.         }
  1906.         static internal bool IsDefined(RuntimeFieldInfo field, Type caType)
  1907.         {
  1908.             bool all = caType == typeof(object) || caType == typeof(Attribute);
  1909.             if (!all && s_pca[caType] == null)
  1910.                 return false;
  1911.            
  1912.             if (all || caType == typeof(MarshalAsAttribute)) {
  1913.                 if (MarshalAsAttribute.IsDefined(field))
  1914.                     return true;
  1915.             }
  1916.             if (all || caType == typeof(FieldOffsetAttribute)) {
  1917.                 if (FieldOffsetAttribute.IsDefined(field))
  1918.                     return true;
  1919.             }
  1920.             if (all || caType == typeof(NonSerializedAttribute)) {
  1921.                 if (NonSerializedAttribute.IsDefined(field))
  1922.                     return true;
  1923.             }
  1924.            
  1925.             return false;
  1926.         }
  1927.        
  1928.         static internal Attribute[] GetCustomAttributes(RuntimeConstructorInfo ctor, Type caType, bool includeSecCa, out int count)
  1929.         {
  1930.             count = 0;
  1931.            
  1932.             bool all = caType == typeof(object) || caType == typeof(Attribute);
  1933.            
  1934.             if (!all && s_pca[caType] == null && !IsSecurityAttribute(caType))
  1935.                 return new Attribute[0];
  1936.            
  1937.             List<Attribute> pcas = new List<Attribute>();
  1938.            
  1939.             if (includeSecCa && (all || IsSecurityAttribute(caType))) {
  1940.                 object[] securityAttributes;
  1941.                
  1942.                 GetSecurityAttributes(ctor.Module.ModuleHandle, ctor.MetadataToken, out securityAttributes);
  1943.                 if (securityAttributes != null)
  1944.                     foreach (object a in securityAttributes)
  1945.                         if (caType == a.GetType() || a.GetType().IsSubclassOf(caType))
  1946.                             pcas.Add((Attribute)a);
  1947.             }
  1948.            
  1949.             count = pcas.Count;
  1950.             return pcas.ToArray();
  1951.         }
  1952.         static internal bool IsDefined(RuntimeConstructorInfo ctor, Type caType)
  1953.         {
  1954.             bool all = caType == typeof(object) || caType == typeof(Attribute);
  1955.            
  1956.             if (!all && s_pca[caType] == null)
  1957.                 return false;
  1958.            
  1959.             if (all || IsSecurityAttribute(caType)) {
  1960.                 int count;
  1961.                
  1962.                 if (GetCustomAttributes(ctor, caType, true, out count).Length != 0)
  1963.                     return true;
  1964.             }
  1965.            
  1966.             return false;
  1967.         }
  1968.        
  1969.         static internal Attribute[] GetCustomAttributes(RuntimePropertyInfo property, Type caType, out int count)
  1970.         {
  1971.             count = 0;
  1972.             return null;
  1973.         }
  1974.         static internal bool IsDefined(RuntimePropertyInfo property, Type caType)
  1975.         {
  1976.             return false;
  1977.         }
  1978.        
  1979.         static internal Attribute[] GetCustomAttributes(RuntimeEventInfo e, Type caType, out int count)
  1980.         {
  1981.             count = 0;
  1982.             return null;
  1983.         }
  1984.         static internal bool IsDefined(RuntimeEventInfo e, Type caType)
  1985.         {
  1986.             return false;
  1987.         }
  1988.         #endregion
  1989.     }
  1990. }

Developer Fusion