Update FileSystemProxyImpl

This commit is contained in:
Alex Barney 2024-03-31 23:27:06 -07:00
parent 7f7c8b6578
commit 27cc721b31
37 changed files with 1146 additions and 936 deletions

View file

@ -15,16 +15,16 @@ Tma,,
Dnmt,, Dnmt,,
Pm,, Pm,,
Ns,, Ns,,
Htc,, Htc,,Htc/ResultHtc.cs
Kvdb,,Kvdb/ResultKvdb.cs Kvdb,,Kvdb/ResultKvdb.cs
Sm,,Sm/ResultSm.cs Sm,,Sm/ResultSm.cs
Ro,, Ro,,
Sdmmc,,Sdmmc/ResultSdmmc.cs Sdmmc,,Sdmmc/ResultSdmmc.cs
Spl,,Spl/ResultSpl.cs Spl,,Spl/ResultSpl.cs
Socket,, Socket,,
HtcLow,, HtcLow,,HtcLow/ResultHtcLow.cs
Ddsf,, Ddsf,,
HtcFs,, HtcFs,,HtcFs/ResultHtcFs.cs
I2C,, I2C,,
Gpio,, Gpio,,
Settings,, Settings,,

1 Namespace Class Name Path
15 Dnmt
16 Pm
17 Ns
18 Htc Htc/ResultHtc.cs
19 Kvdb Kvdb/ResultKvdb.cs
20 Sm Sm/ResultSm.cs
21 Ro
22 Sdmmc Sdmmc/ResultSdmmc.cs
23 Spl Spl/ResultSpl.cs
24 Socket
25 HtcLow HtcLow/ResultHtcLow.cs
26 Ddsf
27 HtcFs HtcFs/ResultHtcFs.cs
28 I2C
29 Gpio
30 Settings

View file

@ -8,8 +8,14 @@ public struct FatReport
public ushort DirectoryPeakOpenCount; public ushort DirectoryPeakOpenCount;
} }
public struct FatReportInfo public struct FatReportInfo1
{ {
public ushort FilePeakOpenCount; public ushort FilePeakOpenCount;
public ushort DirectoryPeakOpenCount; public ushort DirectoryPeakOpenCount;
}
public struct FatReportInfo2
{
public ushort OpenUniqueFileEntryPeakCount;
public ushort OpenUniqueDirectoryEntryPeakCount;
} }

View file

@ -0,0 +1,8 @@
namespace LibHac.Fat;
public struct FatSafeInfo
{
public uint Result;
public uint ErrorNumber;
public uint SafeErrorNumber;
}

View file

@ -165,6 +165,14 @@ public ref struct Path
return Result.Success; return Result.Success;
} }
public Result InitializeAsEmpty()
{
_buffer = EmptyBuffer;
_length = 0;
return Result.Success;
}
public readonly int GetLength() => _length; public readonly int GetLength() => _length;
public readonly ReadOnlySpan<byte> GetString() => _buffer; public readonly ReadOnlySpan<byte> GetString() => _buffer;

View file

@ -5,21 +5,28 @@ namespace LibHac.Fs;
public struct FileSystemProxyErrorInfo public struct FileSystemProxyErrorInfo
{ {
public int RemountForDataCorruptionCount; public uint RemountForDataCorruptionCount;
public int UnrecoverableDataCorruptionByRemountCount; public uint UnrecoverableDataCorruptionByRemountCount;
public FatError FatFsError; public FatError FatFsError;
public int RecoveredByInvalidateCacheCount; public uint RecoveredByInvalidateCacheCount;
public int SaveDataIndexCount; public int SaveDataIndexCount;
public FatReportInfo BisSystemFatReportInfo; public FatReportInfo1 BisSystemFatReportInfo1;
public FatReportInfo BisUserFatReport; public FatReportInfo1 BisUserFatReport1;
public FatReportInfo SdCardFatReport; public FatReportInfo1 SdCardFatReport1;
public Array68<byte> Reserved; public FatReportInfo2 BisSystemFatReportInfo2;
public FatReportInfo2 BisUserFatReport2;
public FatReportInfo2 SdCardFatReport2;
public uint DeepRetryStartCount;
public uint UnrecoverableByGameCardAccessFailedCount;
public FatSafeInfo BisSystemFatSafeInfo;
public FatSafeInfo BisUserFatSafeInfo;
public Array24<byte> Reserved;
} }
public struct StorageErrorInfo public struct StorageErrorInfo
{ {
public int NumActivationFailures; public uint NumActivationFailures;
public int NumActivationErrorCorrections; public uint NumActivationErrorCorrections;
public int NumReadWriteFailures; public uint NumReadWriteFailures;
public int NumReadWriteErrorCorrections; public uint NumReadWriteErrorCorrections;
} }

View file

@ -1,5 +1,9 @@
using System.Runtime.CompilerServices; using System;
using System.Runtime.CompilerServices;
using LibHac.Diag; using LibHac.Diag;
using LibHac.Htc;
using LibHac.HtcFs;
using LibHac.HtcLow;
namespace LibHac.Fs; namespace LibHac.Fs;
@ -75,4 +79,23 @@ public static class ResultHandlingUtility
if (!result.IsSuccess()) if (!result.IsSuccess())
Abort.DoAbort(result); 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
}
} }

View file

@ -60,7 +60,7 @@ public static class Application
using SharedRef<IFileSystemProxy> fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject(); using SharedRef<IFileSystemProxy> fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject();
using var fileSystem = new SharedRef<IFileSystemSf>(); using var fileSystem = new SharedRef<IFileSystemSf>();
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); Ncm.ProgramId.InvalidId.Value, FileSystemProxyType.Package);
if (res.IsFailure()) return res.Miss(); if (res.IsFailure()) return res.Miss();

View file

@ -6,6 +6,7 @@ using LibHac.Fs.Impl;
using LibHac.FsSrv.Sf; using LibHac.FsSrv.Sf;
using LibHac.Ncm; using LibHac.Ncm;
using LibHac.Os; using LibHac.Os;
using LibHac.Sf;
using static LibHac.Fs.Impl.AccessLogStrings; using static LibHac.Fs.Impl.AccessLogStrings;
using IFileSystem = LibHac.Fs.Fsa.IFileSystem; using IFileSystem = LibHac.Fs.Fsa.IFileSystem;
using IFileSystemSf = LibHac.FsSrv.Sf.IFileSystem; using IFileSystemSf = LibHac.FsSrv.Sf.IFileSystem;
@ -20,13 +21,13 @@ namespace LibHac.Fs.Shim;
public static class Code public static class Code
{ {
public static Result MountCode(this FileSystemClient fs, out CodeVerificationData verificationData, 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; Result res;
if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System)) if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System))
{ {
Tick start = fs.Hos.Os.GetSystemTick(); 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(); Tick end = fs.Hos.Os.GetSystemTick();
Span<byte> logBuffer = stackalloc byte[0x300]; Span<byte> logBuffer = stackalloc byte[0x300];
@ -40,7 +41,7 @@ public static class Code
} }
else else
{ {
res = Mount(fs, out verificationData, mountName, path, programId); res = Mount(fs, out verificationData, mountName, path, attributes, programId);
} }
fs.Impl.AbortIfNeeded(res); fs.Impl.AbortIfNeeded(res);
@ -52,7 +53,7 @@ public static class Code
return Result.Success; return Result.Success;
static Result Mount(FileSystemClient fs, out CodeVerificationData verificationData, 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); UnsafeHelpers.SkipParamInit(out verificationData);
@ -71,8 +72,8 @@ public static class Code
using var fileSystem = new SharedRef<IFileSystemSf>(); using var fileSystem = new SharedRef<IFileSystemSf>();
res = fileSystemProxy.Get.OpenCodeFileSystem(ref fileSystem.Ref, out verificationData, in sfPath, res = fileSystemProxy.Get.OpenCodeFileSystem(ref fileSystem.Ref, OutBuffer.FromStruct(ref verificationData),
programId); in sfPath, attributes, programId);
if (res.IsFailure()) return res.Miss(); if (res.IsFailure()) return res.Miss();
using var fileSystemAdapter = using var fileSystemAdapter =

View file

