Update to LibHac 0.19.0 (#5831)
* Update to LibHac v0.19.0 - PartitionFileSystem classes now fully match Nintendo's implementation. Current code creating a PartitionFileSystem now need to use the Initialize method. - Implementing nn::gcsrv and nn::sdmmcsrv now means the FS server now uses that abstraction instead of the old one where we passed in an IDeviceOperator. * Add GetFileSystemAttribute
This commit is contained in:
parent
33ba170315
commit
d773d5152e
18 changed files with 83 additions and 38 deletions
|
@ -18,7 +18,7 @@
|
|||
<PackageVersion Include="GtkSharp.Dependencies" Version="1.1.1" />
|
||||
<PackageVersion Include="GtkSharp.Dependencies.osx" Version="0.0.5" />
|
||||
<PackageVersion Include="jp2masa.Avalonia.Flexbox" Version="0.3.0-beta.4" />
|
||||
<PackageVersion Include="LibHac" Version="0.18.0" />
|
||||
<PackageVersion Include="LibHac" Version="0.19.0" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
|
||||
|
|
|
@ -173,7 +173,7 @@ namespace Ryujinx.Ava.Common
|
|||
string extension = Path.GetExtension(titleFilePath).ToLower();
|
||||
if (extension == ".nsp" || extension == ".pfs0" || extension == ".xci")
|
||||
{
|
||||
PartitionFileSystem pfs;
|
||||
IFileSystem pfs;
|
||||
|
||||
if (extension == ".xci")
|
||||
{
|
||||
|
@ -181,7 +181,9 @@ namespace Ryujinx.Ava.Common
|
|||
}
|
||||
else
|
||||
{
|
||||
pfs = new PartitionFileSystem(file.AsStorage());
|
||||
var pfsTemp = new PartitionFileSystem();
|
||||
pfsTemp.Initialize(file.AsStorage()).ThrowIfFailure();
|
||||
pfs = pfsTemp;
|
||||
}
|
||||
|
||||
foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca"))
|
||||
|
|
|
@ -126,7 +126,8 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
{
|
||||
using FileStream containerFile = File.OpenRead(downloadableContentContainer.ContainerPath);
|
||||
|
||||
PartitionFileSystem partitionFileSystem = new(containerFile.AsStorage());
|
||||
PartitionFileSystem partitionFileSystem = new();
|
||||
partitionFileSystem.Initialize(containerFile.AsStorage()).ThrowIfFailure();
|
||||
|
||||
_virtualFileSystem.ImportTickets(partitionFileSystem);
|
||||
|
||||
|
@ -232,7 +233,8 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
using FileStream containerFile = File.OpenRead(path);
|
||||
|
||||
PartitionFileSystem partitionFileSystem = new(containerFile.AsStorage());
|
||||
PartitionFileSystem partitionFileSystem = new();
|
||||
partitionFileSystem.Initialize(containerFile.AsStorage()).ThrowIfFailure();
|
||||
bool containsDownloadableContent = false;
|
||||
|
||||
_virtualFileSystem.ImportTickets(partitionFileSystem);
|
||||
|
|
|
@ -170,7 +170,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
|||
|
||||
try
|
||||
{
|
||||
(Nca patchNca, Nca controlNca) = ApplicationLibrary.GetGameUpdateDataFromPartition(VirtualFileSystem, new PartitionFileSystem(file.AsStorage()), TitleId.ToString("x16"), 0);
|
||||
var pfs = new PartitionFileSystem();
|
||||
pfs.Initialize(file.AsStorage()).ThrowIfFailure();
|
||||
(Nca patchNca, Nca controlNca) = ApplicationLibrary.GetGameUpdateDataFromPartition(VirtualFileSystem, pfs, TitleId.ToString("x16"), 0);
|
||||
|
||||
if (controlNca != null && patchNca != null)
|
||||
{
|
||||
|
|
|
@ -238,7 +238,8 @@ namespace Ryujinx.HLE.FileSystem
|
|||
if (!mergedToContainer)
|
||||
{
|
||||
using FileStream fileStream = File.OpenRead(containerPath);
|
||||
using PartitionFileSystem partitionFileSystem = new(fileStream.AsStorage());
|
||||
using PartitionFileSystem partitionFileSystem = new();
|
||||
partitionFileSystem.Initialize(fileStream.AsStorage()).ThrowIfFailure();
|
||||
|
||||
_virtualFileSystem.ImportTickets(partitionFileSystem);
|
||||
}
|
||||
|
@ -259,16 +260,16 @@ namespace Ryujinx.HLE.FileSystem
|
|||
{
|
||||
var file = new FileStream(aoc.ContainerPath, FileMode.Open, FileAccess.Read);
|
||||
using var ncaFile = new UniqueRef<IFile>();
|
||||
PartitionFileSystem pfs;
|
||||
|
||||
switch (Path.GetExtension(aoc.ContainerPath))
|
||||
{
|
||||
case ".xci":
|
||||
pfs = new Xci(_virtualFileSystem.KeySet, file.AsStorage()).OpenPartition(XciPartitionType.Secure);
|
||||
pfs.OpenFile(ref ncaFile.Ref, aoc.NcaPath.ToU8Span(), OpenMode.Read);
|
||||
var xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage()).OpenPartition(XciPartitionType.Secure);
|
||||
xci.OpenFile(ref ncaFile.Ref, aoc.NcaPath.ToU8Span(), OpenMode.Read);
|
||||
break;
|
||||
case ".nsp":
|
||||
pfs = new PartitionFileSystem(file.AsStorage());
|
||||
var pfs = new PartitionFileSystem();
|
||||
pfs.Initialize(file.AsStorage());
|
||||
pfs.OpenFile(ref ncaFile.Ref, aoc.NcaPath.ToU8Span(), OpenMode.Read);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -7,6 +7,7 @@ using LibHac.Fs.Shim;
|
|||
using LibHac.FsSrv;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Sdmmc;
|
||||
using LibHac.Spl;
|
||||
using LibHac.Tools.Es;
|
||||
using LibHac.Tools.Fs;
|
||||
|
@ -32,7 +33,7 @@ namespace Ryujinx.HLE.FileSystem
|
|||
|
||||
public KeySet KeySet { get; private set; }
|
||||
public EmulatedGameCard GameCard { get; private set; }
|
||||
public EmulatedSdCard SdCard { get; private set; }
|
||||
public SdmmcApi SdCard { get; private set; }
|
||||
public ModLoader ModLoader { get; private set; }
|
||||
|
||||
private readonly ConcurrentDictionary<ulong, Stream> _romFsByPid;
|
||||
|
@ -198,15 +199,15 @@ namespace Ryujinx.HLE.FileSystem
|
|||
fsServerObjects.FsCreators.EncryptedFileSystemCreator = new EncryptedFileSystemCreator();
|
||||
|
||||
GameCard = fsServerObjects.GameCard;
|
||||
SdCard = fsServerObjects.SdCard;
|
||||
SdCard = fsServerObjects.Sdmmc;
|
||||
|
||||
SdCard.SetSdCardInsertionStatus(true);
|
||||
SdCard.SetSdCardInserted(true);
|
||||
|
||||
var fsServerConfig = new FileSystemServerConfig
|
||||
{
|
||||
DeviceOperator = fsServerObjects.DeviceOperator,
|
||||
ExternalKeySet = KeySet.ExternalKeySet,
|
||||
FsCreators = fsServerObjects.FsCreators,
|
||||
StorageDeviceManagerFactory = fsServerObjects.StorageDeviceManagerFactory,
|
||||
RandomGenerator = randomGenerator,
|
||||
};
|
||||
|
||||
|
|
|
@ -533,7 +533,9 @@ namespace Ryujinx.HLE.HOS
|
|||
|
||||
Logger.Info?.Print(LogClass.ModLoader, "Using replacement ExeFS partition");
|
||||
|
||||
exefs = new PartitionFileSystem(mods.ExefsContainers[0].Path.OpenRead().AsStorage());
|
||||
var pfs = new PartitionFileSystem();
|
||||
pfs.Initialize(mods.ExefsContainers[0].Path.OpenRead().AsStorage()).ThrowIfFailure();
|
||||
exefs = pfs;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,9 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
|
|||
try
|
||||
{
|
||||
LocalStorage storage = new(pfsPath, FileAccess.Read, FileMode.Open);
|
||||
using SharedRef<LibHac.Fs.Fsa.IFileSystem> nsp = new(new PartitionFileSystem(storage));
|
||||
var pfs = new PartitionFileSystem();
|
||||
using SharedRef<LibHac.Fs.Fsa.IFileSystem> nsp = new(pfs);
|
||||
pfs.Initialize(storage).ThrowIfFailure();
|
||||
|
||||
ImportTitleKeysFromNsp(nsp.Get, context.Device.System.KeySet);
|
||||
|
||||
|
@ -90,7 +92,8 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
|
|||
|
||||
try
|
||||
{
|
||||
PartitionFileSystem nsp = new(pfsFile.AsStorage());
|
||||
PartitionFileSystem nsp = new();
|
||||
nsp.Initialize(pfsFile.AsStorage()).ThrowIfFailure();
|
||||
|
||||
ImportTitleKeysFromNsp(nsp, context.Device.System.KeySet);
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using LibHac;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using Path = LibHac.FsSrv.Sf.Path;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
|
||||
|
@ -202,6 +203,16 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy
|
|||
return (ResultCode)result.Value;
|
||||
}
|
||||
|
||||
[CommandCmif(16)]
|
||||
public ResultCode GetFileSystemAttribute(ServiceCtx context)
|
||||
{
|
||||
Result result = _fileSystem.Get.GetFileSystemAttribute(out FileSystemAttribute attribute);
|
||||
|
||||
context.ResponseData.Write(SpanHelpers.AsReadOnlyByteSpan(in attribute));
|
||||
|
||||
return (ResultCode)result.Value;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
if (isDisposing)
|
||||
|
|
|
@ -1380,7 +1380,10 @@ namespace Ryujinx.HLE.HOS.Services.Fs
|
|||
[CommandCmif(1016)]
|
||||
public ResultCode FlushAccessLogOnSdCard(ServiceCtx context)
|
||||
{
|
||||
return (ResultCode)_baseFileSystemProxy.Get.FlushAccessLogOnSdCard().Value;
|
||||
// Logging the access log to the SD card isn't implemented, meaning this function will be a no-op since
|
||||
// there's nothing to flush. Return success until it's implemented.
|
||||
// return (ResultCode)_baseFileSystemProxy.Get.FlushAccessLogOnSdCard().Value;
|
||||
return ResultCode.Success;
|
||||
}
|
||||
|
||||
[CommandCmif(1017)]
|
||||
|
|
|
@ -20,7 +20,11 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
|
|||
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)
|
||||
internal static (bool, ProcessResult) TryLoad<TMetaData, TFormat, THeader, TEntry>(this PartitionFileSystemCore<TMetaData, TFormat, THeader, TEntry> partitionFileSystem, Switch device, string path, out string errorMessage)
|
||||
where TMetaData : PartitionFileSystemMetaCore<TFormat, THeader, TEntry>, new()
|
||||
where TFormat : IPartitionFileSystemFormat
|
||||
where THeader : unmanaged, IPartitionFileSystemHeader
|
||||
where TEntry : unmanaged, IPartitionFileSystemEntry
|
||||
{
|
||||
errorMessage = null;
|
||||
|
||||
|
@ -91,7 +95,8 @@ namespace Ryujinx.HLE.Loaders.Processes.Extensions
|
|||
string updatePath = JsonHelper.DeserializeFromFile(titleUpdateMetadataPath, _titleSerializerContext.TitleUpdateMetadata).Selected;
|
||||
if (File.Exists(updatePath))
|
||||
{
|
||||
PartitionFileSystem updatePartitionFileSystem = new(new FileStream(updatePath, FileMode.Open, FileAccess.Read).AsStorage());
|
||||
PartitionFileSystem updatePartitionFileSystem = new();
|
||||
updatePartitionFileSystem.Initialize(new FileStream(updatePath, FileMode.Open, FileAccess.Read).AsStorage()).ThrowIfFailure();
|
||||
|
||||
device.Configuration.VirtualFileSystem.ImportTickets(updatePartitionFileSystem);
|
||||
|
||||
|
|
|
@ -69,7 +69,8 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||
public bool LoadNsp(string path)
|
||||
{
|
||||
FileStream file = new(path, FileMode.Open, FileAccess.Read);
|
||||
PartitionFileSystem partitionFileSystem = new(file.AsStorage());
|
||||
PartitionFileSystem partitionFileSystem = new();
|
||||
partitionFileSystem.Initialize(file.AsStorage()).ThrowIfFailure();
|
||||
|
||||
(bool success, ProcessResult processResult) = partitionFileSystem.TryLoad(_device, path, out string errorMessage);
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
using LibHac.Account;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Fs.Shim;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Loader;
|
||||
using LibHac.Ncm;
|
||||
using LibHac.Ns;
|
||||
|
@ -33,7 +33,7 @@ namespace Ryujinx.HLE.Loaders.Processes
|
|||
// TODO: Remove this workaround when ASLR is implemented.
|
||||
private const ulong CodeStartOffset = 0x500000UL;
|
||||
|
||||
public static LibHac.Result RegisterProgramMapInfo(Switch device, PartitionFileSystem partitionFileSystem)
|
||||
public static LibHac.Result RegisterProgramMapInfo(Switch device, IFileSystem partitionFileSystem)
|
||||
{
|
||||
ulong applicationId = 0;
|
||||
int programCount = 0;
|
||||
|
|
|
@ -65,7 +65,7 @@ namespace Ryujinx.Ui.App.Common
|
|||
|
||||
if (extension is ".nsp" or ".xci")
|
||||
{
|
||||
PartitionFileSystem pfs;
|
||||
IFileSystem pfs;
|
||||
|
||||
if (extension == ".xci")
|
||||
{
|
||||
|
@ -75,7 +75,9 @@ namespace Ryujinx.Ui.App.Common
|
|||
}
|
||||
else
|
||||
{
|
||||
pfs = new PartitionFileSystem(file.AsStorage());
|
||||
var pfsTemp = new PartitionFileSystem();
|
||||
pfsTemp.Initialize(file.AsStorage()).ThrowIfFailure();
|
||||
pfs = pfsTemp;
|
||||
}
|
||||
|
||||
foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca"))
|
||||
|
|
|
@ -174,7 +174,7 @@ namespace Ryujinx.Ui.App.Common
|
|||
{
|
||||
try
|
||||
{
|
||||
PartitionFileSystem pfs;
|
||||
IFileSystem pfs;
|
||||
|
||||
bool isExeFs = false;
|
||||
|
||||
|
@ -186,7 +186,9 @@ namespace Ryujinx.Ui.App.Common
|
|||
}
|
||||
else
|
||||
{
|
||||
pfs = new PartitionFileSystem(file.AsStorage());
|
||||
var pfsTemp = new PartitionFileSystem();
|
||||
pfsTemp.Initialize(file.AsStorage()).ThrowIfFailure();
|
||||
pfs = pfsTemp;
|
||||
|
||||
// If the NSP doesn't have a main NCA, decrement the number of applications found and then continue to the next application.
|
||||
bool hasMainNca = false;
|
||||
|
@ -500,7 +502,7 @@ namespace Ryujinx.Ui.App.Common
|
|||
ApplicationCountUpdated?.Invoke(null, e);
|
||||
}
|
||||
|
||||
private void GetControlFsAndTitleId(PartitionFileSystem pfs, out IFileSystem controlFs, out string titleId)
|
||||
private void GetControlFsAndTitleId(IFileSystem pfs, out IFileSystem controlFs, out string titleId)
|
||||
{
|
||||
(_, _, Nca controlNca) = GetGameData(_virtualFileSystem, pfs, 0);
|
||||
|
||||
|
@ -563,7 +565,7 @@ namespace Ryujinx.Ui.App.Common
|
|||
{
|
||||
try
|
||||
{
|
||||
PartitionFileSystem pfs;
|
||||
IFileSystem pfs;
|
||||
|
||||
bool isExeFs = false;
|
||||
|
||||
|
@ -575,7 +577,9 @@ namespace Ryujinx.Ui.App.Common
|
|||
}
|
||||
else
|
||||
{
|
||||
pfs = new PartitionFileSystem(file.AsStorage());
|
||||
var pfsTemp = new PartitionFileSystem();
|
||||
pfsTemp.Initialize(file.AsStorage()).ThrowIfFailure();
|
||||
pfs = pfsTemp;
|
||||
|
||||
foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*"))
|
||||
{
|
||||
|
@ -827,7 +831,7 @@ namespace Ryujinx.Ui.App.Common
|
|||
return false;
|
||||
}
|
||||
|
||||
public static (Nca main, Nca patch, Nca control) GetGameData(VirtualFileSystem fileSystem, PartitionFileSystem pfs, int programIndex)
|
||||
public static (Nca main, Nca patch, Nca control) GetGameData(VirtualFileSystem fileSystem, IFileSystem pfs, int programIndex)
|
||||
{
|
||||
Nca mainNca = null;
|
||||
Nca patchNca = null;
|
||||
|
@ -931,7 +935,8 @@ namespace Ryujinx.Ui.App.Common
|
|||
if (File.Exists(updatePath))
|
||||
{
|
||||
FileStream file = new(updatePath, FileMode.Open, FileAccess.Read);
|
||||
PartitionFileSystem nsp = new(file.AsStorage());
|
||||
PartitionFileSystem nsp = new();
|
||||
nsp.Initialize(file.AsStorage()).ThrowIfFailure();
|
||||
|
||||
return GetGameUpdateDataFromPartition(fileSystem, nsp, titleIdBase.ToString("x16"), programIndex);
|
||||
}
|
||||
|
|
|
@ -211,7 +211,7 @@ namespace Ryujinx.Ui.Widgets
|
|||
(System.IO.Path.GetExtension(_titleFilePath).ToLower() == ".pfs0") ||
|
||||
(System.IO.Path.GetExtension(_titleFilePath).ToLower() == ".xci"))
|
||||
{
|
||||
PartitionFileSystem pfs;
|
||||
IFileSystem pfs;
|
||||
|
||||
if (System.IO.Path.GetExtension(_titleFilePath) == ".xci")
|
||||
{
|
||||
|
@ -221,7 +221,9 @@ namespace Ryujinx.Ui.Widgets
|
|||
}
|
||||
else
|
||||
{
|
||||
pfs = new PartitionFileSystem(file.AsStorage());
|
||||
var pfsTemp = new PartitionFileSystem();
|
||||
pfsTemp.Initialize(file.AsStorage()).ThrowIfFailure();
|
||||
pfs = pfsTemp;
|
||||
}
|
||||
|
||||
foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca"))
|
||||
|
|
|
@ -88,7 +88,8 @@ namespace Ryujinx.Ui.Windows
|
|||
|
||||
using FileStream containerFile = File.OpenRead(dlcContainer.ContainerPath);
|
||||
|
||||
PartitionFileSystem pfs = new(containerFile.AsStorage());
|
||||
PartitionFileSystem pfs = new();
|
||||
pfs.Initialize(containerFile.AsStorage()).ThrowIfFailure();
|
||||
|
||||
_virtualFileSystem.ImportTickets(pfs);
|
||||
|
||||
|
@ -153,7 +154,8 @@ namespace Ryujinx.Ui.Windows
|
|||
|
||||
using FileStream containerFile = File.OpenRead(containerPath);
|
||||
|
||||
PartitionFileSystem pfs = new(containerFile.AsStorage());
|
||||
PartitionFileSystem pfs = new();
|
||||
pfs.Initialize(containerFile.AsStorage()).ThrowIfFailure();
|
||||
bool containsDlc = false;
|
||||
|
||||
_virtualFileSystem.ImportTickets(pfs);
|
||||
|
|
|
@ -90,7 +90,8 @@ namespace Ryujinx.Ui.Windows
|
|||
{
|
||||
using FileStream file = new(path, FileMode.Open, FileAccess.Read);
|
||||
|
||||
PartitionFileSystem nsp = new(file.AsStorage());
|
||||
PartitionFileSystem nsp = new();
|
||||
nsp.Initialize(file.AsStorage()).ThrowIfFailure();
|
||||
|
||||
try
|
||||
{
|
||||
|
|
Reference in a new issue