예제 #1
0
 static partial void GetEcmaRuntimeAssembly(AssemblyBindResult bindResult, ref RuntimeAssembly runtimeAssembly)
 {
     if (bindResult.EcmaMetadataReader != null)
     {
         runtimeAssembly = EcmaFormatRuntimeAssembly.GetRuntimeAssembly(bindResult.EcmaMetadataReader);
     }
 }
예제 #2
0
 static partial void GetNativeFormatRuntimeAssembly(AssemblyBindResult bindResult, ref RuntimeAssembly runtimeAssembly)
 {
     if (bindResult.Reader != null)
     {
         runtimeAssembly = NativeFormatRuntimeAssembly.GetRuntimeAssembly(bindResult.Reader, bindResult.ScopeDefinitionHandle, bindResult.OverflowScopes);
     }
 }
        partial void BindEcmaFilePath(string assemblyPath, ref AssemblyBindResult bindResult, ref Exception?exception, ref bool?result)
        {
            // Get a PEReader over a MemoryMappedView of the PE file
            PEReader pe = OpenPEFile(assemblyPath, out var memoryMappedView);

            BindEcma(pe, memoryMappedView, out bindResult, out exception, out result);
        }
        partial void BindEcmaByteArray(byte[] rawAssembly, byte[]?rawSymbolStore, ref AssemblyBindResult bindResult, ref Exception?exception, ref bool?result)
        {
            // Load byte[] into immutable array for use by PEReader/MetadataReader
            ImmutableArray <byte> assemblyData = ImmutableArray.Create(rawAssembly);
            PEReader pe = new PEReader(assemblyData);

            BindEcma(pe, null, out bindResult, out exception, out result);
        }
