internal TType DecodeFieldSignature <TType>(ISignatureTypeProvider <TType> provider) { var decoder = new SignatureDecoder <TType>(provider, _reader); var blobReader = _reader.GetBlobReader(Signature); return(decoder.DecodeFieldSignature(ref blobReader)); }
public MethodSignature <TType> DecodeMethodSignature <TType>(ISignatureTypeProvider <TType> provider) { var decoder = new SignatureDecoder <TType>(provider, _reader); var blobReader = _reader.GetBlobReader(Signature); return(decoder.DecodeMethodSignature(ref blobReader)); }
public TType DecodeFieldSignature <TType, TGenericContext>(ISignatureTypeProvider <TType, TGenericContext> provider, TGenericContext genericContext) { var decoder = new SignatureDecoder <TType, TGenericContext>(provider, _reader, genericContext); var blobReader = _reader.GetBlobReader(Signature); return(decoder.DecodeFieldSignature(ref blobReader)); }
TType DecodeFieldSignature <TType>(ISignatureTypeProvider <TType> provider, SignatureDecoderOptions options = SignatureDecoderOptions.None) { var decoder = new SignatureDecoder <TType>(provider, _reader, options); var blobReader = _reader.GetBlobReader(Signature); return(decoder.DecodeFieldSignature(ref blobReader)); }
/// <summary> /// Gets the fixed (required) string arguments of a custom attribute. /// Only attributes that have only fixed string arguments. /// </summary> private static List<string> GetFixedStringArguments(MetadataReader reader, CustomAttribute attribute) { // TODO: Nick Guerrera ([email protected]) hacked this method for temporary use. // There is a blob decoder feature in progress but it won't ship in time for our milestone. // Replace this method with the blob decoder feature when later it is availale. var signature = reader.GetMemberReference((MemberReferenceHandle)attribute.Constructor).Signature; var signatureReader = reader.GetBlobReader(signature); var valueReader = reader.GetBlobReader(attribute.Value); var arguments = new List<string>(); var prolog = valueReader.ReadUInt16(); if (prolog != 1) { // Invalid custom attribute prolog return arguments; } var header = signatureReader.ReadSignatureHeader(); if (header.Kind != SignatureKind.Method || header.IsGeneric) { // Invalid custom attribute constructor signature return arguments; } int parameterCount; if (!signatureReader.TryReadCompressedInteger(out parameterCount)) { // Invalid custom attribute constructor signature return arguments; } var returnType = signatureReader.ReadSignatureTypeCode(); if (returnType != SignatureTypeCode.Void) { // Invalid custom attribute constructor signature return arguments; } for (int i = 0; i < parameterCount; i++) { var signatureTypeCode = signatureReader.ReadSignatureTypeCode(); if (signatureTypeCode == SignatureTypeCode.String) { // Custom attribute constructor must take only strings arguments.Add(valueReader.ReadSerializedString()); } } return arguments; }
internal ImmutableArray <TType> DecodeSignature <TType>(ISignatureTypeProvider <TType> provider) { var decoder = new Ecma335.SignatureDecoder <TType>(provider, _reader); var blobReader = _reader.GetBlobReader(Signature); return(decoder.DecodeMethodSpecificationSignature(ref blobReader)); }
public ImmutableArray <TType> DecodeSignature <TType, TGenericContext>(ISignatureTypeProvider <TType, TGenericContext> provider, TGenericContext genericContext) { var decoder = new Ecma335.SignatureDecoder <TType, TGenericContext>(provider, _reader, genericContext); var blobReader = _reader.GetBlobReader(Signature); return(decoder.DecodeMethodSpecificationSignature(ref blobReader)); }
public ImmutableArray <TType> DecodeSignature <TType>(ISignatureTypeProvider <TType> provider, SignatureDecoderOptions options = SignatureDecoderOptions.None) { var decoder = new SignatureDecoder <TType>(provider, _reader, options); var blobReader = _reader.GetBlobReader(Signature); return(decoder.DecodeMethodSpecificationSignature(ref blobReader)); }
/// <summary> /// Construct the strong assembly name from metadata /// </summary> internal static string GetAssemblyStrongName(MetadataReader metadataReader) { AssemblyDefinition assemblyDefinition = metadataReader.GetAssemblyDefinition(); string asmName = metadataReader.GetString(assemblyDefinition.Name); string asmVersion = assemblyDefinition.Version.ToString(); string asmCulture = metadataReader.GetString(assemblyDefinition.Culture); asmCulture = (asmCulture == string.Empty) ? "neutral" : asmCulture; AssemblyHashAlgorithm hashAlgorithm = assemblyDefinition.HashAlgorithm; BlobHandle blobHandle = assemblyDefinition.PublicKey; BlobReader blobReader = metadataReader.GetBlobReader(blobHandle); string publicKeyTokenString = "null"; // Extract public key token only if PublicKey exists in the metadata if (blobReader.Length > 0) { byte[] publickey = blobReader.ReadBytes(blobReader.Length); HashAlgorithm hashImpl = null; switch (hashAlgorithm) { case AssemblyHashAlgorithm.Sha1: hashImpl = SHA1.Create(); break; case AssemblyHashAlgorithm.MD5: hashImpl = MD5.Create(); break; case AssemblyHashAlgorithm.Sha256: hashImpl = SHA256.Create(); break; case AssemblyHashAlgorithm.Sha384: hashImpl = SHA384.Create(); break; case AssemblyHashAlgorithm.Sha512: hashImpl = SHA512.Create(); break; default: throw new NotSupportedException(); } byte[] publicKeyHash = hashImpl.ComputeHash(publickey); byte[] publicKeyTokenBytes = new byte[8]; // Note that, the low 8 bytes of the hash of public key in reverse order is the public key tokens. for (int i = 1; i <= 8; i++) { publicKeyTokenBytes[i - 1] = publicKeyHash[publicKeyHash.Length - i]; } // Convert bytes to hex format strings in lower case. publicKeyTokenString = BitConverter.ToString(publicKeyTokenBytes).Replace("-", string.Empty).ToLowerInvariant(); } string strongAssemblyName = string.Format(CultureInfo.InvariantCulture, "{0}, Version={1}, Culture={2}, PublicKeyToken={3}", asmName, asmVersion, asmCulture, publicKeyTokenString); return strongAssemblyName; }
private BlobHandle GetProjectedValue(CustomAttributeValueTreatment treatment) { BlobHandle.VirtualIndex virtualIndex; bool isVersionOrDeprecated; switch (treatment) { case CustomAttributeValueTreatment.AttributeUsageVersionAttribute: case CustomAttributeValueTreatment.AttributeUsageDeprecatedAttribute: virtualIndex = BlobHandle.VirtualIndex.AttributeUsage_AllowMultiple; isVersionOrDeprecated = true; break; case CustomAttributeValueTreatment.AttributeUsageAllowMultiple: virtualIndex = BlobHandle.VirtualIndex.AttributeUsage_AllowMultiple; isVersionOrDeprecated = false; break; case CustomAttributeValueTreatment.AttributeUsageAllowSingle: virtualIndex = BlobHandle.VirtualIndex.AttributeUsage_AllowSingle; isVersionOrDeprecated = false; break; default: Debug.Assert(false); return(default(BlobHandle)); } // Raw blob format: // 01 00 - Fixed prolog for CA's // xx xx xx xx - The Windows.Foundation.Metadata.AttributeTarget value // 00 00 - Indicates 0 name/value pairs following. var rawBlob = _reader.CustomAttributeTable.GetValue(Handle); var rawBlobReader = _reader.GetBlobReader(rawBlob); if (rawBlobReader.Length != 8) { return(rawBlob); } if (rawBlobReader.ReadInt16() != 1) { return(rawBlob); } AttributeTargets projectedValue = ProjectAttributeTargetValue(rawBlobReader.ReadUInt32()); if (isVersionOrDeprecated) { projectedValue |= AttributeTargets.Constructor | AttributeTargets.Property; } return(BlobHandle.FromVirtualIndex(virtualIndex, (ushort)projectedValue)); }
private static string GetFileName(MetadataReader reader, DocumentHandle documentHandle) { var document = reader.GetDocument(documentHandle); if (document.Name.IsNil) { return null; } var nameReader = reader.GetBlobReader(document.Name); int separator = nameReader.ReadByte(); if (!FileNameUtilities.IsDirectorySeparator((char)separator)) { return FileNameUtilities.GetFileName(reader.GetString(document.Name)); } // find the last part handle: BlobHandle partHandle = default(BlobHandle); while (nameReader.RemainingBytes > 0) { partHandle = nameReader.ReadBlobHandle(); } if (partHandle.IsNil) { return string.Empty; } var partReader = reader.GetBlobReader(partHandle); var part = partReader.ReadUTF8(partReader.Length); if (part.IndexOf('\0') >= 0) { // bad metadata return null; } // it is valid to encode document name so that the parts contain directory separators: return FileNameUtilities.GetFileName(part); }
private static string GetMetadataNameWithoutBackticks(MetadataReader reader, StringHandle name) { var blobReader = reader.GetBlobReader(name); var backtickIndex = blobReader.IndexOf((byte)'`'); if (backtickIndex == -1) { return reader.GetString(name); } unsafe { return MetadataStringDecoder.DefaultUTF8.GetString( blobReader.CurrentPointer, backtickIndex); } }
/// <summary> /// Determines if the member reference is to a method or field. /// </summary> public MemberReferenceKind GetKind() { BlobReader blobReader = reader.GetBlobReader(this.Signature); SignatureHeader header = blobReader.ReadSignatureHeader(); switch (header.Kind) { case SignatureKind.Method: return(MemberReferenceKind.Method); case SignatureKind.Field: return(MemberReferenceKind.Field); default: throw new BadImageFormatException(); } }
private string GetPublicKeyToken() { string publicKeyToken = null; AssemblyDefinition ad = _reader.GetAssemblyDefinition(); BlobReader br = _reader.GetBlobReader(ad.PublicKey); byte[] pk = br.ReadBytes(br.Length); if (pk.Length != 0) { AssemblyName an = new AssemblyName(); an.SetPublicKey(pk); byte[] pkt = an.GetPublicKeyToken(); publicKeyToken = BitConverter.ToString(pkt).Replace("-", ""); } if (!String.IsNullOrEmpty(publicKeyToken)) { publicKeyToken = publicKeyToken.ToUpperInvariant(); } return(publicKeyToken); }
/// <summary>Gets the string argument value of an attribute with a single fixed string argument.</summary> /// <param name="reader">The metadata reader.</param> /// <param name="attr">The attribute.</param> /// <param name="value">The value parsed from the attribute, if it could be retrieved; otherwise, the value is left unmodified.</param> private static void GetStringAttributeArgumentValue(MetadataReader reader, CustomAttribute attr, ref string value) { EntityHandle ctorHandle = attr.Constructor; BlobHandle signature; switch (ctorHandle.Kind) { case HandleKind.MemberReference: signature = reader.GetMemberReference((MemberReferenceHandle)ctorHandle).Signature; break; case HandleKind.MethodDefinition: signature = reader.GetMethodDefinition((MethodDefinitionHandle)ctorHandle).Signature; break; default: // Unusual case, potentially invalid IL return; } BlobReader signatureReader = reader.GetBlobReader(signature); BlobReader valueReader = reader.GetBlobReader(attr.Value); const ushort Prolog = 1; // two-byte "prolog" defined by ECMA-335 (II.23.3) to be at the beginning of attribute value blobs if (valueReader.ReadUInt16() == Prolog) { SignatureHeader header = signatureReader.ReadSignatureHeader(); int parameterCount; if (header.Kind == SignatureKind.Method && // attr ctor must be a method !header.IsGeneric && // attr ctor must be non-generic signatureReader.TryReadCompressedInteger(out parameterCount) && // read parameter count parameterCount == 1 && // attr ctor must have 1 parameter signatureReader.ReadSignatureTypeCode() == SignatureTypeCode.Void && // attr ctor return type must be void signatureReader.ReadSignatureTypeCode() == SignatureTypeCode.String) // attr ctor first parameter must be string { value = valueReader.ReadSerializedString(); } } }
private Property HandleProperty(Cts.Ecma.EcmaModule module, Ecma.PropertyDefinitionHandle property) { Ecma.MetadataReader reader = module.MetadataReader; Ecma.PropertyDefinition propDef = reader.GetPropertyDefinition(property); Ecma.PropertyAccessors acc = propDef.GetAccessors(); Cts.MethodDesc getterMethod = acc.Getter.IsNil ? null : module.GetMethod(acc.Getter); Cts.MethodDesc setterMethod = acc.Setter.IsNil ? null : module.GetMethod(acc.Setter); bool getterHasMetadata = getterMethod != null && _policy.GeneratesMetadata(getterMethod); bool setterHasMetadata = setterMethod != null && _policy.GeneratesMetadata(setterMethod); // Policy: If neither the getter nor setter have metadata, property doesn't have metadata if (!getterHasMetadata && !setterHasMetadata) { return(null); } Ecma.BlobReader sigBlobReader = reader.GetBlobReader(propDef.Signature); Cts.PropertySignature sig = new Cts.Ecma.EcmaSignatureParser(module, sigBlobReader, Cts.NotFoundBehavior.Throw).ParsePropertySignature(); Property result = new Property { Name = HandleString(reader.GetString(propDef.Name)), Flags = propDef.Attributes, Signature = new PropertySignature { CallingConvention = sig.IsStatic ? CallingConventions.Standard : CallingConventions.HasThis, Type = HandleType(sig.ReturnType) }, }; result.Signature.Parameters.Capacity = sig.Length; for (int i = 0; i < sig.Length; i++) { result.Signature.Parameters.Add(HandleType(sig[i])); } if (getterHasMetadata) { result.MethodSemantics.Add(new MethodSemantics { Attributes = MethodSemanticsAttributes.Getter, Method = HandleMethodDefinition(getterMethod), }); } if (setterHasMetadata) { result.MethodSemantics.Add(new MethodSemantics { Attributes = MethodSemanticsAttributes.Setter, Method = HandleMethodDefinition(setterMethod), }); } Ecma.ConstantHandle defaultValue = propDef.GetDefaultValue(); if (!defaultValue.IsNil) { result.DefaultValue = HandleConstant(module, defaultValue); } Ecma.CustomAttributeHandleCollection customAttributes = propDef.GetCustomAttributes(); if (customAttributes.Count > 0) { result.CustomAttributes = HandleCustomAttributes(module, customAttributes); } return(result); }
private string GetAttributeArgument(CustomAttribute attribute, MetadataReader metadataReader) { var signature = metadataReader.GetMemberReference((MemberReferenceHandle)attribute.Constructor).Signature; var signatureReader = metadataReader.GetBlobReader(signature); var valueReader = metadataReader.GetBlobReader(attribute.Value); valueReader.ReadUInt16(); // Skip prolog signatureReader.ReadSignatureHeader(); // Skip header int parameterCount; signatureReader.TryReadCompressedInteger(out parameterCount); signatureReader.ReadSignatureTypeCode(); // Skip return type for (int i = 0; i < parameterCount; i++) { var signatureTypeCode = signatureReader.ReadSignatureTypeCode(); if (signatureTypeCode == SignatureTypeCode.String) { return valueReader.ReadSerializedString(); } } return string.Empty; }
private MetadataRecord HandleConstant(Cts.Ecma.EcmaModule module, Ecma.ConstantHandle constantHandle) { Ecma.MetadataReader reader = module.MetadataReader; Ecma.Constant constant = reader.GetConstant(constantHandle); Ecma.BlobReader blob = reader.GetBlobReader(constant.Value); switch (constant.TypeCode) { case ConstantTypeCode.Boolean: return(new ConstantBooleanValue { Value = blob.ReadBoolean() }); case ConstantTypeCode.Byte: return(new ConstantByteValue { Value = blob.ReadByte() }); case ConstantTypeCode.Char: return(new ConstantCharValue { Value = blob.ReadChar() }); case ConstantTypeCode.Double: return(new ConstantDoubleValue { Value = blob.ReadDouble() }); case ConstantTypeCode.Int16: return(new ConstantInt16Value { Value = blob.ReadInt16() }); case ConstantTypeCode.Int32: return(new ConstantInt32Value { Value = blob.ReadInt32() }); case ConstantTypeCode.Int64: return(new ConstantInt64Value { Value = blob.ReadInt64() }); case ConstantTypeCode.SByte: return(new ConstantSByteValue { Value = blob.ReadSByte() }); case ConstantTypeCode.Single: return(new ConstantSingleValue { Value = blob.ReadSingle() }); case ConstantTypeCode.String: return(HandleString(blob.ReadUTF16(blob.Length))); case ConstantTypeCode.UInt16: return(new ConstantUInt16Value { Value = blob.ReadUInt16() }); case ConstantTypeCode.UInt32: return(new ConstantUInt32Value { Value = blob.ReadUInt32() }); case ConstantTypeCode.UInt64: return(new ConstantUInt64Value { Value = blob.ReadUInt64() }); case ConstantTypeCode.NullReference: return(new ConstantReferenceValue()); default: throw new BadImageFormatException(); } }
private Property HandleProperty(Cts.Ecma.EcmaModule module, Ecma.PropertyDefinitionHandle property) { Ecma.MetadataReader reader = module.MetadataReader; Ecma.PropertyDefinition propDef = reader.GetPropertyDefinition(property); Ecma.PropertyAccessors acc = propDef.GetAccessors(); Cts.MethodDesc getterMethod = acc.Getter.IsNil ? null : module.GetMethod(acc.Getter); Cts.MethodDesc setterMethod = acc.Setter.IsNil ? null : module.GetMethod(acc.Setter); bool getterHasMetadata = getterMethod != null && _policy.GeneratesMetadata(getterMethod); bool setterHasMetadata = setterMethod != null && _policy.GeneratesMetadata(setterMethod); // Policy: If neither the getter nor setter have metadata, property doesn't have metadata if (!getterHasMetadata && !setterHasMetadata) { return(null); } Ecma.BlobReader sigBlobReader = reader.GetBlobReader(propDef.Signature); Cts.PropertySignature sig = new Cts.Ecma.EcmaSignatureParser(module, sigBlobReader).ParsePropertySignature(); List <ParameterTypeSignature> parameters; if (sig.Length == 0) { parameters = null; } else { parameters = new List <ParameterTypeSignature>(sig.Length); for (int i = 0; i < parameters.Count; i++) { parameters.Add(HandleParameterTypeSignature(sig[i])); } } Property result = new Property { Name = HandleString(reader.GetString(propDef.Name)), Flags = propDef.Attributes, Signature = new PropertySignature { CallingConvention = sig.IsStatic ? CallingConventions.Standard : CallingConventions.HasThis, // TODO: CustomModifiers Type = HandleType(sig.ReturnType), Parameters = parameters, }, }; if (getterHasMetadata) { result.MethodSemantics.Add(new MethodSemantics { Attributes = MethodSemanticsAttributes.Getter, Method = HandleMethodDefinition(getterMethod), }); } if (setterHasMetadata) { result.MethodSemantics.Add(new MethodSemantics { Attributes = MethodSemanticsAttributes.Setter, Method = HandleMethodDefinition(setterMethod), }); } // TODO: DefaultValue // TODO: CustomAttributes return(result); }