Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / AddIn / AddIn / System / Addin / MiniReflection / MiniAssembly.cs / 1305376 / MiniAssembly.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================ ** ** Class: MiniAssembly ** ** Purpose: Wraps an assembly, using a managed PE reader to ** interpret the metadata. ** ===========================================================*/ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.IO; using System.Text; using System.AddIn.MiniReflection.MetadataReader; using System.Diagnostics; using System.AddIn.Hosting; using System.Diagnostics.Contracts; namespace System.AddIn.MiniReflection { [Serializable] internal sealed class MiniAssembly : MiniModule { private enum Representation { PEFileReader = 1, ReflectionAssembly = 2, } // When loading other assemblies, which directory should we look in? private List_dependencyDirs; private Representation _representation; private System.Reflection.Assembly _reflectionAssembly; private String _fullName; public MiniAssembly(String peFileName) : base(peFileName) { _dependencyDirs = new List (); _dependencyDirs.Add(Path.GetDirectoryName(peFileName)); Assembly = this; _representation = Representation.PEFileReader; } public MiniAssembly(System.Reflection.Assembly assembly) { System.Diagnostics.Contracts.Contract.Requires(assembly != null); _reflectionAssembly = assembly; _representation = Representation.ReflectionAssembly; } public List DependencyDirs { get { return _dependencyDirs; } } internal bool IsReflectionAssembly { get { return (_representation & Representation.ReflectionAssembly) != 0; } } public MiniModule[] GetModules() { // There are two forms of "multiple module" assemblies. The first is a // multi-module assembly where the assembly's ModuleRef lists multiple // different modules. The second is a multi-file assembly, where an // entry in the File metadata table refers to another file on disk and // explicitly declares the file contains metadata (and potentially types). // ALink can produce .netmodules, which seem to show up as multi-file // assemblies. MDTables metaData = _peFile.MetaData; for(uint i=0; i GetTypesWithAttribute(Type customAttribute) { return GetTypesWithAttribute(customAttribute, false); } public TypeInfo FindTypeInfo(String typeName, String nameSpace) { System.Diagnostics.Contracts.Contract.Assert(!IsReflectionAssembly); // Can be implemented using Assembly.GetType MetadataToken token = FindTypeDef(_peFile, _peFile.MetaData, typeName, nameSpace); return new TypeInfo(token, this, typeName, nameSpace); } private static MetadataToken FindTypeDef(PEFileReader peFile, MDTables mdScope, String typeName, String nameSpace) { System.Diagnostics.Contracts.Contract.Requires(typeName != null); uint numTypeDefs = mdScope.RowsInTable(MDTables.Tables.TypeDef); for (uint i = 0; i < numTypeDefs; i++) { mdScope.SeekToRowOfTable(MDTables.Tables.TypeDef, i); peFile.B.ReadUInt32(); // TypeAttributes String rowTypeName = mdScope.ReadString(); if (!String.Equals(typeName, rowTypeName)) continue; String rowNameSpace= mdScope.ReadString(); if (!String.Equals(nameSpace, rowNameSpace)) continue; return new MetadataToken(MDTables.Tables.TypeDef, i + 1); } throw new TypeLoadException(String.Format(CultureInfo.CurrentCulture, Res.CantFindTypeName, nameSpace, typeName)); } // For each module in the assembly, give back all types with the // given attribute, possibly respecting the type's visibility. public IList GetTypesWithAttribute(Type customAttribute, bool includePrivate) { if (IsDisposed) throw new ObjectDisposedException(null); if (customAttribute == null) throw new ArgumentNullException("customAttribute"); System.Diagnostics.Contracts.Contract.EndContractBlock(); List types = new List (); foreach (MiniModule module in GetModules()) { IList newTypes = module.GetTypesWithAttributeInModule(customAttribute, includePrivate); types.AddRange(newTypes); } return types; } public MiniAssembly ResolveAssemblyRef(MetadataToken token, bool throwOnError) { System.Diagnostics.Contracts.Contract.Requires(token.Table == MDTables.Tables.AssemblyRef); PEFileReader peFile = this.PEFileReader; MDTables metaData = peFile.MetaData; metaData.SeekToMDToken(token); peFile.B.ReadUInt64(); // Skip 4 parts of the version number. peFile.B.ReadUInt32(); // AssemblyFlags byte[] publicKeyOrToken = metaData.ReadBlob(); // Public key or token String assemblySimpleName = metaData.ReadString(); // simple name String cultureName = metaData.ReadString(); // assembly culture if (!String.IsNullOrEmpty(cultureName)) throw new BadImageFormatException(Res.UnexpectedlyLoadingASatellite, FullName); if (assemblySimpleName == "mscorlib" && (cultureName.Length == 0 || cultureName == "neutral")) return new MiniAssembly(typeof(Object).Assembly); MiniAssembly loadedAssembly = Open(assemblySimpleName, _dependencyDirs, throwOnError); if (loadedAssembly != null) { // Check whether the reference to the assembly matches what we actually loaded. // We don't respect the "throwOnError" parameter here because if someone does // violate this, they've either severely messed up their deployment, or they're // attempting a security exploit. System.Reflection.AssemblyName loadedAssemblyName = new System.Reflection.AssemblyName(loadedAssembly.FullName); if (!Utils.PublicKeyMatches(loadedAssemblyName, publicKeyOrToken)) { throw new FileLoadException(String.Format(CultureInfo.CurrentCulture, Res.AssemblyLoadRefDefMismatch, assemblySimpleName, publicKeyOrToken, loadedAssemblyName.GetPublicKeyToken())); } if (!String.IsNullOrEmpty(loadedAssemblyName.CultureInfo.Name)) { throw new FileLoadException(String.Format(CultureInfo.CurrentCulture, Res.AssemblyLoadRefDefMismatch, assemblySimpleName, String.Empty, loadedAssemblyName.CultureInfo.Name)); } } return loadedAssembly; } public static MiniAssembly Open(String simpleName, IList dependencyDirs, bool throwOnError) { String fileName = FindAssembly(simpleName, dependencyDirs, throwOnError); if (!throwOnError && fileName == null) return null; return new MiniAssembly(fileName); } private static String FindAssembly(String simpleName, IList searchDirs, bool throwOnError) { System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(simpleName)); System.Diagnostics.Contracts.Contract.Requires(searchDirs != null); String libName = simpleName + ".dll"; String exeName = simpleName + ".exe"; foreach (String dir in searchDirs) { String fileName = Path.Combine(dir, libName); if (File.Exists(fileName)) return fileName; fileName = Path.Combine(dir, exeName); if (File.Exists(fileName)) return fileName; } if (throwOnError) throw new FileNotFoundException(String.Format(CultureInfo.CurrentCulture, Res.FileNotFoundForInspection, simpleName), libName); else return null; } internal String FullName { get { if ((_representation & Representation.ReflectionAssembly) != 0) return AppDomain.CurrentDomain.ApplyPolicy(_reflectionAssembly.FullName); if (_fullName == null) { AssemblyInfo assemblyInfo = new AssemblyInfo(); _peFile.GetAssemblyInfo(ref assemblyInfo); _fullName = AppDomain.CurrentDomain.ApplyPolicy(assemblyInfo.ToString()); } return _fullName; } } public override bool Equals(object obj) { MiniAssembly thatAssembly = obj as MiniAssembly; if (thatAssembly == null) return false; // Note that assembly binding redirects and publisher policy will affect // versioning (ie binds to 2.0.0.0 redirected to 2.0.1.5). But for // the Orcas release, we're only planning on using our existing // directory structure, which does not have a great servicing story. // As long as we use ReflectionOnlyLoad during discovery, we should // be fetching the exact assembly on disk used to build the entire // pipeline (modulo in-place updates which must keep the same // assembly version number), and we'll load the right version // during activation time. That should work for Orcas. // Long term, we may need an approximately-equals method that gets // the assembly info and compares the version number w.r.t. policy. return Utils.AssemblyDefEqualsDef(FullName, thatAssembly.FullName); } // See the comments in Equals - we're doing string comparisons here // to compare full type names. public static bool Equals(MiniAssembly assemblyA, PEFileReader peFileB, MetadataToken assemblyRefB) { System.Diagnostics.Contracts.Contract.Requires(assemblyA != null); System.Diagnostics.Contracts.Contract.Requires(peFileB != null); System.Diagnostics.Contracts.Contract.Requires(assemblyRefB.Table == MDTables.Tables.AssemblyRef); String nameA, nameRefB; if (assemblyA.IsReflectionAssembly) nameA = AppDomain.CurrentDomain.ApplyPolicy(assemblyA._reflectionAssembly.FullName); else { AssemblyInfo assemblyInfoA = new AssemblyInfo(); assemblyA._peFile.GetAssemblyInfo(ref assemblyInfoA); nameA = AppDomain.CurrentDomain.ApplyPolicy(assemblyInfoA.ToString()); } AssemblyInfo assemblyInfoB = ReadAssemblyRef(peFileB, assemblyRefB); nameRefB = AppDomain.CurrentDomain.ApplyPolicy(assemblyInfoB.ToString()); return Utils.AssemblyRefEqualsDef(nameRefB, nameA); } private static AssemblyInfo ReadAssemblyRef(PEFileReader peFile, MetadataToken assemblyRef) { System.Diagnostics.Contracts.Contract.Requires(peFile != null); System.Diagnostics.Contracts.Contract.Requires(assemblyRef.Table == MDTables.Tables.AssemblyRef); MDTables metaData = peFile.MetaData; BinaryReader B = metaData.B; metaData.SeekToMDToken(assemblyRef); UInt16 major = B.ReadUInt16(); UInt16 minor = B.ReadUInt16(); UInt16 build = B.ReadUInt16(); UInt16 revision = B.ReadUInt16(); Version v = new Version(major, minor, build, revision); UInt32 assemblyFlags = B.ReadUInt32(); byte[] publicKey = metaData.ReadBlob(); String simpleName = metaData.ReadString(); String culture = metaData.ReadString(); if ((culture != null) && (culture.Length == 0)) culture = null; return new AssemblyInfo(v, assemblyFlags, publicKey, simpleName, culture); } public override int GetHashCode() { return FullName.GetHashCode(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== /*============================================================ ** ** Class: MiniAssembly ** ** Purpose: Wraps an assembly, using a managed PE reader to ** interpret the metadata. ** ===========================================================*/ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.IO; using System.Text; using System.AddIn.MiniReflection.MetadataReader; using System.Diagnostics; using System.AddIn.Hosting; using System.Diagnostics.Contracts; namespace System.AddIn.MiniReflection { [Serializable] internal sealed class MiniAssembly : MiniModule { private enum Representation { PEFileReader = 1, ReflectionAssembly = 2, } // When loading other assemblies, which directory should we look in? private List _dependencyDirs; private Representation _representation; private System.Reflection.Assembly _reflectionAssembly; private String _fullName; public MiniAssembly(String peFileName) : base(peFileName) { _dependencyDirs = new List (); _dependencyDirs.Add(Path.GetDirectoryName(peFileName)); Assembly = this; _representation = Representation.PEFileReader; } public MiniAssembly(System.Reflection.Assembly assembly) { System.Diagnostics.Contracts.Contract.Requires(assembly != null); _reflectionAssembly = assembly; _representation = Representation.ReflectionAssembly; } public List DependencyDirs { get { return _dependencyDirs; } } internal bool IsReflectionAssembly { get { return (_representation & Representation.ReflectionAssembly) != 0; } } public MiniModule[] GetModules() { // There are two forms of "multiple module" assemblies. The first is a // multi-module assembly where the assembly's ModuleRef lists multiple // different modules. The second is a multi-file assembly, where an // entry in the File metadata table refers to another file on disk and // explicitly declares the file contains metadata (and potentially types). // ALink can produce .netmodules, which seem to show up as multi-file // assemblies. MDTables metaData = _peFile.MetaData; for(uint i=0; i GetTypesWithAttribute(Type customAttribute) { return GetTypesWithAttribute(customAttribute, false); } public TypeInfo FindTypeInfo(String typeName, String nameSpace) { System.Diagnostics.Contracts.Contract.Assert(!IsReflectionAssembly); // Can be implemented using Assembly.GetType MetadataToken token = FindTypeDef(_peFile, _peFile.MetaData, typeName, nameSpace); return new TypeInfo(token, this, typeName, nameSpace); } private static MetadataToken FindTypeDef(PEFileReader peFile, MDTables mdScope, String typeName, String nameSpace) { System.Diagnostics.Contracts.Contract.Requires(typeName != null); uint numTypeDefs = mdScope.RowsInTable(MDTables.Tables.TypeDef); for (uint i = 0; i < numTypeDefs; i++) { mdScope.SeekToRowOfTable(MDTables.Tables.TypeDef, i); peFile.B.ReadUInt32(); // TypeAttributes String rowTypeName = mdScope.ReadString(); if (!String.Equals(typeName, rowTypeName)) continue; String rowNameSpace= mdScope.ReadString(); if (!String.Equals(nameSpace, rowNameSpace)) continue; return new MetadataToken(MDTables.Tables.TypeDef, i + 1); } throw new TypeLoadException(String.Format(CultureInfo.CurrentCulture, Res.CantFindTypeName, nameSpace, typeName)); } // For each module in the assembly, give back all types with the // given attribute, possibly respecting the type's visibility. public IList GetTypesWithAttribute(Type customAttribute, bool includePrivate) { if (IsDisposed) throw new ObjectDisposedException(null); if (customAttribute == null) throw new ArgumentNullException("customAttribute"); System.Diagnostics.Contracts.Contract.EndContractBlock(); List types = new List (); foreach (MiniModule module in GetModules()) { IList newTypes = module.GetTypesWithAttributeInModule(customAttribute, includePrivate); types.AddRange(newTypes); } return types; } public MiniAssembly ResolveAssemblyRef(MetadataToken token, bool throwOnError) { System.Diagnostics.Contracts.Contract.Requires(token.Table == MDTables.Tables.AssemblyRef); PEFileReader peFile = this.PEFileReader; MDTables metaData = peFile.MetaData; metaData.SeekToMDToken(token); peFile.B.ReadUInt64(); // Skip 4 parts of the version number. peFile.B.ReadUInt32(); // AssemblyFlags byte[] publicKeyOrToken = metaData.ReadBlob(); // Public key or token String assemblySimpleName = metaData.ReadString(); // simple name String cultureName = metaData.ReadString(); // assembly culture if (!String.IsNullOrEmpty(cultureName)) throw new BadImageFormatException(Res.UnexpectedlyLoadingASatellite, FullName); if (assemblySimpleName == "mscorlib" && (cultureName.Length == 0 || cultureName == "neutral")) return new MiniAssembly(typeof(Object).Assembly); MiniAssembly loadedAssembly = Open(assemblySimpleName, _dependencyDirs, throwOnError); if (loadedAssembly != null) { // Check whether the reference to the assembly matches what we actually loaded. // We don't respect the "throwOnError" parameter here because if someone does // violate this, they've either severely messed up their deployment, or they're // attempting a security exploit. System.Reflection.AssemblyName loadedAssemblyName = new System.Reflection.AssemblyName(loadedAssembly.FullName); if (!Utils.PublicKeyMatches(loadedAssemblyName, publicKeyOrToken)) { throw new FileLoadException(String.Format(CultureInfo.CurrentCulture, Res.AssemblyLoadRefDefMismatch, assemblySimpleName, publicKeyOrToken, loadedAssemblyName.GetPublicKeyToken())); } if (!String.IsNullOrEmpty(loadedAssemblyName.CultureInfo.Name)) { throw new FileLoadException(String.Format(CultureInfo.CurrentCulture, Res.AssemblyLoadRefDefMismatch, assemblySimpleName, String.Empty, loadedAssemblyName.CultureInfo.Name)); } } return loadedAssembly; } public static MiniAssembly Open(String simpleName, IList dependencyDirs, bool throwOnError) { String fileName = FindAssembly(simpleName, dependencyDirs, throwOnError); if (!throwOnError && fileName == null) return null; return new MiniAssembly(fileName); } private static String FindAssembly(String simpleName, IList searchDirs, bool throwOnError) { System.Diagnostics.Contracts.Contract.Requires(!String.IsNullOrEmpty(simpleName)); System.Diagnostics.Contracts.Contract.Requires(searchDirs != null); String libName = simpleName + ".dll"; String exeName = simpleName + ".exe"; foreach (String dir in searchDirs) { String fileName = Path.Combine(dir, libName); if (File.Exists(fileName)) return fileName; fileName = Path.Combine(dir, exeName); if (File.Exists(fileName)) return fileName; } if (throwOnError) throw new FileNotFoundException(String.Format(CultureInfo.CurrentCulture, Res.FileNotFoundForInspection, simpleName), libName); else return null; } internal String FullName { get { if ((_representation & Representation.ReflectionAssembly) != 0) return AppDomain.CurrentDomain.ApplyPolicy(_reflectionAssembly.FullName); if (_fullName == null) { AssemblyInfo assemblyInfo = new AssemblyInfo(); _peFile.GetAssemblyInfo(ref assemblyInfo); _fullName = AppDomain.CurrentDomain.ApplyPolicy(assemblyInfo.ToString()); } return _fullName; } } public override bool Equals(object obj) { MiniAssembly thatAssembly = obj as MiniAssembly; if (thatAssembly == null) return false; // Note that assembly binding redirects and publisher policy will affect // versioning (ie binds to 2.0.0.0 redirected to 2.0.1.5). But for // the Orcas release, we're only planning on using our existing // directory structure, which does not have a great servicing story. // As long as we use ReflectionOnlyLoad during discovery, we should // be fetching the exact assembly on disk used to build the entire // pipeline (modulo in-place updates which must keep the same // assembly version number), and we'll load the right version // during activation time. That should work for Orcas. // Long term, we may need an approximately-equals method that gets // the assembly info and compares the version number w.r.t. policy. return Utils.AssemblyDefEqualsDef(FullName, thatAssembly.FullName); } // See the comments in Equals - we're doing string comparisons here // to compare full type names. public static bool Equals(MiniAssembly assemblyA, PEFileReader peFileB, MetadataToken assemblyRefB) { System.Diagnostics.Contracts.Contract.Requires(assemblyA != null); System.Diagnostics.Contracts.Contract.Requires(peFileB != null); System.Diagnostics.Contracts.Contract.Requires(assemblyRefB.Table == MDTables.Tables.AssemblyRef); String nameA, nameRefB; if (assemblyA.IsReflectionAssembly) nameA = AppDomain.CurrentDomain.ApplyPolicy(assemblyA._reflectionAssembly.FullName); else { AssemblyInfo assemblyInfoA = new AssemblyInfo(); assemblyA._peFile.GetAssemblyInfo(ref assemblyInfoA); nameA = AppDomain.CurrentDomain.ApplyPolicy(assemblyInfoA.ToString()); } AssemblyInfo assemblyInfoB = ReadAssemblyRef(peFileB, assemblyRefB); nameRefB = AppDomain.CurrentDomain.ApplyPolicy(assemblyInfoB.ToString()); return Utils.AssemblyRefEqualsDef(nameRefB, nameA); } private static AssemblyInfo ReadAssemblyRef(PEFileReader peFile, MetadataToken assemblyRef) { System.Diagnostics.Contracts.Contract.Requires(peFile != null); System.Diagnostics.Contracts.Contract.Requires(assemblyRef.Table == MDTables.Tables.AssemblyRef); MDTables metaData = peFile.MetaData; BinaryReader B = metaData.B; metaData.SeekToMDToken(assemblyRef); UInt16 major = B.ReadUInt16(); UInt16 minor = B.ReadUInt16(); UInt16 build = B.ReadUInt16(); UInt16 revision = B.ReadUInt16(); Version v = new Version(major, minor, build, revision); UInt32 assemblyFlags = B.ReadUInt32(); byte[] publicKey = metaData.ReadBlob(); String simpleName = metaData.ReadString(); String culture = metaData.ReadString(); if ((culture != null) && (culture.Length == 0)) culture = null; return new AssemblyInfo(v, assemblyFlags, publicKey, simpleName, culture); } public override int GetHashCode() { return FullName.GetHashCode(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TraceSection.cs
- DeclarativeCatalogPartDesigner.cs
- TextServicesLoader.cs
- DatagridviewDisplayedBandsData.cs
- ColumnHeader.cs
- NotEqual.cs
- XmlIterators.cs
- OdbcConnectionString.cs
- DataGridViewCellPaintingEventArgs.cs
- ObjectConverter.cs
- HtmlTableRow.cs
- ExtendedProtectionPolicyTypeConverter.cs
- ManagementObjectCollection.cs
- XmlSchemaObjectCollection.cs
- ExpressionConverter.cs
- MetadataArtifactLoaderCompositeFile.cs
- SelectionPattern.cs
- ProcessActivityTreeOptions.cs
- CategoryEditor.cs
- DesignTable.cs
- RoutedCommand.cs
- InOutArgument.cs
- AlignmentXValidation.cs
- AlignmentYValidation.cs
- PageRouteHandler.cs
- SqlHelper.cs
- XmlAttribute.cs
- ValidationHelpers.cs
- FileDialogCustomPlace.cs
- BorderGapMaskConverter.cs
- String.cs
- RadioButtonRenderer.cs
- PagesChangedEventArgs.cs
- AdornerLayer.cs
- ImageAttributes.cs
- XmlDataSourceNodeDescriptor.cs
- ClientBuildManager.cs
- FormViewModeEventArgs.cs
- Scripts.cs
- DataSourceXmlSerializationAttribute.cs
- RelationshipType.cs
- MessageDroppedTraceRecord.cs
- XmlDataSourceNodeDescriptor.cs
- UnionCqlBlock.cs
- DataExpression.cs
- QueryCursorEventArgs.cs
- MSHTMLHostUtil.cs
- Win32SafeHandles.cs
- Registry.cs
- RequestContext.cs
- CqlIdentifiers.cs
- ActiveXHost.cs
- BasicBrowserDialog.cs
- KeyValuePair.cs
- TraceProvider.cs
- MouseEventArgs.cs
- ConfigPathUtility.cs
- SafeLocalMemHandle.cs
- ServicePoint.cs
- FileVersion.cs
- CodeTypeMemberCollection.cs
- SafeMILHandle.cs
- InkSerializer.cs
- ConnectionStringEditor.cs
- WebPartsPersonalizationAuthorization.cs
- FormConverter.cs
- CodeDirectiveCollection.cs
- ConsumerConnectionPointCollection.cs
- ValidatorCollection.cs
- Script.cs
- ThrowHelper.cs
- ToolStripDropDownClosingEventArgs.cs
- PeerToPeerException.cs
- ProfileParameter.cs
- XmlKeywords.cs
- BoolExpression.cs
- mansign.cs
- MobileErrorInfo.cs
- TypeUtils.cs
- OpacityConverter.cs
- ToolStripDropDownButton.cs
- input.cs
- _ListenerAsyncResult.cs
- _OSSOCK.cs
- ConnectionPointCookie.cs
- X509ChainElement.cs
- ParserContext.cs
- XsltException.cs
- Calendar.cs
- AnnotationService.cs
- RightNameExpirationInfoPair.cs
- SemanticKeyElement.cs
- Compiler.cs
- RuleInfoComparer.cs
- JavaScriptObjectDeserializer.cs
- ListControl.cs
- ResizeGrip.cs
- Application.cs
- SqlIdentifier.cs
- PolyQuadraticBezierSegmentFigureLogic.cs