HOS: Load RomFs by pid (#4301)
We currently loading only one RomFs at a time, which could be wrong if one day we want to load more than one guest at time. This PR fixes that by loading romfs by pid.
This commit is contained in:
parent
410be95ab6
commit
f449895e6d
4 changed files with 61 additions and 24 deletions
|
@ -76,11 +76,6 @@ namespace Ryujinx.HLE.HOS
|
|||
|
||||
public void LoadCart(string exeFsDir, string romFsFile = null)
|
||||
{
|
||||
if (romFsFile != null)
|
||||
{
|
||||
_device.Configuration.VirtualFileSystem.LoadRomFs(romFsFile);
|
||||
}
|
||||
|
||||
LocalFileSystem codeFs = new LocalFileSystem(exeFsDir);
|
||||
|
||||
MetaLoader metaData = ReadNpdm(codeFs);
|
||||
|
@ -95,7 +90,12 @@ namespace Ryujinx.HLE.HOS
|
|||
EnsureSaveData(new ApplicationId(TitleId));
|
||||
}
|
||||
|
||||
LoadExeFs(codeFs, string.Empty, metaData);
|
||||
ulong pid = LoadExeFs(codeFs, string.Empty, metaData);
|
||||
|
||||
if (romFsFile != null)
|
||||
{
|
||||
_device.Configuration.VirtualFileSystem.LoadRomFs(pid, romFsFile);
|
||||
}
|
||||
}
|
||||
|
||||
public static (Nca main, Nca patch, Nca control) GetGameData(VirtualFileSystem fileSystem, PartitionFileSystem pfs, int programIndex)
|
||||
|
@ -491,6 +491,8 @@ namespace Ryujinx.HLE.HOS
|
|||
|
||||
_displayVersion = displayVersion;
|
||||
|
||||
ulong pid = LoadExeFs(codeFs, displayVersion, metaData);
|
||||
|
||||
if (dataStorage == null)
|
||||
{
|
||||
Logger.Warning?.Print(LogClass.Loader, "No RomFS found in NCA");
|
||||
|
@ -499,7 +501,7 @@ namespace Ryujinx.HLE.HOS
|
|||
{
|
||||
IStorage newStorage = _device.Configuration.VirtualFileSystem.ModLoader.ApplyRomFsMods(TitleId, dataStorage);
|
||||
|
||||
_device.Configuration.VirtualFileSystem.SetRomFs(newStorage.AsStream(FileAccess.Read));
|
||||
_device.Configuration.VirtualFileSystem.SetRomFs(pid, newStorage.AsStream(FileAccess.Read));
|
||||
}
|
||||
|
||||
// Don't create save data for system programs.
|
||||
|
@ -510,8 +512,6 @@ namespace Ryujinx.HLE.HOS
|
|||
EnsureSaveData(new ApplicationId(TitleId & ~0xFul));
|
||||
}
|
||||
|
||||
LoadExeFs(codeFs, displayVersion, metaData);
|
||||
|
||||
Logger.Info?.Print(LogClass.Loader, $"Application Loaded: {TitleName} v{DisplayVersion} [{TitleIdText}] [{(TitleIs64Bit ? "64-bit" : "32-bit")}]");
|
||||
}
|
||||
|
||||
|
@ -579,7 +579,7 @@ namespace Ryujinx.HLE.HOS
|
|||
}
|
||||
}
|
||||
|
||||
private void LoadExeFs(IFileSystem codeFs, string displayVersion, MetaLoader metaData = null, bool isHomebrew = false)
|
||||
private ulong LoadExeFs(IFileSystem codeFs, string displayVersion, MetaLoader metaData = null, bool isHomebrew = false)
|
||||
{
|
||||
if (_device.Configuration.VirtualFileSystem.ModLoader.ReplaceExefsPartition(TitleId, ref codeFs))
|
||||
{
|
||||
|
@ -654,6 +654,8 @@ namespace Ryujinx.HLE.HOS
|
|||
DiskCacheLoadState = result.DiskCacheLoadState;
|
||||
|
||||
_device.Configuration.VirtualFileSystem.ModLoader.LoadCheats(TitleId, result.TamperInfo, _device.TamperMachine);
|
||||
|
||||
return result.ProcessId;
|
||||
}
|
||||
|
||||
public void LoadProgram(string filePath)
|
||||
|
@ -665,6 +667,7 @@ namespace Ryujinx.HLE.HOS
|
|||
bool isNro = Path.GetExtension(filePath).ToLower() == ".nro";
|
||||
|
||||
IExecutable executable;
|
||||
Stream romfsStream = null;
|
||||
|
||||
if (isNro)
|
||||
{
|
||||
|
@ -697,7 +700,7 @@ namespace Ryujinx.HLE.HOS
|
|||
|
||||
if (romfsSize != 0)
|
||||
{
|
||||
_device.Configuration.VirtualFileSystem.SetRomFs(new HomebrewRomFsStream(input, obj.FileSize + (long)romfsOffset));
|
||||
romfsStream = new HomebrewRomFsStream(input, obj.FileSize + (long)romfsOffset);
|
||||
}
|
||||
|
||||
if (nacpSize != 0)
|
||||
|
@ -758,6 +761,11 @@ namespace Ryujinx.HLE.HOS
|
|||
|
||||
ProgramLoadResult result = ProgramLoader.LoadNsos(_device.System.KernelContext, metaData, programInfo, executables: executable);
|
||||
|
||||
if (romfsStream != null)
|
||||
{
|
||||
_device.Configuration.VirtualFileSystem.SetRomFs(result.ProcessId, romfsStream);
|
||||
}
|
||||
|
||||
DiskCacheLoadState = result.DiskCacheLoadState;
|
||||
|
||||
_device.Configuration.VirtualFileSystem.ModLoader.LoadCheats(TitleId, result.TamperInfo, _device.TamperMachine);
|
||||
|
|
|
@ -41,17 +41,19 @@ namespace Ryujinx.HLE.HOS
|
|||
|
||||
struct ProgramLoadResult
|
||||
{
|
||||
public static ProgramLoadResult Failed => new ProgramLoadResult(false, null, null);
|
||||
public static ProgramLoadResult Failed => new ProgramLoadResult(false, null, null, 0);
|
||||
|
||||
public readonly bool Success;
|
||||
public readonly ProcessTamperInfo TamperInfo;
|
||||
public readonly IDiskCacheLoadState DiskCacheLoadState;
|
||||
public readonly ulong ProcessId;
|
||||
|
||||
public ProgramLoadResult(bool success, ProcessTamperInfo tamperInfo, IDiskCacheLoadState diskCacheLoadState)
|
||||
public ProgramLoadResult(bool success, ProcessTamperInfo tamperInfo, IDiskCacheLoadState diskCacheLoadState, ulong pid)
|
||||
{
|
||||
Success = success;
|
||||
TamperInfo = tamperInfo;
|
||||
DiskCacheLoadState = diskCacheLoadState;
|
||||
ProcessId = pid;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -366,7 +368,7 @@ namespace Ryujinx.HLE.HOS
|
|||
process.MemoryManager.AliasRegionStart,
|
||||
process.MemoryManager.CodeRegionStart);
|
||||
|
||||
return new ProgramLoadResult(true, tamperInfo, processContextFactory.DiskCacheLoadState);
|
||||
return new ProgramLoadResult(true, tamperInfo, processContextFactory.DiskCacheLoadState, process.Pid);
|
||||
}
|
||||
|
||||
private static Result LoadIntoMemory(KProcess process, IExecutable image, ulong baseAddress)
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs
|
|||
class IFileSystemProxy : DisposableIpcService
|
||||
{
|
||||
private SharedRef<LibHac.FsSrv.Sf.IFileSystemProxy> _baseFileSystemProxy;
|
||||
private ulong _pid;
|
||||
|
||||
public IFileSystemProxy(ServiceCtx context) : base(context.Device.System.FsServer)
|
||||
{
|
||||
|
@ -38,6 +39,8 @@ namespace Ryujinx.HLE.HOS.Services.Fs
|
|||
// SetCurrentProcess(u64, pid)
|
||||
public ResultCode SetCurrentProcess(ServiceCtx context)
|
||||
{
|
||||
_pid = context.Request.HandleDesc.PId;
|
||||
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
|
@ -702,7 +705,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs
|
|||
// OpenDataStorageByCurrentProcess() -> object<nn::fssrv::sf::IStorage> dataStorage
|
||||
public ResultCode OpenDataStorageByCurrentProcess(ServiceCtx context)
|
||||
{
|
||||
var storage = context.Device.FileSystem.RomFs.AsStorage(true);
|
||||
var storage = context.Device.FileSystem.GetRomFs(_pid).AsStorage(true);
|
||||
using var sharedStorage = new SharedRef<LibHac.Fs.IStorage>(storage);
|
||||
using var sfStorage = new SharedRef<IStorage>(new StorageInterfaceAdapter(ref sharedStorage.Ref()));
|
||||
|
||||
|
@ -791,7 +794,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs
|
|||
// OpenPatchDataStorageByCurrentProcess() -> object<nn::fssrv::sf::IStorage>
|
||||
public ResultCode OpenPatchDataStorageByCurrentProcess(ServiceCtx context)
|
||||
{
|
||||
var storage = context.Device.FileSystem.RomFs.AsStorage(true);
|
||||
var storage = context.Device.FileSystem.GetRomFs(_pid).AsStorage(true);
|
||||
using var sharedStorage = new SharedRef<LibHac.Fs.IStorage>(storage);
|
||||
using var sfStorage = new SharedRef<IStorage>(new StorageInterfaceAdapter(ref sharedStorage.Ref()));
|
||||
|
||||
|
@ -811,7 +814,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs
|
|||
throw new NotImplementedException($"Accessing storage from other programs is not supported (program index = {programIndex}).");
|
||||
}
|
||||
|
||||
var storage = context.Device.FileSystem.RomFs.AsStorage(true);
|
||||
var storage = context.Device.FileSystem.GetRomFs(_pid).AsStorage(true);
|
||||
using var sharedStorage = new SharedRef<LibHac.Fs.IStorage>(storage);
|
||||
using var sfStorage = new SharedRef<IStorage>(new StorageInterfaceAdapter(ref sharedStorage.Ref()));
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue