using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; namespace System.Reflection.Emit { /// Helps build custom attributes. // Token: 0x020001E4 RID: 484 [ClassInterface(ClassInterfaceType.None)] [ComDefaultInterface(typeof(_CustomAttributeBuilder))] [ComVisible(true)] public class CustomAttributeBuilder : _CustomAttributeBuilder { // Token: 0x0600191D RID: 6429 RVA: 0x000605DC File Offset: 0x0005E7DC internal CustomAttributeBuilder(ConstructorInfo con, byte[] cdata) { this.ctor = con; this.data = (byte[])cdata.Clone(); } /// Initializes an instance of the CustomAttributeBuilder class given the constructor for the custom attribute and the arguments to the constructor. /// The constructor for the custom attribute. /// The arguments to the constructor of the custom attribute. /// /// is static or private.-or- The number of supplied arguments does not match the number of parameters of the constructor as required by the calling convention of the constructor.-or- The type of supplied argument does not match the type of the parameter declared in the constructor. -or-A supplied argument is a reference type other than or . /// /// or is null. // Token: 0x0600191E RID: 6430 RVA: 0x000605FC File Offset: 0x0005E7FC public CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs) { this.Initialize(con, constructorArgs, new PropertyInfo[0], new object[0], new FieldInfo[0], new object[0]); } /// Initializes an instance of the CustomAttributeBuilder class given the constructor for the custom attribute, the arguments to the constructor, and a set of named field/value pairs. /// The constructor for the custom attribute. /// The arguments to the constructor of the custom attribute. /// Named fields of the custom attribute. /// Values for the named fields of the custom attribute. /// The lengths of the and arrays are different.-or- is static or private.-or- The number of supplied arguments does not match the number of parameters of the constructor as required by the calling convention of the constructor.-or- The type of supplied argument does not match the type of the parameter declared in the constructor.-or- The types of the field values do not match the types of the named fields.-or- The field does not belong to the same class or base class as the constructor. -or-A supplied argument or named field is a reference type other than or . /// One of the parameters is null. // Token: 0x0600191F RID: 6431 RVA: 0x00060630 File Offset: 0x0005E830 public CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs, FieldInfo[] namedFields, object[] fieldValues) { this.Initialize(con, constructorArgs, new PropertyInfo[0], new object[0], namedFields, fieldValues); } /// Initializes an instance of the CustomAttributeBuilder class given the constructor for the custom attribute, the arguments to the constructor, and a set of named property or value pairs. /// The constructor for the custom attribute. /// The arguments to the constructor of the custom attribute. /// Named properties of the custom attribute. /// Values for the named properties of the custom attribute. /// The lengths of the and arrays are different.-or- is static or private.-or- The number of supplied arguments does not match the number of parameters of the constructor as required by the calling convention of the constructor.-or- The type of supplied argument does not match the type of the parameter declared in the constructor.-or- The types of the property values do not match the types of the named properties.-or- A property has no setter method.-or- The property does not belong to the same class or base class as the constructor. -or-A supplied argument or named property is a reference type other than or . /// One of the parameters is null. // Token: 0x06001920 RID: 6432 RVA: 0x0006065C File Offset: 0x0005E85C public CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues) { this.Initialize(con, constructorArgs, namedProperties, propertyValues, new FieldInfo[0], new object[0]); } /// Initializes an instance of the CustomAttributeBuilder class given the constructor for the custom attribute, the arguments to the constructor, a set of named property or value pairs, and a set of named field or value pairs. /// The constructor for the custom attribute. /// The arguments to the constructor of the custom attribute. /// Named properties of the custom attribute. /// Values for the named properties of the custom attribute. /// Named fields of the custom attribute. /// Values for the named fields of the custom attribute. /// The lengths of the and arrays are different.-or- The lengths of the and arrays are different.-or- is static or private.-or- The number of supplied arguments does not match the number of parameters of the constructor as required by the calling convention of the constructor.-or- The type of supplied argument does not match the type of the parameter declared in the constructor.-or- The types of the property values do not match the types of the named properties.-or- The types of the field values do not match the types of the corresponding field types.-or- A property has no setter.-or- The property or field does not belong to the same class or base class as the constructor. -or-A supplied argument, named property, or named field is a reference type other than or . /// One of the parameters is null. // Token: 0x06001921 RID: 6433 RVA: 0x00060688 File Offset: 0x0005E888 public CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues, FieldInfo[] namedFields, object[] fieldValues) { this.Initialize(con, constructorArgs, namedProperties, propertyValues, namedFields, fieldValues); } /// Maps a set of names to a corresponding set of dispatch identifiers. /// Reserved for future use. Must be IID_NULL. /// Passed-in array of names to be mapped. /// Count of the names to be mapped. /// The locale context in which to interpret the names. /// Caller-allocated array which receives the IDs corresponding to the names. /// The method is called late-bound using the COM IDispatch interface. // Token: 0x06001922 RID: 6434 RVA: 0x000606AC File Offset: 0x0005E8AC void _CustomAttributeBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) { throw new NotImplementedException(); } /// Retrieves the type information for an object, which can then be used to get the type information for an interface. /// The type information to return. /// The locale identifier for the type information. /// Receives a pointer to the requested type information object. /// The method is called late-bound using the COM IDispatch interface. // Token: 0x06001923 RID: 6435 RVA: 0x000606B4 File Offset: 0x0005E8B4 void _CustomAttributeBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) { throw new NotImplementedException(); } /// Retrieves the number of type information interfaces that an object provides (either 0 or 1). /// Points to a location that receives the number of type information interfaces provided by the object. /// The method is called late-bound using the COM IDispatch interface. // Token: 0x06001924 RID: 6436 RVA: 0x000606BC File Offset: 0x0005E8BC void _CustomAttributeBuilder.GetTypeInfoCount(out uint pcTInfo) { throw new NotImplementedException(); } /// Provides access to properties and methods exposed by an object. /// Identifies the member. /// Reserved for future use. Must be IID_NULL. /// The locale context in which to interpret arguments. /// Flags describing the context of the call. /// Pointer to a structure containing an array of arguments, an array of argument DISPIDs for named arguments, and counts for the number of elements in the arrays. /// Pointer to the location where the result is to be stored. /// Pointer to a structure that contains exception information. /// The index of the first argument that has an error. /// The method is called late-bound using the COM IDispatch interface. // Token: 0x06001925 RID: 6437 RVA: 0x000606C4 File Offset: 0x0005E8C4 void _CustomAttributeBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) { throw new NotImplementedException(); } // Token: 0x1700046A RID: 1130 // (get) Token: 0x06001926 RID: 6438 RVA: 0x000606CC File Offset: 0x0005E8CC internal ConstructorInfo Ctor { get { return this.ctor; } } // Token: 0x1700046B RID: 1131 // (get) Token: 0x06001927 RID: 6439 RVA: 0x000606D4 File Offset: 0x0005E8D4 internal byte[] Data { get { return this.data; } } // Token: 0x06001928 RID: 6440 [MethodImpl(MethodImplOptions.InternalCall)] private static extern byte[] GetBlob(Assembly asmb, ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues, FieldInfo[] namedFields, object[] fieldValues); // Token: 0x06001929 RID: 6441 RVA: 0x000606DC File Offset: 0x0005E8DC private bool IsValidType(Type t) { if (t.IsArray && t.GetArrayRank() > 1) { return false; } if (t is TypeBuilder && t.IsEnum) { Enum.GetUnderlyingType(t); } return true; } // Token: 0x0600192A RID: 6442 RVA: 0x00060720 File Offset: 0x0005E920 private void Initialize(ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues, FieldInfo[] namedFields, object[] fieldValues) { this.ctor = con; if (con == null) { throw new ArgumentNullException("con"); } if (constructorArgs == null) { throw new ArgumentNullException("constructorArgs"); } if (namedProperties == null) { throw new ArgumentNullException("namedProperties"); } if (propertyValues == null) { throw new ArgumentNullException("propertyValues"); } if (namedFields == null) { throw new ArgumentNullException("namedFields"); } if (fieldValues == null) { throw new ArgumentNullException("fieldValues"); } if (con.GetParameterCount() != constructorArgs.Length) { throw new ArgumentException("Parameter count does not match passed in argument value count."); } if (namedProperties.Length != propertyValues.Length) { throw new ArgumentException("Array lengths must be the same.", "namedProperties, propertyValues"); } if (namedFields.Length != fieldValues.Length) { throw new ArgumentException("Array lengths must be the same.", "namedFields, fieldValues"); } if ((con.Attributes & MethodAttributes.Static) == MethodAttributes.Static || (con.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private) { throw new ArgumentException("Cannot have private or static constructor."); } Type declaringType = this.ctor.DeclaringType; int num = 0; foreach (FieldInfo fieldInfo in namedFields) { Type declaringType2 = fieldInfo.DeclaringType; if (!this.IsValidType(declaringType2)) { throw new ArgumentException("Field '" + fieldInfo.Name + "' does not have a valid type."); } if (declaringType != declaringType2 && !declaringType2.IsSubclassOf(declaringType) && !declaringType.IsSubclassOf(declaringType2)) { throw new ArgumentException("Field '" + fieldInfo.Name + "' does not belong to the same class as the constructor"); } if (fieldValues[num] != null && !(fieldInfo.FieldType is TypeBuilder) && !fieldInfo.FieldType.IsEnum && !fieldInfo.FieldType.IsInstanceOfType(fieldValues[num]) && !fieldInfo.FieldType.IsArray) { throw new ArgumentException(string.Concat(new object[] { "Value of field '", fieldInfo.Name, "' does not match field type: ", fieldInfo.FieldType })); } num++; } num = 0; foreach (PropertyInfo propertyInfo in namedProperties) { if (!propertyInfo.CanWrite) { throw new ArgumentException("Property '" + propertyInfo.Name + "' does not have a setter."); } Type declaringType3 = propertyInfo.DeclaringType; if (!this.IsValidType(declaringType3)) { throw new ArgumentException("Property '" + propertyInfo.Name + "' does not have a valid type."); } if (declaringType != declaringType3 && !declaringType3.IsSubclassOf(declaringType) && !declaringType.IsSubclassOf(declaringType3)) { throw new ArgumentException("Property '" + propertyInfo.Name + "' does not belong to the same class as the constructor"); } if (propertyValues[num] != null && !(propertyInfo.PropertyType is TypeBuilder) && !propertyInfo.PropertyType.IsEnum && !propertyInfo.PropertyType.IsInstanceOfType(propertyValues[num]) && !propertyInfo.PropertyType.IsArray) { throw new ArgumentException(string.Concat(new object[] { "Value of property '", propertyInfo.Name, "' does not match property type: ", propertyInfo.PropertyType, " -> ", propertyValues[num] })); } num++; } num = 0; foreach (ParameterInfo parameterInfo in CustomAttributeBuilder.GetParameters(con)) { if (parameterInfo != null) { Type parameterType = parameterInfo.ParameterType; if (!this.IsValidType(parameterType)) { throw new ArgumentException("Argument " + num + " does not have a valid type."); } if (constructorArgs[num] != null && !(parameterType is TypeBuilder) && !parameterType.IsEnum && !parameterType.IsInstanceOfType(constructorArgs[num]) && !parameterType.IsArray) { throw new ArgumentException(string.Concat(new object[] { "Value of argument ", num, " does not match parameter type: ", parameterType, " -> ", constructorArgs[num] })); } } num++; } this.data = CustomAttributeBuilder.GetBlob(declaringType.Assembly, con, constructorArgs, namedProperties, propertyValues, namedFields, fieldValues); } // Token: 0x0600192B RID: 6443 RVA: 0x00060B88 File Offset: 0x0005ED88 internal static int decode_len(byte[] data, int pos, out int rpos) { int num; if ((data[pos] & 128) == 0) { num = (int)(data[pos++] & 127); } else if ((data[pos] & 64) == 0) { num = ((int)(data[pos] & 63) << 8) + (int)data[pos + 1]; pos += 2; } else { num = ((int)(data[pos] & 31) << 24) + ((int)data[pos + 1] << 16) + ((int)data[pos + 2] << 8) + (int)data[pos + 3]; pos += 4; } rpos = pos; return num; } // Token: 0x0600192C RID: 6444 RVA: 0x00060C04 File Offset: 0x0005EE04 internal static string string_from_bytes(byte[] data, int pos, int len) { return Encoding.UTF8.GetString(data, pos, len); } // Token: 0x0600192D RID: 6445 RVA: 0x00060C14 File Offset: 0x0005EE14 internal string string_arg() { int num = 2; int num2 = CustomAttributeBuilder.decode_len(this.data, num, out num); return CustomAttributeBuilder.string_from_bytes(this.data, num, num2); } // Token: 0x0600192E RID: 6446 RVA: 0x00060C40 File Offset: 0x0005EE40 internal static UnmanagedMarshal get_umarshal(CustomAttributeBuilder customBuilder, bool is_field) { byte[] array = customBuilder.Data; UnmanagedType unmanagedType = (UnmanagedType)80; int num = -1; int num2 = -1; bool flag = false; string text = null; Type type = null; string text2 = string.Empty; int num3 = (int)array[2]; num3 |= (int)array[3] << 8; string fullName = CustomAttributeBuilder.GetParameters(customBuilder.Ctor)[0].ParameterType.FullName; int num4 = 6; if (fullName == "System.Int16") { num4 = 4; } int num5 = (int)array[num4++]; num5 |= (int)array[num4++] << 8; int i = 0; while (i < num5) { num4++; int num6 = (int)array[num4++]; if (num6 == 85) { int num7 = CustomAttributeBuilder.decode_len(array, num4, out num4); CustomAttributeBuilder.string_from_bytes(array, num4, num7); num4 += num7; } int num8 = CustomAttributeBuilder.decode_len(array, num4, out num4); string text3 = CustomAttributeBuilder.string_from_bytes(array, num4, num8); num4 += num8; string text4 = text3; if (text4 != null) { if (CustomAttributeBuilder.<>f__switch$map1C == null) { CustomAttributeBuilder.<>f__switch$map1C = new Dictionary(9) { { "ArraySubType", 0 }, { "SizeConst", 1 }, { "SafeArraySubType", 2 }, { "IidParameterIndex", 3 }, { "SafeArrayUserDefinedSubType", 4 }, { "SizeParamIndex", 5 }, { "MarshalType", 6 }, { "MarshalTypeRef", 7 }, { "MarshalCookie", 8 } }; } int num9; if (CustomAttributeBuilder.<>f__switch$map1C.TryGetValue(text4, out num9)) { switch (num9) { case 0: { int num10 = (int)array[num4++]; num10 |= (int)array[num4++] << 8; num10 |= (int)array[num4++] << 16; num10 |= (int)array[num4++] << 24; unmanagedType = (UnmanagedType)num10; break; } case 1: { int num10 = (int)array[num4++]; num10 |= (int)array[num4++] << 8; num10 |= (int)array[num4++] << 16; num10 |= (int)array[num4++] << 24; num = num10; flag = true; break; } case 2: { int num10 = (int)array[num4++]; num10 |= (int)array[num4++] << 8; num10 |= (int)array[num4++] << 16; num10 |= (int)array[num4++] << 24; unmanagedType = (UnmanagedType)num10; break; } case 3: num4 += 4; break; case 4: num8 = CustomAttributeBuilder.decode_len(array, num4, out num4); CustomAttributeBuilder.string_from_bytes(array, num4, num8); num4 += num8; break; case 5: { int num10 = (int)array[num4++]; num10 |= (int)array[num4++] << 8; num2 = num10; flag = true; break; } case 6: num8 = CustomAttributeBuilder.decode_len(array, num4, out num4); text = CustomAttributeBuilder.string_from_bytes(array, num4, num8); num4 += num8; break; case 7: num8 = CustomAttributeBuilder.decode_len(array, num4, out num4); text = CustomAttributeBuilder.string_from_bytes(array, num4, num8); type = Type.GetType(text); num4 += num8; break; case 8: num8 = CustomAttributeBuilder.decode_len(array, num4, out num4); text2 = CustomAttributeBuilder.string_from_bytes(array, num4, num8); num4 += num8; break; default: goto IL_34F; } i++; continue; } } IL_34F: throw new Exception("Unknown MarshalAsAttribute field: " + text3); } UnmanagedType unmanagedType2 = (UnmanagedType)num3; switch (unmanagedType2) { case UnmanagedType.LPArray: if (flag) { return UnmanagedMarshal.DefineLPArrayInternal(unmanagedType, num, num2); } return UnmanagedMarshal.DefineLPArray(unmanagedType); default: if (unmanagedType2 == UnmanagedType.SafeArray) { return UnmanagedMarshal.DefineSafeArray(unmanagedType); } if (unmanagedType2 != UnmanagedType.ByValArray) { if (unmanagedType2 != UnmanagedType.ByValTStr) { return UnmanagedMarshal.DefineUnmanagedMarshal((UnmanagedType)num3); } return UnmanagedMarshal.DefineByValTStr(num); } else { if (!is_field) { throw new ArgumentException("Specified unmanaged type is only valid on fields"); } return UnmanagedMarshal.DefineByValArray(num); } break; case UnmanagedType.CustomMarshaler: return UnmanagedMarshal.DefineCustom(type, text2, text, Guid.Empty); } } // Token: 0x0600192F RID: 6447 RVA: 0x0006104C File Offset: 0x0005F24C private static Type elementTypeToType(int elementType) { switch (elementType) { case 2: return typeof(bool); case 3: return typeof(char); case 4: return typeof(sbyte); case 5: return typeof(byte); case 6: return typeof(short); case 7: return typeof(ushort); case 8: return typeof(int); case 9: return typeof(uint); case 10: return typeof(long); case 11: return typeof(ulong); case 12: return typeof(float); case 13: return typeof(double); case 14: return typeof(string); default: throw new Exception("Unknown element type '" + elementType + "'"); } } // Token: 0x06001930 RID: 6448 RVA: 0x00061148 File Offset: 0x0005F348 private static object decode_cattr_value(Type t, byte[] data, int pos, out int rpos) { TypeCode typeCode = Type.GetTypeCode(t); switch (typeCode) { case TypeCode.Object: { int num = (int)data[pos]; pos++; if (num >= 2 && num <= 14) { return CustomAttributeBuilder.decode_cattr_value(CustomAttributeBuilder.elementTypeToType(num), data, pos, out rpos); } throw new Exception("Subtype '" + num + "' of type object not yet handled in decode_cattr_value"); } default: { if (typeCode == TypeCode.Int32) { rpos = pos + 4; return (int)data[pos] + ((int)data[pos + 1] << 8) + ((int)data[pos + 2] << 16) + ((int)data[pos + 3] << 24); } if (typeCode != TypeCode.String) { throw new Exception("FIXME: Type " + t + " not yet handled in decode_cattr_value."); } if (data[pos] == 255) { rpos = pos + 1; return null; } int num2 = CustomAttributeBuilder.decode_len(data, pos, out pos); rpos = pos + num2; return CustomAttributeBuilder.string_from_bytes(data, pos, num2); } case TypeCode.Boolean: rpos = pos + 1; return data[pos] != 0; } } // Token: 0x06001931 RID: 6449 RVA: 0x0006124C File Offset: 0x0005F44C internal static CustomAttributeBuilder.CustomAttributeInfo decode_cattr(CustomAttributeBuilder customBuilder) { byte[] array = customBuilder.Data; ConstructorInfo constructorInfo = customBuilder.Ctor; int num = 0; CustomAttributeBuilder.CustomAttributeInfo customAttributeInfo = default(CustomAttributeBuilder.CustomAttributeInfo); if (array.Length < 2) { throw new Exception("Custom attr length is only '" + array.Length + "'"); } if (array[0] != 1 || array[1] != 0) { throw new Exception("Prolog invalid"); } num = 2; ParameterInfo[] parameters = CustomAttributeBuilder.GetParameters(constructorInfo); customAttributeInfo.ctor = constructorInfo; customAttributeInfo.ctorArgs = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { customAttributeInfo.ctorArgs[i] = CustomAttributeBuilder.decode_cattr_value(parameters[i].ParameterType, array, num, out num); } int num2 = (int)array[num] + (int)array[num + 1] * 256; num += 2; customAttributeInfo.namedParamNames = new string[num2]; customAttributeInfo.namedParamValues = new object[num2]; for (int j = 0; j < num2; j++) { int num3 = (int)array[num++]; int num4 = (int)array[num++]; string text = null; if (num4 == 85) { int num5 = CustomAttributeBuilder.decode_len(array, num, out num); text = CustomAttributeBuilder.string_from_bytes(array, num, num5); num += num5; } int num6 = CustomAttributeBuilder.decode_len(array, num, out num); string text2 = CustomAttributeBuilder.string_from_bytes(array, num, num6); customAttributeInfo.namedParamNames[j] = text2; num += num6; if (num3 != 83) { throw new Exception("Unknown named type: " + num3); } FieldInfo field = constructorInfo.DeclaringType.GetField(text2, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { throw new Exception(string.Concat(new object[] { "Custom attribute type '", constructorInfo.DeclaringType, "' doesn't contain a field named '", text2, "'" })); } object obj = CustomAttributeBuilder.decode_cattr_value(field.FieldType, array, num, out num); if (text != null) { Type type = Type.GetType(text); obj = Enum.ToObject(type, obj); } customAttributeInfo.namedParamValues[j] = obj; } return customAttributeInfo; } // Token: 0x06001932 RID: 6450 RVA: 0x00061464 File Offset: 0x0005F664 private static ParameterInfo[] GetParameters(ConstructorInfo ctor) { ConstructorBuilder constructorBuilder = ctor as ConstructorBuilder; if (constructorBuilder != null) { return constructorBuilder.GetParametersInternal(); } return ctor.GetParameters(); } // Token: 0x04000781 RID: 1921 private ConstructorInfo ctor; // Token: 0x04000782 RID: 1922 private byte[] data; // Token: 0x020001E5 RID: 485 internal struct CustomAttributeInfo { // Token: 0x04000784 RID: 1924 public ConstructorInfo ctor; // Token: 0x04000785 RID: 1925 public object[] ctorArgs; // Token: 0x04000786 RID: 1926 public string[] namedParamNames; // Token: 0x04000787 RID: 1927 public object[] namedParamValues; } } }