@ -34,8 +34,8 @@ public static class Content
} }
} }
private static Result MountContentImpl(FileSystemClient fs, U8Span mountName, U8Span path, ulong id, private static Result MountContentImpl(FileSystemClient fs, U8Span mountName, U8Span path,
ContentType contentType) ContentAttributes attributes, ulong id, ContentType contentType)
{ {
Result res = fs.Impl.CheckMountNameAcceptingReservedMountName(mountName); Result res = fs.Impl.CheckMountNameAcceptingReservedMountName(mountName);
if (res.IsFailure()) return res.Miss(); if (res.IsFailure()) return res.Miss();
@ -48,7 +48,7 @@ public static class Content
using SharedRef<IFileSystemProxy> fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject(); using SharedRef<IFileSystemProxy> fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject();
using var fileSystem = new SharedRef<IFileSystemSf>(); using var fileSystem = new SharedRef<IFileSystemSf>();
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(); if (res.IsFailure()) return res.Miss();
using var fileSystemAdapter = using var fileSystemAdapter =
@ -63,7 +63,8 @@ public static class Content
return Result.Success; 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; Result res;
Span<byte> logBuffer = stackalloc byte[0x300]; Span<byte> logBuffer = stackalloc byte[0x300];
@ -96,7 +97,7 @@ public static class Content
if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System)) if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System))
{ {
Tick start = fs.Hos.Os.GetSystemTick(); 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(); Tick end = fs.Hos.Os.GetSystemTick();
var idString = new IdString(); var idString = new IdString();
@ -111,7 +112,7 @@ public static class Content
} }
else else
{ {
res = MountContentImpl(fs, mountName, path, programId.Value, contentType); res = MountContentImpl(fs, mountName, path, attributes, programId.Value, contentType);
} }
fs.Impl.AbortIfNeeded(res); 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, public static Result MountContent(this FileSystemClient fs, U8Span mountName, U8Span path,
ContentType contentType) ContentAttributes attributes, ProgramId programId, ContentType contentType)
{ {
Result res; Result res;
Span<byte> logBuffer = stackalloc byte[0x300]; Span<byte> logBuffer = stackalloc byte[0x300];
@ -140,7 +141,7 @@ public static class Content
if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System)) if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System))
{ {
Tick start = fs.Hos.Os.GetSystemTick(); 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(); Tick end = fs.Hos.Os.GetSystemTick();
var idString = new IdString(); var idString = new IdString();
@ -157,7 +158,7 @@ public static class Content
} }
else else
{ {
res = MountContentImpl(fs, mountName, path, programId.Value, contentType); res = MountContentImpl(fs, mountName, path, attributes, programId.Value, contentType);
} }
fs.Impl.AbortIfNeeded(res); fs.Impl.AbortIfNeeded(res);
@ -169,8 +170,8 @@ public static class Content
return Result.Success; return Result.Success;
} }
public static Result MountContent(this FileSystemClient fs, U8Span mountName, U8Span path, DataId dataId, public static Result MountContent(this FileSystemClient fs, U8Span mountName, U8Span path,
ContentType contentType) ContentAttributes attributes, DataId dataId, ContentType contentType)
{ {
Result res; Result res;
Span<byte> logBuffer = stackalloc byte[0x300]; Span<byte> logBuffer = stackalloc byte[0x300];
@ -178,7 +179,7 @@ public static class Content
if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System)) if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System))
{ {
Tick start = fs.Hos.Os.GetSystemTick(); 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(); Tick end = fs.Hos.Os.GetSystemTick();
var idString = new IdString(); var idString = new IdString();
@ -193,7 +194,7 @@ public static class Content
} }
else else
{ {
res = MountContentImpl(fs, mountName, path, dataId.Value, contentType); res = MountContentImpl(fs, mountName, path, attributes, dataId.Value, contentType);
} }
fs.Impl.AbortIfNeeded(res); fs.Impl.AbortIfNeeded(res);

View file

@ -17,7 +17,8 @@ namespace LibHac.Fs.Shim;
/// <remarks>Based on nnSdk 14.3.0</remarks> /// <remarks>Based on nnSdk 14.3.0</remarks>
public static class Logo 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; Result res;
Span<byte> logBuffer = stackalloc byte[0x300]; Span<byte> logBuffer = stackalloc byte[0x300];
@ -25,7 +26,7 @@ public static class Logo
if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System)) if (fs.Impl.IsEnabledAccessLog(AccessLogTarget.System))
{ {
Tick start = fs.Hos.Os.GetSystemTick(); 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(); Tick end = fs.Hos.Os.GetSystemTick();
var sb = new U8StringBuilder(logBuffer, true); var sb = new U8StringBuilder(logBuffer, true);
@ -38,7 +39,7 @@ public static class Logo
} }
else else
{ {
res = Mount(fs, mountName, path, programId); res = Mount(fs, mountName, path, attributes, programId);
} }
fs.Impl.AbortIfNeeded(res); fs.Impl.AbortIfNeeded(res);
@ -49,7 +50,7 @@ public static class Logo
return Result.Success; 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); Result res = fs.Impl.CheckMountName(mountName);
if (res.IsFailure()) return res.Miss(); if (res.IsFailure()) return res.Miss();
@ -60,7 +61,7 @@ public static class Logo
using SharedRef<IFileSystemProxy> fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject(); using SharedRef<IFileSystemProxy> fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject();
using var fileSystem = new SharedRef<IFileSystemSf>(); using var fileSystem = new SharedRef<IFileSystemSf>();
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); FileSystemProxyType.Logo);
if (res.IsFailure()) return res.Miss(); if (res.IsFailure()) return res.Miss();

View file

@ -23,24 +23,13 @@ public static class RightsIdShim
return Result.Success; 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); return GetRightsId(fs, out rightsId, out _, path, attributes);
Result res = PathUtility.ConvertToFspPath(out FspPath sfPath, path);
fs.Impl.AbortIfNeeded(res);
if (res.IsFailure()) return res.Miss();
using SharedRef<IFileSystemProxy> 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;
} }
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); UnsafeHelpers.SkipParamInit(out rightsId, out keyGeneration);
@ -50,7 +39,7 @@ public static class RightsIdShim
using SharedRef<IFileSystemProxy> fileSystemProxy = fs.Impl.GetFileSystemProxyServiceObject(); using SharedRef<IFileSystemProxy> 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); fs.Impl.AbortIfNeeded(res);
if (res.IsFailure()) return res.Miss(); if (res.IsFailure()) return res.Miss();

View file

@ -150,11 +150,6 @@ public readonly struct BaseFileSystemService
return Result.Success; return Result.Success;
} }
public Result SetBisRootForHost(BisPartitionId partitionId, ref readonly FspPath path)
{
throw new NotImplementedException();
}
public Result CreatePaddingFile(long size) public Result CreatePaddingFile(long size)
{ {
// File size must be non-negative // File size must be non-negative

File diff suppressed because it is too large Load diff

View file

@ -125,7 +125,7 @@ public static class FileSystemServerInitializer
ncaFsServiceConfig.SpeedEmulationRange = speedEmulationRange; ncaFsServiceConfig.SpeedEmulationRange = speedEmulationRange;
ncaFsServiceConfig.FsServer = server; ncaFsServiceConfig.FsServer = server;
var ncaFsService = new NcaFileSystemServiceImpl(in ncaFsServiceConfig, config.ExternalKeySet); var ncaFsService = new NcaFileSystemServiceImpl(in ncaFsServiceConfig);
var saveFsServiceConfig = new SaveDataFileSystemServiceImpl.Configuration(); var saveFsServiceConfig = new SaveDataFileSystemServiceImpl.Configuration();
saveFsServiceConfig.BaseFsService = baseFsService; saveFsServiceConfig.BaseFsService = baseFsService;

View file

@ -51,17 +51,17 @@ public class FatFileSystemCreator : IFatFileSystemCreator
_fatFsError = default; _fatFsError = default;
} }
public void GetAndClearFatReportInfo(out FatReportInfo outBisSystemFatReportInfo, public void GetAndClearFatReportInfo(out FatReportInfo1 outBisSystemFatReportInfo1,
out FatReportInfo outBisUserFatReportInfo, out FatReportInfo outSdCardFatReportInfo) out FatReportInfo1 outBisUserFatReportInfo1, out FatReportInfo1 outSdCardFatReportInfo1)
{ {
using var scopedLock = new ScopedLock<SdkMutexType>(ref _fatReportMutex); using var scopedLock = new ScopedLock<SdkMutexType>(ref _fatReportMutex);
outBisSystemFatReportInfo.FilePeakOpenCount = _bisSystemReport.FilePeakOpenCount; outBisSystemFatReportInfo1.FilePeakOpenCount = _bisSystemReport.FilePeakOpenCount;
outBisSystemFatReportInfo.DirectoryPeakOpenCount = _bisSystemReport.DirectoryPeakOpenCount; outBisSystemFatReportInfo1.DirectoryPeakOpenCount = _bisSystemReport.DirectoryPeakOpenCount;
outBisUserFatReportInfo.FilePeakOpenCount = _bisUserReport.FilePeakOpenCount; outBisUserFatReportInfo1.FilePeakOpenCount = _bisUserReport.FilePeakOpenCount;
outBisUserFatReportInfo.DirectoryPeakOpenCount = _bisUserReport.DirectoryPeakOpenCount; outBisUserFatReportInfo1.DirectoryPeakOpenCount = _bisUserReport.DirectoryPeakOpenCount;
outSdCardFatReportInfo.FilePeakOpenCount = _sdCardReport.FilePeakOpenCount; outSdCardFatReportInfo1.FilePeakOpenCount = _sdCardReport.FilePeakOpenCount;
outSdCardFatReportInfo.DirectoryPeakOpenCount = _sdCardReport.DirectoryPeakOpenCount; outSdCardFatReportInfo1.DirectoryPeakOpenCount = _sdCardReport.DirectoryPeakOpenCount;
_bisSystemReport.FilePeakOpenCount = _bisSystemReport.FileCurrentOpenCount; _bisSystemReport.FilePeakOpenCount = _bisSystemReport.FileCurrentOpenCount;
_bisSystemReport.DirectoryPeakOpenCount = _bisSystemReport.DirectoryCurrentOpenCount; _bisSystemReport.DirectoryPeakOpenCount = _bisSystemReport.DirectoryCurrentOpenCount;

View file

@ -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<IFileSystem> outFileSystem, ref readonly SharedRef<IStorage> baseStorage);
}

