aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/Loaders
diff options
context:
space:
mode:
authorTSR Berry <20988865+TSRBerry@users.noreply.github.com>2023-04-08 01:22:00 +0200
committerMary <thog@protonmail.com>2023-04-27 23:51:14 +0200
commitcee712105850ac3385cd0091a923438167433f9f (patch)
tree4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /Ryujinx.HLE/Loaders
parentcd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff)
Move solution and projects to src
Diffstat (limited to 'Ryujinx.HLE/Loaders')
-rw-r--r--Ryujinx.HLE/Loaders/Elf/ElfDynamic.cs15
-rw-r--r--Ryujinx.HLE/Loaders/Elf/ElfDynamicTag.cs75
-rw-r--r--Ryujinx.HLE/Loaders/Elf/ElfSymbol.cs35
-rw-r--r--Ryujinx.HLE/Loaders/Elf/ElfSymbol32.cs14
-rw-r--r--Ryujinx.HLE/Loaders/Elf/ElfSymbol64.cs14
-rw-r--r--Ryujinx.HLE/Loaders/Elf/ElfSymbolBinding.cs9
-rw-r--r--Ryujinx.HLE/Loaders/Elf/ElfSymbolType.cs13
-rw-r--r--Ryujinx.HLE/Loaders/Elf/ElfSymbolVisibility.cs10
-rw-r--r--Ryujinx.HLE/Loaders/Executables/IExecutable.cs18
-rw-r--r--Ryujinx.HLE/Loaders/Executables/KipExecutable.cs86
-rw-r--r--Ryujinx.HLE/Loaders/Executables/NroExecutable.cs38
-rw-r--r--Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs123
-rw-r--r--Ryujinx.HLE/Loaders/Mods/IPSPatcher.cs117
-rw-r--r--Ryujinx.HLE/Loaders/Mods/IPSwitchPatcher.cs275
-rw-r--r--Ryujinx.HLE/Loaders/Mods/MemPatch.cs96
-rw-r--r--Ryujinx.HLE/Loaders/Npdm/ACI0.cs53
-rw-r--r--Ryujinx.HLE/Loaders/Npdm/ACID.cs61
-rw-r--r--Ryujinx.HLE/Loaders/Npdm/FsAccessControl.cs28
-rw-r--r--Ryujinx.HLE/Loaders/Npdm/FsAccessHeader.cs37
-rw-r--r--Ryujinx.HLE/Loaders/Npdm/KernelAccessControl.cs23
-rw-r--r--Ryujinx.HLE/Loaders/Npdm/Npdm.cs72
-rw-r--r--Ryujinx.HLE/Loaders/Npdm/ServiceAccessControl.cs42
-rw-r--r--Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs133
-rw-r--r--Ryujinx.HLE/Loaders/Processes/Extensions/LocalFileSystemExtensions.cs39
-rw-r--r--Ryujinx.HLE/Loaders/Processes/Extensions/MetaLoaderExtensions.cs61
-rw-r--r--Ryujinx.HLE/Loaders/Processes/Extensions/NcaExtensions.cs175
-rw-r--r--Ryujinx.HLE/Loaders/Processes/Extensions/PartitionFileSystemExtensions.cs180
-rw-r--r--Ryujinx.HLE/Loaders/Processes/ProcessConst.cs33
-rw-r--r--Ryujinx.HLE/Loaders/Processes/ProcessLoader.cs244
-rw-r--r--Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs467
-rw-r--r--Ryujinx.HLE/Loaders/Processes/ProcessResult.cs94
31 files changed, 0 insertions, 2680 deletions
diff --git a/Ryujinx.HLE/Loaders/Elf/ElfDynamic.cs b/Ryujinx.HLE/Loaders/Elf/ElfDynamic.cs
deleted file mode 100644
index f489e85a..00000000
--- a/Ryujinx.HLE/Loaders/Elf/ElfDynamic.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace Ryujinx.HLE.Loaders.Elf
-{
- struct ElfDynamic
- {
- public ElfDynamicTag Tag { get; private set; }
-
- public long Value { get; private set; }
-
- public ElfDynamic(ElfDynamicTag tag, long value)
- {
- Tag = tag;
- Value = value;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Elf/ElfDynamicTag.cs b/Ryujinx.HLE/Loaders/Elf/ElfDynamicTag.cs
deleted file mode 100644
index eb37d612..00000000
--- a/Ryujinx.HLE/Loaders/Elf/ElfDynamicTag.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-using System.Diagnostics.CodeAnalysis;
-
-namespace Ryujinx.HLE.Loaders.Elf
-{
- [SuppressMessage("ReSharper", "InconsistentNaming")]
- enum ElfDynamicTag
- {
- DT_NULL = 0,
- DT_NEEDED = 1,
- DT_PLTRELSZ = 2,
- DT_PLTGOT = 3,
- DT_HASH = 4,
- DT_STRTAB = 5,
- DT_SYMTAB = 6,
- DT_RELA = 7,
- DT_RELASZ = 8,
- DT_RELAENT = 9,
- DT_STRSZ = 10,
- DT_SYMENT = 11,
- DT_INIT = 12,
- DT_FINI = 13,
- DT_SONAME = 14,
- DT_RPATH = 15,
- DT_SYMBOLIC = 16,
- DT_REL = 17,
- DT_RELSZ = 18,
- DT_RELENT = 19,
- DT_PLTREL = 20,
- DT_DEBUG = 21,
- DT_TEXTREL = 22,
- DT_JMPREL = 23,
- DT_BIND_NOW = 24,
- DT_INIT_ARRAY = 25,
- DT_FINI_ARRAY = 26,
- DT_INIT_ARRAYSZ = 27,
- DT_FINI_ARRAYSZ = 28,
- DT_RUNPATH = 29,
- DT_FLAGS = 30,
- DT_ENCODING = 32,
- DT_PREINIT_ARRAY = 32,
- DT_PREINIT_ARRAYSZ = 33,
- DT_GNU_PRELINKED = 0x6ffffdf5,
- DT_GNU_CONFLICTSZ = 0x6ffffdf6,
- DT_GNU_LIBLISTSZ = 0x6ffffdf7,
- DT_CHECKSUM = 0x6ffffdf8,
- DT_PLTPADSZ = 0x6ffffdf9,
- DT_MOVEENT = 0x6ffffdfa,
- DT_MOVESZ = 0x6ffffdfb,
- DT_FEATURE_1 = 0x6ffffdfc,
- DT_POSFLAG_1 = 0x6ffffdfd,
- DT_SYMINSZ = 0x6ffffdfe,
- DT_SYMINENT = 0x6ffffdff,
- DT_GNU_HASH = 0x6ffffef5,
- DT_TLSDESC_PLT = 0x6ffffef6,
- DT_TLSDESC_GOT = 0x6ffffef7,
- DT_GNU_CONFLICT = 0x6ffffef8,
- DT_GNU_LIBLIST = 0x6ffffef9,
- DT_CONFIG = 0x6ffffefa,
- DT_DEPAUDIT = 0x6ffffefb,
- DT_AUDIT = 0x6ffffefc,
- DT_PLTPAD = 0x6ffffefd,
- DT_MOVETAB = 0x6ffffefe,
- DT_SYMINFO = 0x6ffffeff,
- DT_VERSYM = 0x6ffffff0,
- DT_RELACOUNT = 0x6ffffff9,
- DT_RELCOUNT = 0x6ffffffa,
- DT_FLAGS_1 = 0x6ffffffb,
- DT_VERDEF = 0x6ffffffc,
- DT_VERDEFNUM = 0x6ffffffd,
- DT_VERNEED = 0x6ffffffe,
- DT_VERNEEDNUM = 0x6fffffff,
- DT_AUXILIARY = 0x7ffffffd,
- DT_FILTER = 0x7fffffff
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Elf/ElfSymbol.cs b/Ryujinx.HLE/Loaders/Elf/ElfSymbol.cs
deleted file mode 100644
index 1cfc0bdc..00000000
--- a/Ryujinx.HLE/Loaders/Elf/ElfSymbol.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-namespace Ryujinx.HLE.Loaders.Elf
-{
- struct ElfSymbol
- {
- public string Name { get; private set; }
-
- public ElfSymbolType Type { get; private set; }
- public ElfSymbolBinding Binding { get; private set; }
- public ElfSymbolVisibility Visibility { get; private set; }
-
- public bool IsFuncOrObject => Type == ElfSymbolType.SttFunc || Type == ElfSymbolType.SttObject;
- public bool IsGlobalOrWeak => Binding == ElfSymbolBinding.StbGlobal || Binding == ElfSymbolBinding.StbWeak;
-
- public int ShIdx { get; private set; }
- public ulong Value { get; private set; }
- public ulong Size { get; private set; }
-
- public ElfSymbol(
- string name,
- int info,
- int other,
- int shIdx,
- ulong value,
- ulong size)
- {
- Name = name;
- Type = (ElfSymbolType)(info & 0xf);
- Binding = (ElfSymbolBinding)(info >> 4);
- Visibility = (ElfSymbolVisibility)other;
- ShIdx = shIdx;
- Value = value;
- Size = size;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Elf/ElfSymbol32.cs b/Ryujinx.HLE/Loaders/Elf/ElfSymbol32.cs
deleted file mode 100644
index 2f84796b..00000000
--- a/Ryujinx.HLE/Loaders/Elf/ElfSymbol32.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace Ryujinx.HLE.Loaders.Elf
-{
- struct ElfSymbol32
- {
-#pragma warning disable CS0649
- public uint NameOffset;
- public uint ValueAddress;
- public uint Size;
- public byte Info;
- public byte Other;
- public ushort SectionIndex;
-#pragma warning restore CS0649
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Elf/ElfSymbol64.cs b/Ryujinx.HLE/Loaders/Elf/ElfSymbol64.cs
deleted file mode 100644
index 665e65b0..00000000
--- a/Ryujinx.HLE/Loaders/Elf/ElfSymbol64.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace Ryujinx.HLE.Loaders.Elf
-{
- struct ElfSymbol64
- {
-#pragma warning disable CS0649
- public uint NameOffset;
- public byte Info;
- public byte Other;
- public ushort SectionIndex;
- public ulong ValueAddress;
- public ulong Size;
-#pragma warning restore CS0649
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Elf/ElfSymbolBinding.cs b/Ryujinx.HLE/Loaders/Elf/ElfSymbolBinding.cs
deleted file mode 100644
index 92274fde..00000000
--- a/Ryujinx.HLE/Loaders/Elf/ElfSymbolBinding.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Ryujinx.HLE.Loaders.Elf
-{
- enum ElfSymbolBinding
- {
- StbLocal = 0,
- StbGlobal = 1,
- StbWeak = 2
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Elf/ElfSymbolType.cs b/Ryujinx.HLE/Loaders/Elf/ElfSymbolType.cs
deleted file mode 100644
index 4110d4c3..00000000
--- a/Ryujinx.HLE/Loaders/Elf/ElfSymbolType.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Ryujinx.HLE.Loaders.Elf
-{
- enum ElfSymbolType
- {
- SttNoType = 0,
- SttObject = 1,
- SttFunc = 2,
- SttSection = 3,
- SttFile = 4,
- SttCommon = 5,
- SttTls = 6
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Elf/ElfSymbolVisibility.cs b/Ryujinx.HLE/Loaders/Elf/ElfSymbolVisibility.cs
deleted file mode 100644
index f026fca8..00000000
--- a/Ryujinx.HLE/Loaders/Elf/ElfSymbolVisibility.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Ryujinx.HLE.Loaders.Elf
-{
- enum ElfSymbolVisibility
- {
- StvDefault = 0,
- StvInternal = 1,
- StvHidden = 2,
- StvProtected = 3
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Executables/IExecutable.cs b/Ryujinx.HLE/Loaders/Executables/IExecutable.cs
deleted file mode 100644
index 27479efe..00000000
--- a/Ryujinx.HLE/Loaders/Executables/IExecutable.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System;
-
-namespace Ryujinx.HLE.Loaders.Executables
-{
- interface IExecutable
- {
- byte[] Program { get; }
- Span<byte> Text { get; }
- Span<byte> Ro { get; }
- Span<byte> Data { get; }
-
- uint TextOffset { get; }
- uint RoOffset { get; }
- uint DataOffset { get; }
- uint BssOffset { get; }
- uint BssSize { get; }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Executables/KipExecutable.cs b/Ryujinx.HLE/Loaders/Executables/KipExecutable.cs
deleted file mode 100644
index ad2b681c..00000000
--- a/Ryujinx.HLE/Loaders/Executables/KipExecutable.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-using LibHac.Common;
-using LibHac.Fs;
-using LibHac.Kernel;
-using System;
-
-namespace Ryujinx.HLE.Loaders.Executables
-{
- class KipExecutable : IExecutable
- {
- public byte[] Program { get; }
- public Span<byte> Text => Program.AsSpan((int)TextOffset, (int)TextSize);
- public Span<byte> Ro => Program.AsSpan((int)RoOffset, (int)RoSize);
- public Span<byte> Data => Program.AsSpan((int)DataOffset, (int)DataSize);
-
- public uint TextOffset { get; }
- public uint RoOffset { get; }
- public uint DataOffset { get; }
- public uint BssOffset { get; }
-
- public uint TextSize { get; }
- public uint RoSize { get; }
- public uint DataSize { get; }
- public uint BssSize { get; }
-
- public uint[] Capabilities { get; }
- public bool UsesSecureMemory { get; }
- public bool Is64BitAddressSpace { get; }
- public bool Is64Bit { get; }
- public ulong ProgramId { get; }
- public byte Priority { get; }
- public int StackSize { get; }
- public byte IdealCoreId { get; }
- public int Version { get; }
- public string Name { get; }
-
- public KipExecutable(in SharedRef<IStorage> inStorage)
- {
- KipReader reader = new KipReader();
-
- reader.Initialize(in inStorage).ThrowIfFailure();
-
- TextOffset = (uint)reader.Segments[0].MemoryOffset;
- RoOffset = (uint)reader.Segments[1].MemoryOffset;
- DataOffset = (uint)reader.Segments[2].MemoryOffset;
- BssOffset = (uint)reader.Segments[3].MemoryOffset;
- BssSize = (uint)reader.Segments[3].Size;
-
- StackSize = reader.StackSize;
-
- UsesSecureMemory = reader.UsesSecureMemory;
- Is64BitAddressSpace = reader.Is64BitAddressSpace;
- Is64Bit = reader.Is64Bit;
-
- ProgramId = reader.ProgramId;
- Priority = reader.Priority;
- IdealCoreId = reader.IdealCoreId;
- Version = reader.Version;
- Name = reader.Name.ToString();
-
- Capabilities = new uint[32];
-
- for (int index = 0; index < Capabilities.Length; index++)
- {
- Capabilities[index] = reader.Capabilities[index];
- }
-
- reader.GetSegmentSize(KipReader.SegmentType.Data, out int uncompressedSize).ThrowIfFailure();
- Program = new byte[DataOffset + uncompressedSize];
-
- TextSize = DecompressSection(reader, KipReader.SegmentType.Text, TextOffset, Program);
- RoSize = DecompressSection(reader, KipReader.SegmentType.Ro, RoOffset, Program);
- DataSize = DecompressSection(reader, KipReader.SegmentType.Data, DataOffset, Program);
- }
-
- private static uint DecompressSection(KipReader reader, KipReader.SegmentType segmentType, uint offset, byte[] program)
- {
- reader.GetSegmentSize(segmentType, out int uncompressedSize).ThrowIfFailure();
-
- var span = program.AsSpan((int)offset, uncompressedSize);
-
- reader.ReadSegment(segmentType, span).ThrowIfFailure();
-
- return (uint)uncompressedSize;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Executables/NroExecutable.cs b/Ryujinx.HLE/Loaders/Executables/NroExecutable.cs
deleted file mode 100644
index 621ab43b..00000000
--- a/Ryujinx.HLE/Loaders/Executables/NroExecutable.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using LibHac.Fs;
-using LibHac.Tools.Ro;
-using System;
-
-namespace Ryujinx.HLE.Loaders.Executables
-{
- class NroExecutable : Nro, IExecutable
- {
- public byte[] Program { get; }
- public Span<byte> Text => Program.AsSpan((int)TextOffset, (int)Header.NroSegments[0].Size);
- public Span<byte> Ro => Program.AsSpan((int)RoOffset, (int)Header.NroSegments[1].Size);
- public Span<byte> Data => Program.AsSpan((int)DataOffset, (int)Header.NroSegments[2].Size);
-
- public uint TextOffset => Header.NroSegments[0].FileOffset;
- public uint RoOffset => Header.NroSegments[1].FileOffset;
- public uint DataOffset => Header.NroSegments[2].FileOffset;
- public uint BssOffset => DataOffset + (uint)Data.Length;
- public uint BssSize => Header.BssSize;
-
- public uint Mod0Offset => (uint)Start.Mod0Offset;
- public uint FileSize => Header.Size;
-
- public ulong SourceAddress { get; private set; }
- public ulong BssAddress { get; private set; }
-
- public NroExecutable(IStorage inStorage, ulong sourceAddress = 0, ulong bssAddress = 0) : base(inStorage)
- {
- Program = new byte[FileSize];
-
- SourceAddress = sourceAddress;
- BssAddress = bssAddress;
-
- OpenNroSegment(NroSegmentType.Text, false).Read(0, Text);
- OpenNroSegment(NroSegmentType.Ro , false).Read(0, Ro);
- OpenNroSegment(NroSegmentType.Data, false).Read(0, Data);
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs b/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs
deleted file mode 100644
index d695449b..00000000
--- a/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs
+++ /dev/null
@@ -1,123 +0,0 @@
-using LibHac.Common.FixedArrays;
-using LibHac.Fs;
-using LibHac.Loader;
-using LibHac.Tools.FsSystem;
-using Ryujinx.Common.Logging;
-using System;
-using System.Text;
-using System.Text.RegularExpressions;
-
-namespace Ryujinx.HLE.Loaders.Executables
-{
- partial class NsoExecutable : IExecutable
- {
- public byte[] Program { get; }
- public Span<byte> Text => Program.AsSpan((int)TextOffset, (int)TextSize);
- public Span<byte> Ro => Program.AsSpan((int)RoOffset, (int)RoSize);
- public Span<byte> Data => Program.AsSpan((int)DataOffset, (int)DataSize);
-
- public uint TextOffset { get; }
- public uint RoOffset { get; }
- public uint DataOffset { get; }
- public uint BssOffset => DataOffset + (uint)Data.Length;
-
- public uint TextSize { get; }
- public uint RoSize { get; }
- public uint DataSize { get; }
- public uint BssSize { get; }
-
- public string Name;
- public Array32<byte> BuildId;
-
- [GeneratedRegex(@"[a-z]:[\\/][ -~]{5,}\.nss", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)]
- private static partial Regex ModuleRegex();
- [GeneratedRegex(@"sdk_version: ([0-9.]*)")]
- private static partial Regex FsSdkRegex();
- [GeneratedRegex(@"SDK MW[ -~]*")]
- private static partial Regex SdkMwRegex();
-
- public NsoExecutable(IStorage inStorage, string name = null)
- {
- NsoReader reader = new NsoReader();
-
- reader.Initialize(inStorage.AsFile(OpenMode.Read)).ThrowIfFailure();
-
- TextOffset = reader.Header.Segments[0].MemoryOffset;
- RoOffset = reader.Header.Segments[1].MemoryOffset;
- DataOffset = reader.Header.Segments[2].MemoryOffset;
- BssSize = reader.Header.BssSize;
-
- reader.GetSegmentSize(NsoReader.SegmentType.Data, out uint uncompressedSize).ThrowIfFailure();
-
- Program = new byte[DataOffset + uncompressedSize];
-
- TextSize = DecompressSection(reader, NsoReader.SegmentType.Text, TextOffset);
- RoSize = DecompressSection(reader, NsoReader.SegmentType.Ro, RoOffset);
- DataSize = DecompressSection(reader, NsoReader.SegmentType.Data, DataOffset);
-
- Name = name;
- BuildId = reader.Header.ModuleId;
-
- PrintRoSectionInfo();
- }
-
- private uint DecompressSection(NsoReader reader, NsoReader.SegmentType segmentType, uint offset)
- {
- reader.GetSegmentSize(segmentType, out uint uncompressedSize).ThrowIfFailure();
-
- var span = Program.AsSpan((int)offset, (int)uncompressedSize);
-
- reader.ReadSegment(segmentType, span).ThrowIfFailure();
-
- return uncompressedSize;
- }
-
- private void PrintRoSectionInfo()
- {
- string rawTextBuffer = Encoding.ASCII.GetString(Ro);
- StringBuilder stringBuilder = new StringBuilder();
-
- string modulePath = null;
-
- if (BitConverter.ToInt32(Ro.Slice(0, 4)) == 0)
- {
- int length = BitConverter.ToInt32(Ro.Slice(4, 4));
- if (length > 0)
- {
- modulePath = Encoding.UTF8.GetString(Ro.Slice(8, length));
- }
- }
-
- if (string.IsNullOrEmpty(modulePath))
- {
- Match moduleMatch = ModuleRegex().Match(rawTextBuffer);
- if (moduleMatch.Success)
- {
- modulePath = moduleMatch.Value;
- }
- }
-
- stringBuilder.AppendLine($" Module: {modulePath}");
-
- Match fsSdkMatch = FsSdkRegex().Match(rawTextBuffer);
- if (fsSdkMatch.Success)
- {
- stringBuilder.AppendLine($" FS SDK Version: {fsSdkMatch.Value.Replace("sdk_version: ", "")}");
- }
-
- MatchCollection sdkMwMatches = SdkMwRegex().Matches(rawTextBuffer);
- if (sdkMwMatches.Count != 0)
- {
- string libHeader = " SDK Libraries: ";
- string libContent = string.Join($"\n{new string(' ', libHeader.Length)}", sdkMwMatches);
-
- stringBuilder.AppendLine($"{libHeader}{libContent}");
- }
-
- if (stringBuilder.Length > 0)
- {
- Logger.Info?.Print(LogClass.Loader, $"{Name}:\n{stringBuilder.ToString().TrimEnd('\r', '\n')}");
- }
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Mods/IPSPatcher.cs b/Ryujinx.HLE/Loaders/Mods/IPSPatcher.cs
deleted file mode 100644
index 510fec05..00000000
--- a/Ryujinx.HLE/Loaders/Mods/IPSPatcher.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-using Ryujinx.Common.Logging;
-using System;
-using System.IO;
-using System.Text;
-
-namespace Ryujinx.HLE.Loaders.Mods
-{
- class IpsPatcher
- {
- MemPatch _patches;
-
- public IpsPatcher(BinaryReader reader)
- {
- _patches = ParseIps(reader);
- if (_patches != null)
- {
- Logger.Info?.Print(LogClass.ModLoader, "IPS patch loaded successfully");
- }
- }
-
- private static MemPatch ParseIps(BinaryReader reader)
- {
- ReadOnlySpan<byte> IpsHeaderMagic = "PATCH"u8;
- ReadOnlySpan<byte> IpsTailMagic = "EOF"u8;
- ReadOnlySpan<byte> Ips32HeaderMagic = "IPS32"u8;
- ReadOnlySpan<byte> Ips32TailMagic = "EEOF"u8;
-
- MemPatch patches = new MemPatch();
- var header = reader.ReadBytes(IpsHeaderMagic.Length).AsSpan();
-
- if (header.Length != IpsHeaderMagic.Length)
- {
- return null;
- }
-
- bool is32;
- ReadOnlySpan<byte> tailSpan;
-
- if (header.SequenceEqual(IpsHeaderMagic))
- {
- is32 = false;
- tailSpan = IpsTailMagic;
- }
- else if (header.SequenceEqual(Ips32HeaderMagic))
- {
- is32 = true;
- tailSpan = Ips32TailMagic;
- }
- else
- {
- return null;
- }
-
- byte[] buf = new byte[tailSpan.Length];
-
- bool ReadNext(int size) => reader.Read(buf, 0, size) != size;
-
- while (true)
- {
- if (ReadNext(buf.Length))
- {
- return null;
- }
-
- if (buf.AsSpan().SequenceEqual(tailSpan))
- {
- break;
- }
-
- int patchOffset = is32 ? buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]
- : buf[0] << 16 | buf[1] << 8 | buf[2];
-
- if (ReadNext(2))
- {
- return null;
- }
-
- int patchSize = buf[0] << 8 | buf[1];
-
- if (patchSize == 0) // RLE/Fill mode
- {
- if (ReadNext(2))
- {
- return null;
- }
-
- int fillLength = buf[0] << 8 | buf[1];
-
- if (ReadNext(1))
- {
- return null;
- }
-
- patches.AddFill((uint)patchOffset, fillLength, buf[0]);
- }
- else // Copy mode
- {
- var patch = reader.ReadBytes(patchSize);
-
- if (patch.Length != patchSize)
- {
- return null;
- }
-
- patches.Add((uint)patchOffset, patch);
- }
- }
-
- return patches;
- }
-
- public void AddPatches(MemPatch patches)
- {
- patches.AddFrom(_patches);
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Mods/IPSwitchPatcher.cs b/Ryujinx.HLE/Loaders/Mods/IPSwitchPatcher.cs
deleted file mode 100644
index 416fc1b4..00000000
--- a/Ryujinx.HLE/Loaders/Mods/IPSwitchPatcher.cs
+++ /dev/null
@@ -1,275 +0,0 @@
-using Ryujinx.Common.Logging;
-using System;
-using System.IO;
-using System.Text;
-
-namespace Ryujinx.HLE.Loaders.Mods
-{
- class IPSwitchPatcher
- {
- const string BidHeader = "@nsobid-";
-
- private enum Token
- {
- Normal,
- String,
- EscapeChar,
- Comment
- }
-
- private readonly StreamReader _reader;
- public string BuildId { get; }
-
- public IPSwitchPatcher(StreamReader reader)
- {
- string header = reader.ReadLine();
- if (header == null || !header.StartsWith(BidHeader))
- {
- Logger.Error?.Print(LogClass.ModLoader, "IPSwitch: Malformed PCHTXT file. Skipping...");
-
- return;
- }
-
- _reader = reader;
- BuildId = header.Substring(BidHeader.Length).TrimEnd().TrimEnd('0');
- }
-
- // Uncomments line and unescapes C style strings within
- private static string PreprocessLine(string line)
- {
- StringBuilder str = new StringBuilder();
- Token state = Token.Normal;
-
- for (int i = 0; i < line.Length; ++i)
- {
- char c = line[i];
- char la = i + 1 != line.Length ? line[i + 1] : '\0';
-
- switch (state)
- {
- case Token.Normal:
- state = c == '"' ? Token.String :
- c == '/' && la == '/' ? Token.Comment :
- c == '/' && la != '/' ? Token.Comment : // Ignore error and stop parsing
- Token.Normal;
- break;
- case Token.String:
- state = c switch
- {
- '"' => Token.Normal,
- '\\' => Token.EscapeChar,
- _ => Token.String
- };
- break;
- case Token.EscapeChar:
- state = Token.String;
- c = c switch
- {
- 'a' => '\a',
- 'b' => '\b',
- 'f' => '\f',
- 'n' => '\n',
- 'r' => '\r',
- 't' => '\t',
- 'v' => '\v',
- '\\' => '\\',
- _ => '?'
- };
- break;
- }
-
- if (state == Token.Comment) break;
-
- if (state < Token.EscapeChar)
- {
- str.Append(c);
- }
- }
-
- return str.ToString().Trim();
- }
-
- static int ParseHexByte(byte c)
- {
- if (c >= '0' && c <= '9')
- {
- return c - '0';
- }
- else if (c >= 'A' && c <= 'F')
- {
- return c - 'A' + 10;
- }
- else if (c >= 'a' && c <= 'f')
- {
- return c - 'a' + 10;
- }
- else
- {
- return 0;
- }
- }
-
- // Big Endian
- static byte[] Hex2ByteArrayBE(string hexstr)
- {
- if ((hexstr.Length & 1) == 1) return null;
-
- byte[] bytes = new byte[hexstr.Length >> 1];
-
- for (int i = 0; i < hexstr.Length; i += 2)
- {
- int high = ParseHexByte((byte)hexstr[i]);
- int low = ParseHexByte((byte)hexstr[i + 1]);
-
- bytes[i >> 1] = (byte)((high << 4) | low);
- }
-
- return bytes;
- }
-
- // Auto base discovery
- private static bool ParseInt(string str, out int value)
- {
- if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
- {
- return int.TryParse(str.AsSpan(2), System.Globalization.NumberStyles.HexNumber, null, out value);
- }
- else
- {
- return int.TryParse(str, System.Globalization.NumberStyles.Integer, null, out value);
- }
- }
-
- private MemPatch Parse()
- {
- if (_reader == null)
- {
- return null;
- }
-
- MemPatch patches = new MemPatch();
-
- bool enabled = false;
- bool printValues = false;
- int offset_shift = 0;
-
- string line;
- int lineNum = 0;
-
- static void Print(string s) => Logger.Info?.Print(LogClass.ModLoader, $"IPSwitch: {s}");
-
- void ParseWarn() => Logger.Warning?.Print(LogClass.ModLoader, $"IPSwitch: Parse error at line {lineNum} for bid={BuildId}");
-
- while ((line = _reader.ReadLine()) != null)
- {
- if (string.IsNullOrWhiteSpace(line))
- {
- enabled = false;
-
- continue;
- }
-
- line = PreprocessLine(line);
- lineNum += 1;
-
- if (line.Length == 0)
- {
- continue;
- }
- else if (line.StartsWith('#'))
- {
- Print(line);
- }
- else if (line.StartsWith("@stop"))
- {
- break;
- }
- else if (line.StartsWith("@enabled"))
- {
- enabled = true;
- }
- else if (line.StartsWith("@disabled"))
- {
- enabled = false;
- }
- else if (line.StartsWith("@flag"))
- {
- var tokens = line.Split(' ', 3, StringSplitOptions.RemoveEmptyEntries);
-
- if (tokens.Length < 2)
- {
- ParseWarn();
-
- continue;
- }
-
- if (tokens[1] == "offset_shift")
- {
- if (tokens.Length != 3 || !ParseInt(tokens[2], out offset_shift))
- {
- ParseWarn();
-
- continue;
- }
- }
- else if (tokens[1] == "print_values")
- {
- printValues = true;
- }
- }
- else if (line.StartsWith('@'))
- {
- // Ignore
- }
- else
- {
- if (!enabled)
- {
- continue;
- }
-
- var tokens = line.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries);
-
- if (tokens.Length < 2)
- {
- ParseWarn();
-
- continue;
- }
-
- if (!int.TryParse(tokens[0], System.Globalization.NumberStyles.HexNumber, null, out int offset))
- {
- ParseWarn();
-
- continue;
- }
-
- offset += offset_shift;
-
- if (printValues)
- {
- Print($"print_values 0x{offset:x} <= {tokens[1]}");
- }
-
- if (tokens[1][0] == '"')
- {
- var patch = Encoding.ASCII.GetBytes(tokens[1].Trim('"') + "\0");
- patches.Add((uint)offset, patch);
- }
- else
- {
- var patch = Hex2ByteArrayBE(tokens[1]);
- patches.Add((uint)offset, patch);
- }
- }
- }
-
- return patches;
- }
-
- public void AddPatches(MemPatch patches)
- {
- patches.AddFrom(Parse());
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Mods/MemPatch.cs b/Ryujinx.HLE/Loaders/Mods/MemPatch.cs
deleted file mode 100644
index f9db7c69..00000000
--- a/Ryujinx.HLE/Loaders/Mods/MemPatch.cs
+++ /dev/null
@@ -1,96 +0,0 @@
-using Ryujinx.Common.Logging;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-namespace Ryujinx.HLE.Loaders.Mods
-{
- public class MemPatch
- {
- readonly Dictionary<uint, byte[]> _patches = new Dictionary<uint, byte[]>();
-
- /// <summary>
- /// Adds a patch to specified offset. Overwrites if already present.
- /// </summary>
- /// <param name="offset">Memory offset</param>
- /// <param name="patch">The patch to add</param>
- public void Add(uint offset, byte[] patch)
- {
- _patches[offset] = patch;
- }
-
- /// <summary>
- /// Adds a patch in the form of an RLE (Fill mode).
- /// </summary>
- /// <param name="offset">Memory offset</param>
- /// <param name="length"The fill length</param>
- /// <param name="filler">The byte to fill</param>
- public void AddFill(uint offset, int length, byte filler)
- {
- // TODO: Can be made space efficient by changing `_patches`
- // Should suffice for now
- byte[] patch = new byte[length];
- patch.AsSpan().Fill(filler);
-
- _patches[offset] = patch;
- }
-
- /// <summary>
- /// Adds all patches from an existing MemPatch
- /// </summary>
- /// <param name="patches">The patches to add</param>
- public void AddFrom(MemPatch patches)
- {
- if (patches == null)
- {
- return;
- }
-
- foreach (var (patchOffset, patch) in patches._patches)
- {
- _patches[patchOffset] = patch;
- }
- }
-
- /// <summary>
- /// Applies all the patches added to this instance.
- /// </summary>
- /// <remarks>
- /// Patches are applied in ascending order of offsets to guarantee
- /// overlapping patches always apply the same way.
- /// </remarks>
- /// <param name="memory">The span of bytes to patch</param>
- /// <param name="maxSize">The maximum size of the slice of patchable memory</param>
- /// <param name="protectedOffset">A secondary offset used in special cases (NSO header)</param>
- /// <returns>Successful patches count</returns>
- public int Patch(Span<byte> memory, int protectedOffset = 0)
- {
- int count = 0;
- foreach (var (offset, patch) in _patches.OrderBy(item => item.Key))
- {
- int patchOffset = (int)offset;
- int patchSize = patch.Length;
-
- if (patchOffset < protectedOffset || patchOffset > memory.Length)
- {
- continue; // Add warning?
- }
-
- patchOffset -= protectedOffset;
-
- if (patchOffset + patchSize > memory.Length)
- {
- patchSize = memory.Length - patchOffset; // Add warning?
- }
-
- Logger.Info?.Print(LogClass.ModLoader, $"Patching address offset {patchOffset:x} <= {BitConverter.ToString(patch).Replace('-', ' ')} len={patchSize}");
-
- patch.AsSpan(0, patchSize).CopyTo(memory.Slice(patchOffset, patchSize));
-
- count++;
- }
-
- return count;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Npdm/ACI0.cs b/Ryujinx.HLE/Loaders/Npdm/ACI0.cs
deleted file mode 100644
index 209e79d1..00000000
--- a/Ryujinx.HLE/Loaders/Npdm/ACI0.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-using Ryujinx.HLE.Exceptions;
-using System.IO;
-
-namespace Ryujinx.HLE.Loaders.Npdm
-{
- public class Aci0
- {
- private const int Aci0Magic = 'A' << 0 | 'C' << 8 | 'I' << 16 | '0' << 24;
-
- public ulong TitleId { get; set; }
-
- public int FsVersion { get; private set; }
- public ulong FsPermissionsBitmask { get; private set; }
-
- public ServiceAccessControl ServiceAccessControl { get; private set; }
- public KernelAccessControl KernelAccessControl { get; private set; }
-
- public Aci0(Stream stream, int offset)
- {
- stream.Seek(offset, SeekOrigin.Begin);
-
- BinaryReader reader = new BinaryReader(stream);
-
- if (reader.ReadInt32() != Aci0Magic)
- {
- throw new InvalidNpdmException("ACI0 Stream doesn't contain ACI0 section!");
- }
-
- stream.Seek(0xc, SeekOrigin.Current);
-
- TitleId = reader.ReadUInt64();
-
- // Reserved.
- stream.Seek(8, SeekOrigin.Current);
-
- int fsAccessHeaderOffset = reader.ReadInt32();
- int fsAccessHeaderSize = reader.ReadInt32();
- int serviceAccessControlOffset = reader.ReadInt32();
- int serviceAccessControlSize = reader.ReadInt32();
- int kernelAccessControlOffset = reader.ReadInt32();
- int kernelAccessControlSize = reader.ReadInt32();
-
- FsAccessHeader fsAccessHeader = new FsAccessHeader(stream, offset + fsAccessHeaderOffset, fsAccessHeaderSize);
-
- FsVersion = fsAccessHeader.Version;
- FsPermissionsBitmask = fsAccessHeader.PermissionsBitmask;
-
- ServiceAccessControl = new ServiceAccessControl(stream, offset + serviceAccessControlOffset, serviceAccessControlSize);
-
- KernelAccessControl = new KernelAccessControl(stream, offset + kernelAccessControlOffset, kernelAccessControlSize);
- }
- }
-}
diff --git a/Ryujinx.HLE/Loaders/Npdm/ACID.cs b/Ryujinx.HLE/Loaders/Npdm/ACID.cs
deleted file mode 100644
index 365495c6..00000000
--- a/Ryujinx.HLE/Loaders/Npdm/ACID.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using Ryujinx.HLE.Exceptions;
-using System.IO;
-
-namespace Ryujinx.HLE.Loaders.Npdm
-{
- public class Acid
- {
- private const int AcidMagic = 'A' << 0 | 'C' << 8 | 'I' << 16 | 'D' << 24;
-
- public byte[] Rsa2048Signature { get; private set; }
- public byte[] Rsa2048Modulus { get; private set; }
- public int Unknown1 { get; private set; }
- public int Flags { get; private set; }
-
- public long TitleIdRangeMin { get; private set; }
- public long TitleIdRangeMax { get; private set; }
-
- public FsAccessControl FsAccessControl { get; private set; }
- public ServiceAccessControl ServiceAccessControl { get; private set; }
- public KernelAccessControl KernelAccessControl { get; private set; }
-
- public Acid(Stream stream, int offset)
- {
- stream.Seek(offset, SeekOrigin.Begin);
-
- BinaryReader reader = new BinaryReader(stream);
-
- Rsa2048Signature = reader.ReadBytes(0x100);
- Rsa2048Modulus = reader.ReadBytes(0x100);
-
- if (reader.ReadInt32() != AcidMagic)
- {
- throw new InvalidNpdmException("ACID Stream doesn't contain ACID section!");
- }
-
- // Size field used with the above signature (?).
- Unknown1 = reader.ReadInt32();
-
- reader.ReadInt32();
-
- // Bit0 must be 1 on retail, on devunit 0 is also allowed. Bit1 is unknown.
- Flags = reader.ReadInt32();
-
- TitleIdRangeMin = reader.ReadInt64();
- TitleIdRangeMax = reader.ReadInt64();
-
- int fsAccessControlOffset = reader.ReadInt32();
- int fsAccessControlSize = reader.ReadInt32();
- int serviceAccessControlOffset = reader.ReadInt32();
- int serviceAccessControlSize = reader.ReadInt32();
- int kernelAccessControlOffset = reader.ReadInt32();
- int kernelAccessControlSize = reader.ReadInt32();
-
- FsAccessControl = new FsAccessControl(stream, offset + fsAccessControlOffset, fsAccessControlSize);
-
- ServiceAccessControl = new ServiceAccessControl(stream, offset + serviceAccessControlOffset, serviceAccessControlSize);
-
- KernelAccessControl = new KernelAccessControl(stream, offset + kernelAccessControlOffset, kernelAccessControlSize);
- }
- }
-}
diff --git a/Ryujinx.HLE/Loaders/Npdm/FsAccessControl.cs b/Ryujinx.HLE/Loaders/Npdm/FsAccessControl.cs
deleted file mode 100644
index d0f349ea..00000000
--- a/Ryujinx.HLE/Loaders/Npdm/FsAccessControl.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System.IO;
-
-namespace Ryujinx.HLE.Loaders.Npdm
-{
- public class FsAccessControl
- {
- public int Version { get; private set; }
- public ulong PermissionsBitmask { get; private set; }
- public int Unknown1 { get; private set; }
- public int Unknown2 { get; private set; }
- public int Unknown3 { get; private set; }
- public int Unknown4 { get; private set; }
-
- public FsAccessControl(Stream stream, int offset, int size)
- {
- stream.Seek(offset, SeekOrigin.Begin);
-
- BinaryReader reader = new BinaryReader(stream);
-
- Version = reader.ReadInt32();
- PermissionsBitmask = reader.ReadUInt64();
- Unknown1 = reader.ReadInt32();
- Unknown2 = reader.ReadInt32();
- Unknown3 = reader.ReadInt32();
- Unknown4 = reader.ReadInt32();
- }
- }
-}
diff --git a/Ryujinx.HLE/Loaders/Npdm/FsAccessHeader.cs b/Ryujinx.HLE/Loaders/Npdm/FsAccessHeader.cs
deleted file mode 100644
index 564b8dc3..00000000
--- a/Ryujinx.HLE/Loaders/Npdm/FsAccessHeader.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using Ryujinx.HLE.Exceptions;
-using System;
-using System.IO;
-
-namespace Ryujinx.HLE.Loaders.Npdm
-{
- class FsAccessHeader
- {
- public int Version { get; private set; }
- public ulong PermissionsBitmask { get; private set; }
-
- public FsAccessHeader(Stream stream, int offset, int size)
- {
- stream.Seek(offset, SeekOrigin.Begin);
-
- BinaryReader reader = new BinaryReader(stream);
-
- Version = reader.ReadInt32();
- PermissionsBitmask = reader.ReadUInt64();
-
- int dataSize = reader.ReadInt32();
-
- if (dataSize != 0x1c)
- {
- throw new InvalidNpdmException("FsAccessHeader is corrupted!");
- }
-
- int contentOwnerIdSize = reader.ReadInt32();
- int dataAndContentOwnerIdSize = reader.ReadInt32();
-
- if (dataAndContentOwnerIdSize != 0x1c)
- {
- throw new NotImplementedException("ContentOwnerId section is not implemented!");
- }
- }
- }
-}
diff --git a/Ryujinx.HLE/Loaders/Npdm/KernelAccessControl.cs b/Ryujinx.HLE/Loaders/Npdm/KernelAccessControl.cs
deleted file mode 100644
index 39803642..00000000
--- a/Ryujinx.HLE/Loaders/Npdm/KernelAccessControl.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System.IO;
-
-namespace Ryujinx.HLE.Loaders.Npdm
-{
- public class KernelAccessControl
- {
- public int[] Capabilities { get; private set; }
-
- public KernelAccessControl(Stream stream, int offset, int size)
- {
- stream.Seek(offset, SeekOrigin.Begin);
-
- Capabilities = new int[size / 4];
-
- BinaryReader reader = new BinaryReader(stream);
-
- for (int index = 0; index < Capabilities.Length; index++)
- {
- Capabilities[index] = reader.ReadInt32();
- }
- }
- }
-}
diff --git a/Ryujinx.HLE/Loaders/Npdm/Npdm.cs b/Ryujinx.HLE/Loaders/Npdm/Npdm.cs
deleted file mode 100644
index 29a2b0fc..00000000
--- a/Ryujinx.HLE/Loaders/Npdm/Npdm.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-using Ryujinx.HLE.Exceptions;
-using System.IO;
-using System.Text;
-
-namespace Ryujinx.HLE.Loaders.Npdm
-{
- // https://github.com/SciresM/hactool/blob/master/npdm.c
- // https://github.com/SciresM/hactool/blob/master/npdm.h
- // http://switchbrew.org/index.php?title=NPDM
- public class Npdm
- {
- private const int MetaMagic = 'M' << 0 | 'E' << 8 | 'T' << 16 | 'A' << 24;
-
- public byte ProcessFlags { get; private set; }
- public bool Is64Bit { get; private set; }
- public byte MainThreadPriority { get; private set; }
- public byte DefaultCpuId { get; private set; }
- public int PersonalMmHeapSize { get; private set; }
- public int Version { get; private set; }
- public int MainThreadStackSize { get; private set; }
- public string TitleName { get; set; }
- public byte[] ProductCode { get; private set; }
-
- public Aci0 Aci0 { get; private set; }
- public Acid Acid { get; private set; }
-
- public Npdm(Stream stream)
- {
- BinaryReader reader = new BinaryReader(stream);
-
- if (reader.ReadInt32() != MetaMagic)
- {
- throw new InvalidNpdmException("NPDM Stream doesn't contain NPDM file!");
- }
-
- reader.ReadInt64();
-
- ProcessFlags = reader.ReadByte();
-
- Is64Bit = (ProcessFlags & 1) != 0;
-
- reader.ReadByte();
-
- MainThreadPriority = reader.ReadByte();
- DefaultCpuId = reader.ReadByte();
-
- reader.ReadInt32();
-
- PersonalMmHeapSize = reader.ReadInt32();
-
- Version = reader.ReadInt32();
-
- MainThreadStackSize = reader.ReadInt32();
-
- byte[] tempTitleName = reader.ReadBytes(0x10);
-
- TitleName = Encoding.UTF8.GetString(tempTitleName, 0, tempTitleName.Length).Trim('\0');
-
- ProductCode = reader.ReadBytes(0x10);
-
- stream.Seek(0x30, SeekOrigin.Current);
-
- int aci0Offset = reader.ReadInt32();
- int aci0Size = reader.ReadInt32();
- int acidOffset = reader.ReadInt32();
- int acidSize = reader.ReadInt32();
-
- Aci0 = new Aci0(stream, aci0Offset);
- Acid = new Acid(stream, acidOffset);
- }
- }
-}
diff --git a/Ryujinx.HLE/Loaders/Npdm/ServiceAccessControl.cs b/Ryujinx.HLE/Loaders/Npdm/ServiceAccessControl.cs
deleted file mode 100644
index 54012b8a..00000000
--- a/Ryujinx.HLE/Loaders/Npdm/ServiceAccessControl.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.IO;
-using System.Text;
-
-namespace Ryujinx.HLE.Loaders.Npdm
-{
- public class ServiceAccessControl
- {
- public IReadOnlyDictionary<string, bool> Services { get; private set; }
-
- public ServiceAccessControl(Stream stream, int offset, int size)
- {
- stream.Seek(offset, SeekOrigin.Begin);
-
- BinaryReader reader = new BinaryReader(stream);
-
- int bytesRead = 0;
-
- Dictionary<string, bool> services = new Dictionary<string, bool>();
-
- while (bytesRead != size)
- {
- byte controlByte = reader.ReadByte();
-
- if (controlByte == 0)
- {
- break;
- }
-
- int length = (controlByte & 0x07) + 1;
- bool registerAllowed = (controlByte & 0x80) != 0;
-
- services[Encoding.ASCII.GetString(reader.ReadBytes(length))] = registerAllowed;
-
- bytesRead += length + 1;
- }
-
- Services = new ReadOnlyDictionary<string, bool>(services);
- }
- }
-}
diff --git a/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs b/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs
deleted file mode 100644
index 58759ddb..00000000
--- a/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs
+++ /dev/null
@@ -1,133 +0,0 @@
-using LibHac.Common;
-using LibHac.Fs;
-using LibHac.Fs.Fsa;
-using LibHac.Loader;
-using LibHac.Ns;
-using LibHac.Tools.FsSystem;
-using Ryujinx.Common.Configuration;
-using Ryujinx.Common.Logging;
-using Ryujinx.HLE.Loaders.Executables;
-using Ryujinx.Memory;
-using System.Linq;
-using static Ryujinx.HLE.HOS.ModLoader;
-
-namespace Ryujinx.HLE.Loaders.Processes.Extensions
-{
- static class FileSystemExtensions
- {
- public static MetaLoader GetNpdm(this IFileSystem fileSystem)
- {
- MetaLoader metaLoader = new();
-
- if (fileSystem == null || !fileSystem.FileExists(ProcessConst.MainNpdmPath))
- {
- Logger.Warning?.Print(LogClass.Loader, "NPDM file not found, using default values!");
-
- metaLoader.LoadDefault();
- }
- else
- {
- metaLoader.LoadFromFile(fileSystem);
- }
-
- return metaLoader;
- }
-
- public static ProcessResult Load(this IFileSystem exeFs, Switch device, BlitStruct<ApplicationControlProperty> nacpData, MetaLoader metaLoader, bool isHomebrew = false)
- {
- ulong programId = metaLoader.GetProgramId();
-
- // Replace the whole ExeFs partition by the modded one.
- if (device.Configuration.VirtualFileSystem.ModLoader.ReplaceExefsPartition(programId, ref exeFs))
- {
- metaLoader = null;
- }
-
- // Reload the MetaLoader in case of ExeFs partition replacement.
- metaLoader ??= exeFs.GetNpdm();
-
- NsoExecutable[] nsoExecutables = new NsoExecutable[ProcessConst.ExeFsPrefixes.Length];
-
- for (int i = 0; i < nsoExecutables.Length; i++)
- {
- string name = ProcessConst.ExeFsPrefixes[i];
-
- if (!exeFs.FileExists($"/{name}"))
- {
- continue; // File doesn't exist, skip.
- }
-
- Logger.Info?.Print(LogClass.Loader, $"Loading {name}...");
-
- using var nsoFile = new UniqueRef<IFile>();
-
- exeFs.OpenFile(ref nsoFile.Ref, $"/{name}".ToU8Span(), OpenMode.Read).ThrowIfFailure();
-
- nsoExecutables[i] = new NsoExecutable(nsoFile.Release().AsStorage(), name);
- }
-
- // ExeFs file replacements.
- ModLoadResult modLoadResult = device.Configuration.VirtualFileSystem.ModLoader.ApplyExefsMods(programId, nsoExecutables);
-
- // Take the Npdm from mods if present.
- if (modLoadResult.Npdm != null)
- {
- metaLoader = modLoadResult.Npdm;
- }
-
- // Collect the Nsos, ignoring ones that aren't used.
- nsoExecutables = nsoExecutables.Where(x => x != null).ToArray();
-
- // Apply Nsos patches.
- device.Configuration.VirtualFileSystem.ModLoader.ApplyNsoPatches(programId, nsoExecutables);
-
- // Don't use PTC if ExeFS files have been replaced.
- bool enablePtc = device.System.EnablePtc && !modLoadResult.Modified;
- if (!enablePtc)
- {
- Logger.Warning?.Print(LogClass.Ptc, $"Detected unsupported ExeFs modifications. PTC disabled.");
- }
-
- // We allow it for nx-hbloader because it can be used to launch homebrew.
- bool allowCodeMemoryForJit = programId == 0x010000000000100DUL || isHomebrew;
-
- string programName = "";
-
- if (!isHomebrew && programId > 0x010000000000FFFF)
- {
- programName = nacpData.Value.Title[(int)device.System.State.DesiredTitleLanguage].NameString.ToString();
-
- if (string.IsNullOrWhiteSpace(programName))
- {
- programName = nacpData.Value.Title.ItemsRo.ToArray().FirstOrDefault(x => x.Name[0] != 0).NameString.ToString();
- }
- }
-
- // Initialize GPU.
- Graphics.Gpu.GraphicsConfig.TitleId = $"{programId:x16}";
- device.Gpu.HostInitalized.Set();
-
- if (!MemoryBlock.SupportsFlags(MemoryAllocationFlags.ViewCompatible))
- {
- device.Configuration.MemoryManagerMode = MemoryManagerMode.SoftwarePageTable;
- }
-
- ProcessResult processResult = ProcessLoaderHelper.LoadNsos(
- device,
- device.System.KernelContext,
- metaLoader,
- nacpData.Value,
- enablePtc,
- allowCodeMemoryForJit,
- programName,
- metaLoader.GetProgramId(),
- null,
- nsoExecutables);
-
- // TODO: This should be stored using ProcessId instead.
- device.System.LibHacHorizonManager.ArpIReader.ApplicationId = new LibHac.ApplicationId(metaLoader.GetProgramId());
-
- return processResult;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Processes/Extensions/LocalFileSystemExtensions.cs b/Ryujinx.HLE/Loaders/Processes/Extensions/LocalFileSystemExtensions.cs
deleted file mode 100644
index 28d90785..00000000
--- a/Ryujinx.HLE/Loaders/Processes/Extensions/LocalFileSystemExtensions.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using LibHac.Common;
-using LibHac.FsSystem;
-using LibHac.Loader;
-using LibHac.Ns;
-using Ryujinx.HLE.Loaders.Processes.Extensions;
-using ApplicationId = LibHac.Ncm.ApplicationId;
-
-namespace Ryujinx.HLE.Loaders.Processes
-{
- static class LocalFileSystemExtensions
- {
- public static ProcessResult Load(this LocalFileSystem exeFs, Switch device, string romFsPath = "")
- {
- MetaLoader metaLoader = exeFs.GetNpdm();
- var nacpData = new BlitStruct<ApplicationControlProperty>(1);
- ulong programId = metaLoader.GetProgramId();
-
- device.Configuration.VirtualFileSystem.ModLoader.CollectMods(
- new[] { programId },
- device.Configuration.VirtualFileSystem.ModLoader.GetModsBasePath(),
- device.Configuration.VirtualFileSystem.ModLoader.GetSdModsBasePath());
-
- if (programId != 0)
- {
- ProcessLoaderHelper.EnsureSaveData(device, new ApplicationId(programId), nacpData);
- }
-
- ProcessResult processResult = exeFs.Load(device, nacpData, metaLoader);
-
- // Load RomFS.
- if (!string.IsNullOrEmpty(romFsPath))
- {
- device.Configuration.VirtualFileSystem.LoadRomFs(processResult.ProcessId, romFsPath);
- }
-
- return processResult;
- }
- }
-}
diff --git a/Ryujinx.HLE/Loaders/Processes/Extensions/MetaLoaderExtensions.cs b/Ryujinx.HLE/Loaders/Processes/Extensions/MetaLoaderExtensions.cs
deleted file mode 100644
index c639ee52..00000000
--- a/Ryujinx.HLE/Loaders/Processes/Extensions/MetaLoaderExtensions.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using LibHac.Common;
-using LibHac.Fs;
-using LibHac.Fs.Fsa;
-using LibHac.Loader;
-using LibHac.Util;
-using Ryujinx.Common;
-using System;
-
-namespace Ryujinx.HLE.Loaders.Processes.Extensions
-{
- public static class MetaLoaderExtensions
- {
- public static ulong GetProgramId(this MetaLoader metaLoader)
- {
- metaLoader.GetNpdm(out var npdm).ThrowIfFailure();
-
- return npdm.Aci.ProgramId.Value;
- }
-
- public static string GetProgramName(this MetaLoader metaLoader)
- {
- metaLoader.GetNpdm(out var npdm).ThrowIfFailure();
-
- return StringUtils.Utf8ZToString(npdm.Meta.ProgramName);
- }
-
- public static bool IsProgram64Bit(this MetaLoader metaLoader)
- {
- metaLoader.GetNpdm(out var npdm).ThrowIfFailure();
-
- return (npdm.Meta.Flags & 1) != 0;
- }
-
- public static void LoadDefault(this MetaLoader metaLoader)
- {
- byte[] npdmBuffer = EmbeddedResources.Read("Ryujinx.HLE/Homebrew.npdm");
-
- metaLoader.Load(npdmBuffer).ThrowIfFailure();
- }
-
- public static void LoadFromFile(this MetaLoader metaLoader, IFileSystem fileSystem, string path = "")
- {
- if (string.IsNullOrEmpty(path))
- {
- path = ProcessConst.MainNpdmPath;
- }
-
- using var npdmFile = new UniqueRef<IFile>();
-
- fileSystem.OpenFile(ref npdmFile.Ref, path.ToU8Span(), OpenMode.Read).ThrowIfFailure();
-
- npdmFile.Get.GetSize(out long fileSize).ThrowIfFailure();
-
- Span<byte> npdmBuffer = new byte[fileSize];
-
- npdmFile.Get.Read(out _, 0, npdmBuffer).ThrowIfFailure();
-
- metaLoader.Load(npdmBuffer).ThrowIfFailure();
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Processes/Extensions/NcaExtensions.cs b/Ryujinx.HLE/Loaders/Processes/Extensions/NcaExtensions.cs
deleted file mode 100644
index 473f374d..00000000
--- a/Ryujinx.HLE/Loaders/Processes/Extensions/NcaExtensions.cs
+++ /dev/null
@@ -1,175 +0,0 @@
-using LibHac;
-using LibHac.Common;
-using LibHac.Fs;
-using LibHac.Fs.Fsa;
-using LibHac.Loader;
-using LibHac.Ncm;
-using LibHac.Ns;
-using LibHac.Tools.FsSystem;
-using LibHac.Tools.FsSystem.NcaUtils;
-using Ryujinx.Common.Logging;
-using System.IO;
-using System.Linq;
-using ApplicationId = LibHac.Ncm.ApplicationId;
-
-namespace Ryujinx.HLE.Loaders.Processes.Extensions
-{
- static class NcaExtensions
- {
- public static ProcessResult Load(this Nca nca, Switch device, Nca patchNca, Nca controlNca)
- {
- // Extract RomFs and ExeFs from NCA.
- IStorage romFs = nca.GetRomFs(device, patchNca);
- IFileSystem exeFs = nca.GetExeFs(device, patchNca);
-
- if (exeFs == null)
- {
- Logger.Error?.Print(LogClass.Loader, "No ExeFS found in NCA");
-
- return ProcessResult.Failed;
- }
-
- // Load Npdm file.
- MetaLoader metaLoader = exeFs.GetNpdm();
-
- // Collecting mods related to AocTitleIds and ProgramId.
- device.Configuration.VirtualFileSystem.ModLoader.CollectMods(
- device.Configuration.ContentManager.GetAocTitleIds().Prepend(metaLoader.GetProgramId()),
- device.Configuration.VirtualFileSystem.ModLoader.GetModsBasePath(),
- device.Configuration.VirtualFileSystem.ModLoader.GetSdModsBasePath());
-
- // Load Nacp file.
- var nacpData = new BlitStruct<ApplicationControlProperty>(1);
-
- if (controlNca != null)
- {
- nacpData = controlNca.GetNacp(device);
- }
-
- /* TODO: Rework this since it's wrong and doesn't work as it takes the DisplayVersion from a "potential" inexistant update.
-
- // Load program 0 control NCA as we are going to need it for display version.
- (_, Nca updateProgram0ControlNca) = GetGameUpdateData(_device.Configuration.VirtualFileSystem, mainNca.Header.TitleId.ToString("x16"), 0, out _);
-
- // NOTE: Nintendo doesn't guarantee that the display version will be updated on sub programs when updating a multi program application.
- // As such, to avoid PTC cache confusion, we only trust the program 0 display version when launching a sub program.
- if (updateProgram0ControlNca != null && _device.Configuration.UserChannelPersistence.Index != 0)
- {
- nacpData.Value.DisplayVersion = updateProgram0ControlNca.GetNacp(_device).Value.DisplayVersion;
- }
-
- */
-
- ProcessResult processResult = exeFs.Load(device, nacpData, metaLoader);
-
- // Load RomFS.
- if (romFs == null)
- {
- Logger.Warning?.Print(LogClass.Loader, "No RomFS found in NCA");
- }
- else
- {
- romFs = device.Configuration.VirtualFileSystem.ModLoader.ApplyRomFsMods(processResult.ProgramId, romFs);
-
- device.Configuration.VirtualFileSystem.SetRomFs(processResult.ProcessId, romFs.AsStream(FileAccess.Read));
- }
-
- // Don't create save data for system programs.
- if (processResult.ProgramId != 0 && (processResult.ProgramId < SystemProgramId.Start.Value || processResult.ProgramId > SystemAppletId.End.Value))
- {
- // Multi-program applications can technically use any program ID for the main program, but in practice they always use 0 in the low nibble.
- // We'll know if this changes in the future because applications will get errors when trying to mount the correct save.
- ProcessLoaderHelper.EnsureSaveData(device, new ApplicationId(processResult.ProgramId & ~0xFul), nacpData);
- }
-
- return processResult;
- }
-
- public static int GetProgramIndex(this Nca nca)
- {
- return (int)(nca.Header.TitleId & 0xF);
- }
-
- public static bool IsProgram(this Nca nca)
- {
- return nca.Header.ContentType == NcaContentType.Program;
- }
-
- public static bool IsPatch(this Nca nca)
- {
- int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program);
-
- return nca.IsProgram() && nca.SectionExists(NcaSectionType.Data) && nca.Header.GetFsHeader(dataIndex).IsPatchSection();
- }
-
- public static bool IsControl(this Nca nca)
- {
- return nca.Header.ContentType == NcaContentType.Control;
- }
-
- public static IFileSystem GetExeFs(this Nca nca, Switch device, Nca patchNca = null)
- {
- IFileSystem exeFs = null;
-
- if (patchNca == null)
- {
- if (nca.CanOpenSection(NcaSectionType.Code))
- {
- exeFs = nca.OpenFileSystem(NcaSectionType.Code, device.System.FsIntegrityCheckLevel);
- }
- }
- else
- {
- if (patchNca.CanOpenSection(NcaSectionType.Code))
- {
- exeFs = nca.OpenFileSystemWithPatch(patchNca, NcaSectionType.Code, device.System.FsIntegrityCheckLevel);
- }
- }
-
- return exeFs;
- }
-
- public static IStorage GetRomFs(this Nca nca, Switch device, Nca patchNca = null)
- {
- IStorage romFs = null;
-
- if (patchNca == null)
- {
- if (nca.CanOpenSection(NcaSectionType.Data))
- {
- romFs = nca.OpenStorage(NcaSectionType.Data, device.System.FsIntegrityCheckLevel);
- }
- }
- else
- {
- if (patchNca.CanOpenSection(NcaSectionType.Data))
- {
- romFs = nca.OpenStorageWithPatch(patchNca, NcaSectionType.Data, device.System.FsIntegrityCheckLevel);
- }
- }
-
- return romFs;
- }
-
- public static BlitStruct<ApplicationControlProperty> GetNacp(this Nca controlNca, Switch device)
- {
- var nacpData = new BlitStruct<ApplicationControlProperty>(1);
-
- using var controlFile = new UniqueRef<IFile>();
-
- Result result = controlNca.OpenFileSystem(NcaSectionType.Data, device.System.FsIntegrityCheckLevel)
- .OpenFile(ref controlFile.Ref, "/control.nacp".ToU8Span(), OpenMode.Read);
-
- if (result.IsSuccess())
- {
- result = controlFile.Get.Read(out long bytesRead, 0, nacpData.ByteSpan, ReadOption.None);
- }
- else
- {
- nacpData.ByteSpan.Clear();
- }
-
- return nacpData;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Processes/Extensions/PartitionFileSystemExtensions.cs b/Ryujinx.HLE/Loaders/Processes/Extensions/PartitionFileSystemExtensions.cs
deleted file mode 100644
index e93802ae..00000000
--- a/Ryujinx.HLE/Loaders/Processes/Extensions/PartitionFileSystemExtensions.cs
+++ /dev/null
@@ -1,180 +0,0 @@
-using LibHac.Common;
-using LibHac.Fs;
-using LibHac.Fs.Fsa;
-using LibHac.FsSystem;
-using LibHac.Tools.Fs;
-using LibHac.Tools.FsSystem;
-using LibHac.Tools.FsSystem.NcaUtils;
-using Ryujinx.Common.Configuration;
-using Ryujinx.Common.Logging;
-using Ryujinx.Common.Utilities;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-
-namespace Ryujinx.HLE.Loaders.Processes.Extensions
-{
- public static class PartitionFileSystemExtensions
- {
- private static readonly DownloadableContentJsonSerializerContext ContentSerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
- private static readonly TitleUpdateMetadataJsonSerializerContext TitleSerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
-
- internal static (bool, ProcessResult) TryLoad(this PartitionFileSystem partitionFileSystem, Switch device, string path, out string errorMessage)
- {
- errorMessage = null;
-
- // Load required NCAs.
- Nca mainNca = null;
- Nca patchNca = null;
- Nca controlNca = null;
-
- try
- {
- device.Configuration.VirtualFileSystem.ImportTickets(partitionFileSystem);
-
- // TODO: To support multi-games container, this should use CNMT NCA instead.
- foreach (DirectoryEntryEx fileEntry in partitionFileSystem.EnumerateEntries("/", "*.nca"))
- {
- Nca nca = partitionFileSystem.GetNca(device, fileEntry.FullPath);
-
- if (nca.GetProgramIndex() != device.Configuration.UserChannelPersistence.Index)
- {
- continue;
- }
-
- if (nca.IsPatch())
- {
- patchNca = nca;
- }
- else if (nca.IsProgram())
- {
- mainNca = nca;
- }
- else if (nca.IsControl())
- {
- controlNca = nca;
- }
- }
-
- ProcessLoaderHelper.RegisterProgramMapInfo(device, partitionFileSystem).ThrowIfFailure();
- }
- catch (Exception ex)
- {
- errorMessage = $"Unable to load: {ex.Message}";
-
- return (false, ProcessResult.Failed);
- }
-
- if (mainNca != null)
- {
- if (mainNca.Header.ContentType != NcaContentType.Program)
- {
- errorMessage = "Selected NCA file is not a \"Program\" NCA";
-
- return (false, ProcessResult.Failed);
- }
-
- // Load Update NCAs.
- Nca updatePatchNca = null;
- Nca updateControlNca = null;
-
- if (ulong.TryParse(mainNca.Header.TitleId.ToString("x16"), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ulong titleIdBase))
- {
- // Clear the program index part.
- titleIdBase &= ~0xFUL;
-
- // Load update information if exists.
- string titleUpdateMetadataPath = System.IO.Path.Combine(AppDataManager.GamesDirPath, titleIdBase.ToString("x16"), "updates.json");
- if (File.Exists(titleUpdateMetadataPath))
- {
- string updatePath = JsonHelper.DeserializeFromFile(titleUpdateMetadataPath, TitleSerializerContext.TitleUpdateMetadata).Selected;
- if (File.Exists(updatePath))
- {
- PartitionFileSystem updatePartitionFileSystem = new(new FileStream(updatePath, FileMode.Open, FileAccess.Read).AsStorage());
-
- device.Configuration.VirtualFileSystem.ImportTickets(updatePartitionFileSystem);
-
- // TODO: This should use CNMT NCA instead.
- foreach (DirectoryEntryEx fileEntry in updatePartitionFileSystem.EnumerateEntries("/", "*.nca"))
- {
- Nca nca = updatePartitionFileSystem.GetNca(device, fileEntry.FullPath);
-
- if (nca.GetProgramIndex() != device.Configuration.UserChannelPersistence.Index)
- {
- continue;
- }
-
- if ($"{nca.Header.TitleId.ToString("x16")[..^3]}000" != titleIdBase.ToString("x16"))
- {
- break;
- }
-
- if (nca.IsProgram())
- {
- updatePatchNca = nca;
- }
- else if (nca.IsControl())
- {
- updateControlNca = nca;
- }
- }
- }
- }
- }
-
- if (updatePatchNca != null)
- {
- patchNca = updatePatchNca;
- }
-
- if (updateControlNca != null)
- {
- controlNca = updateControlNca;
- }
-
- // Load contained DownloadableContents.
- // TODO: If we want to support multi-processes in future, we shouldn't clear AddOnContent data here.
- device.Configuration.ContentManager.ClearAocData();
- device.Configuration.ContentManager.AddAocData(partitionFileSystem, path, mainNca.Header.TitleId, device.Configuration.FsIntegrityCheckLevel);
-
- // Load DownloadableContents.
- string addOnContentMetadataPath = System.IO.Path.Combine(AppDataManager.GamesDirPath, mainNca.Header.TitleId.ToString("x16"), "dlc.json");
- if (File.Exists(addOnContentMetadataPath))
- {
- List<DownloadableContentContainer> dlcContainerList = JsonHelper.DeserializeFromFile(addOnContentMetadataPath, ContentSerializerContext.ListDownloadableContentContainer);
-
- foreach (DownloadableContentContainer downloadableContentContainer in dlcContainerList)
- {
- foreach (DownloadableContentNca downloadableContentNca in downloadableContentContainer.DownloadableContentNcaList)
- {
- if (File.Exists(downloadableContentContainer.ContainerPath) && downloadableContentNca.Enabled)
- {
- device.Configuration.ContentManager.AddAocItem(downloadableContentNca.TitleId, downloadableContentContainer.ContainerPath, downloadableContentNca.FullPath);
- }
- else
- {
- Logger.Warning?.Print(LogClass.Application, $"Cannot find AddOnContent file {downloadableContentContainer.ContainerPath}. It may have been moved or renamed.");
- }
- }
- }
- }
-
- return (true, mainNca.Load(device, patchNca, controlNca));
- }
-
- errorMessage = "Unable to load: Could not find Main NCA";
-
- return (false, ProcessResult.Failed);
- }
-
- public static Nca GetNca(this IFileSystem fileSystem, Switch device, string path)
- {
- using var ncaFile = new UniqueRef<IFile>();
-
- fileSystem.OpenFile(ref ncaFile.Ref, path.ToU8Span(), OpenMode.Read).ThrowIfFailure();
-
- return new Nca(device.Configuration.VirtualFileSystem.KeySet, ncaFile.Release().AsStorage());
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Processes/ProcessConst.cs b/Ryujinx.HLE/Loaders/Processes/ProcessConst.cs
deleted file mode 100644
index 42ae2e89..00000000
--- a/Ryujinx.HLE/Loaders/Processes/ProcessConst.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-namespace Ryujinx.HLE.Loaders.Processes
-{
- static class ProcessConst
- {
- // Binaries from exefs are loaded into mem in this order. Do not change.
- public static readonly string[] ExeFsPrefixes =
- {
- "rtld",
- "main",
- "subsdk0",
- "subsdk1",
- "subsdk2",
- "subsdk3",
- "subsdk4",
- "subsdk5",
- "subsdk6",
- "subsdk7",
- "subsdk8",
- "subsdk9",
- "sdk"
- };
-
- public static readonly string MainNpdmPath = "/main.npdm";
-
- public const int NroAsetMagic = ('A' << 0) | ('S' << 8) | ('E' << 16) | ('T' << 24);
-
- public const bool AslrEnabled = true;
-
- public const int NsoArgsHeaderSize = 8;
- public const int NsoArgsDataSize = 0x9000;
- public const int NsoArgsTotalSize = NsoArgsHeaderSize + NsoArgsDataSize;
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Processes/ProcessLoader.cs b/Ryujinx.HLE/Loaders/Processes/ProcessLoader.cs
deleted file mode 100644
index 785db0e5..00000000
--- a/Ryujinx.HLE/Loaders/Processes/ProcessLoader.cs
+++ /dev/null
@@ -1,244 +0,0 @@
-using LibHac.Common;
-using LibHac.Fs;
-using LibHac.Fs.Fsa;
-using LibHac.FsSystem;
-using LibHac.Ns;
-using LibHac.Tools.Fs;
-using LibHac.Tools.FsSystem;
-using LibHac.Tools.FsSystem.NcaUtils;
-using Ryujinx.Common.Logging;
-using Ryujinx.HLE.Loaders.Executables;
-using Ryujinx.HLE.Loaders.Processes.Extensions;
-using System.Collections.Concurrent;
-using System.IO;
-using System.Linq;
-using Path = System.IO.Path;
-
-namespace Ryujinx.HLE.Loaders.Processes
-{
- public class ProcessLoader
- {
- private readonly Switch _device;
-
- private readonly ConcurrentDictionary<ulong, ProcessResult> _processesByPid;
-
- private ulong _latestPid;
-
- public ProcessResult ActiveApplication => _processesByPid[_latestPid];
-
- public ProcessLoader(Switch device)
- {
- _device = device;
- _processesByPid = new ConcurrentDictionary<ulong, ProcessResult>();
- }
-
- public bool LoadXci(string path)
- {
- FileStream stream = new(path, FileMode.Open, FileAccess.Read);
- Xci xci = new(_device.Configuration.VirtualFileSystem.KeySet, stream.AsStorage());
-
- if (!xci.HasPartition(XciPartitionType.Secure))
- {
- Logger.Error?.Print(LogClass.Loader, "Unable to load XCI: Could not find XCI Secure partition");
-
- return false;
- }
-
- (bool success, ProcessResult processResult) = xci.OpenPartition(XciPartitionType.Secure).TryLoad(_device, path, out string errorMessage);
-
- if (!success)
- {
- Logger.Error?.Print(LogClass.Loader, errorMessage, nameof(PartitionFileSystemExtensions.TryLoad));
-
- return false;
- }
-
- if (processResult.ProcessId != 0 && _processesByPid.TryAdd(processResult.ProcessId, processResult))
- {
- if (processResult.Start(_device))
- {
- _latestPid = processResult.ProcessId;
-
- return true;
- }
- }
-
- return false;
- }
-
- public bool LoadNsp(string path)
- {
- FileStream file = new(path, FileMode.Open, FileAccess.Read);
- PartitionFileSystem partitionFileSystem = new(file.AsStorage());
-
- (bool success, ProcessResult processResult) = partitionFileSystem.TryLoad(_device, path, out string errorMessage);
-
- if (processResult.ProcessId == 0)
- {
- // This is not a normal NSP, it's actually a ExeFS as a NSP
- processResult = partitionFileSystem.Load(_device, new BlitStruct<ApplicationControlProperty>(1), partitionFileSystem.GetNpdm(), true);
- }
-
- if (processResult.ProcessId != 0 && _processesByPid.TryAdd(processResult.ProcessId, processResult))
- {
- if (processResult.Start(_device))
- {
- _latestPid = processResult.ProcessId;
-
- return true;
- }
- }
-
- if (!success)
- {
- Logger.Error?.Print(LogClass.Loader, errorMessage, nameof(PartitionFileSystemExtensions.TryLoad));
- }
-
- return false;
- }
-
- public bool LoadNca(string path)
- {
- FileStream file = new(path, FileMode.Open, FileAccess.Read);
- Nca nca = new(_device.Configuration.VirtualFileSystem.KeySet, file.AsStorage(false));
-
- ProcessResult processResult = nca.Load(_device, null, null);
-
- if (processResult.ProcessId != 0 && _processesByPid.TryAdd(processResult.ProcessId, processResult))
- {
- if (processResult.Start(_device))
- {
- // NOTE: Check if process is SystemApplicationId or ApplicationId
- if (processResult.ProgramId > 0x01000000000007FF)
- {
- _latestPid = processResult.ProcessId;
- }
-
- return true;
- }
- }
-
- return false;
- }
-
- public bool LoadUnpackedNca(string exeFsDirPath, string romFsPath = null)
- {
- ProcessResult processResult = new LocalFileSystem(exeFsDirPath).Load(_device, romFsPath);
-
- if (processResult.ProcessId != 0 && _processesByPid.TryAdd(processResult.ProcessId, processResult))
- {
- if (processResult.Start(_device))
- {
- _latestPid = processResult.ProcessId;
-
- return true;
- }
- }
-
- return false;
- }
-
- public bool LoadNxo(string path)
- {
- var nacpData = new BlitStruct<ApplicationControlProperty>(1);
- IFileSystem dummyExeFs = null;
- Stream romfsStream = null;
-
- string programName = "";
- ulong programId = 0000000000000000;
-
- // Load executable.
- IExecutable executable;
-
- if (Path.GetExtension(path).ToLower() == ".nro")
- {
- FileStream input = new(path, FileMode.Open);
- NroExecutable nro = new(input.AsStorage());
-
- executable = nro;
-
- // Open RomFS if exists.
- IStorage romFsStorage = nro.OpenNroAssetSection(LibHac.Tools.Ro.NroAssetType.RomFs, false);
- romFsStorage.GetSize(out long romFsSize).ThrowIfFailure();
- if (romFsSize != 0)
- {
- romfsStream = romFsStorage.AsStream();
- }
-
- // Load Nacp if exists.
- IStorage nacpStorage = nro.OpenNroAssetSection(LibHac.Tools.Ro.NroAssetType.Nacp, false);
- nacpStorage.GetSize(out long nacpSize).ThrowIfFailure();
- if (nacpSize != 0)
- {
- nacpStorage.Read(0, nacpData.ByteSpan);
-
- programName = nacpData.Value.Title[(int)_device.System.State.DesiredTitleLanguage].NameString.ToString();
-
- if (string.IsNullOrWhiteSpace(programName))
- {
- programName = nacpData.Value.Title.ItemsRo.ToArray().FirstOrDefault(x => x.Name[0] != 0).NameString.ToString();
- }
-
- if (nacpData.Value.PresenceGroupId != 0)
- {
- programId = nacpData.Value.PresenceGroupId;
- }
- else if (nacpData.Value.SaveDataOwnerId != 0)
- {
- programId = nacpData.Value.SaveDataOwnerId;
- }
- else if (nacpData.Value.AddOnContentBaseId != 0)
- {
- programId = nacpData.Value.AddOnContentBaseId - 0x1000;
- }
- }
-
- // TODO: Add icon maybe ?
- }
- else
- {
- programName = System.IO.Path.GetFileNameWithoutExtension(path);
-
- executable = new NsoExecutable(new LocalStorage(path, FileAccess.Read), programName);
- }
-
- // Explicitly null TitleId to disable the shader cache.
- Graphics.Gpu.GraphicsConfig.TitleId = null;
- _device.Gpu.HostInitalized.Set();
-
- ProcessResult processResult = ProcessLoaderHelper.LoadNsos(_device,
- _device.System.KernelContext,
- dummyExeFs.GetNpdm(),
- nacpData.Value,
- diskCacheEnabled: false,
- allowCodeMemoryForJit: true,
- programName,
- programId,
- null,
- executable);
-
- // Make sure the process id is valid.
- if (processResult.ProcessId != 0)
- {
- // Load RomFS.
- if (romfsStream != null)
- {
- _device.Configuration.VirtualFileSystem.SetRomFs(processResult.ProcessId, romfsStream);
- }
-
- // Start process.
- if (_processesByPid.TryAdd(processResult.ProcessId, processResult))
- {
- if (processResult.Start(_device))
- {
- _latestPid = processResult.ProcessId;
-
- return true;
- }
- }
- }
-
- return false;
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs b/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs
deleted file mode 100644
index b802a642..00000000
--- a/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs
+++ /dev/null
@@ -1,467 +0,0 @@
-using LibHac.Account;
-using LibHac.Common;
-using LibHac.Fs;
-using LibHac.Fs.Shim;
-using LibHac.FsSystem;
-using LibHac.Loader;
-using LibHac.Ncm;
-using LibHac.Ns;
-using LibHac.Tools.Fs;
-using LibHac.Tools.FsSystem;
-using LibHac.Tools.FsSystem.NcaUtils;
-using Ryujinx.Common;
-using Ryujinx.Common.Logging;
-using Ryujinx.HLE.HOS;
-using Ryujinx.HLE.HOS.Kernel;
-using Ryujinx.HLE.HOS.Kernel.Common;
-using Ryujinx.HLE.HOS.Kernel.Memory;
-using Ryujinx.HLE.HOS.Kernel.Process;
-using Ryujinx.HLE.Loaders.Executables;
-using Ryujinx.HLE.Loaders.Processes.Extensions;
-using Ryujinx.Horizon.Common;
-using System;
-using System.Linq;
-using System.Runtime.InteropServices;
-using ApplicationId = LibHac.Ncm.ApplicationId;
-
-namespace Ryujinx.HLE.Loaders.Processes
-{
- static class ProcessLoaderHelper
- {
- public static LibHac.Result RegisterProgramMapInfo(Switch device, PartitionFileSystem partitionFileSystem)
- {
- ulong applicationId = 0;
- int programCount = 0;
-
- Span<bool> hasIndex = stackalloc bool[0x10];
-
- foreach (DirectoryEntryEx fileEntry in partitionFileSystem.EnumerateEntries("/", "*.nca"))
- {
- Nca nca = partitionFileSystem.GetNca(device, fileEntry.FullPath);
-
- if (!nca.IsProgram() && nca.IsPatch())
- {
- continue;
- }
-
- ulong currentProgramId = nca.Header.TitleId;
- ulong currentMainProgramId = currentProgramId & ~0xFFFul;
-
- if (applicationId == 0 && currentMainProgramId != 0)
- {
- applicationId = currentMainProgramId;
- }
-
- if (applicationId != currentMainProgramId)
- {
- // Currently there aren't any known multi-application game cards containing multi-program applications,
- // so because multi-application game cards are the only way we could run into multiple applications
- // we'll just return that there's a single program.
- programCount = 1;
-
- break;
- }
-
- hasIndex[(int)(currentProgramId & 0xF)] = true;
- }
-
- if (programCount == 0)
- {
- for (int i = 0; i < hasIndex.Length && hasIndex[i]; i++)
- {
- programCount++;
- }
- }
-
- if (programCount <= 0)
- {
- return LibHac.Result.Success;
- }
-
- Span<ProgramIndexMapInfo> mapInfo = stackalloc ProgramIndexMapInfo[0x10];
-
- for (int i = 0; i < programCount; i++)
- {
- mapInfo[i].ProgramId = new ProgramId(applicationId + (uint)i);
- mapInfo[i].MainProgramId = new ApplicationId(applicationId);
- mapInfo[i].ProgramIndex = (byte)i;
- }
-
- return device.System.LibHacHorizonManager.NsClient.Fs.RegisterProgramIndexMapInfo(mapInfo[..programCount]);
- }
-
- public static LibHac.Result EnsureSaveData(Switch device, ApplicationId applicationId, BlitStruct<ApplicationControlProperty> applicationControlProperty)
- {
- Logger.Info?.Print(LogClass.Application, "Ensuring required savedata exists.");
-
- ref ApplicationControlProperty control = ref applicationControlProperty.Value;
-
- if (LibHac.Common.Utilities.IsZeros(applicationControlProperty.ByteSpan))
- {
- // If the current application doesn't have a loaded control property, create a dummy one and set the savedata sizes so a user savedata will be created.
- control = ref new BlitStruct<ApplicationControlProperty>(1).Value;
-
- // The set sizes don't actually matter as long as they're non-zero because we use directory savedata.
- control.UserAccountSaveDataSize = 0x4000;
- control.UserAccountSaveDataJournalSize = 0x4000;
- control.SaveDataOwnerId = applicationId.Value;
-
- Logger.Warning?.Print(LogClass.Application, "No control file was found for this game. Using a dummy one instead. This may cause inaccuracies in some games.");
- }
-
- LibHac.Result resultCode = device.System.LibHacHorizonManager.RyujinxClient.Fs.EnsureApplicationCacheStorage(out _, out _, applicationId, in control);
- if (resultCode.IsFailure())
- {
- Logger.Error?.Print(LogClass.Application, $"Error calling EnsureApplicationCacheStorage. Result code {resultCode.ToStringWithName()}");
-
- return resultCode;
- }
-
- Uid userId = device.System.AccountManager.LastOpenedUser.UserId.ToLibHacUid();
-
- resultCode = device.System.LibHacHorizonManager.RyujinxClient.Fs.EnsureApplicationSaveData(out _, applicationId, in control, in userId);
- if (resultCode.IsFailure())
- {
- Logger.Error?.Print(LogClass.Application, $"Error calling EnsureApplicationSaveData. Result code {resultCode.ToStringWithName()}");
- }
-
- return resultCode;
- }
-
- public static bool LoadKip(KernelContext context, KipExecutable kip)
- {
- uint endOffset = kip.DataOffset + (uint)kip.Data.Length;
-
- if (kip.BssSize != 0)
- {
- endOffset = kip.BssOffset + kip.BssSize;
- }
-
- uint codeSize = BitUtils.AlignUp<uint>(kip.TextOffset + endOffset, KPageTableBase.PageSize);
- int codePagesCount = (int)(codeSize / KPageTableBase.PageSize);
- ulong codeBaseAddress = kip.Is64BitAddressSpace ? 0x8000000UL : 0x200000UL;
- ulong codeAddress = codeBaseAddress + kip.TextOffset;
-
- ProcessCreationFlags flags = 0;
-
- if (ProcessConst.AslrEnabled)
- {
- // TODO: Randomization.
-
- flags |= ProcessCreationFlags.EnableAslr;
- }
-
- if (kip.Is64BitAddressSpace)
- {
- flags |= ProcessCreationFlags.AddressSpace64Bit;
- }
-
- if (kip.Is64Bit)
- {
- flags |= ProcessCreationFlags.Is64Bit;
- }
-
- ProcessCreationInfo creationInfo = new(kip.Name, kip.Version, kip.ProgramId, codeAddress, codePagesCount, flags, 0, 0);
- MemoryRegion memoryRegion = kip.UsesSecureMemory ? MemoryRegion.Service : MemoryRegion.Application;
- KMemoryRegionManager region = context.MemoryManager.MemoryRegions[(int)memoryRegion];
-
- Result result = region.AllocatePages(out KPageList pageList, (ulong)codePagesCount);
- if (result != Result.Success)
- {
- Logger.Error?.Print(LogClass.Loader, $"Process initialization returned error \"{result}\".");
-
- return false;
- }
-
- KProcess process = new(context);
-
- var processContextFactory = new ArmProcessContextFactory(
- context.Device.System.TickSource,
- context.Device.Gpu,
- string.Empty,
- string.Empty,
- false,
- codeAddress,
- codeSize);
-
- result = process.InitializeKip(creationInfo, kip.Capabilities, pageList, context.ResourceLimit, memoryRegion, processContextFactory);
- if (result != Result.Success)
- {
- Logger.Error?.Print(LogClass.Loader, $"Process initialization returned error \"{result}\".");
-
- return false;
- }
-
- result = LoadIntoMemory(process, kip, codeBaseAddress);
- if (result != Result.Success)
- {
- Logger.Error?.Print(LogClass.Loader, $"Process initialization returned error \"{result}\".");
-
- return false;
- }
-
- process.DefaultCpuCore = kip.IdealCoreId;
-
- result = process.Start(kip.Priority, (ulong)kip.StackSize);
- if (result != Result.Success)
- {
- Logger.Error?.Print(LogClass.Loader, $"Process start returned error \"{result}\".");
-
- return false;
- }
-
- context.Processes.TryAdd(process.Pid, process);
-
- return true;
- }
-
- public static ProcessResult LoadNsos(
- Switch device,
- KernelContext context,
- MetaLoader metaLoader,
- ApplicationControlProperty applicationControlProperties,
- bool diskCacheEnabled,
- bool allowCodeMemoryForJit,
- string name,
- ulong programId,
- byte[] arguments = null,
- params IExecutable[] executables)
- {
- context.Device.System.ServiceTable.WaitServicesReady();
-
- LibHac.Result resultCode = metaLoader.GetNpdm(out var npdm);
-
- if (resultCode.IsFailure())
- {
- Logger.Error?.Print(LogClass.Loader, $"Process initialization failed getting npdm. Result Code {resultCode.ToStringWithName()}");
-
- return ProcessResult.Failed;
- }
-
- ref readonly var meta = ref npdm.Meta;
-
- ulong argsStart = 0;
- uint argsSize = 0;
- ulong codeStart = (meta.Flags & 1) != 0 ? 0x8000000UL : 0x200000UL;
- uint codeSize = 0;
-
- var buildIds = executables.Select(e => (e switch
- {
- NsoExecutable nso => Convert.ToHexString(nso.BuildId.ItemsRo.ToArray()),
- NroExecutable nro => Convert.ToHexString(nro.Header.BuildId),
- _ => ""
- }).ToUpper());
-
- ulong[] nsoBase = new ulong[executables.Length];
-
- for (int index = 0; index < executables.Length; index++)
- {
- IExecutable nso = executables[index];
-
- uint textEnd = nso.TextOffset + (uint)nso.Text.Length;
- uint roEnd = nso.RoOffset + (uint)nso.Ro.Length;
- uint dataEnd = nso.DataOffset + (uint)nso.Data.Length + nso.BssSize;
-
- uint nsoSize = textEnd;
-
- if (nsoSize < roEnd)
- {
- nsoSize = roEnd;
- }
-
- if (nsoSize < dataEnd)
- {
- nsoSize = dataEnd;
- }
-
- nsoSize = BitUtils.AlignUp<uint>(nsoSize, KPageTableBase.PageSize);
-
- nsoBase[index] = codeStart + codeSize;
-
- codeSize += nsoSize;
-
- if (arguments != null && argsSize == 0)
- {
- argsStart = codeSize;
-
- argsSize = (uint)BitUtils.AlignDown(arguments.Length * 2 + ProcessConst.NsoArgsTotalSize - 1, KPageTableBase.PageSize);
-
- codeSize += argsSize;
- }
- }
-
- int codePagesCount = (int)(codeSize / KPageTableBase.PageSize);
- int personalMmHeapPagesCount = (int)(meta.SystemResourceSize / KPageTableBase.PageSize);
-
- ProcessCreationInfo creationInfo = new(
- name,
- (int)meta.Version,
- programId,
- codeStart,
- codePagesCount,
- (ProcessCreationFlags)meta.Flags | ProcessCreationFlags.IsApplication,
- 0,
- personalMmHeapPagesCount);
-
- context.Device.System.LibHacHorizonManager.InitializeApplicationClient(new ProgramId(programId), in npdm);
-
- Result result;
-
- KResourceLimit resourceLimit = new(context);
-
- long applicationRgSize = (long)context.MemoryManager.MemoryRegions[(int)MemoryRegion.Application].Size;
-
- result = resourceLimit.SetLimitValue(LimitableResource.Memory, applicationRgSize);
-
- if (result.IsSuccess)
- {
- result = resourceLimit.SetLimitValue(LimitableResource.Thread, 608);
- }
-
- if (result.IsSuccess)
- {
- result = resourceLimit.SetLimitValue(LimitableResource.Event, 700);
- }
-
- if (result.IsSuccess)
- {
- result = resourceLimit.SetLimitValue(LimitableResource.TransferMemory, 128);
- }
-
- if (result.IsSuccess)
- {
- result = resourceLimit.SetLimitValue(LimitableResource.Session, 894);
- }
-
- if (result != Result.Success)
- {
- Logger.Error?.Print(LogClass.Loader, $"Process initialization failed setting resource limit values.");
-
- return ProcessResult.Failed;
- }
-
- KProcess process = new(context, allowCodeMemoryForJit);
-
- // NOTE: This field doesn't exists one firmware pre-5.0.0, a workaround have to be found.
- MemoryRegion memoryRegion = (MemoryRegion)(npdm.Acid.Flags >> 2 & 0xf);
- if (memoryRegion > MemoryRegion.NvServices)
- {
- Logger.Error?.Print(LogClass.Loader, $"Process initialization failed due to invalid ACID flags.");
-
- return ProcessResult.Failed;
- }
-
- var processContextFactory = new ArmProcessContextFactory(
- context.Device.System.TickSource,
- context.Device.Gpu,
- $"{programId:x16}",
- applicationControlProperties.DisplayVersionString.ToString(),
- diskCacheEnabled,
- codeStart,
- codeSize);
-
- result = process.Initialize(
- creationInfo,
- MemoryMarshal.Cast<byte, uint>(npdm.KernelCapabilityData),
- resourceLimit,
- memoryRegion,
- processContextFactory);
-
- if (result != Result.Success)
- {
- Logger.Error?.Print(LogClass.Loader, $"Process initialization returned error \"{result}\".");
-
- return ProcessResult.Failed;
- }
-
- for (int index = 0; index < executables.Length; index++)
- {
- Logger.Info?.Print(LogClass.Loader, $"Loading image {index} at 0x{nsoBase[index]:x16}...");
-
- result = LoadIntoMemory(process, executables[index], nsoBase[index]);
- if (result != Result.Success)
- {
- Logger.Error?.Print(LogClass.Loader, $"Process initialization returned error \"{result}\".");
-
- return ProcessResult.Failed;
- }
- }
-
- process.DefaultCpuCore = meta.DefaultCpuId;
-
- context.Processes.TryAdd(process.Pid, process);
-
- // Keep the build ids because the tamper machine uses them to know which process to associate a
- // tamper to and also keep the starting address of each executable inside a process because some
- // memory modifications are relative to this address.
- ProcessTamperInfo tamperInfo = new(
- process,
- buildIds,
- nsoBase,
- process.MemoryManager.HeapRegionStart,
- process.MemoryManager.AliasRegionStart,
- process.MemoryManager.CodeRegionStart);
-
- // Once everything is loaded, we can load cheats.
- device.Configuration.VirtualFileSystem.ModLoader.LoadCheats(programId, tamperInfo, device.TamperMachine);
-
- return new ProcessResult(
- metaLoader,
- applicationControlProperties,
- diskCacheEnabled,
- allowCodeMemoryForJit,
- processContextFactory.DiskCacheLoadState,
- process.Pid,
- meta.MainThreadPriority,
- meta.MainThreadStackSize,
- device.System.State.DesiredTitleLanguage);
- }
-
- public static Result LoadIntoMemory(KProcess process, IExecutable image, ulong baseAddress)
- {
- ulong textStart = baseAddress + image.TextOffset;
- ulong roStart = baseAddress + image.RoOffset;
- ulong dataStart = baseAddress + image.DataOffset;
- ulong bssStart = baseAddress + image.BssOffset;
-
- ulong end = dataStart + (ulong)image.Data.Length;
-
- if (image.BssSize != 0)
- {
- end = bssStart + image.BssSize;
- }
-
- process.CpuMemory.Write(textStart, image.Text);
- process.CpuMemory.Write(roStart, image.Ro);
- process.CpuMemory.Write(dataStart, image.Data);
-
- process.CpuMemory.Fill(bssStart, image.BssSize, 0);
-
- Result SetProcessMemoryPermission(ulong address, ulong size, KMemoryPermission permission)
- {
- if (size == 0)
- {
- return Result.Success;
- }
-
- size = BitUtils.AlignUp<ulong>(size, KPageTableBase.PageSize);
-
- return process.MemoryManager.SetProcessMemoryPermission(address, size, permission);
- }
-
- Result result = SetProcessMemoryPermission(textStart, (ulong)image.Text.Length, KMemoryPermission.ReadAndExecute);
- if (result != Result.Success)
- {
- return result;
- }
-
- result = SetProcessMemoryPermission(roStart, (ulong)image.Ro.Length, KMemoryPermission.Read);
- if (result != Result.Success)
- {
- return result;
- }
-
- return SetProcessMemoryPermission(dataStart, end - dataStart, KMemoryPermission.ReadAndWrite);
- }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/Loaders/Processes/ProcessResult.cs b/Ryujinx.HLE/Loaders/Processes/ProcessResult.cs
deleted file mode 100644
index 2801e4e0..00000000
--- a/Ryujinx.HLE/Loaders/Processes/ProcessResult.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-using LibHac.Loader;
-using LibHac.Ns;
-using Ryujinx.Common.Logging;
-using Ryujinx.Cpu;
-using Ryujinx.HLE.HOS.SystemState;
-using Ryujinx.HLE.Loaders.Processes.Extensions;
-using Ryujinx.Horizon.Common;
-using System.Linq;
-
-namespace Ryujinx.HLE.Loaders.Processes
-{
- public struct ProcessResult
- {
- public static ProcessResult Failed => new(null, new ApplicationControlProperty(), false, false, null, 0, 0, 0, TitleLanguage.AmericanEnglish);
-
- private readonly byte _mainThreadPriority;
- private readonly uint _mainThreadStackSize;
-
- public readonly IDiskCacheLoadState DiskCacheLoadState;
-
- public readonly MetaLoader MetaLoader;
- public readonly ApplicationControlProperty ApplicationControlProperties;
-
- public readonly ulong ProcessId;
- public readonly string Name;
- public readonly string DisplayVersion;
- public readonly ulong ProgramId;
- public readonly string ProgramIdText;
- public readonly bool Is64Bit;
- public readonly bool DiskCacheEnabled;
- public readonly bool AllowCodeMemoryForJit;
-
- public ProcessResult(
- MetaLoader metaLoader,
- ApplicationControlProperty applicationControlProperties,
- bool diskCacheEnabled,
- bool allowCodeMemoryForJit,
- IDiskCacheLoadState diskCacheLoadState,
- ulong pid,
- byte mainThreadPriority,
- uint mainThreadStackSize,
- TitleLanguage titleLanguage)
- {
- _mainThreadPriority = mainThreadPriority;
- _mainThreadStackSize = mainThreadStackSize;
-
- DiskCacheLoadState = diskCacheLoadState;
- ProcessId = pid;
-
- MetaLoader = metaLoader;
- ApplicationControlProperties = applicationControlProperties;
-
- if (metaLoader is not null)
- {
- ulong programId = metaLoader.GetProgramId();
-
- Name = ApplicationControlProperties.Title[(int)titleLanguage].NameString.ToString();
-
- if (string.IsNullOrWhiteSpace(Name))
- {
- Name = ApplicationControlProperties.Title.ItemsRo.ToArray().FirstOrDefault(x => x.Name[0] != 0).NameString.ToString();
- }
-
- DisplayVersion = ApplicationControlProperties.DisplayVersionString.ToString();
- ProgramId = programId;
- ProgramIdText = $"{programId:x16}";
- Is64Bit = metaLoader.IsProgram64Bit();
- }
-
- DiskCacheEnabled = diskCacheEnabled;
- AllowCodeMemoryForJit = allowCodeMemoryForJit;
- }
-
- public bool Start(Switch device)
- {
- device.Configuration.ContentManager.LoadEntries(device);
-
- Result result = device.System.KernelContext.Processes[ProcessId].Start(_mainThreadPriority, _mainThreadStackSize);
- if (result != Result.Success)
- {
- Logger.Error?.Print(LogClass.Loader, $"Process start returned error \"{result}\".");
-
- return false;
- }
-
- // TODO: LibHac npdm currently doesn't support version field.
- string version = ProgramId > 0x0100000000007FFF ? DisplayVersion : device.System.ContentManager.GetCurrentFirmwareVersion()?.VersionString ?? "?";
-
- Logger.Info?.Print(LogClass.Loader, $"Application Loaded: {Name} v{version} [{ProgramIdText}] [{(Is64Bit ? "64-bit" : "32-bit")}]");
-
- return true;
- }
- }
-}