aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.UI.Common/App/ApplicationLibrary.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.UI.Common/App/ApplicationLibrary.cs')
-rw-r--r--src/Ryujinx.UI.Common/App/ApplicationLibrary.cs260
1 files changed, 126 insertions, 134 deletions
diff --git a/src/Ryujinx.UI.Common/App/ApplicationLibrary.cs b/src/Ryujinx.UI.Common/App/ApplicationLibrary.cs
index 2baf0608..e7c48162 100644
--- a/src/Ryujinx.UI.Common/App/ApplicationLibrary.cs
+++ b/src/Ryujinx.UI.Common/App/ApplicationLibrary.cs
@@ -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))
- {
- Npdm npdm = new(npdmFile.Get.AsStream());
+ Result result = pfs.OpenFile(ref npdmFile.Ref, "/main.npdm".ToU8Span(), OpenMode.Read);
- data.Name = npdm.TitleName;
- data.Id = npdm.Aci0.TitleId;
- }
-
- return data;
- }
- catch (Exception exception)
+ if (ResultFs.PathNotFound.Includes(result))
{
- Logger.Warning?.Print(LogClass.Application, $"The file encountered was not of a valid type. File: '{filePath}' Error: {exception.Message}");
+ Npdm npdm = new(npdmFile.Get.AsStream());
- return null;
+ data.Name = npdm.TitleName;
+ data.Id = npdm.Aci0.TitleId;
}
+
+ 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,
- };
+ Id = titleId,
+ Path = filePath,
+ };
- Nca mainNca = content.GetNcaByType(_virtualFileSystem.KeySet, ContentType.Program);
- Nca controlNca = content.GetNcaByType(_virtualFileSystem.KeySet, ContentType.Control);
+ Nca mainNca = content.GetNcaByType(_virtualFileSystem.KeySet, ContentType.Program);
+ Nca controlNca = content.GetNcaByType(_virtualFileSystem.KeySet, ContentType.Control);
- BlitStruct<ApplicationControlProperty> controlHolder = new(1);
+ BlitStruct<ApplicationControlProperty> controlHolder = new(1);
- IFileSystem controlFs = controlNca?.OpenFileSystem(NcaSectionType.Data, _checkLevel);
+ 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;
- }
+ // 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;
- }
+ if (controlFs == null)
+ {
+ continue;
+ }
- ReadControlData(controlFs, controlHolder.ByteSpan);
+ ReadControlData(controlFs, controlHolder.ByteSpan);
- GetApplicationInformation(ref controlHolder.Value, ref applicationData);
+ 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();
+ // 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, $"/icon_{_desiredTitleLanguage}.dat".ToU8Span(), OpenMode.Read).ThrowIfFailure();
- using MemoryStream stream = new();
+ using MemoryStream stream = new();
- icon.Get.AsStream().CopyTo(stream);
- applicationData.Icon = stream.ToArray();
- }
- catch (HorizonResultException)
+ icon.Get.AsStream().CopyTo(stream);
+ applicationData.Icon = stream.ToArray();
+ }
+ catch (HorizonResultException)
+ {
+ foreach (DirectoryEntryEx entry in controlFs.EnumerateEntries("/", "*"))
{
- foreach (DirectoryEntryEx entry in controlFs.EnumerateEntries("/", "*"))
+ if (entry.Name == "control.nacp")
{
- if (entry.Name == "control.nacp")
- {
- continue;
- }
+ continue;
+ }
- using var icon = new UniqueRef<IFile>();
+ using var icon = new UniqueRef<IFile>();
- controlFs.OpenFile(ref icon.Ref, entry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
+ controlFs.OpenFile(ref icon.Ref, entry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
- using MemoryStream stream = new();
+ using MemoryStream stream = new();
- icon.Get.AsStream().CopyTo(stream);
- applicationData.Icon = stream.ToArray();
+ icon.Get.AsStream().CopyTo(stream);
+ applicationData.Icon = stream.ToArray();
- if (applicationData.Icon != null)
- {
- break;
- }
+ if (applicationData.Icon != null)
+ {
+ 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,53 +314,44 @@ 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")
- {
- byte[] iconSectionInfo = Read(assetOffset + 8, 0x10);
+ file.Seek(24, SeekOrigin.Begin);
- long iconOffset = BitConverter.ToInt64(iconSectionInfo, 0);
- long iconSize = BitConverter.ToInt64(iconSectionInfo, 8);
+ int assetOffset = reader.ReadInt32();
- ulong nacpOffset = reader.ReadUInt64();
- ulong nacpSize = reader.ReadUInt64();
+ if (Encoding.ASCII.GetString(Read(assetOffset, 4)) == "ASET")
+ {
+ byte[] iconSectionInfo = Read(assetOffset + 8, 0x10);
- // Reads and stores game icon as byte array
- if (iconSize > 0)
- {
- application.Icon = Read(assetOffset + iconOffset, (int)iconSize);
- }
- else
- {
- application.Icon = _nroIcon;
- }
+ long iconOffset = BitConverter.ToInt64(iconSectionInfo, 0);
+ long iconSize = BitConverter.ToInt64(iconSectionInfo, 8);
- // Read the NACP data
- Read(assetOffset + (int)nacpOffset, (int)nacpSize).AsSpan().CopyTo(controlHolder.ByteSpan);
+ ulong nacpOffset = reader.ReadUInt64();
+ ulong nacpSize = reader.ReadUInt64();
- GetApplicationInformation(ref controlHolder.Value, ref application);
+ // Reads and stores game icon as byte array
+ if (iconSize > 0)
+ {
+ application.Icon = Read(assetOffset + iconOffset, (int)iconSize);
}
else
{
application.Icon = _nroIcon;
- application.Name = Path.GetFileNameWithoutExtension(applicationPath);
}
- application.ControlHolder = controlHolder;
- applications.Add(application);
+ // Read the NACP data
+ Read(assetOffset + (int)nacpOffset, (int)nacpSize).AsSpan().CopyTo(controlHolder.ByteSpan);
+
+ GetApplicationInformation(ref controlHolder.Value, ref application);
}
- catch
+ else
{
- Logger.Warning?.Print(LogClass.Application, $"The file encountered was not of a valid type. Errored File: {applicationPath}");
-
- return false;
+ application.Icon = _nroIcon;
+ application.Name = Path.GetFileNameWithoutExtension(applicationPath);
}
+ application.ControlHolder = controlHolder;
+ applications.Add(application);
+
break;
byte[] Read(long position, int size)
@@ -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())
- {
- return false;
- }
+ ApplicationData application = new();
- application.Icon = _ncaIcon;
- application.Name = Path.GetFileNameWithoutExtension(applicationPath);
- application.ControlHolder = controlHolder;
+ Nca nca = new(_virtualFileSystem.KeySet, new FileStream(applicationPath, FileMode.Open, FileAccess.Read).AsStorage());
- applications.Add(application);
- }
- catch (InvalidDataException)
+ if (!nca.IsProgram() || nca.IsPatch())
{
- 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)
{