View file

@ -6,5 +6,5 @@ namespace LibHac.FsSrv.FsCreator;
public interface ISubDirectoryFileSystemCreator public interface ISubDirectoryFileSystemCreator
{ {
Result Create(ref SharedRef<IFileSystem> outSubDirFileSystem, ref SharedRef<IFileSystem> baseFileSystem, ref readonly Path path); Result Create(ref SharedRef<IFileSystem> outSubDirFileSystem, ref readonly SharedRef<IFileSystem> baseFileSystem, ref readonly Path path);
} }

View file

@ -7,7 +7,7 @@ namespace LibHac.FsSrv.FsCreator;
public class SubDirectoryFileSystemCreator : ISubDirectoryFileSystemCreator public class SubDirectoryFileSystemCreator : ISubDirectoryFileSystemCreator
{ {
public Result Create(ref SharedRef<IFileSystem> outSubDirFileSystem, ref SharedRef<IFileSystem> baseFileSystem, public Result Create(ref SharedRef<IFileSystem> outSubDirFileSystem, ref readonly SharedRef<IFileSystem> baseFileSystem,
ref readonly Path path) ref readonly Path path)
{ {
using var directory = new UniqueRef<IDirectory>(); using var directory = new UniqueRef<IDirectory>();
@ -17,7 +17,7 @@ public class SubDirectoryFileSystemCreator : ISubDirectoryFileSystemCreator
directory.Reset(); directory.Reset();
using var subFs = new SharedRef<SubdirectoryFileSystem>(new SubdirectoryFileSystem(ref baseFileSystem)); using var subFs = new SharedRef<SubdirectoryFileSystem>(new SubdirectoryFileSystem(in baseFileSystem));
if (!subFs.HasValue) if (!subFs.HasValue)
return ResultFs.AllocationMemoryFailedInSubDirectoryFileSystemCreatorA.Log(); return ResultFs.AllocationMemoryFailedInSubDirectoryFileSystemCreatorA.Log();

View file

@ -498,6 +498,10 @@ public class AccessControl
return accessBits.CanSetDebugConfiguration(); return accessBits.CanSetDebugConfiguration();
case OperationType.OpenDataStorageByPath: case OperationType.OpenDataStorageByPath:
return accessBits.CanOpenDataStorageByPath(); return accessBits.CanOpenDataStorageByPath();
case OperationType.NotifyErrorContextServiceReady:
return accessBits.CanNotifyErrorContextServiceReady();
case OperationType.GetProgramId:
return accessBits.CanGetProgramId();
default: default:
Abort.UnexpectedDefault(); Abort.UnexpectedDefault();
return default; return default;
@ -593,6 +597,8 @@ public readonly struct AccessControlBits
RegisterProgramIndexMapInfo = 1UL << 34, RegisterProgramIndexMapInfo = 1UL << 34,
CreateOwnSaveData = 1UL << 35, CreateOwnSaveData = 1UL << 35,
MoveCacheStorage = 1UL << 36, MoveCacheStorage = 1UL << 36,
DeviceTreeBlob = 1UL << 37,
NotifyErrorContextServiceReady = 1UL << 38,
Debug = 1UL << 62, Debug = 1UL << 62,
FullPermission = 1UL << 63 FullPermission = 1UL << 63
} }
@ -630,6 +636,7 @@ public readonly struct AccessControlBits
public bool CanGetGameCardAsicInfo() => Has(Bits.GameCardPrivate); public bool CanGetGameCardAsicInfo() => Has(Bits.GameCardPrivate);
public bool CanGetGameCardDeviceCertificate() => Has(Bits.GameCard); public bool CanGetGameCardDeviceCertificate() => Has(Bits.GameCard);
public bool CanGetGameCardIdSet() => Has(Bits.GameCard); public bool CanGetGameCardIdSet() => Has(Bits.GameCard);
public bool CanGetProgramId() => Has(Bits.GetRightsId);
public bool CanGetRightsId() => Has(Bits.GetRightsId); public bool CanGetRightsId() => Has(Bits.GetRightsId);
public bool CanGetSaveDataCommitId() => Has(Bits.SaveDataTransferVersion2 | Bits.SaveDataBackUp); public bool CanGetSaveDataCommitId() => Has(Bits.SaveDataTransferVersion2 | Bits.SaveDataBackUp);
public bool CanInvalidateBisCache() => Has(Bits.BisAllRaw); public bool CanInvalidateBisCache() => Has(Bits.BisAllRaw);
@ -682,6 +689,7 @@ public readonly struct AccessControlBits
public bool CanMountSystemSaveDataWrite() => Has(Bits.SaveDataBackUp | Bits.SystemSaveData); public bool CanMountSystemSaveDataWrite() => Has(Bits.SaveDataBackUp | Bits.SystemSaveData);
public bool CanMountTemporaryDirectoryRead() => Has(Bits.Debug); public bool CanMountTemporaryDirectoryRead() => Has(Bits.Debug);
public bool CanMountTemporaryDirectoryWrite() => Has(Bits.Debug); public bool CanMountTemporaryDirectoryWrite() => Has(Bits.Debug);
public bool CanNotifyErrorContextServiceReady() => Has(Bits.NotifyErrorContextServiceReady);
public bool CanNotifySystemDataUpdateEvent() => Has(Bits.SystemUpdate); public bool CanNotifySystemDataUpdateEvent() => Has(Bits.SystemUpdate);
public bool CanOpenAccessFailureDetectionEventNotifier() => Has(Bits.AccessFailureResolution); public bool CanOpenAccessFailureDetectionEventNotifier() => Has(Bits.AccessFailureResolution);
public bool CanOpenBisPartitionBootConfigAndPackage2Part1Read() => Has(Bits.SystemUpdate | Bits.BisAllRaw); public bool CanOpenBisPartitionBootConfigAndPackage2Part1Read() => Has(Bits.SystemUpdate | Bits.BisAllRaw);
@ -870,7 +878,9 @@ public enum OperationType
FindOwnSaveDataWithFilter, FindOwnSaveDataWithFilter,
OpenSaveDataTransferManagerForRepair, OpenSaveDataTransferManagerForRepair,
SetDebugConfiguration, SetDebugConfiguration,
OpenDataStorageByPath OpenDataStorageByPath,
NotifyErrorContextServiceReady,
GetProgramId
} }
public enum AccessibilityType public enum AccessibilityType

View file

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

View file

@ -47,11 +47,9 @@ public static class FileSystemProxyServiceObject
return ResultFs.PortAcceptableCountLimited.Log(); return ResultFs.PortAcceptableCountLimited.Log();
} }
public Result OpenCodeFileSystem(ref SharedRef<IFileSystem> fileSystem, public Result OpenCodeFileSystem(ref SharedRef<IFileSystem> fileSystem, OutBuffer outVerificationData,
out CodeVerificationData verificationData, ref readonly FspPath path, ProgramId programId) ref readonly FspPath path, ContentAttributes attributes, ProgramId programId)
{ {
UnsafeHelpers.SkipParamInit(out verificationData);
return ResultFs.PortAcceptableCountLimited.Log(); return ResultFs.PortAcceptableCountLimited.Log();
} }

View file

@ -8,9 +8,11 @@ namespace LibHac.FsSrv.Impl;
public interface IRomFileSystemAccessFailureManager : IDisposable public interface IRomFileSystemAccessFailureManager : IDisposable
{ {
Result OpenDataStorageCore(ref SharedRef<IStorage> outStorage, out Hash ncaHeaderDigest, ulong id, StorageId storageId); Result OpenDataStorageCore(ref SharedRef<IStorage> outStorage, ref SharedRef<IAsynchronousAccessSplitter> outStorageAccessSplitter, out Hash ncaHeaderDigest, ulong id, StorageId storageId);
Result HandleResolubleAccessFailure(out bool wasDeferred, Result resultForNoFailureDetected); Result HandleResolubleAccessFailure(out bool wasDeferred, Result nonDeferredResult);
void IncrementRomFsDeepRetryStartCount();
void IncrementRomFsRemountForDataCorruptionCount(); void IncrementRomFsRemountForDataCorruptionCount();
void IncrementRomFsUnrecoverableDataCorruptionByRemountCount(); void IncrementRomFsUnrecoverableDataCorruptionByRemountCount();
void IncrementRomFsRecoveredByInvalidateCacheCount(); void IncrementRomFsRecoveredByInvalidateCacheCount();
void IncrementRomFsUnrecoverableByGameCardAccessFailedCount();
} }

View file

@ -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<SystemDataUpdateEventNotifier> outNotifier)
{
throw new NotImplementedException();
}
public Result NotifySystemDataUpdateEvent()
{
throw new NotImplementedException();
}
public void DeleteNotifier(SystemDataUpdateEventNotifier notifier)
{
throw new NotImplementedException();
}
}

