mirror of
				https://github.com/ryujinx-mirror/ryujinx.git
				synced 2025-11-04 08:59:04 -06:00 
			
		
		
		
	Make sure TryGetApplicationsFromFile() doesn't throw exceptions anymore (#7046)
* Add docstrings for exceptions to methods near TryGetApplicationsFromFile() * Make sure TryGetApplicationsFromFile() doesn't throw exceptions anymore * Add missing filePath to ApplicationData when loading applications from ExeFS * Fix typo Co-authored-by: riperiperi <rhy3756547@hotmail.com> --------- Co-authored-by: riperiperi <rhy3756547@hotmail.com>
This commit is contained in:
		@@ -15,6 +15,12 @@ namespace Ryujinx.HLE.Loaders.Npdm
 | 
			
		||||
        public ServiceAccessControl ServiceAccessControl { get; private set; }
 | 
			
		||||
        public KernelAccessControl KernelAccessControl { get; private set; }
 | 
			
		||||
 | 
			
		||||
        /// <exception cref="InvalidNpdmException">The stream doesn't contain valid ACI0 data.</exception>
 | 
			
		||||
        /// <exception cref="System.ArgumentException">The stream does not support reading, is <see langword="null"/>, or is already closed.</exception>
 | 
			
		||||
        /// <exception cref="EndOfStreamException">The end of the stream is reached.</exception>
 | 
			
		||||
        /// <exception cref="System.ObjectDisposedException">The stream is closed.</exception>
 | 
			
		||||
        /// <exception cref="IOException">An I/O error occurred.</exception>
 | 
			
		||||
        /// <exception cref="System.NotImplementedException">The FsAccessHeader.ContentOwnerId section is not implemented.</exception>
 | 
			
		||||
        public Aci0(Stream stream, int offset)
 | 
			
		||||
        {
 | 
			
		||||
            stream.Seek(offset, SeekOrigin.Begin);
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,11 @@ namespace Ryujinx.HLE.Loaders.Npdm
 | 
			
		||||
        public ServiceAccessControl ServiceAccessControl { get; private set; }
 | 
			
		||||
        public KernelAccessControl KernelAccessControl { get; private set; }
 | 
			
		||||
 | 
			
		||||
        /// <exception cref="InvalidNpdmException">The stream doesn't contain valid ACID data.</exception>
 | 
			
		||||
        /// <exception cref="System.ArgumentException">The stream does not support reading, is <see langword="null"/>, or is already closed.</exception>
 | 
			
		||||
        /// <exception cref="EndOfStreamException">The end of the stream is reached.</exception>
 | 
			
		||||
        /// <exception cref="System.ObjectDisposedException">The stream is closed.</exception>
 | 
			
		||||
        /// <exception cref="IOException">An I/O error occurred.</exception>
 | 
			
		||||
        public Acid(Stream stream, int offset)
 | 
			
		||||
        {
 | 
			
		||||
            stream.Seek(offset, SeekOrigin.Begin);
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,10 @@ namespace Ryujinx.HLE.Loaders.Npdm
 | 
			
		||||
        public int Unknown3 { get; private set; }
 | 
			
		||||
        public int Unknown4 { get; private set; }
 | 
			
		||||
 | 
			
		||||
        /// <exception cref="System.ArgumentException">The stream does not support reading, is <see langword="null"/>, or is already closed.</exception>
 | 
			
		||||
        /// <exception cref="EndOfStreamException">The end of the stream is reached.</exception>
 | 
			
		||||
        /// <exception cref="System.ObjectDisposedException">The stream is closed.</exception>
 | 
			
		||||
        /// <exception cref="IOException">An I/O error occurred.</exception>
 | 
			
		||||
        public FsAccessControl(Stream stream, int offset, int size)
 | 
			
		||||
        {
 | 
			
		||||
            stream.Seek(offset, SeekOrigin.Begin);
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,12 @@ namespace Ryujinx.HLE.Loaders.Npdm
 | 
			
		||||
        public int Version { get; private set; }
 | 
			
		||||
        public ulong PermissionsBitmask { get; private set; }
 | 
			
		||||
 | 
			
		||||
        /// <exception cref="InvalidNpdmException">The stream contains invalid data.</exception>
 | 
			
		||||
        /// <exception cref="NotImplementedException">The ContentOwnerId section is not implemented.</exception>
 | 
			
		||||
        /// <exception cref="ArgumentException">The stream does not support reading, is <see langword="null"/>, or is already closed.</exception>
 | 
			
		||||
        /// <exception cref="EndOfStreamException">The end of the stream is reached.</exception>
 | 
			
		||||
        /// <exception cref="ObjectDisposedException">The stream is closed.</exception>
 | 
			
		||||
        /// <exception cref="IOException">An I/O error occurred.</exception>
 | 
			
		||||
        public FsAccessHeader(Stream stream, int offset, int size)
 | 
			
		||||
        {
 | 
			
		||||
            stream.Seek(offset, SeekOrigin.Begin);
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,10 @@ namespace Ryujinx.HLE.Loaders.Npdm
 | 
			
		||||
    {
 | 
			
		||||
        public int[] Capabilities { get; private set; }
 | 
			
		||||
 | 
			
		||||
        /// <exception cref="System.ArgumentException">The stream does not support reading, is <see langword="null"/>, or is already closed.</exception>
 | 
			
		||||
        /// <exception cref="EndOfStreamException">The end of the stream is reached.</exception>
 | 
			
		||||
        /// <exception cref="System.ObjectDisposedException">The stream is closed.</exception>
 | 
			
		||||
        /// <exception cref="IOException">An I/O error occurred.</exception>
 | 
			
		||||
        public KernelAccessControl(Stream stream, int offset, int size)
 | 
			
		||||
        {
 | 
			
		||||
            stream.Seek(offset, SeekOrigin.Begin);
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,13 @@ namespace Ryujinx.HLE.Loaders.Npdm
 | 
			
		||||
        public Aci0 Aci0 { get; private set; }
 | 
			
		||||
        public Acid Acid { get; private set; }
 | 
			
		||||
 | 
			
		||||
        /// <exception cref="InvalidNpdmException">The stream doesn't contain valid NPDM data.</exception>
 | 
			
		||||
        /// <exception cref="System.NotImplementedException">The FsAccessHeader.ContentOwnerId section is not implemented.</exception>
 | 
			
		||||
        /// <exception cref="System.ArgumentException">The stream does not support reading, is <see langword="null"/>, or is already closed.</exception>
 | 
			
		||||
        /// <exception cref="System.ArgumentException">An error occured while reading bytes from the stream.</exception>
 | 
			
		||||
        /// <exception cref="EndOfStreamException">The end of the stream is reached.</exception>
 | 
			
		||||
        /// <exception cref="System.ObjectDisposedException">The stream is closed.</exception>
 | 
			
		||||
        /// <exception cref="IOException">An I/O error occurred.</exception>
 | 
			
		||||
        public Npdm(Stream stream)
 | 
			
		||||
        {
 | 
			
		||||
            BinaryReader reader = new(stream);
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,11 @@ namespace Ryujinx.HLE.Loaders.Npdm
 | 
			
		||||
    {
 | 
			
		||||
        public IReadOnlyDictionary<string, bool> Services { get; private set; }
 | 
			
		||||
 | 
			
		||||
        /// <exception cref="System.ArgumentException">The stream does not support reading, is <see langword="null"/>, or is already closed.</exception>
 | 
			
		||||
        /// <exception cref="System.ArgumentException">An error occured while reading bytes from the stream.</exception>
 | 
			
		||||
        /// <exception cref="EndOfStreamException">The end of the stream is reached.</exception>
 | 
			
		||||
        /// <exception cref="System.ObjectDisposedException">The stream is closed.</exception>
 | 
			
		||||
        /// <exception cref="IOException">An I/O error occurred.</exception>
 | 
			
		||||
        public ServiceAccessControl(Stream stream, int offset, int size)
 | 
			
		||||
        {
 | 
			
		||||
            stream.Seek(offset, SeekOrigin.Begin);
 | 
			
		||||
 
 | 
			
		||||
@@ -72,37 +72,43 @@ namespace Ryujinx.UI.App.Common
 | 
			
		||||
            return resourceByteArray;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <exception cref="Ryujinx.HLE.Exceptions.InvalidNpdmException">The npdm file doesn't contain valid data.</exception>
 | 
			
		||||
        /// <exception cref="NotImplementedException">The FsAccessHeader.ContentOwnerId section is not implemented.</exception>
 | 
			
		||||
        /// <exception cref="ArgumentException">An error occured while reading bytes from the stream.</exception>
 | 
			
		||||
        /// <exception cref="EndOfStreamException">The end of the stream is reached.</exception>
 | 
			
		||||
        /// <exception cref="IOException">An I/O error occurred.</exception>
 | 
			
		||||
        private ApplicationData GetApplicationFromExeFs(PartitionFileSystem pfs, string filePath)
 | 
			
		||||
        {
 | 
			
		||||
            ApplicationData data = new()
 | 
			
		||||
            {
 | 
			
		||||
                Icon = _nspIcon,
 | 
			
		||||
                Path = filePath,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            using UniqueRef<IFile> npdmFile = new();
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            Result result = pfs.OpenFile(ref npdmFile.Ref, "/main.npdm".ToU8Span(), OpenMode.Read);
 | 
			
		||||
 | 
			
		||||
            if (ResultFs.PathNotFound.Includes(result))
 | 
			
		||||
            {
 | 
			
		||||
                Result result = pfs.OpenFile(ref npdmFile.Ref, "/main.npdm".ToU8Span(), OpenMode.Read);
 | 
			
		||||
                Npdm npdm = new(npdmFile.Get.AsStream());
 | 
			
		||||
 | 
			
		||||
                if (ResultFs.PathNotFound.Includes(result))
 | 
			
		||||
                {
 | 
			
		||||
                    Npdm npdm = new(npdmFile.Get.AsStream());
 | 
			
		||||
 | 
			
		||||
                    data.Name = npdm.TitleName;
 | 
			
		||||
                    data.Id = npdm.Aci0.TitleId;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return data;
 | 
			
		||||
                data.Name = npdm.TitleName;
 | 
			
		||||
                data.Id = npdm.Aci0.TitleId;
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception exception)
 | 
			
		||||
            {
 | 
			
		||||
                Logger.Warning?.Print(LogClass.Application, $"The file encountered was not of a valid type. File: '{filePath}' Error: {exception.Message}");
 | 
			
		||||
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
            return data;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <exception cref="MissingKeyException">The configured key set is missing a key.</exception>
 | 
			
		||||
        /// <exception cref="InvalidDataException">The NCA header could not be decrypted.</exception>
 | 
			
		||||
        /// <exception cref="NotSupportedException">The NCA version is not supported.</exception>
 | 
			
		||||
        /// <exception cref="HorizonResultException">An error occured while reading PFS data.</exception>
 | 
			
		||||
        /// <exception cref="Ryujinx.HLE.Exceptions.InvalidNpdmException">The npdm file doesn't contain valid data.</exception>
 | 
			
		||||
        /// <exception cref="NotImplementedException">The FsAccessHeader.ContentOwnerId section is not implemented.</exception>
 | 
			
		||||
        /// <exception cref="ArgumentException">An error occured while reading bytes from the stream.</exception>
 | 
			
		||||
        /// <exception cref="EndOfStreamException">The end of the stream is reached.</exception>
 | 
			
		||||
        /// <exception cref="IOException">An I/O error occurred.</exception>
 | 
			
		||||
        private ApplicationData GetApplicationFromNsp(PartitionFileSystem pfs, string filePath)
 | 
			
		||||
        {
 | 
			
		||||
            bool isExeFs = false;
 | 
			
		||||
@@ -170,99 +176,88 @@ namespace Ryujinx.UI.App.Common
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <exception cref="MissingKeyException">The configured key set is missing a key.</exception>
 | 
			
		||||
        /// <exception cref="InvalidDataException">The NCA header could not be decrypted.</exception>
 | 
			
		||||
        /// <exception cref="NotSupportedException">The NCA version is not supported.</exception>
 | 
			
		||||
        /// <exception cref="HorizonResultException">An error occured while reading PFS data.</exception>
 | 
			
		||||
        private List<ApplicationData> GetApplicationsFromPfs(IFileSystem pfs, string filePath)
 | 
			
		||||
        {
 | 
			
		||||
            var applications = new List<ApplicationData>();
 | 
			
		||||
            string extension = Path.GetExtension(filePath).ToLower();
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            foreach ((ulong titleId, ContentMetaData content) in pfs.GetContentData(ContentMetaType.Application, _virtualFileSystem, _checkLevel))
 | 
			
		||||
            {
 | 
			
		||||
                foreach ((ulong titleId, ContentMetaData content) in pfs.GetContentData(ContentMetaType.Application, _virtualFileSystem, _checkLevel))
 | 
			
		||||
                ApplicationData applicationData = new()
 | 
			
		||||
                {
 | 
			
		||||
                    ApplicationData applicationData = new()
 | 
			
		||||
                    Id = titleId,
 | 
			
		||||
                    Path = filePath,
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                Nca mainNca = content.GetNcaByType(_virtualFileSystem.KeySet, ContentType.Program);
 | 
			
		||||
                Nca controlNca = content.GetNcaByType(_virtualFileSystem.KeySet, ContentType.Control);
 | 
			
		||||
 | 
			
		||||
                BlitStruct<ApplicationControlProperty> controlHolder = new(1);
 | 
			
		||||
 | 
			
		||||
                IFileSystem controlFs = controlNca?.OpenFileSystem(NcaSectionType.Data, _checkLevel);
 | 
			
		||||
 | 
			
		||||
                // Check if there is an update available.
 | 
			
		||||
                if (IsUpdateApplied(mainNca, out IFileSystem updatedControlFs))
 | 
			
		||||
                {
 | 
			
		||||
                    // Replace the original ControlFs by the updated one.
 | 
			
		||||
                    controlFs = updatedControlFs;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (controlFs == null)
 | 
			
		||||
                {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                ReadControlData(controlFs, controlHolder.ByteSpan);
 | 
			
		||||
 | 
			
		||||
                GetApplicationInformation(ref controlHolder.Value, ref applicationData);
 | 
			
		||||
 | 
			
		||||
                // Read the icon from the ControlFS and store it as a byte array
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    using UniqueRef<IFile> icon = new();
 | 
			
		||||
 | 
			
		||||
                    controlFs.OpenFile(ref icon.Ref, $"/icon_{_desiredTitleLanguage}.dat".ToU8Span(), OpenMode.Read).ThrowIfFailure();
 | 
			
		||||
 | 
			
		||||
                    using MemoryStream stream = new();
 | 
			
		||||
 | 
			
		||||
                    icon.Get.AsStream().CopyTo(stream);
 | 
			
		||||
                    applicationData.Icon = stream.ToArray();
 | 
			
		||||
                }
 | 
			
		||||
                catch (HorizonResultException)
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (DirectoryEntryEx entry in controlFs.EnumerateEntries("/", "*"))
 | 
			
		||||
                    {
 | 
			
		||||
                        Id = titleId,
 | 
			
		||||
                        Path = filePath,
 | 
			
		||||
                    };
 | 
			
		||||
                        if (entry.Name == "control.nacp")
 | 
			
		||||
                        {
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                    Nca mainNca = content.GetNcaByType(_virtualFileSystem.KeySet, ContentType.Program);
 | 
			
		||||
                    Nca controlNca = content.GetNcaByType(_virtualFileSystem.KeySet, ContentType.Control);
 | 
			
		||||
                        using var icon = new UniqueRef<IFile>();
 | 
			
		||||
 | 
			
		||||
                    BlitStruct<ApplicationControlProperty> controlHolder = new(1);
 | 
			
		||||
 | 
			
		||||
                    IFileSystem controlFs = controlNca?.OpenFileSystem(NcaSectionType.Data, _checkLevel);
 | 
			
		||||
 | 
			
		||||
                    // Check if there is an update available.
 | 
			
		||||
                    if (IsUpdateApplied(mainNca, out IFileSystem updatedControlFs))
 | 
			
		||||
                    {
 | 
			
		||||
                        // Replace the original ControlFs by the updated one.
 | 
			
		||||
                        controlFs = updatedControlFs;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (controlFs == null)
 | 
			
		||||
                    {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    ReadControlData(controlFs, controlHolder.ByteSpan);
 | 
			
		||||
 | 
			
		||||
                    GetApplicationInformation(ref controlHolder.Value, ref applicationData);
 | 
			
		||||
 | 
			
		||||
                    // Read the icon from the ControlFS and store it as a byte array
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        using UniqueRef<IFile> icon = new();
 | 
			
		||||
 | 
			
		||||
                        controlFs.OpenFile(ref icon.Ref, $"/icon_{_desiredTitleLanguage}.dat".ToU8Span(), OpenMode.Read).ThrowIfFailure();
 | 
			
		||||
                        controlFs.OpenFile(ref icon.Ref, entry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
 | 
			
		||||
 | 
			
		||||
                        using MemoryStream stream = new();
 | 
			
		||||
 | 
			
		||||
                        icon.Get.AsStream().CopyTo(stream);
 | 
			
		||||
                        applicationData.Icon = stream.ToArray();
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (HorizonResultException)
 | 
			
		||||
                    {
 | 
			
		||||
                        foreach (DirectoryEntryEx entry in controlFs.EnumerateEntries("/", "*"))
 | 
			
		||||
 | 
			
		||||
                        if (applicationData.Icon != null)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (entry.Name == "control.nacp")
 | 
			
		||||
                            {
 | 
			
		||||
                                continue;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            using var icon = new UniqueRef<IFile>();
 | 
			
		||||
 | 
			
		||||
                            controlFs.OpenFile(ref icon.Ref, entry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
 | 
			
		||||
 | 
			
		||||
                            using MemoryStream stream = new();
 | 
			
		||||
 | 
			
		||||
                            icon.Get.AsStream().CopyTo(stream);
 | 
			
		||||
                            applicationData.Icon = stream.ToArray();
 | 
			
		||||
 | 
			
		||||
                            if (applicationData.Icon != null)
 | 
			
		||||
                            {
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        applicationData.Icon ??= extension == ".xci" ? _xciIcon : _nspIcon;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    applicationData.ControlHolder = controlHolder;
 | 
			
		||||
 | 
			
		||||
                    applications.Add(applicationData);
 | 
			
		||||
                    applicationData.Icon ??= extension == ".xci" ? _xciIcon : _nspIcon;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (MissingKeyException exception)
 | 
			
		||||
            {
 | 
			
		||||
                Logger.Warning?.Print(LogClass.Application, $"Your key set is missing a key with the name: {exception.Name}");
 | 
			
		||||
            }
 | 
			
		||||
            catch (InvalidDataException)
 | 
			
		||||
            {
 | 
			
		||||
                Logger.Warning?.Print(LogClass.Application, $"The header key is incorrect or missing and therefore the NCA header content type check has failed. Errored File: {filePath}");
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception exception)
 | 
			
		||||
            {
 | 
			
		||||
                Logger.Warning?.Print(LogClass.Application, $"The file encountered was not of a valid type. File: '{filePath}' Error: {exception}");
 | 
			
		||||
 | 
			
		||||
                applicationData.ControlHolder = controlHolder;
 | 
			
		||||
 | 
			
		||||
                applications.Add(applicationData);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return applications;
 | 
			
		||||
@@ -319,52 +314,43 @@ namespace Ryujinx.UI.App.Common
 | 
			
		||||
                            BinaryReader reader = new(file);
 | 
			
		||||
                            ApplicationData application = new();
 | 
			
		||||
 | 
			
		||||
                            try
 | 
			
		||||
                            file.Seek(24, SeekOrigin.Begin);
 | 
			
		||||
 | 
			
		||||
                            int assetOffset = reader.ReadInt32();
 | 
			
		||||
 | 
			
		||||
                            if (Encoding.ASCII.GetString(Read(assetOffset, 4)) == "ASET")
 | 
			
		||||
                            {
 | 
			
		||||
                                file.Seek(24, SeekOrigin.Begin);
 | 
			
		||||
                                byte[] iconSectionInfo = Read(assetOffset + 8, 0x10);
 | 
			
		||||
 | 
			
		||||
                                int assetOffset = reader.ReadInt32();
 | 
			
		||||
                                long iconOffset = BitConverter.ToInt64(iconSectionInfo, 0);
 | 
			
		||||
                                long iconSize = BitConverter.ToInt64(iconSectionInfo, 8);
 | 
			
		||||
 | 
			
		||||
                                if (Encoding.ASCII.GetString(Read(assetOffset, 4)) == "ASET")
 | 
			
		||||
                                ulong nacpOffset = reader.ReadUInt64();
 | 
			
		||||
                                ulong nacpSize = reader.ReadUInt64();
 | 
			
		||||
 | 
			
		||||
                                // Reads and stores game icon as byte array
 | 
			
		||||
                                if (iconSize > 0)
 | 
			
		||||
                                {
 | 
			
		||||
                                    byte[] iconSectionInfo = Read(assetOffset + 8, 0x10);
 | 
			
		||||
 | 
			
		||||
                                    long iconOffset = BitConverter.ToInt64(iconSectionInfo, 0);
 | 
			
		||||
                                    long iconSize = BitConverter.ToInt64(iconSectionInfo, 8);
 | 
			
		||||
 | 
			
		||||
                                    ulong nacpOffset = reader.ReadUInt64();
 | 
			
		||||
                                    ulong nacpSize = reader.ReadUInt64();
 | 
			
		||||
 | 
			
		||||
                                    // Reads and stores game icon as byte array
 | 
			
		||||
                                    if (iconSize > 0)
 | 
			
		||||
                                    {
 | 
			
		||||
                                        application.Icon = Read(assetOffset + iconOffset, (int)iconSize);
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else
 | 
			
		||||
                                    {
 | 
			
		||||
                                        application.Icon = _nroIcon;
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    // Read the NACP data
 | 
			
		||||
                                    Read(assetOffset + (int)nacpOffset, (int)nacpSize).AsSpan().CopyTo(controlHolder.ByteSpan);
 | 
			
		||||
 | 
			
		||||
                                    GetApplicationInformation(ref controlHolder.Value, ref application);
 | 
			
		||||
                                    application.Icon = Read(assetOffset + iconOffset, (int)iconSize);
 | 
			
		||||
                                }
 | 
			
		||||
                                else
 | 
			
		||||
                                {
 | 
			
		||||
                                    application.Icon = _nroIcon;
 | 
			
		||||
                                    application.Name = Path.GetFileNameWithoutExtension(applicationPath);
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                application.ControlHolder = controlHolder;
 | 
			
		||||
                                applications.Add(application);
 | 
			
		||||
                            }
 | 
			
		||||
                            catch
 | 
			
		||||
                            {
 | 
			
		||||
                                Logger.Warning?.Print(LogClass.Application, $"The file encountered was not of a valid type. Errored File: {applicationPath}");
 | 
			
		||||
                                // Read the NACP data
 | 
			
		||||
                                Read(assetOffset + (int)nacpOffset, (int)nacpSize).AsSpan().CopyTo(controlHolder.ByteSpan);
 | 
			
		||||
 | 
			
		||||
                                return false;
 | 
			
		||||
                                GetApplicationInformation(ref controlHolder.Value, ref application);
 | 
			
		||||
                            }
 | 
			
		||||
                            else
 | 
			
		||||
                            {
 | 
			
		||||
                                application.Icon = _nroIcon;
 | 
			
		||||
                                application.Name = Path.GetFileNameWithoutExtension(applicationPath);
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            application.ControlHolder = controlHolder;
 | 
			
		||||
                            applications.Add(application);
 | 
			
		||||
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
@@ -377,34 +363,21 @@ namespace Ryujinx.UI.App.Common
 | 
			
		||||
                        }
 | 
			
		||||
                    case ".nca":
 | 
			
		||||
                        {
 | 
			
		||||
                            try
 | 
			
		||||
                            ApplicationData application = new();
 | 
			
		||||
 | 
			
		||||
                            Nca nca = new(_virtualFileSystem.KeySet, new FileStream(applicationPath, FileMode.Open, FileAccess.Read).AsStorage());
 | 
			
		||||
 | 
			
		||||
                            if (!nca.IsProgram() || nca.IsPatch())
 | 
			
		||||
                            {
 | 
			
		||||
                                ApplicationData application = new();
 | 
			
		||||
 | 
			
		||||
                                Nca nca = new(_virtualFileSystem.KeySet, new FileStream(applicationPath, FileMode.Open, FileAccess.Read).AsStorage());
 | 
			
		||||
 | 
			
		||||
                                if (!nca.IsProgram() || nca.IsPatch())
 | 
			
		||||
                                {
 | 
			
		||||
                                    return false;
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                application.Icon = _ncaIcon;
 | 
			
		||||
                                application.Name = Path.GetFileNameWithoutExtension(applicationPath);
 | 
			
		||||
                                application.ControlHolder = controlHolder;
 | 
			
		||||
 | 
			
		||||
                                applications.Add(application);
 | 
			
		||||
                            }
 | 
			
		||||
                            catch (InvalidDataException)
 | 
			
		||||
                            {
 | 
			
		||||
                                Logger.Warning?.Print(LogClass.Application, $"The NCA header content type check has failed. This is usually because the header key is incorrect or missing. Errored File: {applicationPath}");
 | 
			
		||||
                            }
 | 
			
		||||
                            catch
 | 
			
		||||
                            {
 | 
			
		||||
                                Logger.Warning?.Print(LogClass.Application, $"The file encountered was not of a valid type. Errored File: {applicationPath}");
 | 
			
		||||
 | 
			
		||||
                                return false;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            application.Icon = _ncaIcon;
 | 
			
		||||
                            application.Name = Path.GetFileNameWithoutExtension(applicationPath);
 | 
			
		||||
                            application.ControlHolder = controlHolder;
 | 
			
		||||
 | 
			
		||||
                            applications.Add(application);
 | 
			
		||||
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
                    // If its an NSO we just set defaults
 | 
			
		||||
@@ -417,16 +390,35 @@ namespace Ryujinx.UI.App.Common
 | 
			
		||||
                            };
 | 
			
		||||
 | 
			
		||||
                            applications.Add(application);
 | 
			
		||||
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (MissingKeyException exception)
 | 
			
		||||
            {
 | 
			
		||||
                Logger.Warning?.Print(LogClass.Application, $"Your key set is missing a key with the name: {exception.Name}");
 | 
			
		||||
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            catch (InvalidDataException)
 | 
			
		||||
            {
 | 
			
		||||
                Logger.Warning?.Print(LogClass.Application, $"The header key is incorrect or missing and therefore the NCA header content type check has failed. Errored File: {applicationPath}");
 | 
			
		||||
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            catch (IOException exception)
 | 
			
		||||
            {
 | 
			
		||||
                Logger.Warning?.Print(LogClass.Application, exception.Message);
 | 
			
		||||
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception exception)
 | 
			
		||||
            {
 | 
			
		||||
                Logger.Warning?.Print(LogClass.Application, $"The file encountered was not of a valid type. File: '{applicationPath}' Error: {exception}");
 | 
			
		||||
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            foreach (var data in applications)
 | 
			
		||||
            {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user