// /*************************************************************************** // Aaru Data Preservation Suite // ---------------------------------------------------------------------------- // // Filename : PluginRegister.cs // Author(s) : Natalia Portillo // // Component : Common types. // // --[ Description ] ---------------------------------------------------------- // // Gets lists of all known plugins. // // --[ License ] -------------------------------------------------------------- // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // ---------------------------------------------------------------------------- // Copyright © 2011-2023 Natalia Portillo // ****************************************************************************/ using System; using System.Collections.Generic; using System.IO; using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Interfaces; using Microsoft.Extensions.DependencyInjection; namespace Aaru.CommonTypes; public class PluginRegister { static PluginRegister _instance; IServiceProvider _serviceProvider; IServiceCollection _services; PluginRegister() {} /// List of byte addressable image plugins public SortedDictionary ByteAddressableImages { get { SortedDictionary byteAddressableImages = new(); foreach(IByteAddressableImage plugin in _serviceProvider.GetServices()) byteAddressableImages[plugin.Name.ToLower()] = plugin; return byteAddressableImages; } } /// List of writable media image plugins public SortedDictionary WritableImages { get { SortedDictionary mediaImages = new(); foreach(IBaseWritableImage plugin in _serviceProvider.GetServices()) mediaImages[plugin.Name.ToLower()] = plugin; return mediaImages; } } /// List of writable floppy image plugins public SortedDictionary WritableFloppyImages { get { SortedDictionary floppyImages = new(); foreach(IWritableFloppyImage plugin in _serviceProvider.GetServices()) floppyImages[plugin.Name.ToLower()] = plugin; return floppyImages; } } /// List of floppy image plugins public SortedDictionary FloppyImages { get { SortedDictionary floppyImages = new(); foreach(IFloppyImage plugin in _serviceProvider.GetServices()) floppyImages[plugin.Name.ToLower()] = plugin; return floppyImages; } } /// List of all media image plugins public SortedDictionary MediaImages { get { SortedDictionary mediaImages = new(); foreach(IMediaImage plugin in _serviceProvider.GetServices()) mediaImages[plugin.Name.ToLower()] = plugin; return mediaImages; } } /// List of read-only filesystem plugins public SortedDictionary ReadOnlyFilesystems { get { SortedDictionary readOnlyFilesystems = new(); foreach(IReadOnlyFilesystem plugin in _serviceProvider.GetServices()) readOnlyFilesystems[plugin.Name.ToLower()] = plugin; return readOnlyFilesystems; } } /// List of all filesystem plugins public SortedDictionary Filesystems { get { SortedDictionary filesystems = new(); foreach(IFilesystem plugin in _serviceProvider.GetServices()) filesystems[plugin.Name.ToLower()] = plugin; return filesystems; } } /// List of all archive formats public SortedDictionary Archives { get { SortedDictionary archives = new(); foreach(IArchive plugin in _serviceProvider.GetServices()) archives[plugin.Name.ToLower()] = plugin; return archives; } } /// List of all partition plugins public SortedDictionary Partitions { get { SortedDictionary partitions = new(); foreach(IPartition plugin in _serviceProvider.GetServices()) partitions[plugin.Name.ToLower()] = plugin; return partitions; } } /// List of filter plugins public SortedDictionary Filters { get { SortedDictionary filters = new(); foreach(IFilter plugin in _serviceProvider.GetServices()) filters[plugin.Name.ToLower()] = plugin; return filters; } } /// List of checksum plugins public SortedDictionary Checksums { get { SortedDictionary checksums = new(); foreach(IChecksum plugin in _serviceProvider.GetServices()) checksums[plugin.Name.ToLower()] = plugin; return checksums; } } /// Gets a singleton with all the known plugins public static PluginRegister Singleton { get { if(_instance != null) return _instance; _instance = new PluginRegister { _services = new ServiceCollection() }; _instance._serviceProvider = _instance._services.BuildServiceProvider(); return _instance; } } /// /// Replaces registered plugins list of this instance with the new ones provided by the providen registrators. /// /// List of plugin registrators as obtained from the assemblies that implement them. public void InitPlugins(IEnumerable registrators) { _services = new ServiceCollection(); foreach(IPluginRegister registrator in registrators) AddPlugins(registrator); _instance._serviceProvider = _instance._services.BuildServiceProvider(); } /// Adds plugins to the central plugin register /// Plugin register void AddPlugins(IPluginRegister pluginRegister) { pluginRegister.RegisterChecksumPlugins(_services); pluginRegister.RegisterFilesystemPlugins(_services); pluginRegister.RegisterFilterPlugins(_services); pluginRegister.RegisterReadOnlyFilesystemPlugins(_services); pluginRegister.RegisterFloppyImagePlugins(_services); pluginRegister.RegisterMediaImagePlugins(_services); pluginRegister.RegisterPartitionPlugins(_services); pluginRegister.RegisterWritableFloppyImagePlugins(_services); pluginRegister.RegisterWritableImagePlugins(_services); pluginRegister.RegisterArchivePlugins(_services); pluginRegister.RegisterByteAddressablePlugins(_services); } /// Gets the filter that allows to read the specified path /// Path /// The filter that allows reading the specified path public IFilter GetFilter(string path) { IFilter noFilter = null; foreach(IFilter filter in Filters.Values) { try { if(filter.Id != new Guid("12345678-AAAA-BBBB-CCCC-123456789000")) { if(!filter.Identify(path)) continue; var foundFilter = (IFilter)filter.GetType().GetConstructor(Type.EmptyTypes)?.Invoke(Array.Empty()); if(foundFilter?.Open(path) == ErrorNumber.NoError) return foundFilter; } else noFilter = filter; } catch(IOException) { // Ignore and continue } } if(!noFilter?.Identify(path) == true) return null; noFilter?.Open(path); return noFilter; } }