View file

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

View file

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

View file

@ -70,4 +70,10 @@ internal static class Utility
Crypto.Sha256.GenerateSha256Hash(SpanHelpers.AsReadOnlyByteSpan(in extraData), hash); Crypto.Sha256.GenerateSha256Hash(SpanHelpers.AsReadOnlyByteSpan(in extraData), hash);
return BitConverter.ToInt64(hash); return BitConverter.ToInt64(hash);
} }
public static ulong ClearPlatformIdInProgramId(ulong programId)
{
const ulong clearPlatformIdMask = 0x_00FF_FFFF_FFFF_FFFF;
return programId & clearPlatformIdMask;
}
} }

View file

@ -8,6 +8,7 @@ using LibHac.FsSrv.Sf;
using LibHac.FsSystem; using LibHac.FsSystem;
using LibHac.Lr; using LibHac.Lr;
using LibHac.Ncm; using LibHac.Ncm;
using LibHac.Sf;
using LibHac.Spl; using LibHac.Spl;
using IFileSystem = LibHac.Fs.Fsa.IFileSystem; using IFileSystem = LibHac.Fs.Fsa.IFileSystem;
using IStorage = LibHac.Fs.IStorage; using IStorage = LibHac.Fs.IStorage;
@ -22,12 +23,14 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
{ {
private const int AocSemaphoreCount = 128; private const int AocSemaphoreCount = 128;
private const int RomSemaphoreCount = 10; private const int RomSemaphoreCount = 10;
private const int RomDivisionSizeUnitCountSemaphoreCount = 128;
private WeakRef<NcaFileSystemService> _selfReference; private WeakRef<NcaFileSystemService> _selfReference;
private NcaFileSystemServiceImpl _serviceImpl; private NcaFileSystemServiceImpl _serviceImpl;
private ulong _processId; private ulong _processId;
private SemaphoreAdapter _aocMountCountSemaphore; private SemaphoreAdapter _aocMountCountSemaphore;
private SemaphoreAdapter _romMountCountSemaphore; private SemaphoreAdapter _romMountCountSemaphore;
private SemaphoreAdapter _romDivisionSizeUnitCountSemaphore;
private NcaFileSystemService(NcaFileSystemServiceImpl serviceImpl, ulong processId) private NcaFileSystemService(NcaFileSystemServiceImpl serviceImpl, ulong processId)
{ {
@ -35,6 +38,7 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
_processId = processId; _processId = processId;
_aocMountCountSemaphore = new SemaphoreAdapter(AocSemaphoreCount, AocSemaphoreCount); _aocMountCountSemaphore = new SemaphoreAdapter(AocSemaphoreCount, AocSemaphoreCount);
_romMountCountSemaphore = new SemaphoreAdapter(RomSemaphoreCount, RomSemaphoreCount); _romMountCountSemaphore = new SemaphoreAdapter(RomSemaphoreCount, RomSemaphoreCount);
_romDivisionSizeUnitCountSemaphore = new SemaphoreAdapter(RomDivisionSizeUnitCountSemaphoreCount, RomDivisionSizeUnitCountSemaphoreCount);
} }
public static SharedRef<NcaFileSystemService> CreateShared(NcaFileSystemServiceImpl serviceImpl, public static SharedRef<NcaFileSystemService> CreateShared(NcaFileSystemServiceImpl serviceImpl,
@ -54,22 +58,26 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
{ {
_aocMountCountSemaphore?.Dispose(); _aocMountCountSemaphore?.Dispose();
_romMountCountSemaphore?.Dispose(); _romMountCountSemaphore?.Dispose();
_romDivisionSizeUnitCountSemaphore?.Dispose();
_selfReference.Destroy(); _selfReference.Destroy();
} }
private Result GetProgramInfo(out ProgramInfo programInfo) 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) 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) 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<IFileSystemSf> outFileSystem, ProgramId programId, public Result OpenFileSystemWithPatch(ref SharedRef<IFileSystemSf> outFileSystem, ProgramId programId,
@ -110,7 +118,8 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
// Try to find the path to the original version of the file system // Try to find the path to the original version of the file system
using var originalPath = new Path(); using var originalPath = new Path();
Result originalResult = _serviceImpl.ResolveApplicationHtmlDocumentPath(out bool isDirectory, 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 // The file system might have a patch version with no original version, so continue if not found
if (originalResult.IsFailure() && !ResultLr.HtmlDocumentNotFound.Includes(originalResult)) 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 // Try to find the path to the patch file system
using var patchPath = new Path(); 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<IFileSystem>(); using var fileSystem = new SharedRef<IFileSystem>();
@ -129,7 +139,7 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
return originalResult; return originalResult;
// There is an original version and no patch version. Open the original directly // 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); isDirectory);
if (res.IsFailure()) return res.Miss(); if (res.IsFailure()) return res.Miss();
} }
@ -143,8 +153,8 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
: ref PathExtensions.GetNullRef(); : ref PathExtensions.GetNullRef();
// Open the file system using both the original and patch versions // Open the file system using both the original and patch versions
res = _serviceImpl.OpenFileSystemWithPatch(ref fileSystem.Ref, in originalNcaPath, in patchPath, res = _serviceImpl.OpenFileSystemWithPatch(ref fileSystem.Ref, in originalNcaPath, contentAttributes,
fsType, programId.Value); in patchPath, patchContentAttributes, fsType, originalProgramId, programId.Value);
if (res.IsFailure()) return res.Miss(); if (res.IsFailure()) return res.Miss();
} }
@ -169,8 +179,8 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
return Result.Success; return Result.Success;
} }
public Result OpenCodeFileSystem(ref SharedRef<IFileSystemSf> outFileSystem, public Result OpenCodeFileSystem(ref SharedRef<IFileSystemSf> outFileSystem, OutBuffer outVerificationData,
out CodeVerificationData verificationData, ref readonly FspPath path, ProgramId programId) ref readonly FspPath path, ContentAttributes attributes, ProgramId programId)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -181,21 +191,32 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
} }
public Result OpenDataStorageByPath(ref SharedRef<IFileSystemSf> outFileSystem, ref readonly FspPath path, public Result OpenDataStorageByPath(ref SharedRef<IFileSystemSf> outFileSystem, ref readonly FspPath path,
FileSystemProxyType fsType) ContentAttributes attributes, FileSystemProxyType fsType)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
private Result TryAcquireAddOnContentOpenCountSemaphore(ref UniqueRef<IUniqueLock> outSemaphoreLock) private Result TryAcquireAddOnContentDivisionSizeUnitCountSemaphore(ref UniqueRef<IUniqueLock> outSemaphore, IStorage storage)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
private Result TryAcquireRomMountCountSemaphore(ref UniqueRef<IUniqueLock> outSemaphoreLock) private Result TryAcquireRomMountCountSemaphore(ref UniqueRef<IUniqueLock> outSemaphore)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
private Result TryAcquireRomDivisionSizeUnitCountSemaphore(ref UniqueRef<IUniqueLock> outSemaphore,
ref UniqueRef<IUniqueLock> mountCountSemaphore, IStorage storage)
{
throw new NotImplementedException();
}
public void IncrementRomFsDeepRetryStartCount()
{
_serviceImpl.IncrementRomFsRemountForDataCorruptionCount();
}
public void IncrementRomFsRemountForDataCorruptionCount() public void IncrementRomFsRemountForDataCorruptionCount()
{ {
_serviceImpl.IncrementRomFsRemountForDataCorruptionCount(); _serviceImpl.IncrementRomFsRemountForDataCorruptionCount();
@ -211,8 +232,14 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
_serviceImpl.IncrementRomFsRecoveredByInvalidateCacheCount(); _serviceImpl.IncrementRomFsRecoveredByInvalidateCacheCount();
} }
private Result OpenDataStorageCore(ref SharedRef<IStorage> outStorage, out Hash ncaHeaderDigest, public void IncrementRomFsUnrecoverableByGameCardAccessFailedCount()
ulong id, StorageId storageId) {
_serviceImpl.IncrementRomFsRecoveredByInvalidateCacheCount();
}
private Result OpenDataStorageCore(ref SharedRef<IStorage> outStorage,
ref SharedRef<IAsynchronousAccessSplitter> outStorageAccessSplitter, out Hash ncaHeaderDigest, ulong id,
StorageId storageId)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -227,8 +254,14 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
throw new NotImplementedException(); throw new NotImplementedException();
} }
public Result OpenFileSystemWithId(ref SharedRef<IFileSystemSf> outFileSystem, ref readonly FspPath path, public Result OpenDataStorageByPath(ref SharedRef<IStorageSf> outStorage, in FspPath path,
ulong id, FileSystemProxyType fsType) ContentAttributes attributes, FileSystemProxyType fspType)
{
throw new NotImplementedException();
}
public Result OpenFileSystemWithId(ref SharedRef<IFileSystemSf> outFileSystem, in FspPath path,
ContentAttributes attributes, ulong id, FileSystemProxyType fsType)
{ {
const StorageLayoutType storageFlag = StorageLayoutType.All; const StorageLayoutType storageFlag = StorageLayoutType.All;
using var scopedContext = new ScopedStorageLayoutTypeSetter(storageFlag); using var scopedContext = new ScopedStorageLayoutTypeSetter(storageFlag);
@ -292,7 +325,7 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
bool isDirectory = PathUtility.IsDirectoryPath(in path); bool isDirectory = PathUtility.IsDirectoryPath(in path);
using var fileSystem = new SharedRef<IFileSystem>(); using var fileSystem = new SharedRef<IFileSystem>();
res = _serviceImpl.OpenFileSystem(ref fileSystem.Ref, in pathNormalized, fsType, canMountSystemDataPrivate, res = _serviceImpl.OpenFileSystem(ref fileSystem.Ref, in pathNormalized, default, fsType, canMountSystemDataPrivate,
id, isDirectory); id, isDirectory);
if (res.IsFailure()) return res.Miss(); if (res.IsFailure()) return res.Miss();
@ -321,6 +354,16 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
throw new NotImplementedException(); throw new NotImplementedException();
} }
public Result OpenDataFileSystemByDataId(ref SharedRef<IFileSystemSf> outFileSystem, DataId dataId, StorageId storageId)
{
throw new NotImplementedException();
}
public Result OpenPatchDataStorageByCurrentProcess(ref SharedRef<IStorageSf> outStorage)
{
throw new NotImplementedException();
}
public Result OpenDataFileSystemWithProgramIndex(ref SharedRef<IFileSystemSf> outFileSystem, byte programIndex) public Result OpenDataFileSystemWithProgramIndex(ref SharedRef<IFileSystemSf> outFileSystem, byte programIndex)
{ {
Result res = GetProgramInfo(out ProgramInfo programInfo); Result res = GetProgramInfo(out ProgramInfo programInfo);
@ -372,13 +415,14 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
return ResultFs.PermissionDenied.Log(); return ResultFs.PermissionDenied.Log();
using var programPath = new Path(); 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 (res.IsFailure()) return res.Miss();
if (isDirectory) if (isDirectory)
return ResultFs.TargetNotFound.Log(); 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(); if (res.IsFailure()) return res.Miss();
outRightsId = rightsId; outRightsId = rightsId;
@ -386,7 +430,8 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
return Result.Success; 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; const ulong checkThroughProgramId = ulong.MaxValue;
UnsafeHelpers.SkipParamInit(out outRightsId, out outKeyGeneration); UnsafeHelpers.SkipParamInit(out outRightsId, out outKeyGeneration);
@ -412,7 +457,7 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
if (PathUtility.IsDirectoryPath(in path)) if (PathUtility.IsDirectoryPath(in path))
return ResultFs.TargetNotFound.Log(); 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)); new ProgramId(checkThroughProgramId));
if (res.IsFailure()) return res.Miss(); if (res.IsFailure()) return res.Miss();
@ -422,9 +467,14 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
return Result.Success; return Result.Success;
} }
public Result GetProgramId(out ProgramId outProgramId, ref readonly FspPath path, ContentAttributes attributes)
{
throw new NotImplementedException();
}
// ReSharper disable once OutParameterValueIsAlwaysDiscarded.Local // ReSharper disable once OutParameterValueIsAlwaysDiscarded.Local
private Result OpenDataFileSystemCore(ref SharedRef<IFileSystem> outFileSystem, out bool isHostFs, private Result OpenDataFileSystemCore(ref SharedRef<IFileSystem> outFileSystem, out bool isHostFs, ulong programId,
ulong programId, StorageId storageId) StorageId storageId)
{ {
UnsafeHelpers.SkipParamInit(out isHostFs); UnsafeHelpers.SkipParamInit(out isHostFs);
@ -432,13 +482,14 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
using var scopedContext = new ScopedStorageLayoutTypeSetter(storageFlag); using var scopedContext = new ScopedStorageLayoutTypeSetter(storageFlag);
using var programPath = new Path(); 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(); if (res.IsFailure()) return res.Miss();
isHostFs = Utility.IsHostFsMountName(programPath.GetString()); isHostFs = Utility.IsHostFsMountName(programPath.GetString());
using var fileSystem = new SharedRef<IFileSystem>(); using var fileSystem = new SharedRef<IFileSystem>();
res = _serviceImpl.OpenDataFileSystem(ref fileSystem.Ref, in programPath, FileSystemProxyType.Rom, res = _serviceImpl.OpenDataFileSystem(ref fileSystem.Ref, in programPath, contentAttributes, FileSystemProxyType.Rom,
programId, isDirectory); programId, isDirectory);
if (res.IsFailure()) return res.Miss(); if (res.IsFailure()) return res.Miss();
@ -529,10 +580,11 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
ulong targetProgramId = programInfo.ProgramIdValue; ulong targetProgramId = programInfo.ProgramIdValue;
using var programPath = new Path(); 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(); if (res.IsFailure()) return res.Miss();
return _serviceImpl.RegisterUpdatePartition(targetProgramId, in programPath); return _serviceImpl.RegisterUpdatePartition(targetProgramId, in programPath, contentAttributes);
} }
public Result OpenRegisteredUpdatePartition(ref SharedRef<IFileSystemSf> outFileSystem) public Result OpenRegisteredUpdatePartition(ref SharedRef<IFileSystemSf> outFileSystem)
@ -583,6 +635,11 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
return _serviceImpl.SetSdCardEncryptionSeed(in encryptionSeed); return _serviceImpl.SetSdCardEncryptionSeed(in encryptionSeed);
} }
public Result OpenHostFileSystem(ref SharedRef<IFileSystemSf> outFileSystem, ref readonly FspPath path)
{
throw new NotImplementedException();
}
public Result OpenSystemDataUpdateEventNotifier(ref SharedRef<IEventNotifier> outEventNotifier) public Result OpenSystemDataUpdateEventNotifier(ref SharedRef<IEventNotifier> outEventNotifier)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
@ -593,14 +650,15 @@ internal class NcaFileSystemService : IRomFileSystemAccessFailureManager
throw new NotImplementedException(); 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<IStorage> outStorage, Result IRomFileSystemAccessFailureManager.OpenDataStorageCore(ref SharedRef<IStorage> outStorage,
out Hash ncaHeaderDigest, ulong id, StorageId storageId) ref SharedRef<IAsynchronousAccessSplitter> 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();
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -13,14 +13,15 @@ namespace LibHac.FsSrv.Sf;
/// <summary> /// <summary>
/// The interface most programs use to interact with the FS service. /// The interface most programs use to interact with the FS service.
/// </summary> /// </summary>
/// <remarks>Based on nnSdk 14.3.0 (FS 14.1.0)</remarks> /// <remarks>Based on nnSdk 17.5.0 (FS 17.0.0)</remarks>
public interface IFileSystemProxy : IDisposable public interface IFileSystemProxy : IDisposable
{ {
Result SetCurrentProcess(ulong processId); Result SetCurrentProcess(ulong processId);
Result OpenDataFileSystemByCurrentProcess(ref SharedRef<IFileSystemSf> outFileSystem); Result OpenDataFileSystemByCurrentProcess(ref SharedRef<IFileSystemSf> outFileSystem);
Result OpenFileSystemWithPatch(ref SharedRef<IFileSystemSf> outFileSystem, ProgramId programId, FileSystemProxyType fsType); Result OpenFileSystemWithPatch(ref SharedRef<IFileSystemSf> outFileSystem, ProgramId programId, FileSystemProxyType fsType);
Result OpenFileSystemWithId(ref SharedRef<IFileSystemSf> outFileSystem, ref readonly FspPath path, ulong id, FileSystemProxyType fsType); Result OpenFileSystemWithIdObsolete(ref SharedRef<IFileSystemSf> outFileSystem, ref readonly FspPath path, ulong programId, FileSystemProxyType fsType);
Result OpenDataFileSystemByProgramId(ref SharedRef<IFileSystemSf> outFileSystem, ProgramId programId); Result OpenDataFileSystemByProgramId(ref SharedRef<IFileSystemSf> outFileSystem, ProgramId programId);
Result OpenFileSystemWithId(ref SharedRef<IFileSystemSf> outFileSystem, ref readonly FspPath path, ContentAttributes attributes, ulong programId, FileSystemProxyType fsType);
Result OpenBisFileSystem(ref SharedRef<IFileSystemSf> outFileSystem, ref readonly FspPath rootPath, BisPartitionId partitionId); Result OpenBisFileSystem(ref SharedRef<IFileSystemSf> outFileSystem, ref readonly FspPath rootPath, BisPartitionId partitionId);
Result OpenBisStorage(ref SharedRef<IStorageSf> outStorage, BisPartitionId partitionId); Result OpenBisStorage(ref SharedRef<IStorageSf> outStorage, BisPartitionId partitionId);
Result InvalidateBisCache(); Result InvalidateBisCache();
@ -72,15 +73,15 @@ public interface IFileSystemProxy : IDisposable
Result OpenBaseFileSystem(ref SharedRef<IFileSystemSf> outFileSystem, BaseFileSystemId fileSystemId); Result OpenBaseFileSystem(ref SharedRef<IFileSystemSf> outFileSystem, BaseFileSystemId fileSystemId);
Result FormatBaseFileSystem(BaseFileSystemId fileSystemId); Result FormatBaseFileSystem(BaseFileSystemId fileSystemId);
Result OpenContentStorageFileSystem(ref SharedRef<IFileSystemSf> outFileSystem, ContentStorageId storageId); Result OpenContentStorageFileSystem(ref SharedRef<IFileSystemSf> outFileSystem, ContentStorageId storageId);
Result OpenCloudBackupWorkStorageFileSystem(ref SharedRef<IFileSystemSf> outFileSystem, CloudBackupWorkStorageId storageId);
Result OpenCustomStorageFileSystem(ref SharedRef<IFileSystemSf> outFileSystem, CustomStorageId storageId); Result OpenCustomStorageFileSystem(ref SharedRef<IFileSystemSf> outFileSystem, CustomStorageId storageId);
Result OpenDataStorageByCurrentProcess(ref SharedRef<IStorageSf> outStorage); Result OpenDataStorageByCurrentProcess(ref SharedRef<IStorageSf> outStorage);
Result OpenDataStorageByProgramId(ref SharedRef<IStorageSf> outStorage, ProgramId programId); Result OpenDataStorageByProgramId(ref SharedRef<IStorageSf> outStorage, ProgramId programId);
Result OpenDataStorageByDataId(ref SharedRef<IStorageSf> outStorage, DataId dataId, StorageId storageId); Result OpenDataStorageByDataId(ref SharedRef<IStorageSf> outStorage, DataId dataId, StorageId storageId);
Result OpenPatchDataStorageByCurrentProcess(ref SharedRef<IStorageSf> outStorage); Result OpenPatchDataStorageByCurrentProcess(ref SharedRef<IStorageSf> outStorage);
Result OpenDataFileSystemWithProgramIndex(ref SharedRef<IFileSystemSf> outFileSystem, byte programIndex); Result OpenDataFileSystemWithProgramIndex(ref SharedRef<IFileSystemSf> outFileSystem, byte programIndex);
Result OpenDataStorageByPath(ref SharedRef<IFileSystemSf> outFileSystem, ref readonly FspPath path, FileSystemProxyType fsType);
Result OpenDataStorageWithProgramIndex(ref SharedRef<IStorageSf> outStorage, byte programIndex); Result OpenDataStorageWithProgramIndex(ref SharedRef<IStorageSf> outStorage, byte programIndex);
Result OpenDataStorageByPath(ref SharedRef<IFileSystemSf> outFileSystem, ref readonly FspPath path, ContentAttributes attributes, FileSystemProxyType fsType);
Result OpenDataFileSystemByDataId(ref SharedRef<IFileSystemSf> outFileSystem, DataId dataId, StorageId storageId);
Result OpenDeviceOperator(ref SharedRef<IDeviceOperator> outDeviceOperator); Result OpenDeviceOperator(ref SharedRef<IDeviceOperator> outDeviceOperator);
Result OpenSdCardDetectionEventNotifier(ref SharedRef<IEventNotifier> outEventNotifier); Result OpenSdCardDetectionEventNotifier(ref SharedRef<IEventNotifier> outEventNotifier);
Result OpenGameCardDetectionEventNotifier(ref SharedRef<IEventNotifier> outEventNotifier); Result OpenGameCardDetectionEventNotifier(ref SharedRef<IEventNotifier> outEventNotifier);
@ -95,8 +96,7 @@ public interface IFileSystemProxy : IDisposable
Result GetRightsId(out RightsId rightsId, ProgramId programId, StorageId storageId); Result GetRightsId(out RightsId rightsId, ProgramId programId, StorageId storageId);
Result RegisterExternalKey(in RightsId rightsId, in AccessKey externalKey); Result RegisterExternalKey(in RightsId rightsId, in AccessKey externalKey);
Result UnregisterAllExternalKey(); Result UnregisterAllExternalKey();
Result GetRightsIdByPath(out RightsId rightsId, ref readonly FspPath path); Result GetRightsIdAndKeyGenerationByPath(out RightsId rightsId, out byte keyGeneration, ref readonly FspPath path, ContentAttributes attributes);
Result GetRightsIdAndKeyGenerationByPath(out RightsId rightsId, out byte keyGeneration, ref readonly FspPath path);
Result SetCurrentPosixTimeWithTimeDifference(long currentTime, int timeDifference); Result SetCurrentPosixTimeWithTimeDifference(long currentTime, int timeDifference);
Result GetFreeSpaceSizeForSaveData(out long freeSpaceSize, SaveDataSpaceId spaceId); Result GetFreeSpaceSizeForSaveData(out long freeSpaceSize, SaveDataSpaceId spaceId);
Result VerifySaveDataFileSystemBySaveDataSpaceId(SaveDataSpaceId spaceId, ulong saveDataId, OutBuffer readBuffer); 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 QuerySaveDataInternalStorageTotalSize(out long size, SaveDataSpaceId spaceId, ulong saveDataId);
Result GetSaveDataCommitId(out long commitId, SaveDataSpaceId spaceId, ulong saveDataId); Result GetSaveDataCommitId(out long commitId, SaveDataSpaceId spaceId, ulong saveDataId);
Result UnregisterExternalKey(in RightsId rightsId); Result UnregisterExternalKey(in RightsId rightsId);
Result GetProgramId(out ProgramId outProgramId, ref readonly FspPath path, ContentAttributes attributes);
Result SetSdCardEncryptionSeed(in EncryptionSeed seed); Result SetSdCardEncryptionSeed(in EncryptionSeed seed);
Result SetSdCardAccessibility(bool isAccessible); Result SetSdCardAccessibility(bool isAccessible);
Result IsSdCardAccessible(out bool isAccessible); Result IsSdCardAccessible(out bool isAccessible);
@ -114,7 +115,6 @@ public interface IFileSystemProxy : IDisposable
Result AbandonAccessFailure(ulong processId); Result AbandonAccessFailure(ulong processId);
Result GetAndClearErrorInfo(out FileSystemProxyErrorInfo errorInfo); Result GetAndClearErrorInfo(out FileSystemProxyErrorInfo errorInfo);
Result RegisterProgramIndexMapInfo(InBuffer programIndexMapInfoBuffer, int programCount); Result RegisterProgramIndexMapInfo(InBuffer programIndexMapInfoBuffer, int programCount);
Result SetBisRootForHost(BisPartitionId partitionId, ref readonly FspPath path);
Result SetSaveDataSize(long saveDataSize, long saveDataJournalSize); Result SetSaveDataSize(long saveDataSize, long saveDataJournalSize);
Result SetSaveDataRootPath(ref readonly FspPath path); Result SetSaveDataRootPath(ref readonly FspPath path);
Result DisableAutoSaveDataCreation(); Result DisableAutoSaveDataCreation();
@ -136,4 +136,5 @@ public interface IFileSystemProxy : IDisposable
Result CorruptSaveDataFileSystemByOffset(SaveDataSpaceId spaceId, ulong saveDataId, long offset); Result CorruptSaveDataFileSystemByOffset(SaveDataSpaceId spaceId, ulong saveDataId, long offset);
Result OpenMultiCommitManager(ref SharedRef<IMultiCommitManager> outCommitManager); Result OpenMultiCommitManager(ref SharedRef<IMultiCommitManager> outCommitManager);
Result OpenBisWiper(ref SharedRef<IWiper> outBisWiper, NativeHandle transferMemoryHandle, ulong transferMemorySize); Result OpenBisWiper(ref SharedRef<IWiper> outBisWiper, NativeHandle transferMemoryHandle, ulong transferMemorySize);
Result NotifyErrorContextServiceReady(bool isReady);
} }

