Compare commits

..

6 Commits

Author SHA1 Message Date
Alex Barney
56fe2ff535 Fix loading tickets from a Sha256PartitionFileSystem (#5844) 2023-10-24 13:26:25 -03:00
Alex Barney
b1f8f868f6 Fix the AOC manager using incorrect paths (#5840)
* Fix the content manager using incorrect path for some AOC NCAs

* Check Results in a few more places in the content manager
2023-10-23 14:34:31 -03:00
Alex Barney
d773d5152e 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
2023-10-22 20:30:46 -03:00
gdkchan
33ba170315 Fix NRE on gather operations with depth compare on macOS (#5832) 2023-10-22 20:31:36 +02:00
TSR Berry
638be5f296 Revert "Ava UI: Input Menu Refactor (#4998)"
This reverts commit 49b37550ca.

This currently breaks the GTK GUI.
2023-10-21 15:19:21 +02:00
Isaac Marovitz
49b37550ca Ava UI: Input Menu Refactor (#4998)
* So much boilerplate

* Slow and steady

* Restructure + Ack suggestions

* Restructure + Ack suggestions

* Restructure

* Clean

* Propogate those fields i forgot about

* It builds

* Progress

* Almost there

* Fix stupid mistake

* Fix more stupid mistakes

* Actually fix fuck ups

* Start localising

* r/therestofthefuckingowl

* Localise ButtonKeyAssigner

* Are you feeling it now mr krabs

* We’re done at last

* Crimes against code

* Try me in the Hague

* Please be quiet

* Crimes are here to stay

* Dispose stuff

* Cleanup a couple things

* Visual fixes and improvements

One weird bug

* Fix rebase errors

* Fixes

* Ack Suggestions

Remaining ack suggestions

Update src/Ryujinx.Ava/UI/Models/Input/ControllerInputConfig.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

Update src/Ryujinx.Ava/UI/Models/Input/ControllerInputConfig.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Formatting and error

More Ava 11-ness

Whoops

* Code style fixes

* Style fixes

* Analyzer fix

* Remove all ReflectionBindings

* Remove ambigious object

* Remove redundant property

* Old man yells at formatter

* r e a d o n l y

* Fix profiles

* Use new Sliders

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2023-10-21 13:26:51 +02:00
19 changed files with 103 additions and 46 deletions

View File

@@ -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" />

View File

@@ -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"))

View File

@@ -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);

View File

@@ -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)
{

View File

@@ -766,7 +766,10 @@ namespace Ryujinx.Graphics.Shader.Instructions
flags |= offset == TexOffset.Ptp ? TextureFlags.Offsets : TextureFlags.Offset;
}
sourcesList.Add(Const((int)component));
if (!hasDepthCompare)
{
sourcesList.Add(Const((int)component));
}
Operand[] sources = sourcesList.ToArray();
Operand[] dests = new Operand[BitOperations.PopCount((uint)componentMask)];

View File

@@ -198,7 +198,7 @@ namespace Ryujinx.HLE.FileSystem
{
using var ncaFile = new UniqueRef<IFile>();
fs.OpenFile(ref ncaFile.Ref, ncaPath.FullPath.ToU8Span(), OpenMode.Read);
fs.OpenFile(ref ncaFile.Ref, ncaPath.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
var nca = new Nca(_virtualFileSystem.KeySet, ncaFile.Get.AsStorage());
if (nca.Header.ContentType != NcaContentType.Meta)
{
@@ -210,7 +210,7 @@ namespace Ryujinx.HLE.FileSystem
using var pfs0 = nca.OpenFileSystem(0, integrityCheckLevel);
using var cnmtFile = new UniqueRef<IFile>();
pfs0.OpenFile(ref cnmtFile.Ref, pfs0.EnumerateEntries().Single().FullPath.ToU8Span(), OpenMode.Read);
pfs0.OpenFile(ref cnmtFile.Ref, pfs0.EnumerateEntries().Single().FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
var cnmt = new Cnmt(cnmtFile.Get.AsStream());
if (cnmt.Type != ContentMetaType.AddOnContent || (cnmt.TitleId & 0xFFFFFFFFFFFFE000) != aocBaseId)
@@ -220,7 +220,7 @@ namespace Ryujinx.HLE.FileSystem
string ncaId = Convert.ToHexString(cnmt.ContentEntries[0].NcaId).ToLower();
AddAocItem(cnmt.TitleId, containerPath, $"{ncaId}.nca", true);
AddAocItem(cnmt.TitleId, containerPath, $"/{ncaId}.nca", true);
}
}
@@ -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,17 +260,17 @@ 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).ThrowIfFailure();
break;
case ".nsp":
pfs = new PartitionFileSystem(file.AsStorage());
pfs.OpenFile(ref ncaFile.Ref, aoc.NcaPath.ToU8Span(), OpenMode.Read);
var pfs = new PartitionFileSystem();
pfs.Initialize(file.AsStorage());
pfs.OpenFile(ref ncaFile.Ref, aoc.NcaPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
break;
default:
return false; // Print error?
@@ -606,11 +607,11 @@ namespace Ryujinx.HLE.FileSystem
if (filesystem.FileExists($"{path}/00"))
{
filesystem.OpenFile(ref file.Ref, $"{path}/00".ToU8Span(), mode);
filesystem.OpenFile(ref file.Ref, $"{path}/00".ToU8Span(), mode).ThrowIfFailure();
}
else
{
filesystem.OpenFile(ref file.Ref, path.ToU8Span(), mode);
filesystem.OpenFile(ref file.Ref, path.ToU8Span(), mode).ThrowIfFailure();
}
return file.Release();

View File

@@ -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,
};
@@ -263,7 +264,16 @@ namespace Ryujinx.HLE.FileSystem
if (result.IsSuccess())
{
Ticket ticket = new(ticketFile.Get.AsStream());
// When reading a file from a Sha256PartitionFileSystem, you can't start a read in the middle
// of the hashed portion (usually the first 0x200 bytes) of the file and end the read after
// the end of the hashed portion, so we read the ticket file using a single read.
byte[] ticketData = new byte[0x2C0];
result = ticketFile.Get.Read(out long bytesRead, 0, ticketData);
if (result.IsFailure() || bytesRead != ticketData.Length)
continue;
Ticket ticket = new(new MemoryStream(ticketData));
var titleKey = ticket.GetTitleKey(KeySet);
if (titleKey != null)

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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)

View File

@@ -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)]

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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"))

View File

@@ -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);
}

View File

@@ -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"))

View File

@@ -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);

View File

@@ -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
{