/// <summary> /// Returns the original location of the corresponding assembly if available, otherwise returns the location of the shadow copy. /// If the corresponding assembly is not in the GAC, null is returned. /// </summary> public static string /*?*/ GetLocation(AssemblyIdentity assemblyIdentity, IMetadataHost metadataHost) { lock (GlobalLock.LockingObject) { #if COMPACTFX var gacKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"\Software\Microsoft\.NETCompactFramework\Installer\Assemblies\Global"); foreach (var gacName in gacKey.GetValueNames()) { if (IdentityMatchesString(assemblyIdentity, gacName)) { var values = gacKey.GetValue(gacName) as string[]; if (values == null || values.Length == 0) { continue; } return(values[0]); } } return(null); #elif COREFX_SUBSET return(null); #else #if __MonoCS__ IAssemblyEnum assemblyEnum = new MonoAssemblyEnum(); #else if (!GlobalAssemblyCache.FusionLoaded) { GlobalAssemblyCache.FusionLoaded = true; var systemAssembly = typeof(object).Assembly; var systemAssemblyLocation = systemAssembly.Location; var dir = Path.GetDirectoryName(systemAssemblyLocation) ?? ""; GlobalAssemblyCache.LoadLibrary(Path.Combine(dir, "fusion.dll")); } IAssemblyEnum assemblyEnum; int rc = CreateAssemblyEnum(out assemblyEnum, null, null, ASM_CACHE.GAC, 0); if (rc < 0 || assemblyEnum == null) { return(null); } #endif IApplicationContext applicationContext; IAssemblyName currentName; while (assemblyEnum.GetNextAssembly(out applicationContext, out currentName, 0) == 0) { //^ assume currentName != null; AssemblyName cn = new AssemblyName(currentName); if (assemblyIdentity.Equals(new AssemblyIdentity(metadataHost.NameTable.GetNameFor(cn.Name), cn.Culture, cn.Version, cn.PublicKeyToken, ""))) { string codeBase = cn.CodeBase; if (codeBase != null && codeBase.StartsWith("file://", StringComparison.OrdinalIgnoreCase)) { Uri u = new Uri(codeBase, UriKind.Absolute); return(u.LocalPath); } return(cn.GetLocation()); } } return(null); #endif } }
/// <summary> /// Returns the original location of the corresponding assembly if available, otherwise returns the location of the shadow copy. /// If the corresponding assembly is not in the GAC, null is returned. /// </summary> public static string /*?*/ GetLocation(AssemblyIdentity assemblyIdentity, IMetadataHost metadataHost) { lock (GlobalLock.LockingObject) { if (!GlobalAssemblyCache.s_fusionLoaded) { GlobalAssemblyCache.s_fusionLoaded = true; System.Reflection.Assembly systemAssembly = typeof(object).Assembly; //^ assume systemAssembly != null; string /*?*/ systemAssemblyLocation = systemAssembly.Location; //^ assume systemAssemblyLocation != null; string dir = Path.GetDirectoryName(systemAssemblyLocation); //^ assume dir != null; GlobalAssemblyCache.LoadLibrary(Path.Combine(dir, "fusion.dll")); } IAssemblyEnum assemblyEnum; CreateAssemblyEnum(out assemblyEnum, null, null, ASM_CACHE.GAC, 0); if (assemblyEnum == null) { return(null); } IApplicationContext applicationContext; IAssemblyName currentName; while (assemblyEnum.GetNextAssembly(out applicationContext, out currentName, 0) == 0) { //^ assume currentName != null; AssemblyName assemblyName = new AssemblyName(currentName); string /*?*/ location = assemblyName.GetLocation(); if (location == null) { location = string.Empty; } if (assemblyIdentity.Equals(new AssemblyIdentity(metadataHost.NameTable.GetNameFor(assemblyName.Name), assemblyName.Culture, assemblyName.Version, assemblyName.PublicKeyToken, location))) { string codeBase = assemblyName.CodeBase; if (codeBase != null && codeBase.StartsWith("file:///")) { return(codeBase.Substring(8)); } return(assemblyName.GetLocation()); } } return(null); } }
/// <summary> /// Returns true if the given object is an identifier that identifies the same object as this identifier. /// </summary> //^ [Confined] public override bool Equals(object /*?*/ obj) { if (obj == (object)this) { return(true); } ModuleIdentity /*?*/ otherMod = obj as ModuleIdentity; if (otherMod == null) { return(false); } if (_containingAssembly == null) { if (otherMod.ContainingAssembly != null) { return(false); } } else { if (otherMod.ContainingAssembly == null) { return(false); } if (!_containingAssembly.Equals(otherMod._containingAssembly)) { return(false); } } if (this.Name.UniqueKeyIgnoringCase != otherMod.Name.UniqueKeyIgnoringCase) { return(false); } if (_containingAssembly != null) { return(true); } return(string.Compare(this.Location, otherMod.Location, StringComparison.OrdinalIgnoreCase) == 0); }
AssemblyStore GetAssemblyStore(AssemblyIdentity assemblyIdentity) { Contract.Requires(assemblyIdentity != null); Contract.Ensures(Contract.Result<AssemblyStore>() != null); IName assemblyName = assemblyIdentity.Name; foreach (AssemblyStore aStore in this.AssemblyHashtable.GetValuesFor((uint)assemblyName.UniqueKey)) { if (assemblyIdentity.Equals(aStore.AssemblyIdentity)) return aStore; } uint value = this.CurrentAssemblyInternValue; this.CurrentAssemblyInternValue += 0x00001000; AssemblyStore aStore1 = new AssemblyStore(assemblyIdentity, value, this.CurrentNamespaceInternValue++); this.AssemblyHashtable.Add((uint)assemblyName.UniqueKey, aStore1); return aStore1; }
/// <summary> /// Returns the identity of the assembly containing the core system types such as System.Object, by asking /// each of the loaded units for its opinion on the matter and returning the opinion with the highest version number. /// If none of the loaded units have an opinion, the identity of the runtime executing the compiler itself is returned. /// </summary> protected virtual AssemblyIdentity GetCoreAssemblySymbolicIdentity() { var coreAssemblyName = typeof(object).Assembly.GetName(); string loc = GetLocalPath(coreAssemblyName); if (this.unitCache.Count > 0) { AssemblyIdentity/*?*/ result = null; foreach (IUnit unit in this.unitCache.Values) { AssemblyIdentity coreId = unit.CoreAssemblySymbolicIdentity; if (coreId.Name.Value.Length == 0) continue; if (result == null || result.Version < coreId.Version) result = coreId; } if (result != null) { //The loaded assemblies have an opinion on the identity of the core assembly. By default, we are going to respect that opinion. if (result.Location.Length == 0) { //However, they do not know where to find it. (This will only be non empty if one of the loaded assemblies itself is the core assembly.) if (loc.Length > 0) { //We don't know where to find the core assembly that the loaded assemblies want, but we do know where to find the core assembly //that we are running on. Perhaps it is the same assembly as the one we've identified. In that case we know where it can be found. var myCore = new AssemblyIdentity(this.NameTable.GetNameFor(coreAssemblyName.Name), "", coreAssemblyName.Version, coreAssemblyName.GetPublicKeyToken(), loc); if (myCore.Equals(result)) return myCore; //myCore is the same as result, but also has a non null location. } //TODO: if the core assembly being referenced is not the same as the one running the host, probe in the standard places to find its location. //put this probing logic in a separate, overridable method and use it in LoadAssembly and LoadModule. //Hook it up with the GAC. } return result; } } //If we get here, none of the assemblies in the unit cache has an opinion on the identity of the core assembly. //Usually this will be because this method was called before any assemblies have been loaded. //In this case, we have little option but to choose the identity of the core assembly of the platform we are running on. return new AssemblyIdentity(this.NameTable.GetNameFor(coreAssemblyName.Name), "", coreAssemblyName.Version, coreAssemblyName.GetPublicKeyToken(), loc); }
AssemblyStore GetAssemblyStore(AssemblyIdentity assemblyIdentity) { IName assemblyName = assemblyIdentity.Name; foreach (AssemblyStore aStore in this.AssemblyHashtable.GetValuesFor((uint)assemblyName.UniqueKey)) { if (assemblyIdentity.Equals(aStore.AssemblyIdentity)) { return aStore; } } uint value = this.CurrentAssemblyInternValue; this.CurrentAssemblyInternValue += 0x00001000; AssemblyStore aStore1 = new AssemblyStore(assemblyIdentity, value, this.CurrentNamespaceInternValue++); this.AssemblyHashtable.Add((uint)assemblyName.UniqueKey, aStore1); return aStore1; }
/// <summary> /// Returns the original location of the corresponding assembly if available, otherwise returns the location of the shadow copy. /// If the corresponding assembly is not in the GAC, null is returned. /// </summary> public static string/*?*/ GetLocation(AssemblyIdentity assemblyIdentity, IMetadataHost metadataHost) { lock (GlobalLock.LockingObject) { #if COMPACTFX var gacKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"\Software\Microsoft\.NETCompactFramework\Installer\Assemblies\Global"); foreach (var gacName in gacKey.GetValueNames()) { if (IdentityMatchesString(assemblyIdentity, gacName)) { var values = gacKey.GetValue(gacName) as string[]; if (values == null || values.Length == 0) continue; return values[0]; } } return null; #else #if __MonoCS__ IAssemblyEnum assemblyEnum = new MonoAssemblyEnum(); #else if (!GlobalAssemblyCache.FusionLoaded) { GlobalAssemblyCache.FusionLoaded = true; var systemAssembly = typeof(object).Assembly; var systemAssemblyLocation = systemAssembly.Location; var dir = Path.GetDirectoryName(systemAssemblyLocation)??""; GlobalAssemblyCache.LoadLibrary(Path.Combine(dir, "fusion.dll")); } IAssemblyEnum assemblyEnum; int rc = CreateAssemblyEnum(out assemblyEnum, null, null, ASM_CACHE.GAC, 0); if (rc < 0 || assemblyEnum == null) return null; #endif IApplicationContext applicationContext; IAssemblyName currentName; while (assemblyEnum.GetNextAssembly(out applicationContext, out currentName, 0) == 0) { //^ assume currentName != null; AssemblyName cn = new AssemblyName(currentName); if (assemblyIdentity.Equals(new AssemblyIdentity(metadataHost.NameTable.GetNameFor(cn.Name), cn.Culture, cn.Version, cn.PublicKeyToken, ""))) { string codeBase = cn.CodeBase; if (codeBase != null && codeBase.StartsWith("file://", StringComparison.OrdinalIgnoreCase)) { Uri u = new Uri(codeBase, UriKind.Absolute); return u.LocalPath; } return cn.GetLocation(); } } return null; #endif } }
/// <summary> /// Returns the identity of the assembly containing the core system types such as System.Object, by asking /// each of the loaded units for its opinion on the matter and returning the opinion with the highest version number. /// If none of the loaded units have an opinion, the identity of the runtime executing the compiler itself is returned. /// </summary> protected virtual AssemblyIdentity GetCoreAssemblySymbolicIdentity() { var coreAssemblyName = typeof(object).Assembly.GetName(); string loc = GetLocalPath(coreAssemblyName); if (this.unitCache.Count > 0) { AssemblyIdentity/*?*/ result = null; IUnit referringUnit = Dummy.Unit; var dummyVersion = new Version(255, 255, 255, 255); lock (GlobalLock.LockingObject) { foreach (IUnit unit in this.unitCache.Values) { AssemblyIdentity coreId = unit.CoreAssemblySymbolicIdentity; if (coreId.Name.Value.Length == 0) continue; if (result == null || result.Version == dummyVersion || (result.Version < coreId.Version && coreId.Version != dummyVersion) || result.Version == coreId.Version && unit.UnitIdentity.Equals(coreId)) { result = coreId; referringUnit = unit; } } } if (result != null) { //The loaded assemblies have an opinion on the identity of the core assembly. By default, we are going to respect that opinion. if (result.Location.Length == 0) { //However, they do not know where to find it. (This will only be non empty if one of the loaded assemblies itself is the core assembly.) if (loc.Length > 0) { //We don't know where to find the core assembly that the loaded assemblies want, but we do know where to find the core assembly //that we are running on. Perhaps it is the same assembly as the one we've identified. In that case we know where it can be found. var myCore = new AssemblyIdentity(this.NameTable.GetNameFor(coreAssemblyName.Name), "", coreAssemblyName.Version, coreAssemblyName.GetPublicKeyToken(), loc); if (myCore.Equals(result)) return myCore; //myCore is the same as result, but also has a non null location. } //Now use host specific heuristics for finding the assembly. this.coreAssemblySymbolicIdentity = result; //in case ProbeAssemblyReference wants to know the core identity return this.ProbeAssemblyReference(referringUnit, result); } return result; } } //If we get here, none of the assemblies in the unit cache has an opinion on the identity of the core assembly. //Usually this will be because this method was called before any assemblies have been loaded. //In this case, we have little option but to choose the identity of the core assembly of the platform we are running on. return new AssemblyIdentity(this.NameTable.GetNameFor(coreAssemblyName.Name), "", coreAssemblyName.Version, coreAssemblyName.GetPublicKeyToken(), loc); }