View file

@ -2,14 +2,15 @@
using LibHac.Common; using LibHac.Common;
using LibHac.Fs; using LibHac.Fs;
using LibHac.Ncm; using LibHac.Ncm;
using LibHac.Sf;
using IFileSystemSf = LibHac.FsSrv.Sf.IFileSystem; using IFileSystemSf = LibHac.FsSrv.Sf.IFileSystem;
namespace LibHac.FsSrv.Sf; namespace LibHac.FsSrv.Sf;
public interface IFileSystemProxyForLoader : IDisposable public interface IFileSystemProxyForLoader : IDisposable
{ {
Result OpenCodeFileSystem(ref SharedRef<IFileSystemSf> fileSystem, Result OpenCodeFileSystem(ref SharedRef<IFileSystemSf> fileSystem, OutBuffer outVerificationData,
out CodeVerificationData verificationData, ref readonly FspPath path, ProgramId programId); ref readonly FspPath path, ContentAttributes attributes, ProgramId programId);
Result IsArchivedProgram(out bool isArchived, ulong processId); Result IsArchivedProgram(out bool isArchived, ulong processId);
Result SetCurrentProcess(ulong processId); Result SetCurrentProcess(ulong processId);

View file

@ -76,15 +76,15 @@ public class StatusReportServiceImpl
Assert.SdkRequiresNotNull(_config.NcaFileSystemServiceImpl); Assert.SdkRequiresNotNull(_config.NcaFileSystemServiceImpl);
_config.NcaFileSystemServiceImpl.GetAndClearRomFsErrorInfo(out errorInfo.RemountForDataCorruptionCount, _config.NcaFileSystemServiceImpl.GetAndClearRomFsErrorInfo(out errorInfo.DeepRetryStartCount,
out errorInfo.UnrecoverableDataCorruptionByRemountCount, out errorInfo.RemountForDataCorruptionCount, out errorInfo.UnrecoverableDataCorruptionByRemountCount,
out errorInfo.RecoveredByInvalidateCacheCount); out errorInfo.RecoveredByInvalidateCacheCount, out errorInfo.UnrecoverableByGameCardAccessFailedCount);
if (_config.FatFileSystemCreator is not null) if (_config.FatFileSystemCreator is not null)
{ {
_config.FatFileSystemCreator.GetAndClearFatFsError(out errorInfo.FatFsError); _config.FatFileSystemCreator.GetAndClearFatFsError(out errorInfo.FatFsError);
_config.FatFileSystemCreator.GetAndClearFatReportInfo(out errorInfo.BisSystemFatReportInfo, _config.FatFileSystemCreator.GetAndClearFatReportInfo(out errorInfo.BisSystemFatReportInfo1,
out errorInfo.BisUserFatReport, out errorInfo.SdCardFatReport); out errorInfo.BisUserFatReport1, out errorInfo.SdCardFatReport1);
} }
Assert.SdkRequiresNotNull(_config.SaveDataFileSystemServiceImpl); Assert.SdkRequiresNotNull(_config.SaveDataFileSystemServiceImpl);

View file

@ -20,9 +20,9 @@ public class SubdirectoryFileSystem : IFileSystem
_baseFileSystem = baseFileSystem; _baseFileSystem = baseFileSystem;
} }
public SubdirectoryFileSystem(ref SharedRef<IFileSystem> baseFileSystem) public SubdirectoryFileSystem(ref readonly SharedRef<IFileSystem> baseFileSystem)
{ {
_baseFileSystemShared = SharedRef<IFileSystem>.CreateMove(ref baseFileSystem); _baseFileSystemShared = SharedRef<IFileSystem>.CreateCopy(in baseFileSystem);
_baseFileSystem = _baseFileSystemShared.Get; _baseFileSystem = _baseFileSystemShared.Get;
} }

