Support HomeBrew Loader (#577)

* Make it possibles to load hb-loader and hb-menu

One issue remains with hb-menu homebrew icons because of SIMD issues
(libjpeg-turbo related) and netloader doesn't work.

* Implement GetApplicationControlData

* Fix shared fonts for NSO/NRO

* Add homebrew NRO romfs support

This readd the NRO support by parsing the ASET header

* Address comments about HomebrewRomFs

* override Dispose in homebrew romfs stream

* Use a struct for file timestamp

* Simplify positional increments in GetApplicationControlData

* Address comments

* improve readability of the memory permission check in SetProcessMemoryPermission

* Fix previous broken check

* Add address space checks in SetProcessMemoryPermission
This commit is contained in:
Thomas Guillemard 2019-02-14 01:44:39 +01:00 committed by jduncanator
parent 7e9f555574
commit b126ea48c6
17 changed files with 633 additions and 17 deletions

View file

@ -102,6 +102,8 @@ namespace Ryujinx.HLE.HOS
public Horizon(Switch device)
{
ControlData = new Nacp();
Device = device;
State = new SystemStateMgr();
@ -549,14 +551,58 @@ namespace Ryujinx.HLE.HOS
bool isNro = Path.GetExtension(filePath).ToLower() == ".nro";
using (FileStream input = new FileStream(filePath, FileMode.Open))
{
IExecutable staticObject = isNro
? (IExecutable)new NxRelocatableObject(input)
: new NxStaticObject(input);
FileStream input = new FileStream(filePath, FileMode.Open);
ProgramLoader.LoadStaticObjects(this, metaData, new IExecutable[] { staticObject });
IExecutable staticObject;
if (isNro)
{
NxRelocatableObject obj = new NxRelocatableObject(input);
staticObject = obj;
// homebrew NRO can actually have some data after the actual NRO
if (input.Length > obj.FileSize)
{
input.Position = obj.FileSize;
BinaryReader reader = new BinaryReader(input);
uint asetMagic = reader.ReadUInt32();
if (asetMagic == 0x54455341)
{
uint asetVersion = reader.ReadUInt32();
if (asetVersion == 0)
{
ulong iconOffset = reader.ReadUInt64();
ulong iconSize = reader.ReadUInt64();
ulong nacpOffset = reader.ReadUInt64();
ulong nacpSize = reader.ReadUInt64();
ulong romfsOffset = reader.ReadUInt64();
ulong romfsSize = reader.ReadUInt64();
if (romfsSize != 0)
{
Device.FileSystem.SetRomFs(new HomebrewRomFsStream(input, obj.FileSize + (long)romfsOffset));
}
}
else
{
Logger.PrintWarning(LogClass.Loader, $"Unsupported ASET header version found \"{asetVersion}\"");
}
}
}
}
else
{
staticObject = new NxStaticObject(input);
}
ContentManager.LoadEntries();
ProgramLoader.LoadStaticObjects(this, metaData, new IExecutable[] { staticObject });
}
private Npdm GetDefaultNpdm()