예제 #5
0
        public sealed override bool Bind(AssemblyName refName, out AssemblyBindResult result, out Exception exception)
        {
            bool foundMatch = false;

            result    = default(AssemblyBindResult);
            exception = null;

            // At least one real-world app calls Type.GetType() for "char" using the assembly name "mscorlib". To accomodate this,
            // we will adopt the desktop CLR rule that anything named "mscorlib" automatically binds to the core assembly.
            bool         useMscorlibNameCompareFunc = false;
            AssemblyName compareRefName             = refName;

            if (refName.Name == "mscorlib")
            {
                useMscorlibNameCompareFunc = true;
                compareRefName             = new AssemblyName(AssemblyBinder.DefaultAssemblyNameForGetType);
            }

            foreach (KeyValuePair <AssemblyNameKey, ScopeDefinitionGroup> group in ScopeGroups)
            {
                bool nameMatches;
                if (useMscorlibNameCompareFunc)
                {
                    nameMatches = MscorlibAssemblyNameMatches(compareRefName, group.Key.AssemblyName);
                }
                else
                {
                    nameMatches = AssemblyNameMatches(refName, group.Key.AssemblyName);
                }

                if (nameMatches)
                {
                    if (foundMatch)
                    {
                        exception = new AmbiguousMatchException();
                        return(false);
                    }

                    foundMatch = true;
                    ScopeDefinitionGroup scopeDefinitionGroup = group.Value;

                    result.Reader = scopeDefinitionGroup.CanonicalScope.Reader;
                    result.ScopeDefinitionHandle = scopeDefinitionGroup.CanonicalScope.Handle;
                    result.OverflowScopes        = scopeDefinitionGroup.OverflowScopes;
                }
            }

            if (!foundMatch)
            {
                exception = new IOException(SR.Format(SR.FileNotFound_AssemblyNotFound, refName.FullName));
                return(false);
            }

            return(true);
        }
 partial void InsertEcmaLoadedAssemblies(List <AssemblyBindResult> loadedAssemblies)
 {
     lock (s_ecmaLoadedAssemblies)
     {
         for (int i = 0; i < s_ecmaLoadedAssemblies.Count; i++)
         {
             PEInfo             info   = s_ecmaLoadedAssemblies[i];
             AssemblyBindResult result = default(AssemblyBindResult);
             result.EcmaMetadataReader = info.Reader;
             loadedAssemblies.Add(result);
         }
     }
 }
        private static RuntimeAssembly GetRuntimeAssembly(AssemblyBindResult bindResult)
        {
            RuntimeAssembly result = null;

            GetNativeFormatRuntimeAssembly(bindResult, ref result);
            if (result != null)
            {
                return(result);
            }

            GetEcmaRuntimeAssembly(bindResult, ref result);
            if (result != null)
            {
                return(result);
            }

            throw new PlatformNotSupportedException();
        }
        public sealed override bool Bind(byte[] rawAssembly, byte[] rawSymbolStore, out AssemblyBindResult bindResult, out Exception exception)
        {
            bool?result = null;

            exception  = null;
            bindResult = default(AssemblyBindResult);

            BindEcmaByteArray(rawAssembly, rawSymbolStore, ref bindResult, ref exception, ref result);

            // If the Ecma assembly binder isn't linked in, simply throw PlatformNotSupportedException
            if (!result.HasValue)
            {
                throw new PlatformNotSupportedException();
            }
            else
            {
                return(result.Value);
            }
        }
        public sealed override bool Bind(string assemblyPath, out AssemblyBindResult bindResult, out Exception exception)
        {
            bool?result = null;

            exception  = null;
            bindResult = default(AssemblyBindResult);

            BindEcmaFilePath(assemblyPath, ref bindResult, ref exception, ref result);

            // If the Ecma assembly binder isn't linked in, simply throw PlatformNotSupportedException
            if (!result.HasValue)
            {
                throw new PlatformNotSupportedException();
            }
            else
            {
                return(result.Value);
            }
        }
        public sealed override IList <AssemblyBindResult> GetLoadedAssemblies()
        {
            List <AssemblyBindResult> loadedAssemblies = new List <AssemblyBindResult>(ScopeGroups.Length);

            foreach (KeyValuePair <RuntimeAssemblyName, ScopeDefinitionGroup> group in ScopeGroups)
            {
                ScopeDefinitionGroup scopeDefinitionGroup = group.Value;

                AssemblyBindResult result = default(AssemblyBindResult);
                result.Reader = scopeDefinitionGroup.CanonicalScope.Reader;
                result.ScopeDefinitionHandle = scopeDefinitionGroup.CanonicalScope.Handle;
                result.OverflowScopes        = scopeDefinitionGroup.OverflowScopes;
                loadedAssemblies.Add(result);
            }

            InsertEcmaLoadedAssemblies(loadedAssemblies);

            return(loadedAssemblies);
        }
        partial void BindEcmaByteArray(byte[] rawAssembly, byte[] rawSymbolStore, ref AssemblyBindResult bindResult, ref Exception exception, ref bool?result)
        {
            // 1. Load byte[] into immutable array for use by PEReader/MetadataReader
            ImmutableArray <byte> assemblyData = ImmutableArray.Create(rawAssembly);
            PEReader       pe     = new PEReader(assemblyData);
            MetadataReader reader = pe.GetMetadataReader();

            // 2. Create AssemblyName from MetadataReader
            RuntimeAssemblyName runtimeAssemblyName = reader.GetAssemblyDefinition().ToRuntimeAssemblyName(reader);
            AssemblyName        asmName             = new AssemblyName();

            runtimeAssemblyName.CopyToAssemblyName(asmName);

            lock (s_ecmaLoadedAssemblies)
            {
                // 3. Attempt to bind to already loaded assembly
                if (Bind(asmName, out bindResult, out exception))
                {
                    result = true;
                    return;
                }
                exception = null;

                // 4. If that fails, then add newly created metareader to global cache of byte array loaded modules
                PEInfo peinfo = new PEInfo(asmName, reader, pe);

                s_ecmaLoadedAssemblies.Add(peinfo);
                ModuleList moduleList    = ModuleList.Instance;
                ModuleInfo newModuleInfo = new EcmaModuleInfo(moduleList.SystemModule.Handle, pe, reader);
                moduleList.RegisterModule(newModuleInfo);

                // 5. Then try to load by name again. This load should always succeed
                if (Bind(asmName, out bindResult, out exception))
                {
                    result = true;
                    return;
                }

                result = false;
                Debug.Assert(exception != null); // We must have an error on load. At this time this could happen due to ambiguous name matching
            }
        }
        partial void BindEcmaAssemblyName(RuntimeAssemblyName refName, ref AssemblyBindResult result, ref Exception exception, ref bool foundMatch)
        {
            lock (s_ecmaLoadedAssemblies)
            {
                for (int i = 0; i < s_ecmaLoadedAssemblies.Count; i++)
                {
                    PEInfo info = s_ecmaLoadedAssemblies[i];
                    if (AssemblyNameMatches(refName, info.Name))
                    {
                        if (foundMatch)
                        {
                            exception = new AmbiguousMatchException();
                            return;
                        }

                        foundMatch = true;
                        result.EcmaMetadataReader = info.Reader;
                    }
                }
            }
        }
 partial void BindEcmaBytes(ReadOnlySpan <byte> rawAssembly, ReadOnlySpan <byte> rawSymbolStore, ref AssemblyBindResult bindResult, ref Exception exception, ref bool?result);
        public sealed override bool Bind(RuntimeAssemblyName refName, bool cacheMissedLookups, out AssemblyBindResult result, out Exception exception)
        {
            bool foundMatch = false;

            result    = default(AssemblyBindResult);
            exception = null;

            Exception preferredException = null;

            foreach (KeyValuePair <RuntimeAssemblyName, ScopeDefinitionGroup> group in ScopeGroups)
            {
                if (AssemblyNameMatches(refName, group.Key, ref preferredException))
                {
                    if (foundMatch)
                    {
                        exception = new AmbiguousMatchException();
                        return(false);
                    }

                    foundMatch = true;
                    ScopeDefinitionGroup scopeDefinitionGroup = group.Value;

                    result.Reader = scopeDefinitionGroup.CanonicalScope.Reader;
                    result.ScopeDefinitionHandle = scopeDefinitionGroup.CanonicalScope.Handle;
                    result.OverflowScopes        = scopeDefinitionGroup.OverflowScopes;
                }
            }

            BindEcmaAssemblyName(refName, cacheMissedLookups, ref result, ref exception, ref preferredException, ref foundMatch);
            if (exception != null)
            {
                return(false);
            }

            if (!foundMatch)
            {
                exception = preferredException ?? new FileNotFoundException(SR.Format(SR.FileNotFound_AssemblyNotFound, refName.FullName));
                return(false);
            }

            return(true);
        }
 partial void BindEcmaAssemblyName(RuntimeAssemblyName refName, bool cacheMissedLookups, ref AssemblyBindResult result, ref Exception exception, ref Exception preferredException, ref bool resultBoolean);
 partial void BindEcmaByteArray(byte[] rawAssembly, byte[] rawSymbolStore, ref AssemblyBindResult bindResult, ref Exception exception, ref bool?result);
 partial void BindEcmaFilePath(string assemblyPath, ref AssemblyBindResult bindResult, ref Exception exception, ref bool?result);