View file

@ -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;
/// <summary>Error code: 2018-0001; Inner value: 0x212</summary>
public static Result.Base ConnectionFailure => new Result.Base(ModuleHtc, 1);
/// <summary>Error code: 2018-0002; Inner value: 0x412</summary>
public static Result.Base NotFound => new Result.Base(ModuleHtc, 2);
/// <summary>Error code: 2018-0003; Inner value: 0x612</summary>
public static Result.Base NotEnoughBuffer => new Result.Base(ModuleHtc, 3);
/// <summary>Error code: 2018-0101; Inner value: 0xca12</summary>
public static Result.Base Cancelled => new Result.Base(ModuleHtc, 101);
/// <summary>Error code: 2018-1023; Inner value: 0x7fe12</summary>
public static Result.Base Result1023 => new Result.Base(ModuleHtc, 1023);
/// <summary>Error code: 2018-2001; Inner value: 0xfa212</summary>
public static Result.Base Result2001 => new Result.Base(ModuleHtc, 2001);
/// <summary>Error code: 2018-2003; Inner value: 0xfa612</summary>
public static Result.Base InvalidTaskId => new Result.Base(ModuleHtc, 2003);
/// <summary>Error code: 2018-2011; Inner value: 0xfb612</summary>
public static Result.Base InvalidSize => new Result.Base(ModuleHtc, 2011);
/// <summary>Error code: 2018-2021; Inner value: 0xfca12</summary>
public static Result.Base TaskCancelled => new Result.Base(ModuleHtc, 2021);
/// <summary>Error code: 2018-2022; Inner value: 0xfcc12</summary>
public static Result.Base TaskNotCompleted => new Result.Base(ModuleHtc, 2022);
/// <summary>Error code: 2018-2023; Inner value: 0xfce12</summary>
public static Result.Base TaskQueueNotAvailable => new Result.Base(ModuleHtc, 2023);
/// <summary>Error code: 2018-2101; Inner value: 0x106a12</summary>
public static Result.Base Result2101 => new Result.Base(ModuleHtc, 2101);
/// <summary>Error code: 2018-2102; Inner value: 0x106c12</summary>
public static Result.Base OutOfRpcTask => new Result.Base(ModuleHtc, 2102);
/// <summary>Error code: 2018-2123; Inner value: 0x109612</summary>
public static Result.Base InvalidCategory => new Result.Base(ModuleHtc, 2123);
}

