Esempio n. 1
0
 public void Remove(DnSpyFile file, bool canDispose)
 {
     options.Dispatcher.VerifyAccess();
     lock (lockObj) {
         files.Remove(file);
         // No need to Dispose() it. The GC will take care of it
     }
     if (canDispose)
     {
         CallGC();
     }
 }
Esempio n. 2
0
        void AddToList_NoLock(DnSpyFile newFile, int index)
        {
            var key = newFile.Key;

            if ((uint)index < (uint)files.Count)
            {
                files.Insert(index, newFile);
            }
            else
            {
                files.Add(newFile);
            }
        }
Esempio n. 3
0
        public DnSpyFile Add(DnSpyFile file)
        {
            options.Dispatcher.VerifyAccess();
            lock (lockObj) {
                var key          = file.Key;
                var existingFile = FindByKey_NoLock(key);
                if (existingFile != null)
                {
                    return(existingFile);
                }

                AddToList_NoLock(file, -1);
                return(file);
            }
        }
Esempio n. 4
0
        internal DnSpyFile AddFile(DnSpyFile newFile, bool canAdd, bool delayLoad, bool canDispose = true)
        {
            lock (lockObj) {
                var file = FindByKey_NoLock(newFile.Key);
                if (file != null)
                {
                    if (canDispose && newFile != file)
                    {
                        newFile.Dispose();
                    }
                    return(file);
                }

                return(ForceAddFileToList_NoLock(newFile, canAdd, delayLoad, -1, canDispose));
            }
        }
Esempio n. 5
0
        DnSpyFile ForceAddFileToList_NoLock(DnSpyFile newFile, bool canAdd, bool delayLoad, int index, bool canDispose)
        {
            if (!canAdd)
            {
                return(newFile);
            }

            delayLoad |= !options.Dispatcher.CheckAccess();

            // Sometimes the treeview will completely mess up if we immediately add the file.
            // Wait a little while for the treeview to finish its things before we add it.
            if (delayLoad)
            {
                return(DelayLoadFile_NoLock(newFile, index, canDispose));
            }
            AddToList_NoLock(newFile, index);
            return(newFile);
        }
Esempio n. 6
0
        DnSpyFile DelayLoadFile_NoLock(DnSpyFile newFile, int index, bool canDispose)
        {
            bool startThread;

            lock (delayLoadedFiles) {
                var key = newFile.Key;
                Tuple <DnSpyFile, int> info;
                if (delayLoadedFiles.TryGetValue(key, out info))
                {
                    if (canDispose && info.Item1 != newFile)
                    {
                        newFile.Dispose();
                    }
                    return(info.Item1);
                }
                delayLoadedFiles.Add(key, Tuple.Create(newFile, index));
                startThread = delayLoadedFiles.Count == 1;
            }
            if (startThread)
            {
                options.Dispatcher.BeginInvoke(DispatcherPrio.Loaded, () => DelayLoadFileMainThread());
            }
            return(newFile);
        }
Esempio n. 7
0
 internal static IDnSpyFile CreateDnSpyFileFromFile(DnSpyFileInfo fileInfo, string filename, bool useMemoryMappedIO, bool loadPDBFiles, IAssemblyResolver asmResolver)
 {
     return(DnSpyFile.CreateDnSpyFileFromFile(fileInfo, filename, useMemoryMappedIO, loadPDBFiles, asmResolver, false));
 }
