From 27cc721b3172b2589d4d42b91071732312b4690a Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Sun, 31 Mar 2024 23:27:06 -0700 Subject: [PATCH] Update FileSystemProxyImpl --- build/CodeGen/result_namespaces.csv | 6 +- src/LibHac/Fat/FatReport.cs | 8 +- src/LibHac/Fat/FatSafeInfo.cs | 8 + src/LibHac/Fs/Common/Path.cs | 8 + src/LibHac/Fs/ErrorInfo.cs | 29 +- src/LibHac/Fs/ResultHandlingUtility.cs | 25 +- src/LibHac/Fs/Shim/Application.cs | 2 +- src/LibHac/Fs/Shim/Code.cs | 13 +- src/LibHac/Fs/Shim/Content.cs | 29 +- src/LibHac/Fs/Shim/Logo.cs | 11 +- src/LibHac/Fs/Shim/RightsId.cs | 21 +- src/LibHac/FsSrv/BaseFileSystemService.cs | 5 - src/LibHac/FsSrv/FileSystemProxyImpl.cs | 363 ++++--- .../FsSrv/FileSystemServerInitializer.cs | 2 +- .../FsSrv/FsCreator/FatFileSystemCreator.cs | 16 +- .../FsCreator/INspRootFileSystemCreator.cs | 10 + .../ISubDirectoryFileSystemCreator.cs | 2 +- .../SubDirectoryFileSystemCreator.cs | 4 +- src/LibHac/FsSrv/Impl/AccessControl.cs | 12 +- src/LibHac/FsSrv/Impl/ExternalKeyManager.cs | 46 + .../Impl/FileSystemProxyServiceObject.cs | 6 +- .../IRomFileSystemAccessFailureManager.cs | 6 +- .../Impl/SystemDataUpdateEventManager.cs | 32 + .../Impl/SystemDataUpdateEventNotifier.cs | 22 + src/LibHac/FsSrv/Impl/UpdatePartitionPath.cs | 67 ++ src/LibHac/FsSrv/Impl/Utility.cs | 6 + src/LibHac/FsSrv/NcaFileSystemService.cs | 122 ++- src/LibHac/FsSrv/NcaFileSystemServiceImpl.cs | 929 ++++++------------ src/LibHac/FsSrv/Sf/IFileSystemProxy.cs | 15 +- .../FsSrv/Sf/IFileSystemProxyForLoader.cs | 5 +- src/LibHac/FsSrv/StatusReportService.cs | 10 +- src/LibHac/FsSystem/SubdirectoryFileSystem.cs | 4 +- src/LibHac/Htc/ResultHtc.cs | 46 + src/LibHac/HtcFs/ResultHtcFs.cs | 57 ++ src/LibHac/HtcLow/ResultHtcLow.cs | 116 +++ tests/LibHac.Tests/Fs/TypeLayoutTests.cs | 15 +- .../LibHac.Tests/FsSrv/AccessControlTests.cs | 4 +- 37 files changed, 1146 insertions(+), 936 deletions(-) create mode 100644 src/LibHac/Fat/FatSafeInfo.cs create mode 100644 src/LibHac/FsSrv/FsCreator/INspRootFileSystemCreator.cs create mode 100644 src/LibHac/FsSrv/Impl/ExternalKeyManager.cs create mode 100644 src/LibHac/FsSrv/Impl/SystemDataUpdateEventManager.cs create mode 100644 src/LibHac/FsSrv/Impl/SystemDataUpdateEventNotifier.cs create mode 100644 src/LibHac/FsSrv/Impl/UpdatePartitionPath.cs create mode 100644 src/LibHac/Htc/ResultHtc.cs create mode 100644 src/LibHac/HtcFs/ResultHtcFs.cs create mode 100644 src/LibHac/HtcLow/ResultHtcLow.cs diff --git a/build/CodeGen/result_namespaces.csv b/build/CodeGen/result_namespaces.csv index 3e65aa1c..637c15e5 100644 --- a/build/CodeGen/result_namespaces.csv +++ b/build/CodeGen/result_namespaces.csv @@ -15,16 +15,16 @@ Tma,, Dnmt,, Pm,, Ns,, -Htc,, +Htc,,Htc/ResultHtc.cs Kvdb,,Kvdb/ResultKvdb.cs Sm,,Sm/ResultSm.cs Ro,, Sdmmc,,Sdmmc/ResultSdmmc.cs Spl,,Spl/ResultSpl.cs Socket,, -HtcLow,, +HtcLow,,HtcLow/ResultHtcLow.cs Ddsf,, -HtcFs,, +HtcFs,,HtcFs/ResultHtcFs.cs I2C,, Gpio,, Settings,, diff --git a/src/LibHac/Fat/FatReport.cs b/src/LibHac/Fat/FatReport.cs index 216a056b..53bdf28c 100644 --- a/src/LibHac/Fat/FatReport.cs +++ b/src/LibHac/Fat/FatReport.cs @@ -8,8 +8,14 @@ public struct FatReport public ushort DirectoryPeakOpenCount; } -public struct FatReportInfo +public struct FatReportInfo1 { public ushort FilePeakOpenCount; public ushort DirectoryPeakOpenCount; +} + +public struct FatReportInfo2 +{ + public ushort OpenUniqueFileEntryPeakCount; + public ushort OpenUniqueDirectoryEntryPeakCount; } \ No newline at end of file diff --git a/src/LibHac/Fat/FatSafeInfo.cs b/src/LibHac/Fat/FatSafeInfo.cs new file mode 100644 index 00000000..1f7c484a --- /dev/null +++ b/src/LibHac/Fat/FatSafeInfo.cs @@ -0,0 +1,8 @@ +namespace LibHac.Fat; + +public struct FatSafeInfo +{ + public uint Result; + public uint ErrorNumber; + public uint SafeErrorNumber; +} \ No newline at end of file diff --git a/src/LibHac/Fs/Common/Path.cs b/src/LibHac/Fs/Common/Path.cs index a6cc7858..fcff40fa 100644 --- a/src/LibHac/Fs/Common/Path.cs +++ b/src/LibHac/Fs/Common/Path.cs @@ -165,6 +165,14 @@ public ref struct Path return Result.Success; } + public Result InitializeAsEmpty() + { + _buffer = EmptyBuffer; + _length = 0; + + return Result.Success; + } + public readonly int GetLength() => _length; public readonly ReadOnlySpan GetString() => _buffer; diff --git a/src/LibHac/Fs/ErrorInfo.cs b/src/LibHac/Fs/ErrorInfo.cs index 3ca56178..acf84ce1 100644 --- a/src/LibHac/Fs/ErrorInfo.cs +++ b/src/LibHac/Fs/ErrorInfo.cs @@ -5,21 +5,28 @@ namespace LibHac.Fs; public struct FileSystemProxyErrorInfo { - public int RemountForDataCorruptionCount; - public int UnrecoverableDataCorruptionByRemountCount; + public uint RemountForDataCorruptionCount; + public uint UnrecoverableDataCorruptionByRemountCount; public FatError FatFsError; - public int RecoveredByInvalidateCacheCount; + public uint RecoveredByInvalidateCacheCount; public int SaveDataIndexCount; - public FatReportInfo BisSystemFatReportInfo; - public FatReportInfo BisUserFatReport; - public FatReportInfo SdCardFatReport; - public Array68 Reserved; + public FatReportInfo1 BisSystemFatReportInfo1; + public FatReportInfo1 BisUserFatReport1; + public FatReportInfo1 SdCardFatReport1; + public FatReportInfo2 BisSystemFatReportInfo2; + public FatReportInfo2 BisUserFatReport2; + public FatReportInfo2 SdCardFatReport2; + public uint DeepRetryStartCount; + public uint UnrecoverableByGameCardAccessFailedCount; + public FatSafeInfo BisSystemFatSafeInfo; + public FatSafeInfo BisUserFatSafeInfo; + public Array24 Reserved; } public struct StorageErrorInfo { - public int NumActivationFailures; - public int NumActivationErrorCorrections; - public int NumReadWriteFailures; - public int NumReadWriteErrorCorrections; + public uint NumActivationFailures; + public uint NumActivationErrorCorrections; + public uint NumReadWriteFailures; + public uint NumReadWriteErrorCorrections; } \ No newline at end of file diff --git a/src/LibHac/Fs/ResultHandlingUtility.cs b/src/LibHac/Fs/ResultHandlingUtility.cs index be1ea0d7..3b593e58 100644 --- a/src/LibHac/Fs/ResultHandlingUtility.cs +++ b/src/LibHac/Fs/ResultHandlingUtility.cs @@ -1,5 +1,9 @@ -using System.Runtime.CompilerServices; +using System; +using System.Runtime.CompilerServices; using LibHac.Diag; +using LibHac.Htc; +using LibHac.HtcFs; +using LibHac.HtcLow; namespace LibHac.Fs; @@ -75,4 +79,23 @@ public static class ResultHandlingUtility if (!result.IsSuccess()) Abort.DoAbort(result); } + + public static bool IsResultHtcAccessFailed(Result result) + { + if (ResultHtc.ConnectionFailure.Module == result.Module) + return true; + + if (ResultHtcLow.ConnectionFailure.Module == result.Module) + return true; + + if (ResultHtcFs.ConnectionFailure.Module == result.Module) + return true; + + return false; + } + + public static void SetErrorContextEnabled(this FileSystemClientImpl fs, bool isEnabled) + { + // Todo + } } \ No newline at end of file diff --git a/src/LibHac/Fs/Shim/Application.cs b/src/LibHac/Fs/Shim/Application.cs index 516852a0..a6c469be 100644 --- a/src/LibHac/Fs/Shim/Application.cs +++ b/src/LibHac/Fs/Shim/Application.cs @@ -60,7 +60,7 @@ public static class Application using SharedRef fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject(); using var fileSystem = new SharedRef(); - res = fileSystemProxy.Get.OpenFileSystemWithId(ref fileSystem.Ref, in sfPath, + res = fileSystemProxy.Get.OpenFileSystemWithId(ref fileSystem.Ref, in sfPath, ContentAttributes.None, Ncm.ProgramId.InvalidId.Value, FileSystemProxyType.Package); if (res.IsFailure()) return res.Miss(); diff --git a/src/LibHac/Fs/Shim/Code.cs b/src/LibHac/Fs/Shim/Code.cs index de9fd63d..da850ace 100644 --- a/src/LibHac/Fs/Shim/Code.cs +++ b/src/LibHac/Fs/Shim/Code.cs @@ -6,6 +6,7 @@ using LibHac.Fs.Impl; using LibHac.FsSrv.Sf; using LibHac.Ncm; using LibHac.Os; +using LibHac.Sf; using static LibHac.Fs.Impl.AccessLogStrings; using IFileSystem = LibHac.Fs.Fsa.IFileSystem; using IFileSystemSf = LibHac.FsSrv.Sf.IFileSystem; @@ -20,13 +21,13 @@ namespace LibHac.Fs.Shim; public static class Code { public static Result MountCode(this FileSystemClient fs, out CodeVerificationData verificationData, - U8Span mountName, U8Span path, ProgramId programId) + U8Span mountName, U8Span path, ContentAttributes attributes, ProgramId programId) { Result res; if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System)) { Tick start = fs.Hos.Os.GetSystemTick(); - res = Mount(fs, out verificationData, mountName, path, programId); + res = Mount(fs, out verificationData, mountName, path, attributes, programId); Tick end = fs.Hos.Os.GetSystemTick(); Span logBuffer = stackalloc byte[0x300]; @@ -40,7 +41,7 @@ public static class Code } else { - res = Mount(fs, out verificationData, mountName, path, programId); + res = Mount(fs, out verificationData, mountName, path, attributes, programId); } fs.Impl.AbortIfNeeded(res); @@ -52,7 +53,7 @@ public static class Code return Result.Success; static Result Mount(FileSystemClient fs, out CodeVerificationData verificationData, - U8Span mountName, U8Span path, ProgramId programId) + U8Span mountName, U8Span path, ContentAttributes attributes, ProgramId programId) { UnsafeHelpers.SkipParamInit(out verificationData); @@ -71,8 +72,8 @@ public static class Code using var fileSystem = new SharedRef(); - res = fileSystemProxy.Get.OpenCodeFileSystem(ref fileSystem.Ref, out verificationData, in sfPath, - programId); + res = fileSystemProxy.Get.OpenCodeFileSystem(ref fileSystem.Ref, OutBuffer.FromStruct(ref verificationData), + in sfPath, attributes, programId); if (res.IsFailure()) return res.Miss(); using var fileSystemAdapter = diff --git a/src/LibHac/Fs/Shim/Content.cs b/src/LibHac/Fs/Shim/Content.cs index 34fc4311..afa3cee9 100644 --- a/src/LibHac/Fs/Shim/Content.cs +++ b/src/LibHac/Fs/Shim/Content.cs @@ -34,8 +34,8 @@ public static class Content } } - private static Result MountContentImpl(FileSystemClient fs, U8Span mountName, U8Span path, ulong id, - ContentType contentType) + private static Result MountContentImpl(FileSystemClient fs, U8Span mountName, U8Span path, + ContentAttributes attributes, ulong id, ContentType contentType) { Result res = fs.Impl.CheckMountNameAcceptingReservedMountName(mountName); if (res.IsFailure()) return res.Miss(); @@ -48,7 +48,7 @@ public static class Content using SharedRef fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject(); using var fileSystem = new SharedRef(); - res = fileSystemProxy.Get.OpenFileSystemWithId(ref fileSystem.Ref, in sfPath, id, fsType); + res = fileSystemProxy.Get.OpenFileSystemWithId(ref fileSystem.Ref, in sfPath, attributes, id, fsType); if (res.IsFailure()) return res.Miss(); using var fileSystemAdapter = @@ -63,7 +63,8 @@ public static class Content return Result.Success; } - public static Result MountContent(this FileSystemClient fs, U8Span mountName, U8Span path, ContentType contentType) + public static Result MountContent(this FileSystemClient fs, U8Span mountName, U8Span path, + ContentAttributes attributes, ContentType contentType) { Result res; Span logBuffer = stackalloc byte[0x300]; @@ -96,7 +97,7 @@ public static class Content if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System)) { Tick start = fs.Hos.Os.GetSystemTick(); - res = MountContentImpl(fs, mountName, path, programId.Value, contentType); + res = MountContentImpl(fs, mountName, path, attributes, programId.Value, contentType); Tick end = fs.Hos.Os.GetSystemTick(); var idString = new IdString(); @@ -111,7 +112,7 @@ public static class Content } else { - res = MountContentImpl(fs, mountName, path, programId.Value, contentType); + res = MountContentImpl(fs, mountName, path, attributes, programId.Value, contentType); } fs.Impl.AbortIfNeeded(res); @@ -131,8 +132,8 @@ public static class Content } } - public static Result MountContent(this FileSystemClient fs, U8Span mountName, U8Span path, ProgramId programId, - ContentType contentType) + public static Result MountContent(this FileSystemClient fs, U8Span mountName, U8Span path, + ContentAttributes attributes, ProgramId programId, ContentType contentType) { Result res; Span logBuffer = stackalloc byte[0x300]; @@ -140,7 +141,7 @@ public static class Content if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System)) { Tick start = fs.Hos.Os.GetSystemTick(); - res = MountContentImpl(fs, mountName, path, programId.Value, contentType); + res = MountContentImpl(fs, mountName, path, attributes, programId.Value, contentType); Tick end = fs.Hos.Os.GetSystemTick(); var idString = new IdString(); @@ -157,7 +158,7 @@ public static class Content } else { - res = MountContentImpl(fs, mountName, path, programId.Value, contentType); + res = MountContentImpl(fs, mountName, path, attributes, programId.Value, contentType); } fs.Impl.AbortIfNeeded(res); @@ -169,8 +170,8 @@ public static class Content return Result.Success; } - public static Result MountContent(this FileSystemClient fs, U8Span mountName, U8Span path, DataId dataId, - ContentType contentType) + public static Result MountContent(this FileSystemClient fs, U8Span mountName, U8Span path, + ContentAttributes attributes, DataId dataId, ContentType contentType) { Result res; Span logBuffer = stackalloc byte[0x300]; @@ -178,7 +179,7 @@ public static class Content if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System)) { Tick start = fs.Hos.Os.GetSystemTick(); - res = MountContentImpl(fs, mountName, path, dataId.Value, contentType); + res = MountContentImpl(fs, mountName, path, attributes, dataId.Value, contentType); Tick end = fs.Hos.Os.GetSystemTick(); var idString = new IdString(); @@ -193,7 +194,7 @@ public static class Content } else { - res = MountContentImpl(fs, mountName, path, dataId.Value, contentType); + res = MountContentImpl(fs, mountName, path, attributes, dataId.Value, contentType); } fs.Impl.AbortIfNeeded(res); diff --git a/src/LibHac/Fs/Shim/Logo.cs b/src/LibHac/Fs/Shim/Logo.cs index 61592f24..8a903014 100644 --- a/src/LibHac/Fs/Shim/Logo.cs +++ b/src/LibHac/Fs/Shim/Logo.cs @@ -17,7 +17,8 @@ namespace LibHac.Fs.Shim; /// Based on nnSdk 14.3.0 public static class Logo { - public static Result MountLogo(this FileSystemClient fs, U8Span mountName, U8Span path, ProgramId programId) + public static Result MountLogo(this FileSystemClient fs, U8Span mountName, U8Span path, + ContentAttributes attributes, ProgramId programId) { Result res; Span logBuffer = stackalloc byte[0x300]; @@ -25,7 +26,7 @@ public static class Logo if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System)) { Tick start = fs.Hos.Os.GetSystemTick(); - res = Mount(fs, mountName, path, programId); + res = Mount(fs, mountName, path, attributes, programId); Tick end = fs.Hos.Os.GetSystemTick(); var sb = new U8StringBuilder(logBuffer, true); @@ -38,7 +39,7 @@ public static class Logo } else { - res = Mount(fs, mountName, path, programId); + res = Mount(fs, mountName, path, attributes, programId); } fs.Impl.AbortIfNeeded(res); @@ -49,7 +50,7 @@ public static class Logo return Result.Success; - static Result Mount(FileSystemClient fs, U8Span mountName, U8Span path, ProgramId programId) + static Result Mount(FileSystemClient fs, U8Span mountName, U8Span path,ContentAttributes attributes, ProgramId programId) { Result res = fs.Impl.CheckMountName(mountName); if (res.IsFailure()) return res.Miss(); @@ -60,7 +61,7 @@ public static class Logo using SharedRef fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject(); using var fileSystem = new SharedRef(); - res = fileSystemProxy.Get.OpenFileSystemWithId(ref fileSystem.Ref, in sfPath, programId.Value, + res = fileSystemProxy.Get.OpenFileSystemWithId(ref fileSystem.Ref, in sfPath, attributes, programId.Value, FileSystemProxyType.Logo); if (res.IsFailure()) return res.Miss(); diff --git a/src/LibHac/Fs/Shim/RightsId.cs b/src/LibHac/Fs/Shim/RightsId.cs index 675edf2b..3e2a61a2 100644 --- a/src/LibHac/Fs/Shim/RightsId.cs +++ b/src/LibHac/Fs/Shim/RightsId.cs @@ -23,24 +23,13 @@ public static class RightsIdShim return Result.Success; } - public static Result GetRightsId(this FileSystemClient fs, out RightsId rightsId, U8Span path) + public static Result GetRightsId(this FileSystemClient fs, out RightsId rightsId, U8Span path, ContentAttributes attributes) { - UnsafeHelpers.SkipParamInit(out rightsId); - - Result res = PathUtility.ConvertToFspPath(out FspPath sfPath, path); - fs.Impl.AbortIfNeeded(res); - if (res.IsFailure()) return res.Miss(); - - using SharedRef fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject(); - - res = fileSystemProxy.Get.GetRightsIdByPath(out rightsId, in sfPath); - fs.Impl.AbortIfNeeded(res); - if (res.IsFailure()) return res.Miss(); - - return Result.Success; + return GetRightsId(fs, out rightsId, out _, path, attributes); } - public static Result GetRightsId(this FileSystemClient fs, out RightsId rightsId, out byte keyGeneration, U8Span path) + public static Result GetRightsId(this FileSystemClient fs, out RightsId rightsId, out byte keyGeneration, + U8Span path, ContentAttributes attributes) { UnsafeHelpers.SkipParamInit(out rightsId, out keyGeneration); @@ -50,7 +39,7 @@ public static class RightsIdShim using SharedRef fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject(); - res = fileSystemProxy.Get.GetRightsIdAndKeyGenerationByPath(out rightsId, out keyGeneration, in sfPath); + res = fileSystemProxy.Get.GetRightsIdAndKeyGenerationByPath(out rightsId, out keyGeneration, in sfPath, attributes); fs.Impl.AbortIfNeeded(res); if (res.IsFailure()) return res.Miss(); diff --git a/src/LibHac/FsSrv/BaseFileSystemService.cs b/src/LibHac/FsSrv/BaseFileSystemService.cs index f9950bd9..7116fa00 100644 --- a/src/LibHac/FsSrv/BaseFileSystemService.cs +++ b/src/LibHac/FsSrv/BaseFileSystemService.cs @@ -150,11 +150,6 @@ public readonly struct BaseFileSystemService return Result.Success; } - public Result SetBisRootForHost(BisPartitionId partitionId, ref readonly FspPath path) - { - throw new NotImplementedException(); - } - public Result CreatePaddingFile(long size) { // File size must be non-negative diff --git a/src/LibHac/FsSrv/FileSystemProxyImpl.cs b/src/LibHac/FsSrv/FileSystemProxyImpl.cs index 4b3b1d5f..8f1f3758 100644 --- a/src/LibHac/FsSrv/FileSystemProxyImpl.cs +++ b/src/LibHac/FsSrv/FileSystemProxyImpl.cs @@ -57,16 +57,16 @@ internal struct FileSystemProxyImplGlobals /// /// Dispatches calls to the various file system service objects. /// -/// Based on nnSdk 13.4.0 (FS 13.1.0) +/// Based on nnSdk 17.5.0 (FS 17.0.0) public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader { - private FileSystemProxyCoreImpl _fsProxyCore; + private readonly FileSystemProxyCoreImpl _fsProxyCore; private SharedRef _ncaFsService; private SharedRef _saveFsService; private ulong _currentProcess; // LibHac addition - private FileSystemServer _fsServer; + private readonly FileSystemServer _fsServer; private ref FileSystemProxyImplGlobals Globals => ref _fsServer.Globals.FileSystemProxyImpl; internal FileSystemProxyImpl(FileSystemServer server) @@ -153,13 +153,22 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader return new DebugConfigurationService(_fsServer, Globals.DebugConfigurationServiceImpl, _currentProcess); } - public Result OpenFileSystemWithId(ref SharedRef outFileSystem, ref readonly FspPath path, - ulong id, FileSystemProxyType fsType) + public Result OpenFileSystemWithIdObsolete(ref SharedRef outFileSystem, ref readonly FspPath path, + ulong programId, FileSystemProxyType fsType) { Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.OpenFileSystemWithId(ref outFileSystem, in path, id, fsType); + return ncaFsService.OpenFileSystemWithId(ref outFileSystem, in path, ContentAttributes.None, programId, fsType).Ret(); + } + + public Result OpenFileSystemWithId(ref SharedRef outFileSystem, ref readonly FspPath path, + ContentAttributes attributes, ulong programId, FileSystemProxyType fsType) + { + Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); + if (res.IsFailure()) return res.Miss(); + + return ncaFsService.OpenFileSystemWithId(ref outFileSystem, in path, attributes, programId, fsType).Ret(); } public Result OpenFileSystemWithPatch(ref SharedRef outFileSystem, @@ -168,18 +177,16 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.OpenFileSystemWithPatch(ref outFileSystem, programId, fsType); + return ncaFsService.OpenFileSystemWithPatch(ref outFileSystem, programId, fsType).Ret(); } - public Result OpenCodeFileSystem(ref SharedRef fileSystem, - out CodeVerificationData verificationData, ref readonly FspPath path, ProgramId programId) + public Result OpenCodeFileSystem(ref SharedRef fileSystem, OutBuffer outVerificationData, + ref readonly FspPath path, ContentAttributes attributes, ProgramId programId) { - UnsafeHelpers.SkipParamInit(out verificationData); - Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.OpenCodeFileSystem(ref fileSystem, out verificationData, in path, programId); + return ncaFsService.OpenCodeFileSystem(ref fileSystem, outVerificationData, in path, attributes, programId).Ret(); } public Result SetCurrentProcess(ulong processId) @@ -205,7 +212,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.GetFreeSpaceSizeForSaveData(out freeSpaceSize, spaceId); + return saveFsService.GetFreeSpaceSizeForSaveData(out freeSpaceSize, spaceId).Ret(); } public Result OpenDataFileSystemByCurrentProcess(ref SharedRef outFileSystem) @@ -213,16 +220,15 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.OpenDataFileSystemByCurrentProcess(ref outFileSystem); + return ncaFsService.OpenDataFileSystemByCurrentProcess(ref outFileSystem).Ret(); } - public Result OpenDataFileSystemByProgramId(ref SharedRef outFileSystem, - ProgramId programId) + public Result OpenDataFileSystemByProgramId(ref SharedRef outFileSystem, ProgramId programId) { Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.OpenDataFileSystemByProgramId(ref outFileSystem, programId); + return ncaFsService.OpenDataFileSystemByProgramId(ref outFileSystem, programId).Ret(); } public Result OpenDataStorageByCurrentProcess(ref SharedRef outStorage) @@ -230,34 +236,40 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.OpenDataStorageByCurrentProcess(ref outStorage); + return ncaFsService.OpenDataStorageByCurrentProcess(ref outStorage).Ret(); } - public Result OpenDataStorageByProgramId(ref SharedRef outStorage, - ProgramId programId) + public Result OpenDataStorageByProgramId(ref SharedRef outStorage, ProgramId programId) { Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.OpenDataStorageByProgramId(ref outStorage, programId); + return ncaFsService.OpenDataStorageByProgramId(ref outStorage, programId).Ret(); } - public Result OpenDataStorageByDataId(ref SharedRef outStorage, DataId dataId, - StorageId storageId) + public Result OpenDataStorageByDataId(ref SharedRef outStorage, DataId dataId, StorageId storageId) { Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.OpenDataStorageByDataId(ref outStorage, dataId, storageId); + return ncaFsService.OpenDataStorageByDataId(ref outStorage, dataId, storageId).Ret(); + } + + public Result OpenDataFileSystemByDataId(ref SharedRef outFileSystem, DataId dataId, StorageId storageId) + { + Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); + if (res.IsFailure()) return res.Miss(); + + return ncaFsService.OpenDataFileSystemByDataId(ref outFileSystem, dataId, storageId).Ret(); } public Result OpenDataStorageByPath(ref SharedRef outFileSystem, ref readonly FspPath path, - FileSystemProxyType fsType) + ContentAttributes attributes, FileSystemProxyType fsType) { Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.OpenDataStorageByPath(ref outFileSystem, in path, fsType); + return ncaFsService.OpenDataStorageByPath(ref outFileSystem, in path, attributes, fsType).Ret(); } public Result OpenPatchDataStorageByCurrentProcess(ref SharedRef outStorage) @@ -271,7 +283,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.OpenDataFileSystemWithProgramIndex(ref outFileSystem, programIndex); + return ncaFsService.OpenDataFileSystemWithProgramIndex(ref outFileSystem, programIndex).Ret(); } public Result OpenDataStorageWithProgramIndex(ref SharedRef outStorage, @@ -280,7 +292,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.OpenDataStorageWithProgramIndex(ref outStorage, programIndex); + return ncaFsService.OpenDataStorageWithProgramIndex(ref outStorage, programIndex).Ret(); } public Result RegisterSaveDataFileSystemAtomicDeletion(InBuffer saveDataIds) @@ -288,7 +300,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.RegisterSaveDataFileSystemAtomicDeletion(saveDataIds); + return saveFsService.RegisterSaveDataFileSystemAtomicDeletion(saveDataIds).Ret(); } public Result DeleteSaveDataFileSystem(ulong saveDataId) @@ -296,7 +308,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.DeleteSaveDataFileSystem(saveDataId); + return saveFsService.DeleteSaveDataFileSystem(saveDataId).Ret(); } public Result DeleteSaveDataFileSystemBySaveDataSpaceId(SaveDataSpaceId spaceId, ulong saveDataId) @@ -304,7 +316,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.DeleteSaveDataFileSystemBySaveDataSpaceId(spaceId, saveDataId); + return saveFsService.DeleteSaveDataFileSystemBySaveDataSpaceId(spaceId, saveDataId).Ret(); } public Result DeleteSaveDataFileSystemBySaveDataAttribute(SaveDataSpaceId spaceId, @@ -313,7 +325,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.DeleteSaveDataFileSystemBySaveDataAttribute(spaceId, in attribute); + return saveFsService.DeleteSaveDataFileSystemBySaveDataAttribute(spaceId, in attribute).Ret(); } public Result UpdateSaveDataMacForDebug(SaveDataSpaceId spaceId, ulong saveDataId) @@ -321,7 +333,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.UpdateSaveDataMacForDebug(spaceId, saveDataId); + return saveFsService.UpdateSaveDataMacForDebug(spaceId, saveDataId).Ret(); } public Result CreateSaveDataFileSystem(in SaveDataAttribute attribute, in SaveDataCreationInfo creationInfo, @@ -330,7 +342,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.CreateSaveDataFileSystem(in attribute, in creationInfo, in metaInfo); + return saveFsService.CreateSaveDataFileSystem(in attribute, in creationInfo, in metaInfo).Ret(); } public Result CreateSaveDataFileSystemWithHashSalt(in SaveDataAttribute attribute, @@ -340,7 +352,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader if (res.IsFailure()) return res.Miss(); return saveFsService.CreateSaveDataFileSystemWithHashSalt(in attribute, in creationInfo, in metaInfo, - in hashSalt); + in hashSalt).Ret(); } public Result CreateSaveDataFileSystemBySystemSaveDataId(in SaveDataAttribute attribute, @@ -349,7 +361,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.CreateSaveDataFileSystemBySystemSaveDataId(in attribute, in creationInfo); + return saveFsService.CreateSaveDataFileSystemBySystemSaveDataId(in attribute, in creationInfo).Ret(); } public Result CreateSaveDataFileSystemWithCreationInfo2(in SaveDataCreationInfo2 creationInfo) @@ -357,7 +369,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.CreateSaveDataFileSystemWithCreationInfo2(in creationInfo); + return saveFsService.CreateSaveDataFileSystemWithCreationInfo2(in creationInfo).Ret(); } public Result ExtendSaveDataFileSystem(SaveDataSpaceId spaceId, ulong saveDataId, long dataSize, @@ -366,7 +378,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.ExtendSaveDataFileSystem(spaceId, saveDataId, dataSize, journalSize); + return saveFsService.ExtendSaveDataFileSystem(spaceId, saveDataId, dataSize, journalSize).Ret(); } public Result OpenSaveDataFileSystem(ref SharedRef outFileSystem, SaveDataSpaceId spaceId, @@ -375,7 +387,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.OpenSaveDataFileSystem(ref outFileSystem, spaceId, in attribute); + return saveFsService.OpenSaveDataFileSystem(ref outFileSystem, spaceId, in attribute).Ret(); } public Result OpenReadOnlySaveDataFileSystem(ref SharedRef outFileSystem, @@ -384,7 +396,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.OpenReadOnlySaveDataFileSystem(ref outFileSystem, spaceId, in attribute); + return saveFsService.OpenReadOnlySaveDataFileSystem(ref outFileSystem, spaceId, in attribute).Ret(); } public Result OpenSaveDataFileSystemBySystemSaveDataId(ref SharedRef outFileSystem, @@ -393,7 +405,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.OpenSaveDataFileSystemBySystemSaveDataId(ref outFileSystem, spaceId, in attribute); + return saveFsService.OpenSaveDataFileSystemBySystemSaveDataId(ref outFileSystem, spaceId, in attribute).Ret(); } public Result ReadSaveDataFileSystemExtraData(OutBuffer extraDataBuffer, ulong saveDataId) @@ -401,7 +413,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.ReadSaveDataFileSystemExtraData(extraDataBuffer, saveDataId); + return saveFsService.ReadSaveDataFileSystemExtraData(extraDataBuffer, saveDataId).Ret(); } public Result ReadSaveDataFileSystemExtraDataBySaveDataAttribute(OutBuffer extraDataBuffer, @@ -411,7 +423,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader if (res.IsFailure()) return res.Miss(); return saveFsService.ReadSaveDataFileSystemExtraDataBySaveDataAttribute(extraDataBuffer, spaceId, - in attribute); + in attribute).Ret(); } public Result ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute(OutBuffer extraDataBuffer, @@ -421,7 +433,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader if (res.IsFailure()) return res.Miss(); return saveFsService.ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute(extraDataBuffer, spaceId, - in attribute, maskBuffer); + in attribute, maskBuffer).Ret(); } public Result ReadSaveDataFileSystemExtraDataBySaveDataSpaceId(OutBuffer extraDataBuffer, @@ -430,7 +442,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.ReadSaveDataFileSystemExtraDataBySaveDataSpaceId(extraDataBuffer, spaceId, saveDataId); + return saveFsService.ReadSaveDataFileSystemExtraDataBySaveDataSpaceId(extraDataBuffer, spaceId, saveDataId).Ret(); } public Result WriteSaveDataFileSystemExtraData(ulong saveDataId, SaveDataSpaceId spaceId, @@ -439,7 +451,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.WriteSaveDataFileSystemExtraData(saveDataId, spaceId, extraDataBuffer); + return saveFsService.WriteSaveDataFileSystemExtraData(saveDataId, spaceId, extraDataBuffer).Ret(); } public Result WriteSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute(in SaveDataAttribute attribute, @@ -449,7 +461,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader if (res.IsFailure()) return res.Miss(); return saveFsService.WriteSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute(in attribute, spaceId, - extraDataBuffer, maskBuffer); + extraDataBuffer, maskBuffer).Ret(); } public Result WriteSaveDataFileSystemExtraDataWithMask(ulong saveDataId, SaveDataSpaceId spaceId, @@ -459,44 +471,44 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader if (res.IsFailure()) return res.Miss(); return saveFsService.WriteSaveDataFileSystemExtraDataWithMask(saveDataId, spaceId, extraDataBuffer, - maskBuffer); + maskBuffer).Ret(); } public Result OpenImageDirectoryFileSystem(ref SharedRef outFileSystem, ImageDirectoryId directoryId) { - return GetBaseFileSystemService().OpenImageDirectoryFileSystem(ref outFileSystem, directoryId); + return GetBaseFileSystemService().OpenImageDirectoryFileSystem(ref outFileSystem, directoryId).Ret(); } public Result OpenBaseFileSystem(ref SharedRef outFileSystem, BaseFileSystemId fileSystemId) { - return GetBaseFileSystemService().OpenBaseFileSystem(ref outFileSystem, fileSystemId); + return GetBaseFileSystemService().OpenBaseFileSystem(ref outFileSystem, fileSystemId).Ret(); } public Result FormatBaseFileSystem(BaseFileSystemId fileSystemId) { - return GetBaseFileSystemService().FormatBaseFileSystem(fileSystemId); + return GetBaseFileSystemService().FormatBaseFileSystem(fileSystemId).Ret(); } public Result OpenBisFileSystem(ref SharedRef outFileSystem, ref readonly FspPath rootPath, BisPartitionId partitionId) { - return GetBaseFileSystemService().OpenBisFileSystem(ref outFileSystem, in rootPath, partitionId); + return GetBaseFileSystemService().OpenBisFileSystem(ref outFileSystem, in rootPath, partitionId).Ret(); } public Result OpenBisStorage(ref SharedRef outStorage, BisPartitionId partitionId) { - return GetBaseStorageService().OpenBisStorage(ref outStorage, partitionId); + return GetBaseStorageService().OpenBisStorage(ref outStorage, partitionId).Ret(); } public Result InvalidateBisCache() { - return GetBaseStorageService().InvalidateBisCache(); + return GetBaseStorageService().InvalidateBisCache().Ret(); } public Result OpenHostFileSystem(ref SharedRef outFileSystem, ref readonly FspPath path) { - return OpenHostFileSystemWithOption(ref outFileSystem, in path, MountHostOption.None); + return OpenHostFileSystemWithOption(ref outFileSystem, in path, MountHostOption.None).Ret(); } public Result OpenHostFileSystemWithOption(ref SharedRef outFileSystem, @@ -534,15 +546,20 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader bool isCaseSensitive = option.Flags.HasFlag(MountHostOptionFlag.PseudoCaseSensitive); - res = _fsProxyCore.OpenHostFileSystem(ref hostFileSystem.Ref, in pathNormalized, isCaseSensitive); - if (res.IsFailure()) return res.Miss(); + Result result = _fsProxyCore.OpenHostFileSystem(ref hostFileSystem.Ref, in pathNormalized, isCaseSensitive); + if (ResultHandlingUtility.IsResultHtcAccessFailed(result)) + { + return ResultFs.TargetNotFound.LogConverted(result); + } - var adapterFlags = new PathFlags(); + if (result.IsFailure()) return result.Miss(); + + PathFlags pathFlags = FileSystemInterfaceAdapter.GetDefaultPathFlags(); if (path.Str.At(0) == NullTerminator) - adapterFlags.AllowWindowsPath(); + pathFlags.AllowWindowsPath(); using SharedRef fileSystemAdapter = - FileSystemInterfaceAdapter.CreateShared(ref hostFileSystem.Ref, adapterFlags, false); + FileSystemInterfaceAdapter.CreateShared(ref hostFileSystem.Ref, pathFlags, allowAllOperations: false); outFileSystem.SetByMove(ref fileSystemAdapter.Ref); @@ -551,48 +568,48 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader public Result OpenSdCardFileSystem(ref SharedRef outFileSystem) { - return GetBaseFileSystemService().OpenSdCardFileSystem(ref outFileSystem); + return GetBaseFileSystemService().OpenSdCardFileSystem(ref outFileSystem).Ret(); } public Result FormatSdCardFileSystem() { - return GetBaseFileSystemService().FormatSdCardFileSystem(); + return GetBaseFileSystemService().FormatSdCardFileSystem().Ret(); } public Result FormatSdCardDryRun() { - return GetBaseFileSystemService().FormatSdCardDryRun(); + return GetBaseFileSystemService().FormatSdCardDryRun().Ret(); } public Result IsExFatSupported(out bool isSupported) { - return GetBaseFileSystemService().IsExFatSupported(out isSupported); + return GetBaseFileSystemService().IsExFatSupported(out isSupported).Ret(); } public Result OpenGameCardStorage(ref SharedRef outStorage, GameCardHandle handle, GameCardPartitionRaw partitionId) { - return GetBaseStorageService().OpenGameCardStorage(ref outStorage, handle, partitionId); + return GetBaseStorageService().OpenGameCardStorage(ref outStorage, handle, partitionId).Ret(); } public Result OpenDeviceOperator(ref SharedRef outDeviceOperator) { - return GetBaseStorageService().OpenDeviceOperator(ref outDeviceOperator); + return GetBaseStorageService().OpenDeviceOperator(ref outDeviceOperator).Ret(); } public Result OpenSdCardDetectionEventNotifier(ref SharedRef outEventNotifier) { - return GetBaseStorageService().OpenSdCardDetectionEventNotifier(ref outEventNotifier); + return GetBaseStorageService().OpenSdCardDetectionEventNotifier(ref outEventNotifier).Ret(); } public Result OpenGameCardDetectionEventNotifier(ref SharedRef outEventNotifier) { - return GetBaseStorageService().OpenGameCardDetectionEventNotifier(ref outEventNotifier); + return GetBaseStorageService().OpenGameCardDetectionEventNotifier(ref outEventNotifier).Ret(); } public Result SimulateDeviceDetectionEvent(SdmmcPort port, SimulatingDeviceDetectionMode mode, bool signalEvent) { - return GetBaseStorageService().SimulateDeviceDetectionEvent(port, mode, signalEvent); + return GetBaseStorageService().SimulateDeviceDetectionEvent(port, mode, signalEvent).Ret(); } public Result OpenSystemDataUpdateEventNotifier(ref SharedRef outEventNotifier) @@ -600,7 +617,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.OpenSystemDataUpdateEventNotifier(ref outEventNotifier); + return ncaFsService.OpenSystemDataUpdateEventNotifier(ref outEventNotifier).Ret(); } public Result NotifySystemDataUpdateEvent() @@ -608,7 +625,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.NotifySystemDataUpdateEvent(); + return ncaFsService.NotifySystemDataUpdateEvent().Ret(); } public Result OpenSaveDataInfoReader(ref SharedRef outInfoReader) @@ -616,7 +633,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.OpenSaveDataInfoReader(ref outInfoReader); + return saveFsService.OpenSaveDataInfoReader(ref outInfoReader).Ret(); } public Result OpenSaveDataInfoReaderBySaveDataSpaceId( @@ -625,7 +642,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.OpenSaveDataInfoReaderBySaveDataSpaceId(ref outInfoReader, spaceId); + return saveFsService.OpenSaveDataInfoReaderBySaveDataSpaceId(ref outInfoReader, spaceId).Ret(); } public Result OpenSaveDataInfoReaderWithFilter(ref SharedRef outInfoReader, @@ -634,7 +651,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.OpenSaveDataInfoReaderWithFilter(ref outInfoReader, spaceId, in filter); + return saveFsService.OpenSaveDataInfoReaderWithFilter(ref outInfoReader, spaceId, in filter).Ret(); } public Result FindSaveDataWithFilter(out long count, OutBuffer saveDataInfoBuffer, SaveDataSpaceId spaceId, @@ -645,7 +662,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.FindSaveDataWithFilter(out count, saveDataInfoBuffer, spaceId, in filter); + return saveFsService.FindSaveDataWithFilter(out count, saveDataInfoBuffer, spaceId, in filter).Ret(); } public Result OpenSaveDataInternalStorageFileSystem(ref SharedRef outFileSystem, @@ -654,7 +671,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.OpenSaveDataInternalStorageFileSystem(ref outFileSystem, spaceId, saveDataId); + return saveFsService.OpenSaveDataInternalStorageFileSystem(ref outFileSystem, spaceId, saveDataId).Ret(); } public Result QuerySaveDataInternalStorageTotalSize(out long size, SaveDataSpaceId spaceId, ulong saveDataId) @@ -664,7 +681,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.QuerySaveDataInternalStorageTotalSize(out size, spaceId, saveDataId); + return saveFsService.QuerySaveDataInternalStorageTotalSize(out size, spaceId, saveDataId).Ret(); } public Result GetSaveDataCommitId(out long commitId, SaveDataSpaceId spaceId, ulong saveDataId) @@ -674,7 +691,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.GetSaveDataCommitId(out commitId, spaceId, saveDataId); + return saveFsService.GetSaveDataCommitId(out commitId, spaceId, saveDataId).Ret(); } public Result OpenSaveDataInfoReaderOnlyCacheStorage(ref SharedRef outInfoReader) @@ -682,7 +699,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.OpenSaveDataInfoReaderOnlyCacheStorage(ref outInfoReader); + return saveFsService.OpenSaveDataInfoReaderOnlyCacheStorage(ref outInfoReader).Ret(); } public Result OpenSaveDataMetaFile(ref SharedRef outFile, SaveDataSpaceId spaceId, @@ -691,7 +708,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.OpenSaveDataMetaFile(ref outFile, spaceId, in attribute, type); + return saveFsService.OpenSaveDataMetaFile(ref outFile, spaceId, in attribute, type).Ret(); } public Result DeleteCacheStorage(ushort index) @@ -699,7 +716,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.DeleteCacheStorage(index); + return saveFsService.DeleteCacheStorage(index).Ret(); } public Result GetCacheStorageSize(out long dataSize, out long journalSize, ushort index) @@ -709,7 +726,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.GetCacheStorageSize(out dataSize, out journalSize, index); + return saveFsService.GetCacheStorageSize(out dataSize, out journalSize, index).Ret(); } public Result OpenSaveDataTransferManager(ref SharedRef outTransferManager) @@ -717,7 +734,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.OpenSaveDataTransferManager(ref outTransferManager); + return saveFsService.OpenSaveDataTransferManager(ref outTransferManager).Ret(); } public Result OpenSaveDataTransferManagerVersion2( @@ -726,7 +743,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.OpenSaveDataTransferManagerVersion2(ref outTransferManager); + return saveFsService.OpenSaveDataTransferManagerVersion2(ref outTransferManager).Ret(); } public Result OpenSaveDataTransferManagerForSaveDataRepair( @@ -735,7 +752,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.OpenSaveDataTransferManagerForSaveDataRepair(ref outTransferManager); + return saveFsService.OpenSaveDataTransferManagerForSaveDataRepair(ref outTransferManager).Ret(); } public Result OpenSaveDataTransferManagerForRepair( @@ -744,7 +761,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.OpenSaveDataTransferManagerForRepair(ref outTransferManager); + return saveFsService.OpenSaveDataTransferManagerForRepair(ref outTransferManager).Ret(); } public Result OpenSaveDataTransferProhibiter(ref SharedRef outProhibiter, @@ -753,7 +770,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.OpenSaveDataTransferProhibiter(ref outProhibiter, applicationId); + return saveFsService.OpenSaveDataTransferProhibiter(ref outProhibiter, applicationId).Ret(); } public Result ListAccessibleSaveDataOwnerId(out int readCount, OutBuffer idBuffer, ProgramId programId, @@ -765,7 +782,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader if (res.IsFailure()) return res.Miss(); return saveFsService.ListAccessibleSaveDataOwnerId(out readCount, idBuffer, programId, startIndex, - bufferIdCount); + bufferIdCount).Ret(); } public Result OpenSaveDataMover(ref SharedRef outSaveDataMover, SaveDataSpaceId sourceSpaceId, @@ -775,11 +792,12 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader if (res.IsFailure()) return res.Miss(); return saveFsService.OpenSaveDataMover(ref outSaveDataMover, sourceSpaceId, destinationSpaceId, - workBufferHandle, workBufferSize); + workBufferHandle, workBufferSize).Ret(); } public Result SetSaveDataSize(long saveDataSize, long saveDataJournalSize) { + // This method doesn't do anything. return Result.Success; } @@ -788,7 +806,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.SetSaveDataRootPath(in path); + return saveFsService.SetSaveDataRootPath(in path).Ret(); } public Result UnsetSaveDataRootPath() @@ -796,7 +814,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.UnsetSaveDataRootPath(); + return saveFsService.UnsetSaveDataRootPath().Ret(); } public Result OpenContentStorageFileSystem(ref SharedRef outFileSystem, @@ -805,56 +823,22 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.OpenContentStorageFileSystem(ref outFileSystem, storageId); - } - - public Result OpenCloudBackupWorkStorageFileSystem(ref SharedRef outFileSystem, - CloudBackupWorkStorageId storageId) - { - var storageFlag = StorageLayoutType.NonGameCard; - using var scopedContext = new ScopedStorageLayoutTypeSetter(storageFlag); - - Result res = GetProgramInfo(out ProgramInfo programInfo); - if (res.IsFailure()) return res.Miss(); - - Accessibility accessibility = - programInfo.AccessControl.GetAccessibilityFor(AccessibilityType.MountCloudBackupWorkStorage); - - if (!accessibility.CanRead || !accessibility.CanWrite) - return ResultFs.PermissionDenied.Log(); - - using var fileSystem = new SharedRef(); - res = _fsProxyCore.OpenCloudBackupWorkStorageFileSystem(ref fileSystem.Ref, storageId); - if (res.IsFailure()) return res.Miss(); - - // Add all the wrappers for the file system - using var typeSetFileSystem = - new SharedRef(new StorageLayoutTypeSetFileSystem(ref fileSystem.Ref, storageFlag)); - - using var asyncFileSystem = - new SharedRef(new AsynchronousAccessFileSystem(ref typeSetFileSystem.Ref)); - - using SharedRef fileSystemAdapter = - FileSystemInterfaceAdapter.CreateShared(ref asyncFileSystem.Ref, false); - - outFileSystem.SetByMove(ref fileSystemAdapter.Ref); - - return Result.Success; + return ncaFsService.OpenContentStorageFileSystem(ref outFileSystem, storageId).Ret(); } public Result OpenCustomStorageFileSystem(ref SharedRef outFileSystem, CustomStorageId storageId) { - var storageFlag = StorageLayoutType.NonGameCard; + const StorageLayoutType storageFlag = StorageLayoutType.NonGameCard; using var scopedContext = new ScopedStorageLayoutTypeSetter(storageFlag); Result res = GetProgramInfo(out ProgramInfo programInfo); if (res.IsFailure()) return res.Miss(); - AccessibilityType accessType = storageId > CustomStorageId.SdCard + AccessibilityType accessibilityType = storageId > CustomStorageId.SdCard ? AccessibilityType.NotMount : AccessibilityType.MountCustomStorage; - Accessibility accessibility = programInfo.AccessControl.GetAccessibilityFor(accessType); + Accessibility accessibility = programInfo.AccessControl.GetAccessibilityFor(accessibilityType); if (!accessibility.CanRead || !accessibility.CanWrite) return ResultFs.PermissionDenied.Log(); @@ -871,7 +855,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader new SharedRef(new AsynchronousAccessFileSystem(ref typeSetFileSystem.Ref)); using SharedRef fileSystemAdapter = - FileSystemInterfaceAdapter.CreateShared(ref asyncFileSystem.Ref, false); + FileSystemInterfaceAdapter.CreateShared(ref asyncFileSystem.Ref, allowAllOperations: false); outFileSystem.SetByMove(ref fileSystemAdapter.Ref); @@ -881,7 +865,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader public Result OpenGameCardFileSystem(ref SharedRef outFileSystem, GameCardHandle handle, GameCardPartition partitionId) { - return GetBaseFileSystemService().OpenGameCardFileSystem(ref outFileSystem, handle, partitionId); + return GetBaseFileSystemService().OpenGameCardFileSystem(ref outFileSystem, handle, partitionId).Ret(); } public Result IsArchivedProgram(out bool isArchived, ulong processId) @@ -891,7 +875,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.IsArchivedProgram(out isArchived, processId); + return ncaFsService.IsArchivedProgram(out isArchived, processId).Ret(); } public Result QuerySaveDataTotalSize(out long totalSize, long dataSize, long journalSize) @@ -901,12 +885,12 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.QuerySaveDataTotalSize(out totalSize, dataSize, journalSize); + return saveFsService.QuerySaveDataTotalSize(out totalSize, dataSize, journalSize).Ret(); } public Result SetCurrentPosixTimeWithTimeDifference(long currentTime, int timeDifference) { - return GetTimeService().SetCurrentPosixTimeWithTimeDifference(currentTime, timeDifference); + return GetTimeService().SetCurrentPosixTimeWithTimeDifference(currentTime, timeDifference).Ret(); } public Result GetRightsId(out RightsId rightsId, ProgramId programId, StorageId storageId) @@ -916,23 +900,28 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.GetRightsId(out rightsId, programId, storageId); - } - - public Result GetRightsIdByPath(out RightsId rightsId, ref readonly FspPath path) - { - return GetRightsIdAndKeyGenerationByPath(out rightsId, out _, in path); + return ncaFsService.GetRightsId(out rightsId, programId, storageId).Ret(); } public Result GetRightsIdAndKeyGenerationByPath(out RightsId rightsId, out byte keyGeneration, - ref readonly FspPath path) + ref readonly FspPath path, ContentAttributes attributes) { UnsafeHelpers.SkipParamInit(out rightsId, out keyGeneration); Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.GetRightsIdAndKeyGenerationByPath(out rightsId, out keyGeneration, in path); + return ncaFsService.GetRightsIdAndKeyGenerationByPath(out rightsId, out keyGeneration, in path, attributes).Ret(); + } + + public Result GetProgramId(out ProgramId outProgramId, ref readonly FspPath path, ContentAttributes attributes) + { + UnsafeHelpers.SkipParamInit(out outProgramId); + + Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); + if (res.IsFailure()) return res.Miss(); + + return ncaFsService.GetProgramId(out outProgramId, in path, attributes).Ret(); } public Result RegisterExternalKey(in RightsId rightsId, in AccessKey externalKey) @@ -940,7 +929,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.RegisterExternalKey(in rightsId, in externalKey); + return ncaFsService.RegisterExternalKey(in rightsId, in externalKey).Ret(); } public Result UnregisterExternalKey(in RightsId rightsId) @@ -948,7 +937,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.UnregisterExternalKey(in rightsId); + return ncaFsService.UnregisterExternalKey(in rightsId).Ret(); } public Result UnregisterAllExternalKey() @@ -956,7 +945,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.UnregisterAllExternalKey(); + return ncaFsService.UnregisterAllExternalKey().Ret(); } public Result SetSdCardEncryptionSeed(in EncryptionSeed seed) @@ -979,23 +968,18 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.SetSdCardEncryptionSeed(in seed); + return ncaFsService.SetSdCardEncryptionSeed(in seed).Ret(); } public Result GetAndClearErrorInfo(out FileSystemProxyErrorInfo errorInfo) { - return GetStatusReportService().GetAndClearFileSystemProxyErrorInfo(out errorInfo); + return GetStatusReportService().GetAndClearFileSystemProxyErrorInfo(out errorInfo).Ret(); } public Result RegisterProgramIndexMapInfo(InBuffer programIndexMapInfoBuffer, int programCount) { return GetProgramIndexRegistryService() - .RegisterProgramIndexMapInfo(programIndexMapInfoBuffer, programCount); - } - - public Result SetBisRootForHost(BisPartitionId partitionId, ref readonly FspPath path) - { - return GetBaseFileSystemService().SetBisRootForHost(partitionId, in path); + .RegisterProgramIndexMapInfo(programIndexMapInfoBuffer, programCount).Ret(); } public Result VerifySaveDataFileSystemBySaveDataSpaceId(SaveDataSpaceId spaceId, ulong saveDataId, @@ -1004,12 +988,12 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.VerifySaveDataFileSystemBySaveDataSpaceId(spaceId, saveDataId, readBuffer); + return saveFsService.VerifySaveDataFileSystemBySaveDataSpaceId(spaceId, saveDataId, readBuffer).Ret(); } public Result VerifySaveDataFileSystem(ulong saveDataId, OutBuffer readBuffer) { - return VerifySaveDataFileSystemBySaveDataSpaceId(SaveDataSpaceId.System, saveDataId, readBuffer); + return VerifySaveDataFileSystemBySaveDataSpaceId(SaveDataSpaceId.System, saveDataId, readBuffer).Ret(); } public Result CorruptSaveDataFileSystemByOffset(SaveDataSpaceId spaceId, ulong saveDataId, long offset) @@ -1017,7 +1001,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.CorruptSaveDataFileSystemByOffset(spaceId, saveDataId, offset); + return saveFsService.CorruptSaveDataFileSystemByOffset(spaceId, saveDataId, offset).Ret(); } public Result CorruptSaveDataFileSystemBySaveDataSpaceId(SaveDataSpaceId spaceId, ulong saveDataId) @@ -1026,62 +1010,63 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = CorruptSaveDataFileSystemByOffset(spaceId, saveDataId, 0); if (res.IsFailure()) return res.Miss(); - return CorruptSaveDataFileSystemByOffset(spaceId, saveDataId, 0x4000); + return CorruptSaveDataFileSystemByOffset(spaceId, saveDataId, 0x4000).Ret(); } public Result CorruptSaveDataFileSystem(ulong saveDataId) { - return CorruptSaveDataFileSystemBySaveDataSpaceId(SaveDataSpaceId.System, saveDataId); + return CorruptSaveDataFileSystemBySaveDataSpaceId(SaveDataSpaceId.System, saveDataId).Ret(); } public Result CreatePaddingFile(long size) { - return GetBaseFileSystemService().CreatePaddingFile(size); + return GetBaseFileSystemService().CreatePaddingFile(size).Ret(); } public Result DeleteAllPaddingFiles() { - return GetBaseFileSystemService().DeleteAllPaddingFiles(); + return GetBaseFileSystemService().DeleteAllPaddingFiles().Ret(); } public Result DisableAutoSaveDataCreation() { + // This method doesn't do anything. return Result.Success; } public Result SetGlobalAccessLogMode(GlobalAccessLogMode mode) { - return GetAccessLogService().SetAccessLogMode(mode); + return GetAccessLogService().SetAccessLogMode(mode).Ret(); } public Result GetGlobalAccessLogMode(out GlobalAccessLogMode mode) { - return GetAccessLogService().GetAccessLogMode(out mode); + return GetAccessLogService().GetAccessLogMode(out mode).Ret(); } public Result GetProgramIndexForAccessLog(out int programIndex, out int programCount) { - return GetProgramIndexRegistryService().GetProgramIndex(out programIndex, out programCount); + return GetProgramIndexRegistryService().GetProgramIndex(out programIndex, out programCount).Ret(); } public Result OutputAccessLogToSdCard(InBuffer textBuffer) { - return GetAccessLogService().OutputAccessLogToSdCard(textBuffer); + return GetAccessLogService().OutputAccessLogToSdCard(textBuffer).Ret(); } public Result OutputMultiProgramTagAccessLog() { - return GetAccessLogService().OutputMultiProgramTagAccessLog(); + return GetAccessLogService().OutputMultiProgramTagAccessLog().Ret(); } public Result OutputApplicationInfoAccessLog(in ApplicationInfo applicationInfo) { - return GetAccessLogService().OutputApplicationInfoAccessLog(in applicationInfo); + return GetAccessLogService().OutputApplicationInfoAccessLog(in applicationInfo).Ret(); } public Result FlushAccessLogOnSdCard() { - return GetAccessLogService().FlushAccessLogOnSdCard(); + return GetAccessLogService().FlushAccessLogOnSdCard().Ret(); } public Result RegisterUpdatePartition() @@ -1089,7 +1074,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.RegisterUpdatePartition(); + return ncaFsService.RegisterUpdatePartition().Ret(); } public Result OpenRegisteredUpdatePartition(ref SharedRef outFileSystem) @@ -1097,17 +1082,17 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetNcaFileSystemService(out NcaFileSystemService ncaFsService); if (res.IsFailure()) return res.Miss(); - return ncaFsService.OpenRegisteredUpdatePartition(ref outFileSystem); + return ncaFsService.OpenRegisteredUpdatePartition(ref outFileSystem).Ret(); } public Result GetAndClearMemoryReportInfo(out MemoryReportInfo reportInfo) { - return GetStatusReportService().GetAndClearMemoryReportInfo(out reportInfo); + return GetStatusReportService().GetAndClearMemoryReportInfo(out reportInfo).Ret(); } public Result GetFsStackUsage(out uint stackUsage, FsStackUsageThreadType threadType) { - return GetStatusReportService().GetFsStackUsage(out stackUsage, threadType); + return GetStatusReportService().GetFsStackUsage(out stackUsage, threadType).Ret(); } public Result OverrideSaveDataTransferTokenSignVerificationKey(InBuffer key) @@ -1115,7 +1100,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.OverrideSaveDataTransferTokenSignVerificationKey(key); + return saveFsService.OverrideSaveDataTransferTokenSignVerificationKey(key).Ret(); } public Result SetSdCardAccessibility(bool isAccessible) @@ -1123,7 +1108,7 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.SetSdCardAccessibility(isAccessible); + return saveFsService.SetSdCardAccessibility(isAccessible).Ret(); } public Result IsSdCardAccessible(out bool isAccessible) @@ -1133,34 +1118,34 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.IsSdCardAccessible(out isAccessible); + return saveFsService.IsSdCardAccessible(out isAccessible).Ret(); } public Result OpenAccessFailureDetectionEventNotifier(ref SharedRef outEventNotifier, ulong processId, bool notifyOnDeepRetry) { return GetAccessFailureManagementService() - .OpenAccessFailureDetectionEventNotifier(ref outEventNotifier, processId, notifyOnDeepRetry); + .OpenAccessFailureDetectionEventNotifier(ref outEventNotifier, processId, notifyOnDeepRetry).Ret(); } public Result GetAccessFailureDetectionEvent(out NativeHandle eventHandle) { - return GetAccessFailureManagementService().GetAccessFailureDetectionEvent(out eventHandle); + return GetAccessFailureManagementService().GetAccessFailureDetectionEvent(out eventHandle).Ret(); } public Result IsAccessFailureDetected(out bool isDetected, ulong processId) { - return GetAccessFailureManagementService().IsAccessFailureDetected(out isDetected, processId); + return GetAccessFailureManagementService().IsAccessFailureDetected(out isDetected, processId).Ret(); } public Result ResolveAccessFailure(ulong processId) { - return GetAccessFailureManagementService().ResolveAccessFailure(processId); + return GetAccessFailureManagementService().ResolveAccessFailure(processId).Ret(); } public Result AbandonAccessFailure(ulong processId) { - return GetAccessFailureManagementService().AbandonAccessFailure(processId); + return GetAccessFailureManagementService().AbandonAccessFailure(processId).Ret(); } public Result OpenMultiCommitManager(ref SharedRef outCommitManager) @@ -1168,22 +1153,34 @@ public class FileSystemProxyImpl : IFileSystemProxy, IFileSystemProxyForLoader Result res = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService); if (res.IsFailure()) return res.Miss(); - return saveFsService.OpenMultiCommitManager(ref outCommitManager); + return saveFsService.OpenMultiCommitManager(ref outCommitManager).Ret(); } public Result OpenBisWiper(ref SharedRef outBisWiper, NativeHandle transferMemoryHandle, ulong transferMemorySize) { - return GetBaseFileSystemService().OpenBisWiper(ref outBisWiper, transferMemoryHandle, transferMemorySize); + return GetBaseFileSystemService().OpenBisWiper(ref outBisWiper, transferMemoryHandle, transferMemorySize).Ret(); } public Result RegisterDebugConfiguration(uint key, long value) { - return GetDebugConfigurationService().Register(key, value); + return GetDebugConfigurationService().Register(key, value).Ret(); } public Result UnregisterDebugConfiguration(uint key) { - return GetDebugConfigurationService().Unregister(key); + return GetDebugConfigurationService().Unregister(key).Ret(); + } + + public Result NotifyErrorContextServiceReady(bool isReady) + { + Result res = GetProgramInfo(out ProgramInfo programInfo); + if (res.IsFailure()) return res.Miss(); + + if (!programInfo.AccessControl.CanCall(OperationType.NotifyErrorContextServiceReady)) + return ResultFs.PermissionDenied.Log(); + + _fsServer.Hos.Fs.Impl.SetErrorContextEnabled(isReady); + return Result.Success; } } \ No newline at end of file diff --git a/src/LibHac/FsSrv/FileSystemServerInitializer.cs b/src/LibHac/FsSrv/FileSystemServerInitializer.cs index 18e247d9..6de58e05 100644 --- a/src/LibHac/FsSrv/FileSystemServerInitializer.cs +++ b/src/LibHac/FsSrv/FileSystemServerInitializer.cs @@ -125,7 +125,7 @@ public static class FileSystemServerInitializer ncaFsServiceConfig.SpeedEmulationRange = speedEmulationRange; ncaFsServiceConfig.FsServer = server; - var ncaFsService = new NcaFileSystemServiceImpl(in ncaFsServiceConfig, config.ExternalKeySet); + var ncaFsService = new NcaFileSystemServiceImpl(in ncaFsServiceConfig); var saveFsServiceConfig = new SaveDataFileSystemServiceImpl.Configuration(); saveFsServiceConfig.BaseFsService = baseFsService; diff --git a/src/LibHac/FsSrv/FsCreator/FatFileSystemCreator.cs b/src/LibHac/FsSrv/FsCreator/FatFileSystemCreator.cs index 46187f11..e4ea1d5e 100644 --- a/src/LibHac/FsSrv/FsCreator/FatFileSystemCreator.cs +++ b/src/LibHac/FsSrv/FsCreator/FatFileSystemCreator.cs @@ -51,17 +51,17 @@ public class FatFileSystemCreator : IFatFileSystemCreator _fatFsError = default; } - public void GetAndClearFatReportInfo(out FatReportInfo outBisSystemFatReportInfo, - out FatReportInfo outBisUserFatReportInfo, out FatReportInfo outSdCardFatReportInfo) + public void GetAndClearFatReportInfo(out FatReportInfo1 outBisSystemFatReportInfo1, + out FatReportInfo1 outBisUserFatReportInfo1, out FatReportInfo1 outSdCardFatReportInfo1) { using var scopedLock = new ScopedLock(ref _fatReportMutex); - outBisSystemFatReportInfo.FilePeakOpenCount = _bisSystemReport.FilePeakOpenCount; - outBisSystemFatReportInfo.DirectoryPeakOpenCount = _bisSystemReport.DirectoryPeakOpenCount; - outBisUserFatReportInfo.FilePeakOpenCount = _bisUserReport.FilePeakOpenCount; - outBisUserFatReportInfo.DirectoryPeakOpenCount = _bisUserReport.DirectoryPeakOpenCount; - outSdCardFatReportInfo.FilePeakOpenCount = _sdCardReport.FilePeakOpenCount; - outSdCardFatReportInfo.DirectoryPeakOpenCount = _sdCardReport.DirectoryPeakOpenCount; + outBisSystemFatReportInfo1.FilePeakOpenCount = _bisSystemReport.FilePeakOpenCount; + outBisSystemFatReportInfo1.DirectoryPeakOpenCount = _bisSystemReport.DirectoryPeakOpenCount; + outBisUserFatReportInfo1.FilePeakOpenCount = _bisUserReport.FilePeakOpenCount; + outBisUserFatReportInfo1.DirectoryPeakOpenCount = _bisUserReport.DirectoryPeakOpenCount; + outSdCardFatReportInfo1.FilePeakOpenCount = _sdCardReport.FilePeakOpenCount; + outSdCardFatReportInfo1.DirectoryPeakOpenCount = _sdCardReport.DirectoryPeakOpenCount; _bisSystemReport.FilePeakOpenCount = _bisSystemReport.FileCurrentOpenCount; _bisSystemReport.DirectoryPeakOpenCount = _bisSystemReport.DirectoryCurrentOpenCount; diff --git a/src/LibHac/FsSrv/FsCreator/INspRootFileSystemCreator.cs b/src/LibHac/FsSrv/FsCreator/INspRootFileSystemCreator.cs new file mode 100644 index 00000000..01d93cea --- /dev/null +++ b/src/LibHac/FsSrv/FsCreator/INspRootFileSystemCreator.cs @@ -0,0 +1,10 @@ +using LibHac.Common; +using LibHac.Fs; +using LibHac.Fs.Fsa; + +namespace LibHac.FsSrv.FsCreator; + +public interface INspRootFileSystemCreator +{ + Result Create(ref SharedRef outFileSystem, ref readonly SharedRef baseStorage); +} \ No newline at end of file diff --git a/src/LibHac/FsSrv/FsCreator/ISubDirectoryFileSystemCreator.cs b/src/LibHac/FsSrv/FsCreator/ISubDirectoryFileSystemCreator.cs index e910d5c8..fd9b1f80 100644 --- a/src/LibHac/FsSrv/FsCreator/ISubDirectoryFileSystemCreator.cs +++ b/src/LibHac/FsSrv/FsCreator/ISubDirectoryFileSystemCreator.cs @@ -6,5 +6,5 @@ namespace LibHac.FsSrv.FsCreator; public interface ISubDirectoryFileSystemCreator { - Result Create(ref SharedRef outSubDirFileSystem, ref SharedRef baseFileSystem, ref readonly Path path); + Result Create(ref SharedRef outSubDirFileSystem, ref readonly SharedRef baseFileSystem, ref readonly Path path); } \ No newline at end of file diff --git a/src/LibHac/FsSrv/FsCreator/SubDirectoryFileSystemCreator.cs b/src/LibHac/FsSrv/FsCreator/SubDirectoryFileSystemCreator.cs index a3aa90d8..09f0eaa3 100644 --- a/src/LibHac/FsSrv/FsCreator/SubDirectoryFileSystemCreator.cs +++ b/src/LibHac/FsSrv/FsCreator/SubDirectoryFileSystemCreator.cs @@ -7,7 +7,7 @@ namespace LibHac.FsSrv.FsCreator; public class SubDirectoryFileSystemCreator : ISubDirectoryFileSystemCreator { - public Result Create(ref SharedRef outSubDirFileSystem, ref SharedRef baseFileSystem, + public Result Create(ref SharedRef outSubDirFileSystem, ref readonly SharedRef baseFileSystem, ref readonly Path path) { using var directory = new UniqueRef(); @@ -17,7 +17,7 @@ public class SubDirectoryFileSystemCreator : ISubDirectoryFileSystemCreator directory.Reset(); - using var subFs = new SharedRef(new SubdirectoryFileSystem(ref baseFileSystem)); + using var subFs = new SharedRef(new SubdirectoryFileSystem(in baseFileSystem)); if (!subFs.HasValue) return ResultFs.AllocationMemoryFailedInSubDirectoryFileSystemCreatorA.Log(); diff --git a/src/LibHac/FsSrv/Impl/AccessControl.cs b/src/LibHac/FsSrv/Impl/AccessControl.cs index df8e4835..0de5380b 100644 --- a/src/LibHac/FsSrv/Impl/AccessControl.cs +++ b/src/LibHac/FsSrv/Impl/AccessControl.cs @@ -498,6 +498,10 @@ public class AccessControl return accessBits.CanSetDebugConfiguration(); case OperationType.OpenDataStorageByPath: return accessBits.CanOpenDataStorageByPath(); + case OperationType.NotifyErrorContextServiceReady: + return accessBits.CanNotifyErrorContextServiceReady(); + case OperationType.GetProgramId: + return accessBits.CanGetProgramId(); default: Abort.UnexpectedDefault(); return default; @@ -593,6 +597,8 @@ public readonly struct AccessControlBits RegisterProgramIndexMapInfo = 1UL << 34, CreateOwnSaveData = 1UL << 35, MoveCacheStorage = 1UL << 36, + DeviceTreeBlob = 1UL << 37, + NotifyErrorContextServiceReady = 1UL << 38, Debug = 1UL << 62, FullPermission = 1UL << 63 } @@ -630,6 +636,7 @@ public readonly struct AccessControlBits public bool CanGetGameCardAsicInfo() => Has(Bits.GameCardPrivate); public bool CanGetGameCardDeviceCertificate() => Has(Bits.GameCard); public bool CanGetGameCardIdSet() => Has(Bits.GameCard); + public bool CanGetProgramId() => Has(Bits.GetRightsId); public bool CanGetRightsId() => Has(Bits.GetRightsId); public bool CanGetSaveDataCommitId() => Has(Bits.SaveDataTransferVersion2 | Bits.SaveDataBackUp); public bool CanInvalidateBisCache() => Has(Bits.BisAllRaw); @@ -682,6 +689,7 @@ public readonly struct AccessControlBits public bool CanMountSystemSaveDataWrite() => Has(Bits.SaveDataBackUp | Bits.SystemSaveData); public bool CanMountTemporaryDirectoryRead() => Has(Bits.Debug); public bool CanMountTemporaryDirectoryWrite() => Has(Bits.Debug); + public bool CanNotifyErrorContextServiceReady() => Has(Bits.NotifyErrorContextServiceReady); public bool CanNotifySystemDataUpdateEvent() => Has(Bits.SystemUpdate); public bool CanOpenAccessFailureDetectionEventNotifier() => Has(Bits.AccessFailureResolution); public bool CanOpenBisPartitionBootConfigAndPackage2Part1Read() => Has(Bits.SystemUpdate | Bits.BisAllRaw); @@ -870,7 +878,9 @@ public enum OperationType FindOwnSaveDataWithFilter, OpenSaveDataTransferManagerForRepair, SetDebugConfiguration, - OpenDataStorageByPath + OpenDataStorageByPath, + NotifyErrorContextServiceReady, + GetProgramId } public enum AccessibilityType diff --git a/src/LibHac/FsSrv/Impl/ExternalKeyManager.cs b/src/LibHac/FsSrv/Impl/ExternalKeyManager.cs new file mode 100644 index 00000000..53317c36 --- /dev/null +++ b/src/LibHac/FsSrv/Impl/ExternalKeyManager.cs @@ -0,0 +1,46 @@ +using System; +using LibHac.Fs; +using LibHac.Os; +using LibHac.Spl; + +namespace LibHac.FsSrv.Impl; + +public class ExternalKeyManager +{ + private SdkMutexType _mutex; + + public ExternalKeyManager() + { + _mutex = new SdkMutexType(); + } + + public Result Register(in RightsId rightsId, in AccessKey accessKey) + { + throw new NotImplementedException(); + } + + public Result Unregister(in RightsId rightsId) + { + throw new NotImplementedException(); + } + + public Result UnregisterAll() + { + throw new NotImplementedException(); + } + + public bool IsAvailableKeySource(ReadOnlySpan keySource) + { + throw new NotImplementedException(); + } + + public Result Find(out AccessKey outAccessKey, in RightsId rightsId) + { + throw new NotImplementedException(); + } + + private Result FindCore(out AccessKey outAccessKey, in RightsId rightsId) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/src/LibHac/FsSrv/Impl/FileSystemProxyServiceObject.cs b/src/LibHac/FsSrv/Impl/FileSystemProxyServiceObject.cs index 0f09a232..dd050fda 100644 --- a/src/LibHac/FsSrv/Impl/FileSystemProxyServiceObject.cs +++ b/src/LibHac/FsSrv/Impl/FileSystemProxyServiceObject.cs @@ -47,11 +47,9 @@ public static class FileSystemProxyServiceObject return ResultFs.PortAcceptableCountLimited.Log(); } - public Result OpenCodeFileSystem(ref SharedRef fileSystem, - out CodeVerificationData verificationData, ref readonly FspPath path, ProgramId programId) + public Result OpenCodeFileSystem(ref SharedRef fileSystem, OutBuffer outVerificationData, + ref readonly FspPath path, ContentAttributes attributes, ProgramId programId) { - UnsafeHelpers.SkipParamInit(out verificationData); - return ResultFs.PortAcceptableCountLimited.Log(); } diff --git a/src/LibHac/FsSrv/Impl/IRomFileSystemAccessFailureManager.cs b/src/LibHac/FsSrv/Impl/IRomFileSystemAccessFailureManager.cs index cd171e57..459b986c 100644 --- a/src/LibHac/FsSrv/Impl/IRomFileSystemAccessFailureManager.cs +++ b/src/LibHac/FsSrv/Impl/IRomFileSystemAccessFailureManager.cs @@ -8,9 +8,11 @@ namespace LibHac.FsSrv.Impl; public interface IRomFileSystemAccessFailureManager : IDisposable { - Result OpenDataStorageCore(ref SharedRef outStorage, out Hash ncaHeaderDigest, ulong id, StorageId storageId); - Result HandleResolubleAccessFailure(out bool wasDeferred, Result resultForNoFailureDetected); + Result OpenDataStorageCore(ref SharedRef outStorage, ref SharedRef outStorageAccessSplitter, out Hash ncaHeaderDigest, ulong id, StorageId storageId); + Result HandleResolubleAccessFailure(out bool wasDeferred, Result nonDeferredResult); + void IncrementRomFsDeepRetryStartCount(); void IncrementRomFsRemountForDataCorruptionCount(); void IncrementRomFsUnrecoverableDataCorruptionByRemountCount(); void IncrementRomFsRecoveredByInvalidateCacheCount(); + void IncrementRomFsUnrecoverableByGameCardAccessFailedCount(); } \ No newline at end of file diff --git a/src/LibHac/FsSrv/Impl/SystemDataUpdateEventManager.cs b/src/LibHac/FsSrv/Impl/SystemDataUpdateEventManager.cs new file mode 100644 index 00000000..28801098 --- /dev/null +++ b/src/LibHac/FsSrv/Impl/SystemDataUpdateEventManager.cs @@ -0,0 +1,32 @@ +using System; +using LibHac.Common; + +namespace LibHac.FsSrv.Impl; + +public class SystemDataUpdateEventManager : IDisposable +{ + public SystemDataUpdateEventManager() + { + // Todo: Implement + } + + public void Dispose() + { + throw new NotImplementedException(); + } + + public Result CreateNotifier(ref UniqueRef outNotifier) + { + throw new NotImplementedException(); + } + + public Result NotifySystemDataUpdateEvent() + { + throw new NotImplementedException(); + } + + public void DeleteNotifier(SystemDataUpdateEventNotifier notifier) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/src/LibHac/FsSrv/Impl/SystemDataUpdateEventNotifier.cs b/src/LibHac/FsSrv/Impl/SystemDataUpdateEventNotifier.cs new file mode 100644 index 00000000..a7fc3855 --- /dev/null +++ b/src/LibHac/FsSrv/Impl/SystemDataUpdateEventNotifier.cs @@ -0,0 +1,22 @@ +using System; +using LibHac.Sf; + +namespace LibHac.FsSrv.Impl; + +public class SystemDataUpdateEventNotifier : IDisposable +{ + public SystemDataUpdateEventNotifier() + { + throw new NotImplementedException(); + } + + public void Dispose() + { + throw new NotImplementedException(); + } + + public Result GetEventHandle(out NativeHandle outHandle) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/src/LibHac/FsSrv/Impl/UpdatePartitionPath.cs b/src/LibHac/FsSrv/Impl/UpdatePartitionPath.cs new file mode 100644 index 00000000..c6db0855 --- /dev/null +++ b/src/LibHac/FsSrv/Impl/UpdatePartitionPath.cs @@ -0,0 +1,67 @@ +using System; +using LibHac.Common; +using LibHac.Fs; +using LibHac.Fs.Impl; +using LibHac.Os; + +namespace LibHac.FsSrv.Impl; + +public class UpdatePartitionPath : IDisposable +{ + private Path.Stored _path; + private ContentAttributes _contentAttributes; + private ulong _updaterProgramId; + private SdkMutexType _mutex; + + public UpdatePartitionPath() + { + _path = new Path.Stored(); + _mutex = new SdkMutexType(); + _path.InitializeAsEmpty(); + } + + public void Dispose() + { + _path.Dispose(); + } + + public Result Set(ulong updaterProgramId, ref readonly Path path, ContentAttributes contentAttributes) + { + using ScopedLock scopedLock = ScopedLock.Lock(ref _mutex); + + if (path.IsEmpty()) + { + return _path.InitializeAsEmpty().Ret(); + } + + if (path.IsMatchHead(CommonMountNames.RegisteredUpdatePartitionMountName, CommonMountNames.RegisteredUpdatePartitionMountName.Length)) + { + return ResultFs.InvalidPath.Log(); + } + + Result res = _path.Initialize(in path); + if (res.IsFailure()) return res.Miss(); + + _updaterProgramId = updaterProgramId; + _contentAttributes = contentAttributes; + + return Result.Success; + } + + public Result Get(ref Path outPath, out ContentAttributes outContentAttributes, out ulong outUpdaterProgramId) + { + UnsafeHelpers.SkipParamInit(out outContentAttributes); + + using ScopedLock scopedLock = ScopedLock.Lock(ref _mutex); + using Path tempPath = _path.DangerousGetPath(); + + outUpdaterProgramId = _updaterProgramId; + + Result res = _path.Initialize(in tempPath); + if (res.IsFailure()) return res.Miss(); + + outContentAttributes = _contentAttributes; + + return Result.Success; + } +} \ No newline at end of file diff --git a/src/LibHac/FsSrv/Impl/Utility.cs b/src/LibHac/FsSrv/Impl/Utility.cs index c8df560d..7700a5d4 100644 --- a/src/LibHac/FsSrv/Impl/Utility.cs +++ b/src/LibHac/FsSrv/Impl/Utility.cs @@ -70,4 +70,10 @@ internal static class Utility Crypto.Sha256.GenerateSha256Hash(SpanHelpers.AsReadOnlyByteSpan(in extraData), hash); return BitConverter.ToInt64(hash); } + + public static ulong ClearPlatformIdInProgramId(ulong programId) + { + const ulong clearPlatformIdMask = 0x_00FF_FFFF_FFFF_FFFF; + return programId & clearPlatformIdMask; + } } \ No newline at end of file diff --git a/src/LibHac/FsSrv/NcaFileSystemService.cs b/src/LibHac/FsSrv/NcaFileSystemService.cs index 85d394a2..3912f7a5 100644 --- a/src/LibHac/FsSrv/NcaFileSystemService.cs +++ b/src/LibHac/FsSrv/NcaFileSystemService.cs @@ -8,6 +8,7 @@ using LibHac.FsSrv.Sf; using LibHac.FsSystem; using LibHac.Lr; using LibHac.Ncm; +using LibHac.Sf; using LibHac.Spl; using IFileSystem = LibHac.Fs.Fsa.IFileSystem; using IStorage = LibHac.Fs.IStorage; @@ -22,12 +23,14 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager { private const int AocSemaphoreCount = 128; private const int RomSemaphoreCount = 10; + private const int RomDivisionSizeUnitCountSemaphoreCount = 128; private WeakRef _selfReference; private NcaFileSystemServiceImpl _serviceImpl; private ulong _processId; private SemaphoreAdapter _aocMountCountSemaphore; private SemaphoreAdapter _romMountCountSemaphore; + private SemaphoreAdapter _romDivisionSizeUnitCountSemaphore; private NcaFileSystemService(NcaFileSystemServiceImpl serviceImpl, ulong processId) { @@ -35,6 +38,7 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager _processId = processId; _aocMountCountSemaphore = new SemaphoreAdapter(AocSemaphoreCount, AocSemaphoreCount); _romMountCountSemaphore = new SemaphoreAdapter(RomSemaphoreCount, RomSemaphoreCount); + _romDivisionSizeUnitCountSemaphore = new SemaphoreAdapter(RomDivisionSizeUnitCountSemaphoreCount, RomDivisionSizeUnitCountSemaphoreCount); } public static SharedRef CreateShared(NcaFileSystemServiceImpl serviceImpl, @@ -54,22 +58,26 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager { _aocMountCountSemaphore?.Dispose(); _romMountCountSemaphore?.Dispose(); + _romDivisionSizeUnitCountSemaphore?.Dispose(); _selfReference.Destroy(); } private Result GetProgramInfo(out ProgramInfo programInfo) { - return _serviceImpl.GetProgramInfoByProcessId(out programInfo, _processId); + var programRegistry = new ProgramRegistryImpl(_serviceImpl.FsServer); + return programRegistry.GetProgramInfo(out programInfo, _processId).Ret(); } private Result GetProgramInfoByProcessId(out ProgramInfo programInfo, ulong processId) { - return _serviceImpl.GetProgramInfoByProcessId(out programInfo, processId); + var programRegistry = new ProgramRegistryImpl(_serviceImpl.FsServer); + return programRegistry.GetProgramInfo(out programInfo, processId).Ret(); } private Result GetProgramInfoByProgramId(out ProgramInfo programInfo, ulong programId) { - return _serviceImpl.GetProgramInfoByProgramId(out programInfo, programId); + var programRegistry = new ProgramRegistryImpl(_serviceImpl.FsServer); + return programRegistry.GetProgramInfoByProgramId(out programInfo, programId).Ret(); } public Result OpenFileSystemWithPatch(ref SharedRef outFileSystem, ProgramId programId, @@ -110,7 +118,8 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager // Try to find the path to the original version of the file system using var originalPath = new Path(); Result originalResult = _serviceImpl.ResolveApplicationHtmlDocumentPath(out bool isDirectory, - ref originalPath.Ref(), new Ncm.ApplicationId(programId.Value), ownerProgramInfo.StorageId); + ref originalPath.Ref(), out ContentAttributes contentAttributes, out ulong originalProgramId, + programId.Value, ownerProgramInfo.StorageId); // The file system might have a patch version with no original version, so continue if not found if (originalResult.IsFailure() && !ResultLr.HtmlDocumentNotFound.Includes(originalResult)) @@ -118,7 +127,8 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager // Try to find the path to the patch file system using var patchPath = new Path(); - Result patchResult = _serviceImpl.ResolveRegisteredHtmlDocumentPath(ref patchPath.Ref(), programId.Value); + Result patchResult = _serviceImpl.ResolveRegisteredHtmlDocumentPath(ref patchPath.Ref(), + out ContentAttributes patchContentAttributes, programId.Value); using var fileSystem = new SharedRef(); @@ -129,7 +139,7 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager return originalResult; // There is an original version and no patch version. Open the original directly - res = _serviceImpl.OpenFileSystem(ref fileSystem.Ref, in originalPath, fsType, programId.Value, + res = _serviceImpl.OpenFileSystem(ref fileSystem.Ref, in originalPath, default, fsType, programId.Value, isDirectory); if (res.IsFailure()) return res.Miss(); } @@ -143,8 +153,8 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager : ref PathExtensions.GetNullRef(); // Open the file system using both the original and patch versions - res = _serviceImpl.OpenFileSystemWithPatch(ref fileSystem.Ref, in originalNcaPath, in patchPath, - fsType, programId.Value); + res = _serviceImpl.OpenFileSystemWithPatch(ref fileSystem.Ref, in originalNcaPath, contentAttributes, + in patchPath, patchContentAttributes, fsType, originalProgramId, programId.Value); if (res.IsFailure()) return res.Miss(); } @@ -169,8 +179,8 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager return Result.Success; } - public Result OpenCodeFileSystem(ref SharedRef outFileSystem, - out CodeVerificationData verificationData, ref readonly FspPath path, ProgramId programId) + public Result OpenCodeFileSystem(ref SharedRef outFileSystem, OutBuffer outVerificationData, + ref readonly FspPath path, ContentAttributes attributes, ProgramId programId) { throw new NotImplementedException(); } @@ -181,21 +191,32 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager } public Result OpenDataStorageByPath(ref SharedRef outFileSystem, ref readonly FspPath path, - FileSystemProxyType fsType) + ContentAttributes attributes, FileSystemProxyType fsType) { throw new NotImplementedException(); } - private Result TryAcquireAddOnContentOpenCountSemaphore(ref UniqueRef outSemaphoreLock) + private Result TryAcquireAddOnContentDivisionSizeUnitCountSemaphore(ref UniqueRef outSemaphore, IStorage storage) { throw new NotImplementedException(); } - private Result TryAcquireRomMountCountSemaphore(ref UniqueRef outSemaphoreLock) + private Result TryAcquireRomMountCountSemaphore(ref UniqueRef outSemaphore) { throw new NotImplementedException(); } + private Result TryAcquireRomDivisionSizeUnitCountSemaphore(ref UniqueRef outSemaphore, + ref UniqueRef mountCountSemaphore, IStorage storage) + { + throw new NotImplementedException(); + } + + public void IncrementRomFsDeepRetryStartCount() + { + _serviceImpl.IncrementRomFsRemountForDataCorruptionCount(); + } + public void IncrementRomFsRemountForDataCorruptionCount() { _serviceImpl.IncrementRomFsRemountForDataCorruptionCount(); @@ -211,8 +232,14 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager _serviceImpl.IncrementRomFsRecoveredByInvalidateCacheCount(); } - private Result OpenDataStorageCore(ref SharedRef outStorage, out Hash ncaHeaderDigest, - ulong id, StorageId storageId) + public void IncrementRomFsUnrecoverableByGameCardAccessFailedCount() + { + _serviceImpl.IncrementRomFsRecoveredByInvalidateCacheCount(); + } + + private Result OpenDataStorageCore(ref SharedRef outStorage, + ref SharedRef outStorageAccessSplitter, out Hash ncaHeaderDigest, ulong id, + StorageId storageId) { throw new NotImplementedException(); } @@ -227,8 +254,14 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager throw new NotImplementedException(); } - public Result OpenFileSystemWithId(ref SharedRef outFileSystem, ref readonly FspPath path, - ulong id, FileSystemProxyType fsType) + public Result OpenDataStorageByPath(ref SharedRef outStorage, in FspPath path, + ContentAttributes attributes, FileSystemProxyType fspType) + { + throw new NotImplementedException(); + } + + public Result OpenFileSystemWithId(ref SharedRef outFileSystem, in FspPath path, + ContentAttributes attributes, ulong id, FileSystemProxyType fsType) { const StorageLayoutType storageFlag = StorageLayoutType.All; using var scopedContext = new ScopedStorageLayoutTypeSetter(storageFlag); @@ -292,7 +325,7 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager bool isDirectory = PathUtility.IsDirectoryPath(in path); using var fileSystem = new SharedRef(); - res = _serviceImpl.OpenFileSystem(ref fileSystem.Ref, in pathNormalized, fsType, canMountSystemDataPrivate, + res = _serviceImpl.OpenFileSystem(ref fileSystem.Ref, in pathNormalized, default, fsType, canMountSystemDataPrivate, id, isDirectory); if (res.IsFailure()) return res.Miss(); @@ -321,6 +354,16 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager throw new NotImplementedException(); } + public Result OpenDataFileSystemByDataId(ref SharedRef outFileSystem, DataId dataId, StorageId storageId) + { + throw new NotImplementedException(); + } + + public Result OpenPatchDataStorageByCurrentProcess(ref SharedRef outStorage) + { + throw new NotImplementedException(); + } + public Result OpenDataFileSystemWithProgramIndex(ref SharedRef outFileSystem, byte programIndex) { Result res = GetProgramInfo(out ProgramInfo programInfo); @@ -372,13 +415,14 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager return ResultFs.PermissionDenied.Log(); using var programPath = new Path(); - res = _serviceImpl.ResolveProgramPath(out bool isDirectory, ref programPath.Ref(), programId, storageId); + res = _serviceImpl.ResolveProgramPath(out bool isDirectory, ref programPath.Ref(), + out ContentAttributes contentAttributes, programId, storageId); if (res.IsFailure()) return res.Miss(); if (isDirectory) return ResultFs.TargetNotFound.Log(); - res = _serviceImpl.GetRightsId(out RightsId rightsId, out _, in programPath, programId); + res = _serviceImpl.GetRightsId(out RightsId rightsId, out _, in programPath, contentAttributes, programId); if (res.IsFailure()) return res.Miss(); outRightsId = rightsId; @@ -386,7 +430,8 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager return Result.Success; } - public Result GetRightsIdAndKeyGenerationByPath(out RightsId outRightsId, out byte outKeyGeneration, ref readonly FspPath path) + public Result GetRightsIdAndKeyGenerationByPath(out RightsId outRightsId, out byte outKeyGeneration, + ref readonly FspPath path, ContentAttributes attributes) { const ulong checkThroughProgramId = ulong.MaxValue; UnsafeHelpers.SkipParamInit(out outRightsId, out outKeyGeneration); @@ -412,7 +457,7 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager if (PathUtility.IsDirectoryPath(in path)) return ResultFs.TargetNotFound.Log(); - res = _serviceImpl.GetRightsId(out RightsId rightsId, out byte keyGeneration, in pathNormalized, + res = _serviceImpl.GetRightsId(out RightsId rightsId, out byte keyGeneration, in pathNormalized, default, new ProgramId(checkThroughProgramId)); if (res.IsFailure()) return res.Miss(); @@ -422,9 +467,14 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager return Result.Success; } + public Result GetProgramId(out ProgramId outProgramId, ref readonly FspPath path, ContentAttributes attributes) + { + throw new NotImplementedException(); + } + // ReSharper disable once OutParameterValueIsAlwaysDiscarded.Local - private Result OpenDataFileSystemCore(ref SharedRef outFileSystem, out bool isHostFs, - ulong programId, StorageId storageId) + private Result OpenDataFileSystemCore(ref SharedRef outFileSystem, out bool isHostFs, ulong programId, + StorageId storageId) { UnsafeHelpers.SkipParamInit(out isHostFs); @@ -432,13 +482,14 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager using var scopedContext = new ScopedStorageLayoutTypeSetter(storageFlag); using var programPath = new Path(); - Result res = _serviceImpl.ResolveRomPath(out bool isDirectory, ref programPath.Ref(), programId, storageId); + Result res = _serviceImpl.ResolveRomPath(out bool isDirectory, ref programPath.Ref(), + out ContentAttributes contentAttributes, out _, programId, storageId); if (res.IsFailure()) return res.Miss(); isHostFs = Utility.IsHostFsMountName(programPath.GetString()); using var fileSystem = new SharedRef(); - res = _serviceImpl.OpenDataFileSystem(ref fileSystem.Ref, in programPath, FileSystemProxyType.Rom, + res = _serviceImpl.OpenDataFileSystem(ref fileSystem.Ref, in programPath, contentAttributes, FileSystemProxyType.Rom, programId, isDirectory); if (res.IsFailure()) return res.Miss(); @@ -529,10 +580,11 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager ulong targetProgramId = programInfo.ProgramIdValue; using var programPath = new Path(); - res = _serviceImpl.ResolveRomPath(out _, ref programPath.Ref(), targetProgramId, programInfo.StorageId); + res = _serviceImpl.ResolveRomPath(out _, ref programPath.Ref(), out ContentAttributes contentAttributes, out _, + targetProgramId, programInfo.StorageId); if (res.IsFailure()) return res.Miss(); - return _serviceImpl.RegisterUpdatePartition(targetProgramId, in programPath); + return _serviceImpl.RegisterUpdatePartition(targetProgramId, in programPath, contentAttributes); } public Result OpenRegisteredUpdatePartition(ref SharedRef outFileSystem) @@ -583,6 +635,11 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager return _serviceImpl.SetSdCardEncryptionSeed(in encryptionSeed); } + public Result OpenHostFileSystem(ref SharedRef outFileSystem, ref readonly FspPath path) + { + throw new NotImplementedException(); + } + public Result OpenSystemDataUpdateEventNotifier(ref SharedRef outEventNotifier) { throw new NotImplementedException(); @@ -593,14 +650,15 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager throw new NotImplementedException(); } - public Result HandleResolubleAccessFailure(out bool wasDeferred, Result resultForNoFailureDetected) + public Result HandleResolubleAccessFailure(out bool wasDeferred, Result nonDeferredResult) { - return _serviceImpl.HandleResolubleAccessFailure(out wasDeferred, resultForNoFailureDetected, _processId); + return _serviceImpl.HandleResolubleAccessFailure(out wasDeferred, nonDeferredResult, _processId); } Result IRomFileSystemAccessFailureManager.OpenDataStorageCore(ref SharedRef outStorage, - out Hash ncaHeaderDigest, ulong id, StorageId storageId) + ref SharedRef outStorageAccessSplitter, out Hash ncaHeaderDigest, ulong id, + StorageId storageId) { - return OpenDataStorageCore(ref outStorage, out ncaHeaderDigest, id, storageId); + return OpenDataStorageCore(ref outStorage, ref outStorageAccessSplitter, out ncaHeaderDigest, id, storageId).Ret(); } } \ No newline at end of file diff --git a/src/LibHac/FsSrv/NcaFileSystemServiceImpl.cs b/src/LibHac/FsSrv/NcaFileSystemServiceImpl.cs index 6ab93ce2..24c214fc 100644 --- a/src/LibHac/FsSrv/NcaFileSystemServiceImpl.cs +++ b/src/LibHac/FsSrv/NcaFileSystemServiceImpl.cs @@ -1,7 +1,6 @@ using System; -using System.Buffers.Text; -using System.Runtime.CompilerServices; using LibHac.Common; +using LibHac.Diag; using LibHac.Fs; using LibHac.Fs.Fsa; using LibHac.FsSrv.FsCreator; @@ -10,35 +9,73 @@ using LibHac.FsSystem; using LibHac.Ncm; using LibHac.Os; using LibHac.Spl; -using LibHac.Tools.FsSystem.NcaUtils; -using LibHac.Util; -using static LibHac.Fs.Impl.CommonMountNames; +using NcaFsHeader = LibHac.FsSystem.NcaFsHeader; using RightsId = LibHac.Fs.RightsId; -using Utility = LibHac.FsSystem.Utility; +using Utility = LibHac.FsSrv.Impl.Utility; namespace LibHac.FsSrv; -public class NcaFileSystemServiceImpl +file static class Anonymous +{ + public static Result GetDeviceHandleByMountName(out GameCardHandle outHandle, U8Span name) + { + throw new NotImplementedException(); + } + + public static Result GetGameCardPartitionByMountName(out GameCardPartition outPartition, U8Span name) + { + throw new NotImplementedException(); + } + + public static Result GetPartitionIndex(out int outIndex, FileSystemProxyType type) + { + switch (type) + { + case FileSystemProxyType.Code: + case FileSystemProxyType.Control: + case FileSystemProxyType.Manual: + case FileSystemProxyType.Meta: + case FileSystemProxyType.Data: + outIndex = 0; + return Result.Success; + case FileSystemProxyType.Rom: + case FileSystemProxyType.RegisteredUpdate: + outIndex = 1; + return Result.Success; + case FileSystemProxyType.Logo: + outIndex = 2; + return Result.Success; + default: + UnsafeHelpers.SkipParamInit(out outIndex); + return ResultFs.InvalidArgument.Log(); + } + } + + public static void GenerateNcaDigest(out Hash outDigest, NcaReader reader1, NcaReader reader2) + { + throw new NotImplementedException(); + } + + public static Result LoadNspdVerificationData(out CodeVerificationData outCodeVerificationData, IFileSystem fileSystem) + { + throw new NotImplementedException(); + } +} + +public class NcaFileSystemServiceImpl : IDisposable { private Configuration _config; - // UpdatePartitionPath - private ExternalKeySet _externalKeyManager; - private LocationResolverSet _locationResolverSet; - // SystemDataUpdateEventManager + private UpdatePartitionPath _updatePartitionPath; + private ExternalKeyManager _externalKeyManager; + private SystemDataUpdateEventManager _systemDataUpdateEventManager; private EncryptionSeed _encryptionSeed; - private int _romFsRemountForDataCorruptionCount; - private int _romfsUnrecoverableDataCorruptionByRemountCount; - private int _romFsRecoveredByInvalidateCacheCount; + private uint _romFsDeepRetryStartCount; + private uint _romFsRemountForDataCorruptionCount; + private uint _romfsUnrecoverableDataCorruptionByRemountCount; + private uint _romFsRecoveredByInvalidateCacheCount; + private uint _romFsUnrecoverableByGameCardAccessFailedCount; private SdkMutexType _romfsCountMutex; - public NcaFileSystemServiceImpl(in Configuration configuration, ExternalKeySet externalKeySet) - { - _config = configuration; - _externalKeyManager = externalKeySet; - _locationResolverSet = new LocationResolverSet(_config.FsServer); - _romfsCountMutex.Initialize(); - } - public struct Configuration { public BaseFileSystemServiceImpl BaseFsService; @@ -49,9 +86,13 @@ public class NcaFileSystemServiceImpl public IStorageOnNcaCreator StorageOnNcaCreator; public ISubDirectoryFileSystemCreator SubDirectoryFsCreator; public IEncryptedFileSystemCreator EncryptedFsCreator; + public INspRootFileSystemCreator NspRootFileSystemCreator; + private LocationResolverSet LocationResolverSet; public ProgramRegistryServiceImpl ProgramRegistryService; public AccessFailureManagementServiceImpl AccessFailureManagementService; public InternalProgramIdRangeForSpeedEmulation SpeedEmulationRange; + public long AddOnContentDivisionSize; + public long RomDivisionSize; // LibHac additions public FileSystemServer FsServer; @@ -59,251 +100,165 @@ public class NcaFileSystemServiceImpl private struct MountInfo { - public bool IsGameCard; - public int GcHandle; - public bool IsHostFs; + public enum FileSystemType + { + None, + GameCard, + HostFs, + LocalFs + } + + public FileSystemType FsType; + public GameCardHandle GcHandle; public bool CanMountNca; + + public MountInfo() + { + FsType = FileSystemType.None; + GcHandle = 0; + CanMountNca = false; + } + + public readonly bool IsGameCard() => FsType == FileSystemType.GameCard; + public readonly bool IsHostOrLocalFs() => FsType == FileSystemType.HostFs || FsType == FileSystemType.LocalFs; } - public Result OpenFileSystem(ref SharedRef outFileSystem, ref readonly Path path, - FileSystemProxyType type, ulong id, bool isDirectory) + public FileSystemServer FsServer => _config.FsServer; + + public NcaFileSystemServiceImpl(in Configuration configuration) { - return OpenFileSystem(ref outFileSystem, out Unsafe.NullRef(), in path, type, false, id, - isDirectory); + _config = configuration; + _updatePartitionPath = new UpdatePartitionPath(); + _externalKeyManager = new ExternalKeyManager(); + _systemDataUpdateEventManager = new SystemDataUpdateEventManager(); + + _romFsDeepRetryStartCount = 0; + _romFsRemountForDataCorruptionCount = 0; + _romfsUnrecoverableDataCorruptionByRemountCount = 0; + _romFsRecoveredByInvalidateCacheCount = 0; + _romFsUnrecoverableByGameCardAccessFailedCount = 0; + + _romfsCountMutex = new SdkMutexType(); } - public Result OpenFileSystem(ref SharedRef outFileSystem, ref readonly Path path, - FileSystemProxyType type, bool canMountSystemDataPrivate, ulong id, bool isDirectory) + public void Dispose() { - return OpenFileSystem(ref outFileSystem, out Unsafe.NullRef(), in path, type, - canMountSystemDataPrivate, id, isDirectory); + _updatePartitionPath.Dispose(); } - public Result OpenFileSystem(ref SharedRef outFileSystem, out CodeVerificationData verificationData, - ref readonly Path path, FileSystemProxyType type, bool canMountSystemDataPrivate, ulong id, bool isDirectory) - { - UnsafeHelpers.SkipParamInit(out verificationData); - - if (!Unsafe.IsNullRef(ref verificationData)) - verificationData.HasData = false; - - // Get a reference to the path that will be advanced as each part of the path is parsed - var currentPath = new U8Span(path.GetString()); - - // Open the root filesystem based on the path's mount name - using var baseFileSystem = new SharedRef(); - Result res = ParseMountName(ref currentPath, ref baseFileSystem.Ref, out bool shouldContinue, - out MountInfo mountNameInfo); - if (res.IsFailure()) return res.Miss(); - - // Don't continue if the rest of the path is empty - if (!shouldContinue) - return ResultFs.InvalidArgument.Log(); - - if (type == FileSystemProxyType.Logo && mountNameInfo.IsGameCard) - { - res = _config.BaseFsService.OpenGameCardFileSystem(ref outFileSystem, (uint)mountNameInfo.GcHandle, - GameCardPartition.Logo); - - if (res.IsSuccess()) - return Result.Success; - - if (!ResultFs.PartitionNotFound.Includes(res)) - return res; - } - - res = CheckDirOrNcaOrNsp(ref currentPath, out isDirectory); - if (res.IsFailure()) return res.Miss(); - - if (isDirectory) - { - if (!mountNameInfo.IsHostFs) - return ResultFs.PermissionDenied.Log(); - - using var directoryPath = new Path(); - res = directoryPath.InitializeWithNormalization(currentPath.Value); - if (res.IsFailure()) return res.Miss(); - - if (type == FileSystemProxyType.Manual) - { - using var hostFileSystem = new SharedRef(); - using var readOnlyFileSystem = new SharedRef(); - - res = ParseDirWithPathCaseNormalizationOnCaseSensitiveHostFs(ref hostFileSystem.Ref, - in directoryPath); - if (res.IsFailure()) return res.Miss(); - - readOnlyFileSystem.Reset(new ReadOnlyFileSystem(ref hostFileSystem.Ref)); - outFileSystem.SetByMove(ref readOnlyFileSystem.Ref); - - return Result.Success; - } - - return ParseDir(in directoryPath, ref outFileSystem, ref baseFileSystem.Ref, type, true); - } - - using var nspFileSystem = new SharedRef(); - using SharedRef tempFileSystem = SharedRef.CreateCopy(in baseFileSystem); - res = ParseNsp(ref currentPath, ref nspFileSystem.Ref, ref baseFileSystem.Ref); - - if (res.IsSuccess()) - { - // Must be the end of the path to open Application Package FS type - if (currentPath.Value.At(0) == 0) - { - if (type == FileSystemProxyType.Package) - { - outFileSystem.SetByMove(ref nspFileSystem.Ref); - return Result.Success; - } - - return ResultFs.InvalidArgument.Log(); - } - - baseFileSystem.SetByMove(ref nspFileSystem.Ref); - } - - if (!mountNameInfo.CanMountNca) - { - return ResultFs.UnexpectedInNcaFileSystemServiceImplA.Log(); - } - - ulong openProgramId = mountNameInfo.IsHostFs ? ulong.MaxValue : id; - - res = ParseNca(ref currentPath, out Nca nca, ref baseFileSystem.Ref, openProgramId); - if (res.IsFailure()) return res.Miss(); - - using var ncaSectionStorage = new SharedRef(); - res = OpenStorageByContentType(ref ncaSectionStorage.Ref, nca, out NcaFormatType fsType, type, - mountNameInfo.IsGameCard, canMountSystemDataPrivate); - if (res.IsFailure()) return res.Miss(); - - switch (fsType) - { - case NcaFormatType.Romfs: - return _config.RomFsCreator.Create(ref outFileSystem, ref ncaSectionStorage.Ref); - case NcaFormatType.Pfs0: - return _config.PartitionFsCreator.Create(ref outFileSystem, ref ncaSectionStorage.Ref); - default: - return ResultFs.InvalidNcaFileSystemType.Log(); - } - } - - public Result OpenDataFileSystem(ref SharedRef outFileSystem, ref readonly Path path, - FileSystemProxyType fsType, ulong programId, bool isDirectory) + public long GetAddOnContentDivisionSize() { throw new NotImplementedException(); } - public Result OpenStorageWithPatch(ref SharedRef outStorage, out Hash ncaHeaderDigest, - ref readonly Path originalNcaPath, ref readonly Path currentNcaPath, FileSystemProxyType fsType, ulong id) + public long GetRomDivisionSize() + { + throw new NotImplementedException(); + } + + public Result OpenFileSystem(ref SharedRef outFileSystem, ref readonly Path path, + ContentAttributes attributes, FileSystemProxyType type, bool canMountSystemDataPrivate, ulong id, + bool isDirectory) + { + throw new NotImplementedException(); + } + + public Result OpenFileSystem(ref SharedRef outFileSystem, ref readonly Path path, + ContentAttributes attributes, FileSystemProxyType type, ulong id, bool isDirectory) + { + throw new NotImplementedException(); + } + + public Result OpenFileSystem(ref SharedRef outFileSystem, out CodeVerificationData outVerificationData, + ref readonly Path path, ContentAttributes attributes, FileSystemProxyType type, bool canMountSystemDataPrivate, + ulong id, bool isDirectory) + { + throw new NotImplementedException(); + } + + public Result OpenDataFileSystem(ref SharedRef outFileSystem, ref readonly Path path, + ContentAttributes attributes, FileSystemProxyType fsType, ulong programId, bool isDirectory) + { + throw new NotImplementedException(); + } + + public Result OpenDataFileSystem(ref SharedRef outFileSystem) + { + throw new NotImplementedException(); + } + + public Result OpenDataStorage(ref SharedRef outStorage, + ref SharedRef outStorageAccessSplitter, out Hash outNcaHeaderDigest, + ref readonly Path path, ContentAttributes attributes, FileSystemProxyType fsType, ulong id) + { + throw new NotImplementedException(); + } + + public Result OpenDataStorage(ref SharedRef outStorage, + ref SharedRef outStorageAccessSplitter, out Hash outNcaHeaderDigest, + ref readonly Path path, ContentAttributes attributes, FileSystemProxyType fsType, ulong id, + bool canMountSystemDataPrivate) + { + throw new NotImplementedException(); + } + + public Result OpenStorageWithPatch(ref SharedRef outStorage, + ref SharedRef outStorageAccessSplitter, out Hash ncaHeaderDigest, + ref readonly Path originalNcaPath, ContentAttributes originalAttributes, ref readonly Path currentNcaPath, + ContentAttributes currentAttributes, FileSystemProxyType fsType, ulong originalId, ulong currentId) + { + throw new NotImplementedException(); + } + + public Result OpenStorageWithPatch(ref SharedRef outStorage, + ref SharedRef outStorageAccessSplitter, out Hash ncaHeaderDigest, + ref readonly Path originalNcaPath, ContentAttributes originalAttributes, ref readonly Path currentNcaPath, + ContentAttributes currentAttributes, FileSystemProxyType fsType, ulong originalId, ulong currentId, + bool canMountSystemDataPrivate) { throw new NotImplementedException(); } public Result OpenFileSystemWithPatch(ref SharedRef outFileSystem, ref readonly Path originalNcaPath, - ref readonly Path currentNcaPath, FileSystemProxyType fsType, ulong id) + ContentAttributes originalAttributes, ref readonly Path currentNcaPath, ContentAttributes currentAttributes, + FileSystemProxyType fsType, ulong originalId, ulong currentId) { - using var romFsStorage = new SharedRef(); - Result res = OpenStorageWithPatch(ref romFsStorage.Ref, out Unsafe.NullRef(), in originalNcaPath, - in currentNcaPath, fsType, id); - if (res.IsFailure()) return res.Miss(); - - return _config.RomFsCreator.Create(ref outFileSystem, ref romFsStorage.Ref); + throw new NotImplementedException(); } public Result OpenContentStorageFileSystem(ref SharedRef outFileSystem, ContentStorageId contentStorageId) { - using var fileSystem = new SharedRef(); - Result res; - - // Open the appropriate base file system for the content storage ID - switch (contentStorageId) - { - case ContentStorageId.System: - res = _config.BaseFsService.OpenBisFileSystem(ref fileSystem.Ref, BisPartitionId.System); - if (res.IsFailure()) return res.Miss(); - break; - case ContentStorageId.User: - res = _config.BaseFsService.OpenBisFileSystem(ref fileSystem.Ref, BisPartitionId.User); - if (res.IsFailure()) return res.Miss(); - break; - case ContentStorageId.SdCard: - res = _config.BaseFsService.OpenSdCardProxyFileSystem(ref fileSystem.Ref); - if (res.IsFailure()) return res.Miss(); - break; - default: - return ResultFs.InvalidArgument.Log(); - } - - Span contentStoragePathBuffer = stackalloc byte[64]; - //Unsafe.SkipInit(out Array64 contentStoragePathBuffer); - - // Build the appropriate path for the content storage ID - if (contentStorageId == ContentStorageId.SdCard) - { - var sb = new U8StringBuilder(contentStoragePathBuffer); - sb.Append(StringTraits.DirectorySeparator).Append(CommonDirNames.SdCardNintendoRootDirectoryName); - sb.Append(StringTraits.DirectorySeparator).Append(CommonDirNames.ContentStorageDirectoryName); - } - else - { - var sb = new U8StringBuilder(contentStoragePathBuffer); - sb.Append(StringTraits.DirectorySeparator).Append(CommonDirNames.ContentStorageDirectoryName); - } - - using scoped var contentStoragePath = new Path(); - res = PathFunctions.SetUpFixedPath(ref contentStoragePath.Ref(), contentStoragePathBuffer); - if (res.IsFailure()) return res.Miss(); - - // Make sure the content storage path exists - res = Utility.EnsureDirectory(fileSystem.Get, in contentStoragePath); - if (res.IsFailure()) return res.Miss(); - - using var subDirFs = new SharedRef(); - res = _config.SubDirectoryFsCreator.Create(ref subDirFs.Ref, ref fileSystem.Ref, in contentStoragePath); - if (res.IsFailure()) return res.Miss(); - - // Only content on the SD card is encrypted - if (contentStorageId == ContentStorageId.SdCard) - { - using SharedRef tempFileSystem = SharedRef.CreateMove(ref subDirFs.Ref); - res = _config.EncryptedFsCreator.Create(ref subDirFs.Ref, ref tempFileSystem.Ref, - IEncryptedFileSystemCreator.KeyId.Content, in _encryptionSeed); - if (res.IsFailure()) return res.Miss(); - } - - outFileSystem.SetByMove(ref subDirFs.Ref); - - return Result.Success; + throw new NotImplementedException(); } - public Result GetRightsId(out RightsId rightsId, out byte keyGeneration, ref readonly Path path, ProgramId programId) + public Result GetRightsId(out RightsId rightsId, out byte keyGeneration, ref readonly Path path, + ContentAttributes attributes, ProgramId programId) + { + throw new NotImplementedException(); + } + + public Result GetProgramId(out ProgramId outProgramId, ref readonly Path path, ContentAttributes attributes, ProgramId programId) { throw new NotImplementedException(); } public Result RegisterExternalKey(in RightsId rightsId, in AccessKey accessKey) { - return _externalKeyManager.Add(rightsId, accessKey); + return _externalKeyManager.Register(in rightsId, in accessKey).Ret(); } public Result UnregisterExternalKey(in RightsId rightsId) { - _externalKeyManager.Remove(rightsId); - - return Result.Success; + return _externalKeyManager.Unregister(in rightsId).Ret(); } public Result UnregisterAllExternalKey() { - _externalKeyManager.Clear(); - - return Result.Success; + return _externalKeyManager.UnregisterAll().Ret(); } - public Result RegisterUpdatePartition(ulong programId, ref readonly Path path) + public Result RegisterUpdatePartition(ulong programId, ref readonly Path path, ContentAttributes attributes) { throw new NotImplementedException(); } @@ -313,360 +268,78 @@ public class NcaFileSystemServiceImpl throw new NotImplementedException(); } - private Result ParseMountName(ref U8Span path, ref SharedRef outFileSystem, - out bool shouldContinue, out MountInfo info) + private Result ParseMountName(ref U8Span path, ref SharedRef outFileSystem, out MountInfo outMountInfo) { - info = new MountInfo(); - shouldContinue = true; - - if (StringUtils.Compare(path, GameCardFileSystemMountName, - GameCardFileSystemMountName.Length) == 0) - { - path = path.Slice(GameCardFileSystemMountName.Length); - - if (StringUtils.GetLength(path.Value, 9) < 9) - return ResultFs.InvalidPath.Log(); - - GameCardPartition partition; - if (StringUtils.CompareCaseInsensitive(path, GameCardFileSystemMountNameSuffixUpdate) == 0) - partition = GameCardPartition.Update; - else if (StringUtils.CompareCaseInsensitive(path, GameCardFileSystemMountNameSuffixNormal) == 0) - partition = GameCardPartition.Normal; - else if (StringUtils.CompareCaseInsensitive(path, GameCardFileSystemMountNameSuffixSecure) == 0) - partition = GameCardPartition.Secure; - else - return ResultFs.InvalidPath.Log(); - - path = path.Slice(1); - bool handleParsed = Utf8Parser.TryParse(path, out int handle, out int bytesConsumed); - - if (!handleParsed || handle == -1 || bytesConsumed != 8) - return ResultFs.InvalidPath.Log(); - - path = path.Slice(8); - - Result res = _config.BaseFsService.OpenGameCardFileSystem(ref outFileSystem, (uint)handle, partition); - if (res.IsFailure()) return res.Miss(); - - info.GcHandle = handle; - info.IsGameCard = true; - info.CanMountNca = true; - } - - else if (StringUtils.Compare(path, ContentStorageSystemMountName, - ContentStorageSystemMountName.Length) == 0) - { - path = path.Slice(ContentStorageSystemMountName.Length); - - Result res = OpenContentStorageFileSystem(ref outFileSystem, ContentStorageId.System); - if (res.IsFailure()) return res.Miss(); - - info.CanMountNca = true; - } - - else if (StringUtils.Compare(path, ContentStorageUserMountName, - ContentStorageUserMountName.Length) == 0) - { - path = path.Slice(ContentStorageUserMountName.Length); - - Result res = OpenContentStorageFileSystem(ref outFileSystem, ContentStorageId.User); - if (res.IsFailure()) return res.Miss(); - - info.CanMountNca = true; - } - - else if (StringUtils.Compare(path, ContentStorageSdCardMountName, - ContentStorageSdCardMountName.Length) == 0) - { - path = path.Slice(ContentStorageSdCardMountName.Length); - - Result res = OpenContentStorageFileSystem(ref outFileSystem, ContentStorageId.SdCard); - if (res.IsFailure()) return res.Miss(); - - info.CanMountNca = true; - } - - else if (StringUtils.Compare(path, BisCalibrationFilePartitionMountName, - BisCalibrationFilePartitionMountName.Length) == 0) - { - path = path.Slice(BisCalibrationFilePartitionMountName.Length); - - Result res = _config.BaseFsService.OpenBisFileSystem(ref outFileSystem, BisPartitionId.CalibrationFile); - if (res.IsFailure()) return res.Miss(); - } - - else if (StringUtils.Compare(path, BisSafeModePartitionMountName, - BisSafeModePartitionMountName.Length) == 0) - { - path = path.Slice(BisSafeModePartitionMountName.Length); - - Result res = _config.BaseFsService.OpenBisFileSystem(ref outFileSystem, BisPartitionId.SafeMode); - if (res.IsFailure()) return res.Miss(); - } - - else if (StringUtils.Compare(path, BisUserPartitionMountName, - BisUserPartitionMountName.Length) == 0) - { - path = path.Slice(BisUserPartitionMountName.Length); - - Result res = _config.BaseFsService.OpenBisFileSystem(ref outFileSystem, BisPartitionId.User); - if (res.IsFailure()) return res.Miss(); - } - - else if (StringUtils.Compare(path, BisSystemPartitionMountName, - BisSystemPartitionMountName.Length) == 0) - { - path = path.Slice(BisSystemPartitionMountName.Length); - - Result res = _config.BaseFsService.OpenBisFileSystem(ref outFileSystem, BisPartitionId.System); - if (res.IsFailure()) return res.Miss(); - } - - else if (StringUtils.Compare(path, SdCardFileSystemMountName, - SdCardFileSystemMountName.Length) == 0) - { - path = path.Slice(SdCardFileSystemMountName.Length); - - Result res = _config.BaseFsService.OpenSdCardProxyFileSystem(ref outFileSystem); - if (res.IsFailure()) return res.Miss(); - } - - else if (StringUtils.Compare(path, HostRootFileSystemMountName, - HostRootFileSystemMountName.Length) == 0) - { - path = path.Slice(HostRootFileSystemMountName.Length); - - using var rootPathEmpty = new Path(); - Result res = rootPathEmpty.InitializeAsEmpty(); - if (res.IsFailure()) return res.Miss(); - - info.IsHostFs = true; - info.CanMountNca = true; - - res = OpenHostFileSystem(ref outFileSystem, in rootPathEmpty, openCaseSensitive: false); - if (res.IsFailure()) return res.Miss(); - } - - else if (StringUtils.Compare(path, RegisteredUpdatePartitionMountName, - RegisteredUpdatePartitionMountName.Length) == 0) - { - path = path.Slice(RegisteredUpdatePartitionMountName.Length); - - info.CanMountNca = true; - - throw new NotImplementedException(); - } - - else - { - return ResultFs.PathNotFound.Log(); - } - - if (StringUtils.GetLength(path, PathTool.EntryNameLengthMax) == 0) - { - shouldContinue = false; - } - - return Result.Success; + throw new NotImplementedException(); } - private Result CheckDirOrNcaOrNsp(ref U8Span path, out bool isDirectory) + private Result CheckNcaOrNsp(ref U8Span path) { - UnsafeHelpers.SkipParamInit(out isDirectory); - - ReadOnlySpan mountSeparator = ":/"u8; - - if (StringUtils.Compare(mountSeparator, path, mountSeparator.Length) != 0) - { - return ResultFs.PathNotFound.Log(); - } - - path = path.Slice(1); - int pathLen = StringUtils.GetLength(path); - - if (path[pathLen - 1] == '/') - { - isDirectory = true; - return Result.Success; - } - - // Now make sure the path has a content file extension - if (pathLen < 5) - return ResultFs.PathNotFound.Log(); - - ReadOnlySpan fileExtension = path.Value.Slice(pathLen - 4); - - ReadOnlySpan ncaExtension = ".nca"u8; - ReadOnlySpan nspExtension = ".nsp"u8; - - if (StringUtils.CompareCaseInsensitive(fileExtension, ncaExtension) == 0 || - StringUtils.CompareCaseInsensitive(fileExtension, nspExtension) == 0) - { - isDirectory = false; - return Result.Success; - } - - return ResultFs.PathNotFound.Log(); + throw new NotImplementedException(); } private Result ParseDir(ref readonly Path path, ref SharedRef outContentFileSystem, ref SharedRef baseFileSystem, FileSystemProxyType fsType, bool preserveUnc) { using var fileSystem = new SharedRef(); - Result res = _config.SubDirectoryFsCreator.Create(ref fileSystem.Ref, ref baseFileSystem, in path); + Result res = _config.SubDirectoryFsCreator.Create(ref fileSystem.Ref, baseFileSystem, path); if (res.IsFailure()) return res.Miss(); return ParseContentTypeForDirectory(ref outContentFileSystem, ref fileSystem.Ref, fsType); } - private Result ParseDirWithPathCaseNormalizationOnCaseSensitiveHostFs(ref SharedRef outFileSystem, - ref readonly Path path) + private Result ParseDirWithPathCaseNormalizationOnCaseSensitiveHostOrLocalFs( + ref SharedRef outFileSystem, ref readonly Path path, MountInfo.FileSystemType fsType) { - using var pathRoot = new Path(); - using var pathData = new Path(); - - Result res = PathFunctions.SetUpFixedPath(ref pathData.Ref(), "/data"u8); - if (res.IsFailure()) return res.Miss(); - - res = pathRoot.Combine(in path, in pathData); - if (res.IsFailure()) return res.Miss(); - - res = _config.TargetManagerFsCreator.NormalizeCaseOfPath(out bool isSupported, ref pathRoot.Ref()); - if (res.IsFailure()) return res.Miss(); - - res = _config.TargetManagerFsCreator.Create(ref outFileSystem, in pathRoot, isSupported, false, - Result.Success); - if (res.IsFailure()) return res.Miss(); - - return Result.Success; + throw new NotImplementedException(); } - private Result ParseNsp(ref U8Span path, ref SharedRef outFileSystem, - ref SharedRef baseFileSystem) + private Result ParseNsp(out bool outFoundNspPath, ref U8Span path, ref SharedRef outFileSystem, + ref readonly SharedRef baseFileSystem) { - ReadOnlySpan nspExtension = ".nsp"u8; - - // Search for the end of the nsp part of the path - int nspPathLen = 0; - - while (true) - { - U8Span currentSpan; - - while (true) - { - currentSpan = path.Slice(nspPathLen); - if (StringUtils.CompareCaseInsensitive(nspExtension, currentSpan, 4) == 0) - break; - - if (currentSpan.Length == 0 || currentSpan[0] == 0) - { - return ResultFs.PathNotFound.Log(); - } - - nspPathLen++; - } - - // The nsp filename must be the end of the entire path or the end of a path segment - if (currentSpan.Length <= 4 || currentSpan[4] == 0 || currentSpan[4] == (byte)'/') - break; - - nspPathLen += 4; - } - - nspPathLen += 4; - - using var pathNsp = new Path(); - Result res = pathNsp.InitializeWithNormalization(path, nspPathLen); - if (res.IsFailure()) return res.Miss(); - - using var nspFileStorage = new SharedRef(new FileStorageBasedFileSystem()); - - res = nspFileStorage.Get.Initialize(ref baseFileSystem, in pathNsp, OpenMode.Read); - if (res.IsFailure()) return res.Miss(); - - using SharedRef tempStorage = SharedRef.CreateMove(ref nspFileStorage.Ref); - res = _config.PartitionFsCreator.Create(ref outFileSystem, ref tempStorage.Ref); - - if (res.IsSuccess()) - { - path = path.Slice(nspPathLen); - } - - return res; + throw new NotImplementedException(); } - private Result ParseNca(ref U8Span path, out Nca nca, ref SharedRef baseFileSystem, ulong ncaId) + private Result ParseNca(ref SharedRef outNcaReader, ref readonly SharedRef baseFileSystem, + U8Span path, ContentAttributes attributes, ulong programId) + { + throw new NotImplementedException(); + } + + private Result ParseNca(ref SharedRef outNcaReader, out bool outIsGameCard, U8Span path, + ContentAttributes attributes, ulong programId) { throw new NotImplementedException(); } private Result ParseContentTypeForDirectory(ref SharedRef outFileSystem, - ref SharedRef baseFileSystem, FileSystemProxyType fsType) + ref readonly SharedRef baseFileSystem, FileSystemProxyType fsType) { - ReadOnlySpan dirName; - - // Get the name of the subdirectory for the filesystem type - switch (fsType) - { - case FileSystemProxyType.Package: - outFileSystem.SetByMove(ref baseFileSystem); - return Result.Success; - - case FileSystemProxyType.Code: - dirName = "/code/"u8; - break; - case FileSystemProxyType.Rom: - case FileSystemProxyType.Control: - case FileSystemProxyType.Manual: - case FileSystemProxyType.Meta: - case FileSystemProxyType.RegisteredUpdate: - dirName = "/data/"u8; - break; - case FileSystemProxyType.Logo: - dirName = "/logo/"u8; - break; - - default: - return ResultFs.InvalidArgument.Log(); - } - - using var subDirFs = new SharedRef(); - - using var directoryPath = new Path(); - Result res = PathFunctions.SetUpFixedPath(ref directoryPath.Ref(), dirName); - if (res.IsFailure()) return res.Miss(); - - if (directoryPath.IsEmpty()) - return ResultFs.InvalidArgument.Log(); - - // Open the subdirectory filesystem - res = _config.SubDirectoryFsCreator.Create(ref subDirFs.Ref, ref baseFileSystem, in directoryPath); - if (res.IsFailure()) return res.Miss(); - - outFileSystem.SetByMove(ref subDirFs.Ref); - return Result.Success; + throw new NotImplementedException(); } - private Result SetExternalKeyForRightsId(Nca nca) + public Result SetExternalKeyForRightsId(NcaReader ncaReader) { - var rightsId = new RightsId(nca.Header.RightsId); - var zero = new RightsId(); - - if (Crypto.CryptoUtil.IsSameBytes(rightsId.Value, zero.Value, Unsafe.SizeOf())) - return Result.Success; - - // ReSharper disable once UnusedVariable - Result res = _externalKeyManager.Get(rightsId, out AccessKey accessKey); - if (res.IsFailure()) return res.Miss(); - - // todo: Set key in nca reader - - return Result.Success; + throw new NotImplementedException(); } - private Result OpenStorageByContentType(ref SharedRef outNcaStorage, Nca nca, - out NcaFormatType fsType, FileSystemProxyType fsProxyType, bool isGameCard, bool canMountSystemDataPrivate) + public bool IsAvailableKeySource(ReadOnlySpan keySource) + { + throw new NotImplementedException(); + } + + public Result OpenStorageByContentType(ref SharedRef outNcaStorage, + ref SharedRef outStorageAccessSplitter, + ref readonly SharedRef ncaReader, out NcaFsHeader.FsType outFsType, FileSystemProxyType fsProxyType, + bool isGameCard, bool canMountSystemDataPrivate) + { + throw new NotImplementedException(); + } + + public Result OpenStorageWithPatchByContentType(ref SharedRef outNcaStorage, + ref SharedRef outStorageAccessSplitter, + ref readonly SharedRef originalNcaReader, ref readonly SharedRef currentNcaReader, + out NcaFsHeader.FsType outFsType, FileSystemProxyType fsProxyType, bool canMountSystemDataPrivate) { throw new NotImplementedException(); } @@ -678,105 +351,151 @@ public class NcaFileSystemServiceImpl return Result.Success; } - public Result ResolveRomReferenceProgramId(out ProgramId targetProgramId, ProgramId programId, + public Result ResolveRomReferenceProgramId(out ProgramId outTargetProgramId, ProgramId programId, byte programIndex) { - UnsafeHelpers.SkipParamInit(out targetProgramId); + UnsafeHelpers.SkipParamInit(out outTargetProgramId); - ProgramId mainProgramId = _config.ProgramRegistryService.GetProgramIdByIndex(programId, programIndex); - if (mainProgramId == ProgramId.InvalidId) + ProgramId targetProgramId = _config.ProgramRegistryService.GetProgramIdByIndex(programId, programIndex); + if (targetProgramId == ProgramId.InvalidId) return ResultFs.ProgramIndexNotFound.Log(); - targetProgramId = mainProgramId; + outTargetProgramId = targetProgramId; return Result.Success; } - public Result ResolveProgramPath(out bool isDirectory, ref Path path, ProgramId programId, StorageId storageId) + public Result ResolveProgramPath(out bool isDirectory, ref Path outPath, out ContentAttributes outContentAttributes, + ProgramId programId, StorageId storageId) { - Result res = _locationResolverSet.ResolveProgramPath(out isDirectory, ref path, programId, storageId); - if (res.IsSuccess()) - return Result.Success; - - isDirectory = false; - - res = _locationResolverSet.ResolveDataPath(ref path, new DataId(programId.Value), storageId); - if (res.IsSuccess()) - return Result.Success; - - return ResultFs.TargetNotFound.Log(); + throw new NotImplementedException(); } - public Result ResolveRomPath(out bool isDirectory, ref Path path, ulong id, StorageId storageId) + public Result ResolveApplicationControlPath(ref Path outPath, out ContentAttributes outContentAttributes, + ApplicationId applicationId, StorageId storageId) { - return _locationResolverSet.ResolveRomPath(out isDirectory, ref path, new ProgramId(id), storageId); + throw new NotImplementedException(); } - public Result ResolveApplicationHtmlDocumentPath(out bool isDirectory, ref Path path, - Ncm.ApplicationId applicationId, StorageId storageId) + public Result ResolveRomPath(out bool isDirectory, ref Path outPath, out ContentAttributes outContentAttributes, + out ulong outOriginalProgramId, ulong programId, StorageId storageId) { - return _locationResolverSet.ResolveApplicationHtmlDocumentPath(out isDirectory, ref path, applicationId, - storageId); + throw new NotImplementedException(); } - public Result ResolveRegisteredHtmlDocumentPath(ref Path path, ulong id) + public Result ResolveApplicationHtmlDocumentPath(out bool isDirectory, ref Path outPath, + out ContentAttributes outContentAttributes, out ulong outOriginalProgramId, ulong programId, + StorageId storageId) { - return _locationResolverSet.ResolveRegisteredHtmlDocumentPath(ref path, id); + throw new NotImplementedException(); + } + + public Result ResolveDataPath(ref Path outPath, out ContentAttributes outContentAttributes, DataId dataId, + StorageId storageId) + { + throw new NotImplementedException(); + } + + public Result ResolveAddOnContentPath(ref Path outPath, out ContentAttributes outContentAttributes, + ref Path outPatchPath, out ContentAttributes outPatchContentAttributes, DataId dataId) + { + throw new NotImplementedException(); + } + + public Result ResolveRegisteredProgramPath(ref Path outPath, out ContentAttributes outContentAttributes, + ulong programId) + { + throw new NotImplementedException(); + } + + public Result ResolveRegisteredHtmlDocumentPath(ref Path outPath, out ContentAttributes outContentAttributes, + ulong programId) + { + throw new NotImplementedException(); } internal StorageLayoutType GetStorageFlag(ulong programId) { - if (programId >= _config.SpeedEmulationRange.ProgramIdMin && - programId <= _config.SpeedEmulationRange.ProgramIdMax) + Assert.SdkRequiresNotEqual(_config.SpeedEmulationRange.ProgramIdWithoutPlatformIdMax, 0ul); + + ulong programIdWithoutPlatformId = Utility.ClearPlatformIdInProgramId(programId); + + if (programIdWithoutPlatformId >= _config.SpeedEmulationRange.ProgramIdWithoutPlatformIdMin && + programIdWithoutPlatformId <= _config.SpeedEmulationRange.ProgramIdWithoutPlatformIdMax) return StorageLayoutType.Bis; else return StorageLayoutType.All; } - public Result HandleResolubleAccessFailure(out bool wasDeferred, Result resultForNoFailureDetected, + public Result HandleResolubleAccessFailure(out bool wasDeferred, Result nonDeferredResult, ulong processId) { - throw new NotImplementedException(); + return _config.AccessFailureManagementService + .HandleResolubleAccessFailure(out wasDeferred, nonDeferredResult, processId).Ret(); + } + + public void IncrementRomFsDeepRetryStartCount() + { + using ScopedLock scopedLock = ScopedLock.Lock(ref _romfsCountMutex); + _romFsDeepRetryStartCount++; } public void IncrementRomFsRemountForDataCorruptionCount() { - using ScopedLock lk = ScopedLock.Lock(ref _romfsCountMutex); - + using ScopedLock scopedLock = ScopedLock.Lock(ref _romfsCountMutex); _romFsRemountForDataCorruptionCount++; } public void IncrementRomFsUnrecoverableDataCorruptionByRemountCount() { - using ScopedLock lk = ScopedLock.Lock(ref _romfsCountMutex); - + using ScopedLock scopedLock = ScopedLock.Lock(ref _romfsCountMutex); _romfsUnrecoverableDataCorruptionByRemountCount++; } public void IncrementRomFsRecoveredByInvalidateCacheCount() { - using ScopedLock lk = ScopedLock.Lock(ref _romfsCountMutex); - + using ScopedLock scopedLock = ScopedLock.Lock(ref _romfsCountMutex); _romFsRecoveredByInvalidateCacheCount++; } - public void GetAndClearRomFsErrorInfo(out int recoveredByRemountCount, out int unrecoverableCount, - out int recoveredByCacheInvalidationCount) + public void IncrementRomFsUnrecoverableByGameCardAccessFailedCount() { - using ScopedLock lk = ScopedLock.Lock(ref _romfsCountMutex); + using ScopedLock scopedLock = ScopedLock.Lock(ref _romfsCountMutex); + _romFsUnrecoverableByGameCardAccessFailedCount++; + } - recoveredByRemountCount = _romFsRemountForDataCorruptionCount; - unrecoverableCount = _romfsUnrecoverableDataCorruptionByRemountCount; - recoveredByCacheInvalidationCount = _romFsRecoveredByInvalidateCacheCount; + public void GetAndClearRomFsErrorInfo(out uint outDeepRetryStartCount, out uint outRemountForDataCorruptionCount, + out uint outUnrecoverableDataCorruptionByRemountCount, out uint outRecoveredByInvalidateCacheCount, + out uint outUnrecoverableByGameCardAccessFailedCount) + { + using ScopedLock scopedLock = ScopedLock.Lock(ref _romfsCountMutex); + outDeepRetryStartCount = _romFsDeepRetryStartCount; + outRemountForDataCorruptionCount = _romFsRemountForDataCorruptionCount; + outUnrecoverableDataCorruptionByRemountCount = _romfsUnrecoverableDataCorruptionByRemountCount; + outRecoveredByInvalidateCacheCount = _romFsRecoveredByInvalidateCacheCount; + outUnrecoverableByGameCardAccessFailedCount = _romFsUnrecoverableByGameCardAccessFailedCount; + + _romFsDeepRetryStartCount = 0; _romFsRemountForDataCorruptionCount = 0; _romfsUnrecoverableDataCorruptionByRemountCount = 0; _romFsRecoveredByInvalidateCacheCount = 0; + _romFsUnrecoverableByGameCardAccessFailedCount = 0; + } + + public Result CreateNotifier(ref UniqueRef outNotifier) + { + throw new NotImplementedException(); + } + + public Result NotifySystemDataUpdateEvent() + { + throw new NotImplementedException(); } public Result OpenHostFileSystem(ref SharedRef outFileSystem, ref readonly Path rootPath, bool openCaseSensitive) { return _config.TargetManagerFsCreator.Create(ref outFileSystem, in rootPath, openCaseSensitive, false, - Result.Success); + Result.Success).Ret(); } internal Result GetProgramInfoByProcessId(out ProgramInfo programInfo, ulong processId) @@ -790,40 +509,16 @@ public class NcaFileSystemServiceImpl var registry = new ProgramRegistryImpl(_config.FsServer); return registry.GetProgramInfoByProgramId(out programInfo, programId); } - - private Result GetPartitionIndex(out int index, FileSystemProxyType fspType) - { - switch (fspType) - { - case FileSystemProxyType.Code: - case FileSystemProxyType.Control: - case FileSystemProxyType.Manual: - case FileSystemProxyType.Meta: - case FileSystemProxyType.Data: - index = 0; - return Result.Success; - case FileSystemProxyType.Rom: - case FileSystemProxyType.RegisteredUpdate: - index = 1; - return Result.Success; - case FileSystemProxyType.Logo: - index = 2; - return Result.Success; - default: - UnsafeHelpers.SkipParamInit(out index); - return ResultFs.InvalidArgument.Log(); - } - } } public readonly struct InternalProgramIdRangeForSpeedEmulation { - public readonly ulong ProgramIdMin; - public readonly ulong ProgramIdMax; + public readonly ulong ProgramIdWithoutPlatformIdMin; + public readonly ulong ProgramIdWithoutPlatformIdMax; public InternalProgramIdRangeForSpeedEmulation(ulong min, ulong max) { - ProgramIdMin = min; - ProgramIdMax = max; + ProgramIdWithoutPlatformIdMin = min; + ProgramIdWithoutPlatformIdMax = max; } } \ No newline at end of file diff --git a/src/LibHac/FsSrv/Sf/IFileSystemProxy.cs b/src/LibHac/FsSrv/Sf/IFileSystemProxy.cs index 59c346ee..3295fdff 100644 --- a/src/LibHac/FsSrv/Sf/IFileSystemProxy.cs +++ b/src/LibHac/FsSrv/Sf/IFileSystemProxy.cs @@ -13,14 +13,15 @@ namespace LibHac.FsSrv.Sf; /// /// The interface most programs use to interact with the FS service. /// -/// Based on nnSdk 14.3.0 (FS 14.1.0) +/// Based on nnSdk 17.5.0 (FS 17.0.0) public interface IFileSystemProxy : IDisposable { Result SetCurrentProcess(ulong processId); Result OpenDataFileSystemByCurrentProcess(ref SharedRef outFileSystem); Result OpenFileSystemWithPatch(ref SharedRef outFileSystem, ProgramId programId, FileSystemProxyType fsType); - Result OpenFileSystemWithId(ref SharedRef outFileSystem, ref readonly FspPath path, ulong id, FileSystemProxyType fsType); + Result OpenFileSystemWithIdObsolete(ref SharedRef outFileSystem, ref readonly FspPath path, ulong programId, FileSystemProxyType fsType); Result OpenDataFileSystemByProgramId(ref SharedRef outFileSystem, ProgramId programId); + Result OpenFileSystemWithId(ref SharedRef outFileSystem, ref readonly FspPath path, ContentAttributes attributes, ulong programId, FileSystemProxyType fsType); Result OpenBisFileSystem(ref SharedRef outFileSystem, ref readonly FspPath rootPath, BisPartitionId partitionId); Result OpenBisStorage(ref SharedRef outStorage, BisPartitionId partitionId); Result InvalidateBisCache(); @@ -72,15 +73,15 @@ public interface IFileSystemProxy : IDisposable Result OpenBaseFileSystem(ref SharedRef outFileSystem, BaseFileSystemId fileSystemId); Result FormatBaseFileSystem(BaseFileSystemId fileSystemId); Result OpenContentStorageFileSystem(ref SharedRef outFileSystem, ContentStorageId storageId); - Result OpenCloudBackupWorkStorageFileSystem(ref SharedRef outFileSystem, CloudBackupWorkStorageId storageId); Result OpenCustomStorageFileSystem(ref SharedRef outFileSystem, CustomStorageId storageId); Result OpenDataStorageByCurrentProcess(ref SharedRef outStorage); Result OpenDataStorageByProgramId(ref SharedRef outStorage, ProgramId programId); Result OpenDataStorageByDataId(ref SharedRef outStorage, DataId dataId, StorageId storageId); Result OpenPatchDataStorageByCurrentProcess(ref SharedRef outStorage); Result OpenDataFileSystemWithProgramIndex(ref SharedRef outFileSystem, byte programIndex); - Result OpenDataStorageByPath(ref SharedRef outFileSystem, ref readonly FspPath path, FileSystemProxyType fsType); Result OpenDataStorageWithProgramIndex(ref SharedRef outStorage, byte programIndex); + Result OpenDataStorageByPath(ref SharedRef outFileSystem, ref readonly FspPath path, ContentAttributes attributes, FileSystemProxyType fsType); + Result OpenDataFileSystemByDataId(ref SharedRef outFileSystem, DataId dataId, StorageId storageId); Result OpenDeviceOperator(ref SharedRef outDeviceOperator); Result OpenSdCardDetectionEventNotifier(ref SharedRef outEventNotifier); Result OpenGameCardDetectionEventNotifier(ref SharedRef outEventNotifier); @@ -95,8 +96,7 @@ public interface IFileSystemProxy : IDisposable Result GetRightsId(out RightsId rightsId, ProgramId programId, StorageId storageId); Result RegisterExternalKey(in RightsId rightsId, in AccessKey externalKey); Result UnregisterAllExternalKey(); - Result GetRightsIdByPath(out RightsId rightsId, ref readonly FspPath path); - Result GetRightsIdAndKeyGenerationByPath(out RightsId rightsId, out byte keyGeneration, ref readonly FspPath path); + Result GetRightsIdAndKeyGenerationByPath(out RightsId rightsId, out byte keyGeneration, ref readonly FspPath path, ContentAttributes attributes); Result SetCurrentPosixTimeWithTimeDifference(long currentTime, int timeDifference); Result GetFreeSpaceSizeForSaveData(out long freeSpaceSize, SaveDataSpaceId spaceId); Result VerifySaveDataFileSystemBySaveDataSpaceId(SaveDataSpaceId spaceId, ulong saveDataId, OutBuffer readBuffer); @@ -104,6 +104,7 @@ public interface IFileSystemProxy : IDisposable Result QuerySaveDataInternalStorageTotalSize(out long size, SaveDataSpaceId spaceId, ulong saveDataId); Result GetSaveDataCommitId(out long commitId, SaveDataSpaceId spaceId, ulong saveDataId); Result UnregisterExternalKey(in RightsId rightsId); + Result GetProgramId(out ProgramId outProgramId, ref readonly FspPath path, ContentAttributes attributes); Result SetSdCardEncryptionSeed(in EncryptionSeed seed); Result SetSdCardAccessibility(bool isAccessible); Result IsSdCardAccessible(out bool isAccessible); @@ -114,7 +115,6 @@ public interface IFileSystemProxy : IDisposable Result AbandonAccessFailure(ulong processId); Result GetAndClearErrorInfo(out FileSystemProxyErrorInfo errorInfo); Result RegisterProgramIndexMapInfo(InBuffer programIndexMapInfoBuffer, int programCount); - Result SetBisRootForHost(BisPartitionId partitionId, ref readonly FspPath path); Result SetSaveDataSize(long saveDataSize, long saveDataJournalSize); Result SetSaveDataRootPath(ref readonly FspPath path); Result DisableAutoSaveDataCreation(); @@ -136,4 +136,5 @@ public interface IFileSystemProxy : IDisposable Result CorruptSaveDataFileSystemByOffset(SaveDataSpaceId spaceId, ulong saveDataId, long offset); Result OpenMultiCommitManager(ref SharedRef outCommitManager); Result OpenBisWiper(ref SharedRef outBisWiper, NativeHandle transferMemoryHandle, ulong transferMemorySize); + Result NotifyErrorContextServiceReady(bool isReady); } \ No newline at end of file diff --git a/src/LibHac/FsSrv/Sf/IFileSystemProxyForLoader.cs b/src/LibHac/FsSrv/Sf/IFileSystemProxyForLoader.cs index 58e6f54e..3027dccd 100644 --- a/src/LibHac/FsSrv/Sf/IFileSystemProxyForLoader.cs +++ b/src/LibHac/FsSrv/Sf/IFileSystemProxyForLoader.cs @@ -2,14 +2,15 @@ using LibHac.Common; using LibHac.Fs; using LibHac.Ncm; +using LibHac.Sf; using IFileSystemSf = LibHac.FsSrv.Sf.IFileSystem; namespace LibHac.FsSrv.Sf; public interface IFileSystemProxyForLoader : IDisposable { - Result OpenCodeFileSystem(ref SharedRef fileSystem, - out CodeVerificationData verificationData, ref readonly FspPath path, ProgramId programId); + Result OpenCodeFileSystem(ref SharedRef fileSystem, OutBuffer outVerificationData, + ref readonly FspPath path, ContentAttributes attributes, ProgramId programId); Result IsArchivedProgram(out bool isArchived, ulong processId); Result SetCurrentProcess(ulong processId); diff --git a/src/LibHac/FsSrv/StatusReportService.cs b/src/LibHac/FsSrv/StatusReportService.cs index fcc96117..aed44c7f 100644 --- a/src/LibHac/FsSrv/StatusReportService.cs +++ b/src/LibHac/FsSrv/StatusReportService.cs @@ -76,15 +76,15 @@ public class StatusReportServiceImpl Assert.SdkRequiresNotNull(_config.NcaFileSystemServiceImpl); - _config.NcaFileSystemServiceImpl.GetAndClearRomFsErrorInfo(out errorInfo.RemountForDataCorruptionCount, - out errorInfo.UnrecoverableDataCorruptionByRemountCount, - out errorInfo.RecoveredByInvalidateCacheCount); + _config.NcaFileSystemServiceImpl.GetAndClearRomFsErrorInfo(out errorInfo.DeepRetryStartCount, + out errorInfo.RemountForDataCorruptionCount, out errorInfo.UnrecoverableDataCorruptionByRemountCount, + out errorInfo.RecoveredByInvalidateCacheCount, out errorInfo.UnrecoverableByGameCardAccessFailedCount); if (_config.FatFileSystemCreator is not null) { _config.FatFileSystemCreator.GetAndClearFatFsError(out errorInfo.FatFsError); - _config.FatFileSystemCreator.GetAndClearFatReportInfo(out errorInfo.BisSystemFatReportInfo, - out errorInfo.BisUserFatReport, out errorInfo.SdCardFatReport); + _config.FatFileSystemCreator.GetAndClearFatReportInfo(out errorInfo.BisSystemFatReportInfo1, + out errorInfo.BisUserFatReport1, out errorInfo.SdCardFatReport1); } Assert.SdkRequiresNotNull(_config.SaveDataFileSystemServiceImpl); diff --git a/src/LibHac/FsSystem/SubdirectoryFileSystem.cs b/src/LibHac/FsSystem/SubdirectoryFileSystem.cs index dd65e375..025f8afe 100644 --- a/src/LibHac/FsSystem/SubdirectoryFileSystem.cs +++ b/src/LibHac/FsSystem/SubdirectoryFileSystem.cs @@ -20,9 +20,9 @@ public class SubdirectoryFileSystem : IFileSystem _baseFileSystem = baseFileSystem; } - public SubdirectoryFileSystem(ref SharedRef baseFileSystem) + public SubdirectoryFileSystem(ref readonly SharedRef baseFileSystem) { - _baseFileSystemShared = SharedRef.CreateMove(ref baseFileSystem); + _baseFileSystemShared = SharedRef.CreateCopy(in baseFileSystem); _baseFileSystem = _baseFileSystemShared.Get; } diff --git a/src/LibHac/Htc/ResultHtc.cs b/src/LibHac/Htc/ResultHtc.cs new file mode 100644 index 00000000..eab2c9a8 --- /dev/null +++ b/src/LibHac/Htc/ResultHtc.cs @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------------- +// This file was automatically generated. +// Changes to this file will be lost when the file is regenerated. +// +// To change this file, modify /build/CodeGen/results.csv at the root of this +// repo and run the build script. +// +// The script can be run with the "codegen" option to run only the +// code generation portion of the build. +//----------------------------------------------------------------------------- + +namespace LibHac.Htc; + +public static class ResultHtc +{ + public const int ModuleHtc = 18; + + /// Error code: 2018-0001; Inner value: 0x212 + public static Result.Base ConnectionFailure => new Result.Base(ModuleHtc, 1); + /// Error code: 2018-0002; Inner value: 0x412 + public static Result.Base NotFound => new Result.Base(ModuleHtc, 2); + /// Error code: 2018-0003; Inner value: 0x612 + public static Result.Base NotEnoughBuffer => new Result.Base(ModuleHtc, 3); + /// Error code: 2018-0101; Inner value: 0xca12 + public static Result.Base Cancelled => new Result.Base(ModuleHtc, 101); + /// Error code: 2018-1023; Inner value: 0x7fe12 + public static Result.Base Result1023 => new Result.Base(ModuleHtc, 1023); + /// Error code: 2018-2001; Inner value: 0xfa212 + public static Result.Base Result2001 => new Result.Base(ModuleHtc, 2001); + /// Error code: 2018-2003; Inner value: 0xfa612 + public static Result.Base InvalidTaskId => new Result.Base(ModuleHtc, 2003); + /// Error code: 2018-2011; Inner value: 0xfb612 + public static Result.Base InvalidSize => new Result.Base(ModuleHtc, 2011); + /// Error code: 2018-2021; Inner value: 0xfca12 + public static Result.Base TaskCancelled => new Result.Base(ModuleHtc, 2021); + /// Error code: 2018-2022; Inner value: 0xfcc12 + public static Result.Base TaskNotCompleted => new Result.Base(ModuleHtc, 2022); + /// Error code: 2018-2023; Inner value: 0xfce12 + public static Result.Base TaskQueueNotAvailable => new Result.Base(ModuleHtc, 2023); + /// Error code: 2018-2101; Inner value: 0x106a12 + public static Result.Base Result2101 => new Result.Base(ModuleHtc, 2101); + /// Error code: 2018-2102; Inner value: 0x106c12 + public static Result.Base OutOfRpcTask => new Result.Base(ModuleHtc, 2102); + /// Error code: 2018-2123; Inner value: 0x109612 + public static Result.Base InvalidCategory => new Result.Base(ModuleHtc, 2123); +} \ No newline at end of file diff --git a/src/LibHac/HtcFs/ResultHtcFs.cs b/src/LibHac/HtcFs/ResultHtcFs.cs new file mode 100644 index 00000000..6badfac4 --- /dev/null +++ b/src/LibHac/HtcFs/ResultHtcFs.cs @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// This file was automatically generated. +// Changes to this file will be lost when the file is regenerated. +// +// To change this file, modify /build/CodeGen/results.csv at the root of this +// repo and run the build script. +// +// The script can be run with the "codegen" option to run only the +// code generation portion of the build. +//----------------------------------------------------------------------------- + +using System.Runtime.CompilerServices; + +namespace LibHac.HtcFs; + +public static class ResultHtcFs +{ + public const int ModuleHtcFs = 31; + + /// Error code: 2031-0003; Inner value: 0x61f + public static Result.Base InvalidArgument => new Result.Base(ModuleHtcFs, 3); + + /// Error code: 2031-0100; Range: 100-199; Inner value: 0xc81f + public static Result.Base ConnectionFailure => new Result.Base(ModuleHtcFs, 100, 199); + /// Error code: 2031-0101; Inner value: 0xca1f + public static Result.Base HtclowChannelClosed => new Result.Base(ModuleHtcFs, 101); + + /// Error code: 2031-0110; Range: 110-119; Inner value: 0xdc1f + public static Result.Base UnexpectedResponse => new Result.Base(ModuleHtcFs, 110, 119); + /// Error code: 2031-0111; Inner value: 0xde1f + public static Result.Base UnexpectedResponseProtocolId => new Result.Base(ModuleHtcFs, 111); + /// Error code: 2031-0112; Inner value: 0xe01f + public static Result.Base UnexpectedResponseProtocolVersion => new Result.Base(ModuleHtcFs, 112); + /// Error code: 2031-0113; Inner value: 0xe21f + public static Result.Base UnexpectedResponsePacketCategory => new Result.Base(ModuleHtcFs, 113); + /// Error code: 2031-0114; Inner value: 0xe41f + public static Result.Base UnexpectedResponsePacketType => new Result.Base(ModuleHtcFs, 114); + /// Error code: 2031-0115; Inner value: 0xe61f + public static Result.Base UnexpectedResponseBodySize => new Result.Base(ModuleHtcFs, 115); + /// Error code: 2031-0116; Inner value: 0xe81f + public static Result.Base UnexpectedResponseBody => new Result.Base(ModuleHtcFs, 116); + + /// Error code: 2031-0200; Range: 200-299; Inner value: 0x1901f + public static Result.Base InternalError { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleHtcFs, 200, 299); } + /// Error code: 2031-0201; Inner value: 0x1921f + public static Result.Base InvalidSize => new Result.Base(ModuleHtcFs, 201); + /// Error code: 2031-0211; Inner value: 0x1a61f + public static Result.Base UnknownError => new Result.Base(ModuleHtcFs, 211); + /// Error code: 2031-0212; Inner value: 0x1a81f + public static Result.Base UnsupportedProtocolVersion => new Result.Base(ModuleHtcFs, 212); + /// Error code: 2031-0213; Inner value: 0x1aa1f + public static Result.Base InvalidRequest => new Result.Base(ModuleHtcFs, 213); + /// Error code: 2031-0214; Inner value: 0x1ac1f + public static Result.Base InvalidHandle => new Result.Base(ModuleHtcFs, 214); + /// Error code: 2031-0215; Inner value: 0x1ae1f + public static Result.Base OutOfHandle => new Result.Base(ModuleHtcFs, 215); +} \ No newline at end of file diff --git a/src/LibHac/HtcLow/ResultHtcLow.cs b/src/LibHac/HtcLow/ResultHtcLow.cs new file mode 100644 index 00000000..9ef0d228 --- /dev/null +++ b/src/LibHac/HtcLow/ResultHtcLow.cs @@ -0,0 +1,116 @@ +//----------------------------------------------------------------------------- +// This file was automatically generated. +// Changes to this file will be lost when the file is regenerated. +// +// To change this file, modify /build/CodeGen/results.csv at the root of this +// repo and run the build script. +// +// The script can be run with the "codegen" option to run only the +// code generation portion of the build. +//----------------------------------------------------------------------------- + +using System.Runtime.CompilerServices; + +namespace LibHac.HtcLow; + +public static class ResultHtcLow +{ + public const int ModuleHtcLow = 29; + + /// Error code: 2029-0001; Inner value: 0x21d + public static Result.Base ConnectionFailure => new Result.Base(ModuleHtcLow, 1); + /// Error code: 2029-0003; Inner value: 0x61d + public static Result.Base UnknownDriverType => new Result.Base(ModuleHtcLow, 3); + /// Error code: 2029-0005; Inner value: 0xa1d + public static Result.Base NonBlockingReceiveFailed => new Result.Base(ModuleHtcLow, 5); + /// Error code: 2029-0008; Inner value: 0x101d + public static Result.Base ChannelWaitCancelled => new Result.Base(ModuleHtcLow, 8); + /// Error code: 2029-0009; Inner value: 0x121d + public static Result.Base ChannelAlreadyExist => new Result.Base(ModuleHtcLow, 9); + /// Error code: 2029-0010; Inner value: 0x141d + public static Result.Base ChannelNotExist => new Result.Base(ModuleHtcLow, 10); + /// Error code: 2029-0151; Inner value: 0x12e1d + public static Result.Base OutOfChannel => new Result.Base(ModuleHtcLow, 151); + /// Error code: 2029-0152; Inner value: 0x1301d + public static Result.Base OutOfTask => new Result.Base(ModuleHtcLow, 152); + /// Error code: 2029-0200; Inner value: 0x1901d + public static Result.Base InvalidChannelState => new Result.Base(ModuleHtcLow, 200); + /// Error code: 2029-0201; Inner value: 0x1921d + public static Result.Base InvalidChannelStateDisconnected => new Result.Base(ModuleHtcLow, 201); + + /// Error code: 2029-1000; Range: 1000-2999; Inner value: 0x7d01d + public static Result.Base InternalError { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleHtcLow, 1000, 2999); } + /// Error code: 2029-1001; Inner value: 0x7d21d + public static Result.Base Overflow => new Result.Base(ModuleHtcLow, 1001); + /// Error code: 2029-1002; Inner value: 0x7d41d + public static Result.Base OutOfMemory => new Result.Base(ModuleHtcLow, 1002); + /// Error code: 2029-1003; Inner value: 0x7d61d + public static Result.Base InvalidArgument => new Result.Base(ModuleHtcLow, 1003); + /// Error code: 2029-1004; Inner value: 0x7d81d + public static Result.Base ProtocolError => new Result.Base(ModuleHtcLow, 1004); + /// Error code: 2029-1005; Inner value: 0x7da1d + public static Result.Base Cancelled => new Result.Base(ModuleHtcLow, 1005); + + /// Error code: 2029-1100; Range: 1100-1199; Inner value: 0x8981d + public static Result.Base MuxError { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleHtcLow, 1100, 1199); } + /// Error code: 2029-1101; Inner value: 0x89a1d + public static Result.Base ChannelBufferOverflow => new Result.Base(ModuleHtcLow, 1101); + /// Error code: 2029-1102; Inner value: 0x89c1d + public static Result.Base ChannelBufferHasNotEnoughData => new Result.Base(ModuleHtcLow, 1102); + /// Error code: 2029-1103; Inner value: 0x89e1d + public static Result.Base ChannelVersionNotMatched => new Result.Base(ModuleHtcLow, 1103); + /// Error code: 2029-1104; Inner value: 0x8a01d + public static Result.Base ChannelStateTransitionError => new Result.Base(ModuleHtcLow, 1104); + /// Error code: 2029-1106; Inner value: 0x8a41d + public static Result.Base ChannelReceiveBufferEmpty => new Result.Base(ModuleHtcLow, 1106); + /// Error code: 2029-1107; Inner value: 0x8a61d + public static Result.Base ChannelSequenceIdNotMatched => new Result.Base(ModuleHtcLow, 1107); + /// Error code: 2029-1108; Inner value: 0x8a81d + public static Result.Base ChannelCannotDiscard => new Result.Base(ModuleHtcLow, 1108); + + /// Error code: 2029-1200; Range: 1200-1999; Inner value: 0x9601d + public static Result.Base DriverError { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleHtcLow, 1200, 1999); } + /// Error code: 2029-1201; Inner value: 0x9621d + public static Result.Base DriverOpened => new Result.Base(ModuleHtcLow, 1201); + + /// Error code: 2029-1300; Range: 1300-1399; Inner value: 0xa281d + public static Result.Base SocketDriverError { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleHtcLow, 1300, 1399); } + /// Error code: 2029-1301; Inner value: 0xa2a1d + public static Result.Base SocketSocketExemptError => new Result.Base(ModuleHtcLow, 1301); + /// Error code: 2029-1302; Inner value: 0xa2c1d + public static Result.Base SocketBindError => new Result.Base(ModuleHtcLow, 1302); + /// Error code: 2029-1304; Inner value: 0xa301d + public static Result.Base SocketListenError => new Result.Base(ModuleHtcLow, 1304); + /// Error code: 2029-1305; Inner value: 0xa321d + public static Result.Base SocketAcceptError => new Result.Base(ModuleHtcLow, 1305); + /// Error code: 2029-1306; Inner value: 0xa341d + public static Result.Base SocketReceiveError => new Result.Base(ModuleHtcLow, 1306); + /// Error code: 2029-1307; Inner value: 0xa361d + public static Result.Base SocketSendError => new Result.Base(ModuleHtcLow, 1307); + /// Error code: 2029-1308; Inner value: 0xa381d + public static Result.Base SocketReceiveFromError => new Result.Base(ModuleHtcLow, 1308); + /// Error code: 2029-1309; Inner value: 0xa3a1d + public static Result.Base SocketSendToError => new Result.Base(ModuleHtcLow, 1309); + /// Error code: 2029-1310; Inner value: 0xa3c1d + public static Result.Base SocketSetSockOptError => new Result.Base(ModuleHtcLow, 1310); + /// Error code: 2029-1311; Inner value: 0xa3e1d + public static Result.Base SocketGetSockNameError => new Result.Base(ModuleHtcLow, 1311); + + /// Error code: 2029-1400; Range: 1400-1499; Inner value: 0xaf01d + public static Result.Base UsbDriverError { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleHtcLow, 1400, 1499); } + /// Error code: 2029-1401; Inner value: 0xaf21d + public static Result.Base UsbDriverUnknownError => new Result.Base(ModuleHtcLow, 1401); + /// Error code: 2029-1402; Inner value: 0xaf41d + public static Result.Base UsbDriverBusyError => new Result.Base(ModuleHtcLow, 1402); + /// Error code: 2029-1403; Inner value: 0xaf61d + public static Result.Base UsbDriverReceiveError => new Result.Base(ModuleHtcLow, 1403); + /// Error code: 2029-1404; Inner value: 0xaf81d + public static Result.Base UsbDriverSendError => new Result.Base(ModuleHtcLow, 1404); + + /// Error code: 2029-2000; Inner value: 0xfa01d + public static Result.Base HtcctrlError => new Result.Base(ModuleHtcLow, 2000); + /// Error code: 2029-2001; Inner value: 0xfa21d + public static Result.Base HtcctrlStateTransitionNotAllowed => new Result.Base(ModuleHtcLow, 2001); + /// Error code: 2029-2002; Inner value: 0xfa41d + public static Result.Base HtcctrlReceiveUnexpectedPacket => new Result.Base(ModuleHtcLow, 2002); +} \ No newline at end of file diff --git a/tests/LibHac.Tests/Fs/TypeLayoutTests.cs b/tests/LibHac.Tests/Fs/TypeLayoutTests.cs index 77079e00..2cc07bda 100644 --- a/tests/LibHac.Tests/Fs/TypeLayoutTests.cs +++ b/tests/LibHac.Tests/Fs/TypeLayoutTests.cs @@ -240,10 +240,17 @@ public class TypeLayoutTests Assert.Equal(0x08, GetOffset(in s, in s.FatFsError)); Assert.Equal(0x28, GetOffset(in s, in s.RecoveredByInvalidateCacheCount)); Assert.Equal(0x2C, GetOffset(in s, in s.SaveDataIndexCount)); - Assert.Equal(0x30, GetOffset(in s, in s.BisSystemFatReportInfo)); - Assert.Equal(0x34, GetOffset(in s, in s.BisUserFatReport)); - Assert.Equal(0x38, GetOffset(in s, in s.SdCardFatReport)); - Assert.Equal(0x3C, GetOffset(in s, in s.Reserved)); + Assert.Equal(0x30, GetOffset(in s, in s.BisSystemFatReportInfo1)); + Assert.Equal(0x34, GetOffset(in s, in s.BisUserFatReport1)); + Assert.Equal(0x38, GetOffset(in s, in s.SdCardFatReport1)); + Assert.Equal(0x3C, GetOffset(in s, in s.BisSystemFatReportInfo2)); + Assert.Equal(0x40, GetOffset(in s, in s.BisUserFatReport2)); + Assert.Equal(0x44, GetOffset(in s, in s.SdCardFatReport2)); + Assert.Equal(0x48, GetOffset(in s, in s.DeepRetryStartCount)); + Assert.Equal(0x4C, GetOffset(in s, in s.UnrecoverableByGameCardAccessFailedCount)); + Assert.Equal(0x50, GetOffset(in s, in s.BisSystemFatSafeInfo)); + Assert.Equal(0x5C, GetOffset(in s, in s.BisUserFatSafeInfo)); + Assert.Equal(0x68, GetOffset(in s, in s.Reserved)); } [Fact] diff --git a/tests/LibHac.Tests/FsSrv/AccessControlTests.cs b/tests/LibHac.Tests/FsSrv/AccessControlTests.cs index fd9df95d..fa415cdb 100644 --- a/tests/LibHac.Tests/FsSrv/AccessControlTests.cs +++ b/tests/LibHac.Tests/FsSrv/AccessControlTests.cs @@ -31,7 +31,7 @@ public class AccessControlTests StorageId.BuiltInUser, SpanHelpers.AsReadOnlyByteSpan(in dataHeader), SpanHelpers.AsReadOnlyByteSpan(in descriptor))); - Result res = client.Fs.MountContent("test"u8, "@System:/fake.nca"u8, ContentType.Meta); + Result res = client.Fs.MountContent("test"u8, "@System:/fake.nca"u8, ContentAttributes.None, ContentType.Meta); Assert.Result(ResultFs.PermissionDenied, res); } @@ -57,7 +57,7 @@ public class AccessControlTests SpanHelpers.AsReadOnlyByteSpan(in descriptor))); // We should get UnexpectedInNcaFileSystemServiceImplA because mounting NCAs from @System isn't allowed - Result res = client.Fs.MountContent("test"u8, "@System:/fake.nca"u8, ContentType.Meta); + Result res = client.Fs.MountContent("test"u8, "@System:/fake.nca"u8, ContentAttributes.None, ContentType.Meta); Assert.Result(ResultFs.UnexpectedInNcaFileSystemServiceImplA, res); } } \ No newline at end of file