View file

@ -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;
/// <summary>Error code: 2031-0003; Inner value: 0x61f</summary>
public static Result.Base InvalidArgument => new Result.Base(ModuleHtcFs, 3);
/// <summary>Error code: 2031-0100; Range: 100-199; Inner value: 0xc81f</summary>
public static Result.Base ConnectionFailure => new Result.Base(ModuleHtcFs, 100, 199);
/// <summary>Error code: 2031-0101; Inner value: 0xca1f</summary>
public static Result.Base HtclowChannelClosed => new Result.Base(ModuleHtcFs, 101);
/// <summary>Error code: 2031-0110; Range: 110-119; Inner value: 0xdc1f</summary>
public static Result.Base UnexpectedResponse => new Result.Base(ModuleHtcFs, 110, 119);
/// <summary>Error code: 2031-0111; Inner value: 0xde1f</summary>
public static Result.Base UnexpectedResponseProtocolId => new Result.Base(ModuleHtcFs, 111);
/// <summary>Error code: 2031-0112; Inner value: 0xe01f</summary>
public static Result.Base UnexpectedResponseProtocolVersion => new Result.Base(ModuleHtcFs, 112);
/// <summary>Error code: 2031-0113; Inner value: 0xe21f</summary>
public static Result.Base UnexpectedResponsePacketCategory => new Result.Base(ModuleHtcFs, 113);
/// <summary>Error code: 2031-0114; Inner value: 0xe41f</summary>
public static Result.Base UnexpectedResponsePacketType => new Result.Base(ModuleHtcFs, 114);
/// <summary>Error code: 2031-0115; Inner value: 0xe61f</summary>
public static Result.Base UnexpectedResponseBodySize => new Result.Base(ModuleHtcFs, 115);
/// <summary>Error code: 2031-0116; Inner value: 0xe81f</summary>
public static Result.Base UnexpectedResponseBody => new Result.Base(ModuleHtcFs, 116);
/// <summary>Error code: 2031-0200; Range: 200-299; Inner value: 0x1901f</summary>
public static Result.Base InternalError { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleHtcFs, 200, 299); }
/// <summary>Error code: 2031-0201; Inner value: 0x1921f</summary>
public static Result.Base InvalidSize => new Result.Base(ModuleHtcFs, 201);
/// <summary>Error code: 2031-0211; Inner value: 0x1a61f</summary>
public static Result.Base UnknownError => new Result.Base(ModuleHtcFs, 211);
/// <summary>Error code: 2031-0212; Inner value: 0x1a81f</summary>
public static Result.Base UnsupportedProtocolVersion => new Result.Base(ModuleHtcFs, 212);
/// <summary>Error code: 2031-0213; Inner value: 0x1aa1f</summary>
public static Result.Base InvalidRequest => new Result.Base(ModuleHtcFs, 213);
/// <summary>Error code: 2031-0214; Inner value: 0x1ac1f</summary>
public static Result.Base InvalidHandle => new Result.Base(ModuleHtcFs, 214);
/// <summary>Error code: 2031-0215; Inner value: 0x1ae1f</summary>
public static Result.Base OutOfHandle => new Result.Base(ModuleHtcFs, 215);
}

View file