예제 #18
0
 partial void BindEcmaAssemblyName(RuntimeAssemblyName refName, ref AssemblyBindResult result, ref Exception exception, ref bool resultBoolean);
        partial void BindEcmaAssemblyName(RuntimeAssemblyName refName, bool cacheMissedLookups, ref AssemblyBindResult result, ref Exception exception, ref Exception preferredException, ref bool foundMatch)
        {
            lock (s_ecmaLoadedAssemblies)
            {
                for (int i = 0; i < s_ecmaLoadedAssemblies.Count; i++)
                {
                    PEInfo info = s_ecmaLoadedAssemblies[i];
                    if (AssemblyNameMatches(refName, info.Name, ref preferredException))
                    {
                        if (foundMatch)
                        {
                            exception = new AmbiguousMatchException();
                            return;
                        }

                        result.EcmaMetadataReader = info.Reader;
                        foundMatch = result.EcmaMetadataReader != null;

                        // For failed matches, we will never be able to succeed, so return now
                        if (!foundMatch)
                        {
                            return;
                        }
                    }
                }

                if (!foundMatch)
                {
                    try
                    {
                        // Not found in already loaded list, attempt to source assembly from disk
                        foreach (string filePath in FilePathsForAssembly(refName))
                        {
                            FileStream ownedFileStream = null;
                            PEReader   ownedPEReader   = null;
                            try
                            {
                                if (!RuntimeAugments.FileExists(filePath))
                                {
                                    continue;
                                }

                                try
                                {
                                    ownedFileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
                                }
                                catch (System.IO.IOException)
                                {
                                    // Failure to open a file is not fundamentally an assembly load error, but it does indicate this file cannot be used
                                    continue;
                                }

                                ownedPEReader = new PEReader(ownedFileStream);
                                // FileStream ownership transferred to ownedPEReader
                                ownedFileStream = null;

                                if (!ownedPEReader.HasMetadata)
                                {
                                    continue;
                                }

                                MetadataReader reader = ownedPEReader.GetMetadataReader();
                                // Create AssemblyName from MetadataReader
                                RuntimeAssemblyName runtimeAssemblyName = reader.GetAssemblyDefinition().ToRuntimeAssemblyName(reader).CanonicalizePublicKeyToken();

                                // If assembly name doesn't match, it isn't the one we're looking for. Continue to look for more assemblies
                                if (!AssemblyNameMatches(refName, runtimeAssemblyName, ref preferredException))
                                {
                                    continue;
                                }

                                // This is the one we are looking for, add it to the list of loaded assemblies
                                PEInfo peinfo = new PEInfo(runtimeAssemblyName, reader, ownedPEReader);

                                s_ecmaLoadedAssemblies.Add(peinfo);

                                // At this point the PE reader is no longer owned by this code, but is owned by the s_ecmaLoadedAssemblies list
                                PEReader pe = ownedPEReader;
                                ownedPEReader = null;

                                ModuleList moduleList    = ModuleList.Instance;
                                ModuleInfo newModuleInfo = new EcmaModuleInfo(moduleList.SystemModule.Handle, pe, reader);
                                moduleList.RegisterModule(newModuleInfo);

                                foundMatch = true;
                                result.EcmaMetadataReader = peinfo.Reader;
                                break;
                            }
                            finally
                            {
                                if (ownedFileStream != null)
                                {
                                    ownedFileStream.Dispose();
                                }

                                if (ownedPEReader != null)
                                {
                                    ownedPEReader.Dispose();
                                }
                            }
                        }
                    }
                    catch (System.IO.IOException)
                    { }
                    catch (System.ArgumentException)
                    { }
                    catch (System.BadImageFormatException badImageFormat)
                    {
                        exception = badImageFormat;
                    }

                    // Cache missed lookups
                    if (cacheMissedLookups && !foundMatch)
                    {
                        PEInfo peinfo = new PEInfo(refName, null, null);
                        s_ecmaLoadedAssemblies.Add(peinfo);
                    }
                }
            }
        }
 static partial void GetEcmaRuntimeAssembly(AssemblyBindResult bindResult, ref RuntimeAssembly runtimeAssembly);
 // Use C# partial method feature to avoid complex #if logic, whichever code files are included will drive behavior
 static partial void GetNativeFormatRuntimeAssembly(AssemblyBindResult bindResult, ref RuntimeAssembly runtimeAssembly);
        private void BindEcma(PEReader pe, MemoryMappedViewAccessor?memoryMappedView, out AssemblyBindResult bindResult, out Exception?exception, out bool?result)
        {
            MetadataReader reader = pe.GetMetadataReader();

            // 1. Create AssemblyName from MetadataReader
            RuntimeAssemblyName runtimeAssemblyName = reader.GetAssemblyDefinition().ToRuntimeAssemblyName(reader);

            lock (s_ecmaLoadedAssemblies)
            {
                // 2. Attempt to bind to already loaded assembly
                if (Bind(runtimeAssemblyName, cacheMissedLookups: false, out bindResult, out exception))
                {
                    result = true;
                    return;
                }
                exception = null;

                // 3. If that fails, then add newly created metareader to global cache of loaded modules
                PEInfo peinfo = new PEInfo(runtimeAssemblyName, reader, pe, memoryMappedView);

                s_ecmaLoadedAssemblies.Add(peinfo);
                ModuleList moduleList    = ModuleList.Instance;
                ModuleInfo newModuleInfo = new EcmaModuleInfo(moduleList.SystemModule.Handle, pe, reader);
                moduleList.RegisterModule(newModuleInfo);

                // 4. Then try to load by name again. This load should always succeed
                if (Bind(runtimeAssemblyName, cacheMissedLookups: true, out bindResult, out exception))
                {
                    result = true;
                    return;
                }

                result = false;
                Debug.Assert(exception != null); // We must have an error on load. At this time this could happen due to ambiguous name matching
            }
        }