aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/OsHle
diff options
context:
space:
mode:
authorThomas Guillemard <thog@protonmail.com>2018-07-17 21:14:27 +0200
committergdkchan <gab.dark.100@gmail.com>2018-07-17 16:14:27 -0300
commitc2c765b30fdfa9184df580133e22ae946eebc022 (patch)
tree3784a0bdaab54f47c6cdc0ca83ed78a0de4563f5 /Ryujinx.HLE/OsHle
parent5d698a7d8d240b9d324e385fb05c0ce9f26fb410 (diff)
hbabi: Implement argv (#272)
This commit implements the argv config key in Ryujinx (by creating a temporary copy of the homebrew executable in the sdmc VFS) to make it possible to load libnx's "romfs" files. This commit also call Os.Dispose in Ns.OnFinish to dispose all resources when exiting
Diffstat (limited to 'Ryujinx.HLE/OsHle')
-rw-r--r--Ryujinx.HLE/OsHle/Homebrew.cs10
-rw-r--r--Ryujinx.HLE/OsHle/Horizon.cs29
-rw-r--r--Ryujinx.HLE/OsHle/Process.cs10
3 files changed, 41 insertions, 8 deletions
diff --git a/Ryujinx.HLE/OsHle/Homebrew.cs b/Ryujinx.HLE/OsHle/Homebrew.cs
index 4266c8db..778e52fe 100644
--- a/Ryujinx.HLE/OsHle/Homebrew.cs
+++ b/Ryujinx.HLE/OsHle/Homebrew.cs
@@ -1,11 +1,14 @@
using ChocolArm64.Memory;
+using System.Text;
namespace Ryujinx.HLE.OsHle
{
static class Homebrew
{
+ public const string TemporaryNroSuffix = ".ryu_tmp.nro";
+
//http://switchbrew.org/index.php?title=Homebrew_ABI
- public static void WriteHbAbiData(AMemory Memory, long Position, int MainThreadHandle)
+ public static void WriteHbAbiData(AMemory Memory, long Position, int MainThreadHandle, string SwitchPath)
{
Memory.Manager.Map(Position, AMemoryMgr.PageSize, (int)MemoryType.Normal, AMemoryPerm.RW);
@@ -15,6 +18,11 @@ namespace Ryujinx.HLE.OsHle
//NextLoadPath
WriteConfigEntry(Memory, ref Position, 2, 0, Position + 0x200, Position + 0x400);
+ // Argv
+ long ArgvPosition = Position + 0xC00;
+ WriteConfigEntry(Memory, ref Position, 5, 0, 0, ArgvPosition);
+ Memory.WriteBytes(ArgvPosition, Encoding.ASCII.GetBytes(SwitchPath + "\0"));
+
//AppletType
WriteConfigEntry(Memory, ref Position, 7);
diff --git a/Ryujinx.HLE/OsHle/Horizon.cs b/Ryujinx.HLE/OsHle/Horizon.cs
index a5bf0616..9d8a937f 100644
--- a/Ryujinx.HLE/OsHle/Horizon.cs
+++ b/Ryujinx.HLE/OsHle/Horizon.cs
@@ -87,19 +87,36 @@ namespace Ryujinx.HLE.OsHle
MainProcess.Run();
}
- public void LoadProgram(string FileName)
+ public void LoadProgram(string FilePath)
{
- bool IsNro = Path.GetExtension(FileName).ToLower() == ".nro";
+ bool IsNro = Path.GetExtension(FilePath).ToLower() == ".nro";
- string Name = Path.GetFileNameWithoutExtension(FileName);
+ string Name = Path.GetFileNameWithoutExtension(FilePath);
+ string SwitchFilePath = Ns.VFs.SystemPathToSwitchPath(FilePath);
+
+ if (IsNro && (SwitchFilePath == null || !SwitchFilePath.StartsWith("sdmc:/")))
+ {
+ // TODO: avoid copying the file if we are already inside a sdmc directory
+ string SwitchPath = $"sdmc:/switch/{Name}{Homebrew.TemporaryNroSuffix}";
+ string TempPath = Ns.VFs.SwitchPathToSystemPath(SwitchPath);
+
+ string SwitchDir = Path.GetDirectoryName(TempPath);
+ if (!Directory.Exists(SwitchDir))
+ {
+ Directory.CreateDirectory(SwitchDir);
+ }
+ File.Copy(FilePath, TempPath, true);
+
+ FilePath = TempPath;
+ }
Process MainProcess = MakeProcess();
- using (FileStream Input = new FileStream(FileName, FileMode.Open))
+ using (FileStream Input = new FileStream(FilePath, FileMode.Open))
{
MainProcess.LoadProgram(IsNro
- ? (IExecutable)new Nro(Input, Name)
- : (IExecutable)new Nso(Input, Name));
+ ? (IExecutable)new Nro(Input, FilePath)
+ : (IExecutable)new Nso(Input, FilePath));
}
MainProcess.SetEmptyArgs();
diff --git a/Ryujinx.HLE/OsHle/Process.cs b/Ryujinx.HLE/OsHle/Process.cs
index 53e357ab..be27dcc2 100644
--- a/Ryujinx.HLE/OsHle/Process.cs
+++ b/Ryujinx.HLE/OsHle/Process.cs
@@ -13,6 +13,7 @@ using Ryujinx.HLE.OsHle.Services.Nv;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.IO;
using System.Text;
namespace Ryujinx.HLE.OsHle
@@ -155,7 +156,9 @@ namespace Ryujinx.HLE.OsHle
{
HbAbiDataPosition = AMemoryHelper.PageRoundUp(Executables[0].ImageEnd);
- Homebrew.WriteHbAbiData(Memory, HbAbiDataPosition, Handle);
+ string SwitchPath = Ns.VFs.SystemPathToSwitchPath(Executables[0].FilePath);
+
+ Homebrew.WriteHbAbiData(Memory, HbAbiDataPosition, Handle, SwitchPath);
MainThread.Thread.ThreadState.X0 = (ulong)HbAbiDataPosition;
MainThread.Thread.ThreadState.X1 = ulong.MaxValue;
@@ -400,6 +403,11 @@ namespace Ryujinx.HLE.OsHle
{
if (Disposing && !Disposed)
{
+ if (NeedsHbAbi && Executables[0].FilePath.EndsWith(Homebrew.TemporaryNroSuffix))
+ {
+ File.Delete(Executables[0].FilePath);
+ }
+
//If there is still some thread running, disposing the objects is not
//safe as the thread may try to access those resources. Instead, we set
//the flag to have the Process disposed when all threads finishes.