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
- ProfileSection.cs
- SecureEnvironment.cs
- MethodBody.cs
- SessionEndingEventArgs.cs
- SettingsPropertyCollection.cs
- BitmapEffectGroup.cs
- DataGrid.cs
- UserControlAutomationPeer.cs
- FileFormatException.cs
- ProcessRequestArgs.cs
- QilLoop.cs
- WebPartManagerInternals.cs
- CodeDelegateInvokeExpression.cs
- ListViewAutomationPeer.cs
- StsCommunicationException.cs
- EntityDataSource.cs
- SecurityTokenReferenceStyle.cs
- QueryableDataSource.cs
- KeyValuePair.cs
- RequestCachePolicy.cs
- BoundField.cs
- Light.cs
- XmlSchemaImport.cs
- ComplusEndpointConfigContainer.cs
- JumpTask.cs
- metadatamappinghashervisitor.hashsourcebuilder.cs
- TypeExtension.cs
- DataGridPagerStyle.cs
- ToolStripItemEventArgs.cs
- StaticExtension.cs
- RoutedEventConverter.cs
- XamlVector3DCollectionSerializer.cs
- BehaviorEditorPart.cs
- XXXOnTypeBuilderInstantiation.cs
- UpdatePanel.cs
- WsrmTraceRecord.cs
- TabControl.cs
- TimeSpanOrInfiniteValidator.cs
- Rect.cs
- DynamicActivityXamlReader.cs
- Int32Animation.cs
- Base64Decoder.cs
- RectangleGeometry.cs
- Size.cs
- XamlStyleSerializer.cs
- InvocationExpression.cs
- DataControlButton.cs
- ManipulationLogic.cs
- Single.cs
- SQLMembershipProvider.cs
- SafeHandles.cs
- OptimizedTemplateContentHelper.cs
- CompositionAdorner.cs
- ImageUrlEditor.cs
- ObjectPersistData.cs
- SetStoryboardSpeedRatio.cs
- TagPrefixCollection.cs
- DataGrid.cs
- SymmetricAlgorithm.cs
- SponsorHelper.cs
- DescendantQuery.cs
- Base64Encoder.cs
- Attributes.cs
- COM2EnumConverter.cs
- WindowsClientElement.cs
- CodeAccessPermission.cs
- ToolboxCategory.cs
- XmlUTF8TextWriter.cs
- DateTimeUtil.cs
- peersecurityelement.cs
- ToolStripSeparator.cs
- FileAuthorizationModule.cs
- CheckPair.cs
- TabItemAutomationPeer.cs
- ToolStripDesignerUtils.cs
- GridEntry.cs
- MgmtResManager.cs
- FuncCompletionCallbackWrapper.cs
- XmlSerializerVersionAttribute.cs
- SettingsPropertyIsReadOnlyException.cs
- AddressAlreadyInUseException.cs
- ExecutionEngineException.cs
- DiscoveryRequestHandler.cs
- BuildProviderAppliesToAttribute.cs
- BuiltInExpr.cs
- JsonDataContract.cs
- ImmutableObjectAttribute.cs
- WebPartEditorApplyVerb.cs
- LoginStatusDesigner.cs
- GridViewColumn.cs
- RbTree.cs
- PointAnimationUsingPath.cs
- ClockGroup.cs
- IItemContainerGenerator.cs
- PixelFormats.cs
- XmlQueryCardinality.cs
- HwndHostAutomationPeer.cs
- BinaryMethodMessage.cs
- RMPublishingDialog.cs
- Shape.cs