Esempio n. 8
0
        public DnSpyFile Resolve(IAssembly assembly, ModuleDef sourceModule = null, bool delayLoad = false)
        {
            FrameworkRedirect.ApplyFrameworkRedirect(ref assembly, sourceModule);

            if (assembly.IsContentTypeWindowsRuntime)
            {
                return(ResolveWinMD(assembly, sourceModule, delayLoad));
            }

            // WinMD files have a reference to mscorlib but its version is always 255.255.255.255
            // since mscorlib isn't really loaded. The resolver only loads exact versions, so
            // we must change the version or the resolve will fail.
            if (assembly.Name == "mscorlib" && assembly.Version == invalidMscorlibVersion)
            {
                assembly = new AssemblyNameInfo(assembly)
                {
                    Version = newMscorlibVersion
                }
            }
            ;

            return(ResolveNormal(assembly, sourceModule, delayLoad));
        }

        DnSpyFile ResolveNormal(IAssembly assembly, ModuleDef sourceModule, bool delayLoad)
        {
            var existingFile = fileList.FindAssembly(assembly);

            if (existingFile != null)
            {
                return(existingFile);
            }

            var file = LookupFromSearchPaths(assembly, sourceModule, true);

            if (file != null)
            {
                return(fileList.AddFile(file, fileList.AssemblyLoadEnabled, delayLoad));
            }

            if (fileList.UseGAC)
            {
                var gacFile = GacInterop.FindAssemblyInNetGac(assembly);
                if (gacFile != null)
                {
                    return(fileList.GetOrCreate(gacFile, fileList.AssemblyLoadEnabled, true, delayLoad));
                }
                foreach (var path in GacInfo.OtherGacPaths)
                {
                    file = TryLoadFromDir(assembly, true, path);
                    if (file != null)
                    {
                        return(fileList.AddFile(file, fileList.AssemblyLoadEnabled, delayLoad));
                    }
                }
            }

            file = LookupFromSearchPaths(assembly, sourceModule, false);
            if (file != null)
            {
                return(fileList.AddFile(file, fileList.AssemblyLoadEnabled, delayLoad));
            }

            return(null);
        }

        DnSpyFile LookupFromSearchPaths(IAssembly asmName, ModuleDef sourceModule, bool exactCheck)
        {
            DnSpyFile file;
            string    sourceModuleDir = null;

            if (sourceModule != null && File.Exists(sourceModule.Location))
            {
                sourceModuleDir = Path.GetDirectoryName(sourceModule.Location);
                file            = TryLoadFromDir(asmName, exactCheck, sourceModuleDir);
                if (file != null)
                {
                    return(file);
                }
            }
            var ary = asmSearchPathsArray;

            foreach (var path in ary)
            {
                file = TryLoadFromDir(asmName, exactCheck, path);
                if (file != null)
                {
                    return(file);
                }
            }

            return(null);
        }

        DnSpyFile TryLoadFromDir(IAssembly asmName, bool exactCheck, string dirPath)
        {
            string baseName;

            try {
                baseName = Path.Combine(dirPath, asmName.Name);
            }
            catch (ArgumentException) {             // eg. invalid chars in asmName.Name
                return(null);
            }
            return(TryLoadFromDir2(asmName, exactCheck, baseName + ".dll") ??
                   TryLoadFromDir2(asmName, exactCheck, baseName + ".exe"));
        }

        DnSpyFile TryLoadFromDir2(IAssembly asmName, bool exactCheck, string filename)
        {
            if (!File.Exists(filename))
            {
                return(null);
            }

            DnSpyFile file  = null;
            bool      error = true;

            try {
                file = fileList.CreateDnSpyFile(filename);
                file.IsAutoLoaded = true;
                var asm = file.AssemblyDef;
                if (asm == null)
                {
                    return(null);
                }
                bool b = exactCheck ?
                         AssemblyNameComparer.CompareAll.Equals(asmName, asm) :
                         AssemblyNameComparer.NameAndPublicKeyTokenOnly.Equals(asmName, asm);
                if (!b)
                {
                    return(null);
                }

                error = false;
                return(file);
            }
            finally {
                if (error)
                {
                    if (file != null)
                    {
                        file.Dispose();
                    }
                }
            }
        }

        DnSpyFile ResolveWinMD(IAssembly assembly, ModuleDef sourceModule, bool delayLoad)
        {
            var existingFile = fileList.FindAssembly(assembly);

            if (existingFile != null)
            {
                return(existingFile);
            }

            foreach (var winmdPath in GacInfo.WinmdPaths)
            {
                string file;
                try {
                    file = Path.Combine(winmdPath, assembly.Name + ".winmd");
                }
                catch (ArgumentException) {
                    continue;
                }
                if (File.Exists(file))
                {
                    return(fileList.GetOrCreate(file, fileList.AssemblyLoadEnabled, true, delayLoad));
                }
            }
            return(null);
        }
    }
Esempio n. 9
0
 internal void Insert_NoLock(int index, DnSpyFile file)
 {
     files.Insert(index, file);
 }
Esempio n. 10
0
 internal int IndexOf_NoLock(DnSpyFile file)
 {
     return(files.IndexOf(file));
 }
Esempio n. 11
0
 internal DnSpyFile ForceAddFileToList(DnSpyFile newFile, bool canAdd, bool delayLoad, int index, bool canDispose)
 {
     lock (lockObj)
         return(ForceAddFileToList_NoLock(newFile, canAdd, delayLoad, index, canDispose));
 }
Esempio n. 12
0
 DnSpyFile CreateDnSpyFile(string filename, bool useMemoryMappedIO, bool loadSyms)
 {
     return(DnSpyFile.CreateFromFile(filename, options.UseMemoryMappedIO, options.UseDebugSymbols, assemblyResolver));
 }
Esempio n. 13
0
 internal DnSpyFile CreateDnSpyFile(ModuleDef module)
 {
     return(DnSpyFile.Create(module, options.UseDebugSymbols, assemblyResolver));
 }