@ -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;
/// <summary>Error code: 2029-0001; Inner value: 0x21d</summary>
public static Result.Base ConnectionFailure => new Result.Base(ModuleHtcLow, 1);
/// <summary>Error code: 2029-0003; Inner value: 0x61d</summary>
public static Result.Base UnknownDriverType => new Result.Base(ModuleHtcLow, 3);
/// <summary>Error code: 2029-0005; Inner value: 0xa1d</summary>
public static Result.Base NonBlockingReceiveFailed => new Result.Base(ModuleHtcLow, 5);
/// <summary>Error code: 2029-0008; Inner value: 0x101d</summary>
public static Result.Base ChannelWaitCancelled => new Result.Base(ModuleHtcLow, 8);
/// <summary>Error code: 2029-0009; Inner value: 0x121d</summary>
public static Result.Base ChannelAlreadyExist => new Result.Base(ModuleHtcLow, 9);
/// <summary>Error code: 2029-0010; Inner value: 0x141d</summary>
public static Result.Base ChannelNotExist => new Result.Base(ModuleHtcLow, 10);
/// <summary>Error code: 2029-0151; Inner value: 0x12e1d</summary>
public static Result.Base OutOfChannel => new Result.Base(ModuleHtcLow, 151);
/// <summary>Error code: 2029-0152; Inner value: 0x1301d</summary>
public static Result.Base OutOfTask => new Result.Base(ModuleHtcLow, 152);
/// <summary>Error code: 2029-0200; Inner value: 0x1901d</summary>
public static Result.Base InvalidChannelState => new Result.Base(ModuleHtcLow, 200);
/// <summary>Error code: 2029-0201; Inner value: 0x1921d</summary>
public static Result.Base InvalidChannelStateDisconnected => new Result.Base(ModuleHtcLow, 201);
/// <summary>Error code: 2029-1000; Range: 1000-2999; Inner value: 0x7d01d</summary>
public static Result.Base InternalError { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleHtcLow, 1000, 2999); }
/// <summary>Error code: 2029-1001; Inner value: 0x7d21d</summary>
public static Result.Base Overflow => new Result.Base(ModuleHtcLow, 1001);
/// <summary>Error code: 2029-1002; Inner value: 0x7d41d</summary>
public static Result.Base OutOfMemory => new Result.Base(ModuleHtcLow, 1002);
/// <summary>Error code: 2029-1003; Inner value: 0x7d61d</summary>
public static Result.Base InvalidArgument => new Result.Base(ModuleHtcLow, 1003);
/// <summary>Error code: 2029-1004; Inner value: 0x7d81d</summary>
public static Result.Base ProtocolError => new Result.Base(ModuleHtcLow, 1004);
/// <summary>Error code: 2029-1005; Inner value: 0x7da1d</summary>
public static Result.Base Cancelled => new Result.Base(ModuleHtcLow, 1005);
/// <summary>Error code: 2029-1100; Range: 1100-1199; Inner value: 0x8981d</summary>
public static Result.Base MuxError { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleHtcLow, 1100, 1199); }
/// <summary>Error code: 2029-1101; Inner value: 0x89a1d</summary>
public static Result.Base ChannelBufferOverflow => new Result.Base(ModuleHtcLow, 1101);
/// <summary>Error code: 2029-1102; Inner value: 0x89c1d</summary>
public static Result.Base ChannelBufferHasNotEnoughData => new Result.Base(ModuleHtcLow, 1102);
/// <summary>Error code: 2029-1103; Inner value: 0x89e1d</summary>
public static Result.Base ChannelVersionNotMatched => new Result.Base(ModuleHtcLow, 1103);
/// <summary>Error code: 2029-1104; Inner value: 0x8a01d</summary>
public static Result.Base ChannelStateTransitionError => new Result.Base(ModuleHtcLow, 1104);
/// <summary>Error code: 2029-1106; Inner value: 0x8a41d</summary>
public static Result.Base ChannelReceiveBufferEmpty => new Result.Base(ModuleHtcLow, 1106);
/// <summary>Error code: 2029-1107; Inner value: 0x8a61d</summary>
public static Result.Base ChannelSequenceIdNotMatched => new Result.Base(ModuleHtcLow, 1107);
/// <summary>Error code: 2029-1108; Inner value: 0x8a81d</summary>
public static Result.Base ChannelCannotDiscard => new Result.Base(ModuleHtcLow, 1108);
/// <summary>Error code: 2029-1200; Range: 1200-1999; Inner value: 0x9601d</summary>
public static Result.Base DriverError { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleHtcLow, 1200, 1999); }
/// <summary>Error code: 2029-1201; Inner value: 0x9621d</summary>
public static Result.Base DriverOpened => new Result.Base(ModuleHtcLow, 1201);
/// <summary>Error code: 2029-1300; Range: 1300-1399; Inner value: 0xa281d</summary>
public static Result.Base SocketDriverError { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleHtcLow, 1300, 1399); }
/// <summary>Error code: 2029-1301; Inner value: 0xa2a1d</summary>
public static Result.Base SocketSocketExemptError => new Result.Base(ModuleHtcLow, 1301);
/// <summary>Error code: 2029-1302; Inner value: 0xa2c1d</summary>
public static Result.Base SocketBindError => new Result.Base(ModuleHtcLow, 1302);
/// <summary>Error code: 2029-1304; Inner value: 0xa301d</summary>
public static Result.Base SocketListenError => new Result.Base(ModuleHtcLow, 1304);
/// <summary>Error code: 2029-1305; Inner value: 0xa321d</summary>
public static Result.Base SocketAcceptError => new Result.Base(ModuleHtcLow, 1305);
/// <summary>Error code: 2029-1306; Inner value: 0xa341d</summary>
public static Result.Base SocketReceiveError => new Result.Base(ModuleHtcLow, 1306);
/// <summary>Error code: 2029-1307; Inner value: 0xa361d</summary>
public static Result.Base SocketSendError => new Result.Base(ModuleHtcLow, 1307);
/// <summary>Error code: 2029-1308; Inner value: 0xa381d</summary>
public static Result.Base SocketReceiveFromError => new Result.Base(ModuleHtcLow, 1308);
/// <summary>Error code: 2029-1309; Inner value: 0xa3a1d</summary>
public static Result.Base SocketSendToError => new Result.Base(ModuleHtcLow, 1309);
/// <summary>Error code: 2029-1310; Inner value: 0xa3c1d</summary>
public static Result.Base SocketSetSockOptError => new Result.Base(ModuleHtcLow, 1310);
/// <summary>Error code: 2029-1311; Inner value: 0xa3e1d</summary>
public static Result.Base SocketGetSockNameError => new Result.Base(ModuleHtcLow, 1311);
/// <summary>Error code: 2029-1400; Range: 1400-1499; Inner value: 0xaf01d</summary>
public static Result.Base UsbDriverError { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleHtcLow, 1400, 1499); }
/// <summary>Error code: 2029-1401; Inner value: 0xaf21d</summary>
public static Result.Base UsbDriverUnknownError => new Result.Base(ModuleHtcLow, 1401);
/// <summary>Error code: 2029-1402; Inner value: 0xaf41d</summary>
public static Result.Base UsbDriverBusyError => new Result.Base(ModuleHtcLow, 1402);
/// <summary>Error code: 2029-1403; Inner value: 0xaf61d</summary>
public static Result.Base UsbDriverReceiveError => new Result.Base(ModuleHtcLow, 1403);
/// <summary>Error code: 2029-1404; Inner value: 0xaf81d</summary>
public static Result.Base UsbDriverSendError => new Result.Base(ModuleHtcLow, 1404);
/// <summary>Error code: 2029-2000; Inner value: 0xfa01d</summary>
public static Result.Base HtcctrlError => new Result.Base(ModuleHtcLow, 2000);
/// <summary>Error code: 2029-2001; Inner value: 0xfa21d</summary>
public static Result.Base HtcctrlStateTransitionNotAllowed => new Result.Base(ModuleHtcLow, 2001);
/// <summary>Error code: 2029-2002; Inner value: 0xfa41d</summary>
public static Result.Base HtcctrlReceiveUnexpectedPacket => new Result.Base(ModuleHtcLow, 2002);
}

View file

@ -240,10 +240,17 @@ public class TypeLayoutTests
Assert.Equal(0x08, GetOffset(in s, in s.FatFsError)); Assert.Equal(0x08, GetOffset(in s, in s.FatFsError));
Assert.Equal(0x28, GetOffset(in s, in s.RecoveredByInvalidateCacheCount)); Assert.Equal(0x28, GetOffset(in s, in s.RecoveredByInvalidateCacheCount));
Assert.Equal(0x2C, GetOffset(in s, in s.SaveDataIndexCount)); Assert.Equal(0x2C, GetOffset(in s, in s.SaveDataIndexCount));
Assert.Equal(0x30, GetOffset(in s, in s.BisSystemFatReportInfo)); Assert.Equal(0x30, GetOffset(in s, in s.BisSystemFatReportInfo1));
Assert.Equal(0x34, GetOffset(in s, in s.BisUserFatReport)); Assert.Equal(0x34, GetOffset(in s, in s.BisUserFatReport1));
Assert.Equal(0x38, GetOffset(in s, in s.SdCardFatReport)); Assert.Equal(0x38, GetOffset(in s, in s.SdCardFatReport1));
Assert.Equal(0x3C, GetOffset(in s, in s.Reserved)); 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] [Fact]

View file

@ -31,7 +31,7 @@ public class AccessControlTests
StorageId.BuiltInUser, SpanHelpers.AsReadOnlyByteSpan(in dataHeader), StorageId.BuiltInUser, SpanHelpers.AsReadOnlyByteSpan(in dataHeader),
SpanHelpers.AsReadOnlyByteSpan(in descriptor))); 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); Assert.Result(ResultFs.PermissionDenied, res);
} }
@ -57,7 +57,7 @@ public class AccessControlTests
SpanHelpers.AsReadOnlyByteSpan(in descriptor))); SpanHelpers.AsReadOnlyByteSpan(in descriptor)));
// We should get UnexpectedInNcaFileSystemServiceImplA because mounting NCAs from @System isn't allowed // 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); Assert.Result(ResultFs.UnexpectedInNcaFileSystemServiceImplA, res);
} }
} }