mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Update NcaFileSystemServiceImpl
This commit is contained in:
parent
492716af74
commit
dc6acacf45
29 changed files with 1474 additions and 199 deletions
|
@ -84,14 +84,6 @@ public static class PathExtensions
|
|||
return p == null;
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe bool IsNullRef(ref readonly int path)
|
||||
{
|
||||
fixed (int* p = &path)
|
||||
{
|
||||
return p == null;
|
||||
}
|
||||
}
|
||||
#pragma warning restore CS8500 // This takes the address of, gets the size of, or declares a pointer to a managed type
|
||||
#pragma warning restore LH0001 // DoNotCopyValue
|
||||
}
|
||||
|
|
|
@ -21,7 +21,9 @@ public enum BisPartitionId
|
|||
System = 31,
|
||||
SystemProperEncryption = 32,
|
||||
SystemProperPartition = 33,
|
||||
SignedSystemPartitionOnSafeMode = 34
|
||||
SignedSystemPartitionOnSafeMode = 34,
|
||||
DeviceTreeBlob = 35,
|
||||
System0 = 36
|
||||
}
|
||||
|
||||
public enum ContentStorageId
|
||||
|
|
|
@ -10,6 +10,9 @@ public static class CommonMountNames
|
|||
/// <summary>"<c>@Host</c>"</summary>
|
||||
public static ReadOnlySpan<byte> HostRootFileSystemMountName => "@Host"u8;
|
||||
|
||||
/// <summary>"<c>@Local</c>"</summary>
|
||||
public static ReadOnlySpan<byte> LocalRootFileSystemMountName => "@Local"u8;
|
||||
|
||||
/// <summary>"<c>@Sdcard</c>"</summary>
|
||||
public static ReadOnlySpan<byte> SdCardFileSystemMountName => "@Sdcard"u8;
|
||||
|
||||
|
@ -38,6 +41,9 @@ public static class CommonMountNames
|
|||
/// <summary>"<c>@System</c>"</summary>
|
||||
public static ReadOnlySpan<byte> BisSystemPartitionMountName => "@System"u8;
|
||||
|
||||
/// <summary>"<c>@System0</c>"</summary>
|
||||
public static ReadOnlySpan<byte> BisSystemPartition0MountName => "@System0"u8;
|
||||
|
||||
//Content storage names.
|
||||
/// <summary>"<c>@SystemContent</c>"</summary>
|
||||
public static ReadOnlySpan<byte> ContentStorageSystemMountName => "@SystemContent"u8;
|
||||
|
|
|
@ -65,7 +65,7 @@ public class FileSystemProxyCoreImpl
|
|||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
tempFs.SetByMove(ref fileSystem.Ref);
|
||||
res = _fsCreators.EncryptedFileSystemCreator.Create(ref fileSystem.Ref, ref tempFs.Ref,
|
||||
res = _fsCreators.EncryptedFileSystemCreator.Create(ref fileSystem.Ref, in tempFs,
|
||||
IEncryptedFileSystemCreator.KeyId.CustomStorage, in _sdEncryptionSeed);
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
}
|
||||
|
|
|
@ -13,8 +13,10 @@ namespace LibHac.FsSrv;
|
|||
|
||||
public static class FileSystemServerInitializer
|
||||
{
|
||||
private const ulong SpeedEmulationProgramIdMinimum = 0x100000000000000;
|
||||
private const ulong SpeedEmulationProgramIdMaximum = 0x100000000001FFF;
|
||||
private const ulong SpeedEmulationProgramIdWithoutPlatformIdMinimum = 0;
|
||||
private const ulong SpeedEmulationProgramIdWithoutPlatformIdMaximum = 0x1FFF;
|
||||
|
||||
private const uint ContentDivisionSize = ConcatenationFileSystem.DefaultInternalFileSize;
|
||||
|
||||
private const int BufferManagerHeapSize = 1024 * 1024 * 14;
|
||||
private const int BufferManagerCacheSize = 1024;
|
||||
|
@ -108,8 +110,8 @@ public static class FileSystemServerInitializer
|
|||
new AccessFailureManagementServiceImpl(in accessFailureManagementServiceConfig);
|
||||
|
||||
var speedEmulationRange =
|
||||
new InternalProgramIdRangeForSpeedEmulation(SpeedEmulationProgramIdMinimum,
|
||||
SpeedEmulationProgramIdMaximum);
|
||||
new InternalProgramIdRangeForSpeedEmulation(SpeedEmulationProgramIdWithoutPlatformIdMinimum,
|
||||
SpeedEmulationProgramIdWithoutPlatformIdMaximum);
|
||||
|
||||
var ncaFsServiceConfig = new NcaFileSystemServiceImpl.Configuration();
|
||||
ncaFsServiceConfig.BaseFsService = baseFsService;
|
||||
|
@ -123,6 +125,8 @@ public static class FileSystemServerInitializer
|
|||
ncaFsServiceConfig.ProgramRegistryService = programRegistryService;
|
||||
ncaFsServiceConfig.AccessFailureManagementService = accessFailureManagementService;
|
||||
ncaFsServiceConfig.SpeedEmulationRange = speedEmulationRange;
|
||||
ncaFsServiceConfig.AddOnContentDivisionSize = ContentDivisionSize;
|
||||
ncaFsServiceConfig.RomDivisionSize = ContentDivisionSize;
|
||||
ncaFsServiceConfig.FsServer = server;
|
||||
|
||||
var ncaFsService = new NcaFileSystemServiceImpl(in ncaFsServiceConfig);
|
||||
|
@ -141,6 +145,12 @@ public static class FileSystemServerInitializer
|
|||
saveFsServiceConfig.SaveDataFileSystemCacheCount = 1;
|
||||
saveFsServiceConfig.SaveIndexerManager = saveDataIndexerManager;
|
||||
saveFsServiceConfig.DebugConfigService = debugConfigurationService;
|
||||
saveFsServiceConfig.JournalIntegritySaveDataVersion = 0x50000;
|
||||
saveFsServiceConfig.JournalIntegritySupportedVersionMin = 0x40000;
|
||||
saveFsServiceConfig.JournalIntegritySupportedVersionMax = 0x50000;
|
||||
saveFsServiceConfig.IntegritySaveDataVersion = 0x10000;
|
||||
saveFsServiceConfig.IntegritySupportedVersionMin = 0x10000;
|
||||
saveFsServiceConfig.IntegritySupportedVersionMax = 0x10000;
|
||||
saveFsServiceConfig.FsServer = server;
|
||||
|
||||
var saveFsService = new SaveDataFileSystemServiceImpl(in saveFsServiceConfig);
|
||||
|
|
|
@ -16,7 +16,7 @@ public class EncryptedFileSystemCreator : IEncryptedFileSystemCreator
|
|||
KeySet = keySet;
|
||||
}
|
||||
|
||||
public Result Create(ref SharedRef<IFileSystem> outEncryptedFileSystem, ref SharedRef<IFileSystem> baseFileSystem, KeyId idIndex, in EncryptionSeed encryptionSeed)
|
||||
public Result Create(ref SharedRef<IFileSystem> outEncryptedFileSystem, ref readonly SharedRef<IFileSystem> baseFileSystem, KeyId idIndex, in EncryptionSeed encryptionSeed)
|
||||
{
|
||||
if (idIndex < KeyId.Save || idIndex > KeyId.CustomStorage)
|
||||
{
|
||||
|
@ -26,7 +26,7 @@ public class EncryptedFileSystemCreator : IEncryptedFileSystemCreator
|
|||
// todo: "proper" key generation instead of a lazy hack
|
||||
KeySet.SetSdSeed(encryptionSeed.Value);
|
||||
|
||||
using var encryptedFileSystem = new SharedRef<AesXtsFileSystem>(new AesXtsFileSystem(ref baseFileSystem,
|
||||
using var encryptedFileSystem = new SharedRef<AesXtsFileSystem>(new AesXtsFileSystem(in baseFileSystem,
|
||||
KeySet.SdCardEncryptionKeys[(int)idIndex].DataRo.ToArray(), 0x4000));
|
||||
|
||||
outEncryptedFileSystem.SetByMove(ref encryptedFileSystem.Ref);
|
||||
|
|
|
@ -13,6 +13,6 @@ public interface IEncryptedFileSystemCreator
|
|||
CustomStorage = 2
|
||||
}
|
||||
|
||||
Result Create(ref SharedRef<IFileSystem> outEncryptedFileSystem, ref SharedRef<IFileSystem> baseFileSystem,
|
||||
Result Create(ref SharedRef<IFileSystem> outEncryptedFileSystem, ref readonly SharedRef<IFileSystem> baseFileSystem,
|
||||
KeyId idIndex, in EncryptionSeed encryptionSeed);
|
||||
}
|
|
@ -7,4 +7,9 @@ namespace LibHac.FsSrv.FsCreator;
|
|||
public interface ILocalFileSystemCreator
|
||||
{
|
||||
Result Create(ref SharedRef<IFileSystem> outFileSystem, ref readonly Path rootPath, bool openCaseSensitive, bool ensureRootPathExists, Result pathNotFoundResult);
|
||||
|
||||
public Result Create(ref SharedRef<IFileSystem> outFileSystem, ref readonly Path rootPath, bool openCaseSensitive)
|
||||
{
|
||||
return Create(ref outFileSystem, in rootPath, openCaseSensitive, false, Result.Success).Ret();
|
||||
}
|
||||
}
|
|
@ -6,5 +6,5 @@ namespace LibHac.FsSrv.FsCreator;
|
|||
|
||||
public interface IPartitionFileSystemCreator
|
||||
{
|
||||
Result Create(ref SharedRef<IFileSystem> outFileSystem, ref SharedRef<IStorage> baseStorage);
|
||||
Result Create(ref SharedRef<IFileSystem> outFileSystem, ref readonly SharedRef<IStorage> baseStorage);
|
||||
}
|
|
@ -6,5 +6,5 @@ namespace LibHac.FsSrv.FsCreator;
|
|||
|
||||
public interface IRomFileSystemCreator
|
||||
{
|
||||
Result Create(ref SharedRef<IFileSystem> outFileSystem, ref SharedRef<IStorage> romFsStorage);
|
||||
Result Create(ref SharedRef<IFileSystem> outFileSystem, ref readonly SharedRef<IStorage> romFsStorage);
|
||||
}
|
|
@ -7,11 +7,11 @@ namespace LibHac.FsSrv.FsCreator;
|
|||
public interface IStorageOnNcaCreator
|
||||
{
|
||||
Result Create(ref SharedRef<IStorage> outStorage,
|
||||
ref SharedRef<IAsynchronousAccessSplitter> outStorageAccessSplitter, out NcaFsHeaderReader outHeaderReader,
|
||||
ref SharedRef<IAsynchronousAccessSplitter> outStorageAccessSplitter, ref NcaFsHeaderReader outHeaderReader,
|
||||
ref readonly SharedRef<NcaReader> ncaReader, int fsIndex);
|
||||
|
||||
Result CreateWithPatch(ref SharedRef<IStorage> outStorage,
|
||||
ref SharedRef<IAsynchronousAccessSplitter> outStorageAccessSplitter, out NcaFsHeaderReader outHeaderReader,
|
||||
ref SharedRef<IAsynchronousAccessSplitter> outStorageAccessSplitter, ref NcaFsHeaderReader outHeaderReader,
|
||||
ref readonly SharedRef<NcaReader> originalNcaReader, ref readonly SharedRef<NcaReader> currentNcaReader,
|
||||
int fsIndex);
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace LibHac.FsSrv.FsCreator;
|
|||
|
||||
public class PartitionFileSystemCreator : IPartitionFileSystemCreator
|
||||
{
|
||||
public Result Create(ref SharedRef<IFileSystem> outFileSystem, ref SharedRef<IStorage> baseStorage)
|
||||
public Result Create(ref SharedRef<IFileSystem> outFileSystem, ref readonly SharedRef<IStorage> baseStorage)
|
||||
{
|
||||
using var partitionFs = new SharedRef<PartitionFileSystem>(new PartitionFileSystem());
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@ namespace LibHac.FsSrv.FsCreator;
|
|||
public class RomFileSystemCreator : IRomFileSystemCreator
|
||||
{
|
||||
// todo: Implement properly
|
||||
public Result Create(ref SharedRef<IFileSystem> outFileSystem, ref SharedRef<IStorage> romFsStorage)
|
||||
public Result Create(ref SharedRef<IFileSystem> outFileSystem, ref readonly SharedRef<IStorage> romFsStorage)
|
||||
{
|
||||
outFileSystem.Reset(new RomFsFileSystem(ref romFsStorage));
|
||||
outFileSystem.Reset(new RomFsFileSystem(in romFsStorage));
|
||||
return Result.Success;
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@ public class StorageOnNcaCreator : IStorageOnNcaCreator
|
|||
}
|
||||
|
||||
public Result Create(ref SharedRef<IStorage> outStorage,
|
||||
ref SharedRef<IAsynchronousAccessSplitter> outStorageAccessSplitter, out NcaFsHeaderReader outHeaderReader,
|
||||
ref SharedRef<IAsynchronousAccessSplitter> outStorageAccessSplitter, ref NcaFsHeaderReader outHeaderReader,
|
||||
ref readonly SharedRef<NcaReader> ncaReader, int fsIndex)
|
||||
{
|
||||
var ncaFsDriver = new NcaFileSystemDriver(in ncaReader, _memoryResource, _bufferManager, _hashGeneratorFactorySelector);
|
||||
|
@ -36,7 +36,7 @@ public class StorageOnNcaCreator : IStorageOnNcaCreator
|
|||
using var storage = new SharedRef<IStorage>();
|
||||
using var storageAccessSplitter = new SharedRef<IAsynchronousAccessSplitter>();
|
||||
Result res = RomResultConverter.ConvertRomResult(ncaFsDriver.OpenStorage(ref storage.Ref,
|
||||
ref storageAccessSplitter.Ref, out outHeaderReader, fsIndex));
|
||||
ref storageAccessSplitter.Ref, ref outHeaderReader, fsIndex));
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
using var resultConvertStorage = new SharedRef<RomResultConvertStorage>(new RomResultConvertStorage(in storage));
|
||||
|
@ -48,7 +48,7 @@ public class StorageOnNcaCreator : IStorageOnNcaCreator
|
|||
}
|
||||
|
||||
public Result CreateWithPatch(ref SharedRef<IStorage> outStorage,
|
||||
ref SharedRef<IAsynchronousAccessSplitter> outStorageAccessSplitter, out NcaFsHeaderReader outHeaderReader,
|
||||
ref SharedRef<IAsynchronousAccessSplitter> outStorageAccessSplitter, ref NcaFsHeaderReader outHeaderReader,
|
||||
ref readonly SharedRef<NcaReader> originalNcaReader, ref readonly SharedRef<NcaReader> currentNcaReader,
|
||||
int fsIndex)
|
||||
{
|
||||
|
@ -58,7 +58,7 @@ public class StorageOnNcaCreator : IStorageOnNcaCreator
|
|||
using var storage = new SharedRef<IStorage>();
|
||||
using var storageAccessSplitter = new SharedRef<IAsynchronousAccessSplitter>();
|
||||
Result res = RomResultConverter.ConvertRomResult(ncaFsDriver.OpenStorage(ref storage.Ref,
|
||||
ref storageAccessSplitter.Ref, out outHeaderReader, fsIndex));
|
||||
ref storageAccessSplitter.Ref, ref outHeaderReader, fsIndex));
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
using var resultConvertStorage = new SharedRef<RomResultConvertStorage>(new RomResultConvertStorage(in storage));
|
||||
|
|
|
@ -34,12 +34,12 @@ public class ExternalKeyManager
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result Find(out AccessKey outAccessKey, in RightsId rightsId)
|
||||
public Result Find(out AccessKey outAccessKey, RightsId rightsId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Result FindCore(out AccessKey outAccessKey, in RightsId rightsId)
|
||||
private Result FindCore(out AccessKey outAccessKey, RightsId rightsId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
|
|
@ -12,14 +12,14 @@ namespace LibHac.FsSrv.Impl;
|
|||
|
||||
public static class LocationResolverSetGlobalMethods
|
||||
{
|
||||
public static void InitializeLocationResolverSet(this FileSystemServer fsSrv)
|
||||
public static void InitializeLocationResolverSet(this FileSystemServer fsServer)
|
||||
{
|
||||
ref LocationResolverSetGlobals globals = ref fsSrv.Globals.LocationResolverSet;
|
||||
ref LocationResolverSetGlobals globals = ref fsServer.Globals.LocationResolverSet;
|
||||
using ScopedLock<SdkMutexType> scopedLock = ScopedLock.Lock(ref globals.Mutex);
|
||||
|
||||
if (!globals.IsLrInitialized)
|
||||
{
|
||||
fsSrv.Hos.Lr.Initialize();
|
||||
fsServer.Hos.Lr.Initialize();
|
||||
globals.IsLrInitialized = true;
|
||||
}
|
||||
}
|
||||
|
@ -39,8 +39,8 @@ internal struct LocationResolverSetGlobals
|
|||
/// <summary>
|
||||
/// Manages resolving the location of NCAs via the <c>lr</c> service.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 13.4.0 (FS 13.1.0)</remarks>
|
||||
internal class LocationResolverSet : IDisposable
|
||||
/// <remarks>Based on nnSdk 17.5.0 (FS 17.0.0)</remarks>
|
||||
public class LocationResolverSet : IDisposable
|
||||
{
|
||||
private Array5<Optional<LocationResolver>> _resolvers;
|
||||
private Optional<AddOnContentLocationResolver> _aocResolver;
|
||||
|
@ -76,16 +76,16 @@ internal class LocationResolverSet : IDisposable
|
|||
|
||||
private static Result SetUpFsPath(ref Fs.Path outPath, ref readonly Lr.Path lrPath)
|
||||
{
|
||||
var pathFlags = new PathFlags();
|
||||
pathFlags.AllowMountName();
|
||||
var flags = new PathFlags();
|
||||
flags.AllowMountName();
|
||||
|
||||
if (Utility.IsHostFsMountName(lrPath.Value))
|
||||
pathFlags.AllowWindowsPath();
|
||||
flags.AllowWindowsPath();
|
||||
|
||||
Result res = outPath.InitializeWithReplaceUnc(lrPath.Value);
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
res = outPath.Normalize(pathFlags);
|
||||
res = outPath.Normalize(flags);
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
return Result.Success;
|
||||
|
@ -124,7 +124,7 @@ internal class LocationResolverSet : IDisposable
|
|||
{
|
||||
_fsServer.InitializeLocationResolverSet();
|
||||
|
||||
return Hos.Lr.OpenRegisteredLocationResolver(out resolver);
|
||||
return Hos.Lr.OpenRegisteredLocationResolver(out resolver).Ret();
|
||||
}
|
||||
|
||||
private Result GetAddOnContentLocationResolver(out AddOnContentLocationResolver resolver)
|
||||
|
@ -147,75 +147,109 @@ internal class LocationResolverSet : IDisposable
|
|||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result ResolveApplicationControlPath(ref Fs.Path outPath, Ncm.ApplicationId applicationId, StorageId storageId)
|
||||
public Result ResolveApplicationControlPath(ref Fs.Path outPath, out ContentAttributes outContentAttributes,
|
||||
Ncm.ApplicationId applicationId, StorageId storageId)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outContentAttributes);
|
||||
|
||||
Result res = GetLocationResolver(out LocationResolver resolver, storageId);
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
res = resolver.ResolveApplicationControlPath(out Lr.Path path, applicationId);
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
return SetUpFsPath(ref outPath, in path);
|
||||
outContentAttributes = ContentAttributes.None;
|
||||
return SetUpFsPath(ref outPath, in path).Ret();
|
||||
}
|
||||
|
||||
public Result ResolveApplicationHtmlDocumentPath(out bool isDirectory, ref Fs.Path outPath, Ncm.ApplicationId applicationId, StorageId storageId)
|
||||
public Result ResolveApplicationHtmlDocumentPath(out bool outIsDirectory, ref Fs.Path outPath,
|
||||
out ContentAttributes outContentAttributes, ulong applicationId, StorageId storageId)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out isDirectory);
|
||||
UnsafeHelpers.SkipParamInit(out outIsDirectory, out outContentAttributes);
|
||||
|
||||
Result res = GetLocationResolver(out LocationResolver resolver, storageId);
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
res = resolver.ResolveApplicationHtmlDocumentPath(out Lr.Path path, applicationId);
|
||||
res = resolver.ResolveApplicationHtmlDocumentPath(out Lr.Path path, new ProgramId(applicationId));
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
isDirectory = PathUtility.IsDirectoryPath(path.Value);
|
||||
outContentAttributes = ContentAttributes.None;
|
||||
outIsDirectory = PathUtility.IsDirectoryPath(path.Value);
|
||||
|
||||
return SetUpFsPath(ref outPath, in path);
|
||||
return SetUpFsPath(ref outPath, in path).Ret();
|
||||
}
|
||||
|
||||
public Result ResolveProgramPath(out bool isDirectory, ref Fs.Path outPath, ProgramId programId, StorageId storageId)
|
||||
public Result ResolveProgramPath(out bool outIsDirectory, ref Fs.Path outPath,
|
||||
out ContentAttributes outContentAttributes, ulong programId, StorageId storageId)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out isDirectory);
|
||||
UnsafeHelpers.SkipParamInit(out outIsDirectory, out outContentAttributes);
|
||||
|
||||
Result res = GetLocationResolver(out LocationResolver resolver, storageId);
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
res = resolver.ResolveProgramPath(out Lr.Path path, programId);
|
||||
res = resolver.ResolveProgramPath(out Lr.Path path, new ProgramId(programId));
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
isDirectory = PathUtility.IsDirectoryPath(path.Value);
|
||||
outContentAttributes = ContentAttributes.None;
|
||||
outIsDirectory = PathUtility.IsDirectoryPath(path.Value);
|
||||
|
||||
return SetUpFsPath(ref outPath, in path);
|
||||
return SetUpFsPath(ref outPath, in path).Ret();
|
||||
}
|
||||
|
||||
public Result ResolveRomPath(out bool isDirectory, ref Fs.Path outPath, ProgramId programId, StorageId storageId)
|
||||
public Result ResolveRomPath(out bool outIsDirectory, ref Fs.Path outPath,
|
||||
out ContentAttributes outContentAttributes, ulong programId, StorageId storageId)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out isDirectory);
|
||||
UnsafeHelpers.SkipParamInit(out outIsDirectory, out outContentAttributes);
|
||||
|
||||
Result res = GetLocationResolver(out LocationResolver resolver, storageId);
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
res = resolver.ResolveProgramPathForDebug(out Lr.Path path, programId);
|
||||
res = resolver.ResolveProgramPathForDebug(out Lr.Path path, new ProgramId(programId));
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
isDirectory = PathUtility.IsDirectoryPath(path.Value);
|
||||
outContentAttributes = ContentAttributes.None;
|
||||
outIsDirectory = PathUtility.IsDirectoryPath(path.Value);
|
||||
|
||||
return SetUpFsPath(ref outPath, in path);
|
||||
return SetUpFsPath(ref outPath, in path).Ret();
|
||||
}
|
||||
|
||||
public Result ResolveAddOnContentPath(ref Fs.Path outPath, DataId dataId)
|
||||
public Result ResolveAddOnContentPath(ref Fs.Path outPath, out ContentAttributes outContentAttributes,
|
||||
ref Fs.Path outPatchPath, out ContentAttributes outPatchContentAttributes, DataId dataId)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outContentAttributes, out outPatchContentAttributes);
|
||||
|
||||
Result res = GetAddOnContentLocationResolver(out AddOnContentLocationResolver resolver);
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
res = resolver.ResolveAddOnContentPath(out Lr.Path path, dataId);
|
||||
res = resolver.GetRegisteredAddOnContentPaths(out Lr.Path path, out Lr.Path patchPath, dataId);
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
return SetUpFsPath(ref outPath, in path);
|
||||
outContentAttributes = ContentAttributes.None;
|
||||
|
||||
if (patchPath.Value[0] != 0)
|
||||
{
|
||||
// Note: FS appears to assign the paths to the wrong outputs here
|
||||
res = SetUpFsPath(ref outPath, in patchPath);
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
res = SetUpFsPath(ref outPatchPath, in path);
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
outPatchContentAttributes = ContentAttributes.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = SetUpFsPath(ref outPath, in path);
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
}
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result ResolveDataPath(ref Fs.Path outPath, DataId dataId, StorageId storageId)
|
||||
public Result ResolveDataPath(ref Fs.Path outPath, out ContentAttributes outContentAttributes, DataId dataId, StorageId storageId)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outContentAttributes);
|
||||
|
||||
if (storageId == StorageId.None)
|
||||
return ResultFs.InvalidAlignment.Log();
|
||||
|
||||
|
@ -225,11 +259,14 @@ internal class LocationResolverSet : IDisposable
|
|||
res = resolver.ResolveDataPath(out Lr.Path path, dataId);
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
return SetUpFsPath(ref outPath, in path);
|
||||
outContentAttributes = ContentAttributes.None;
|
||||
return SetUpFsPath(ref outPath, in path).Ret();
|
||||
}
|
||||
|
||||
public Result ResolveRegisteredProgramPath(ref Fs.Path outPath, ulong id)
|
||||
public Result ResolveRegisteredProgramPath(ref Fs.Path outPath, out ContentAttributes outContentAttributes, ulong id)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outContentAttributes);
|
||||
|
||||
RegisteredLocationResolver resolver = null;
|
||||
try
|
||||
{
|
||||
|
@ -239,7 +276,8 @@ internal class LocationResolverSet : IDisposable
|
|||
res = resolver.ResolveProgramPath(out Lr.Path path, new ProgramId(id));
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
return SetUpFsPath(ref outPath, in path);
|
||||
outContentAttributes = ContentAttributes.None;
|
||||
return SetUpFsPath(ref outPath, in path).Ret();
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -247,8 +285,10 @@ internal class LocationResolverSet : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
public Result ResolveRegisteredHtmlDocumentPath(ref Fs.Path outPath, ulong id)
|
||||
public Result ResolveRegisteredHtmlDocumentPath(ref Fs.Path outPath, out ContentAttributes outContentAttributes, ulong id)
|
||||
{
|
||||
UnsafeHelpers.SkipParamInit(out outContentAttributes);
|
||||
|
||||
RegisteredLocationResolver resolver = null;
|
||||
try
|
||||
{
|
||||
|
@ -258,7 +298,8 @@ internal class LocationResolverSet : IDisposable
|
|||
res = resolver.ResolveHtmlDocumentPath(out Lr.Path path, new ProgramId(id));
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
return SetUpFsPath(ref outPath, in path);
|
||||
outContentAttributes = ContentAttributes.None;
|
||||
return SetUpFsPath(ref outPath, in path).Ret();
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
172
src/LibHac/FsSrv/Impl/NpdmVerificationFileSystem.cs
Normal file
172
src/LibHac/FsSrv/Impl/NpdmVerificationFileSystem.cs
Normal file
|
@ -0,0 +1,172 @@
|
|||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
|
||||
namespace LibHac.FsSrv.Impl;
|
||||
|
||||
[InlineArray(0x20)]
|
||||
public struct NpdmHash
|
||||
{
|
||||
private byte _data;
|
||||
}
|
||||
|
||||
public class NpdmVerificationFile : IFile
|
||||
{
|
||||
private NpdmHash _hash;
|
||||
private UniqueRef<IFile> _baseFile;
|
||||
|
||||
public NpdmVerificationFile(ref UniqueRef<IFile> baseFile, NpdmHash hash)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
_baseFile.Destroy();
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
protected override Result DoRead(out long bytesRead, long offset, Span<byte> destination, in ReadOption option)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoWrite(long offset, ReadOnlySpan<byte> source, in WriteOption option)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoFlush()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoSetSize(long size)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoGetSize(out long size)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoOperateRange(Span<byte> outBuffer, OperationId operationId, long offset, long size, ReadOnlySpan<byte> inBuffer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public class NpdmVerificationFileSystem : IFileSystem
|
||||
{
|
||||
private NpdmHash _hash;
|
||||
private ReadOnlyFileSystem _baseFileSystem;
|
||||
|
||||
public NpdmVerificationFileSystem(in SharedRef<IFileSystem> baseFileSystem, NpdmHash hash)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
_baseFileSystem.Dispose();
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
protected override Result DoOpenFile(ref UniqueRef<IFile> outFile, ref readonly Path path, OpenMode mode)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoCreateFile(ref readonly Path path, long size, CreateFileOptions option)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoDeleteFile(ref readonly Path path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoCreateDirectory(ref readonly Path path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoDeleteDirectory(ref readonly Path path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoDeleteDirectoryRecursively(ref readonly Path path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoCleanDirectoryRecursively(ref readonly Path path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoRenameFile(ref readonly Path currentPath, ref readonly Path newPath)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoRenameDirectory(ref readonly Path currentPath, ref readonly Path newPath)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoGetEntryType(out DirectoryEntryType entryType, ref readonly Path path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoGetFreeSpaceSize(out long freeSpace, ref readonly Path path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoGetTotalSpaceSize(out long totalSpace, ref readonly Path path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoOpenDirectory(ref UniqueRef<IDirectory> outDirectory, ref readonly Path path, OpenDirectoryMode mode)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoCommit()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoCommitProvisionally(long counter)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoRollback()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoFlush()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoGetFileTimeStampRaw(out FileTimeStampRaw timeStamp, ref readonly Path path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Result DoQueryEntry(Span<byte> outBuffer, ReadOnlySpan<byte> inBuffer, QueryId queryId, ref readonly Path path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
|
@ -10,9 +10,10 @@ namespace LibHac.FsSrv.Impl;
|
|||
/// <summary>
|
||||
/// Keeps track of the program IDs and program indexes of each program in a multi-program application.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 13.4.0 (FS 13.1.0)</remarks>
|
||||
/// <remarks>Based on nnSdk 17.5.0 (FS 17.0.0)</remarks>
|
||||
public class ProgramIndexMapInfoManager : IDisposable
|
||||
{
|
||||
// Changed: The original uses an intrusive list for the entries
|
||||
private LinkedList<ProgramIndexMapInfo> _mapEntries;
|
||||
private SdkMutexType _mutex;
|
||||
|
||||
|
@ -38,21 +39,29 @@ public class ProgramIndexMapInfoManager : IDisposable
|
|||
|
||||
ClearImpl();
|
||||
|
||||
for (int i = 0; i < programIndexMapInfo.Length; i++)
|
||||
bool isSuccess = false;
|
||||
try
|
||||
{
|
||||
var entry = new ProgramIndexMapInfo
|
||||
for (int i = 0; i < programIndexMapInfo.Length; i++)
|
||||
{
|
||||
ProgramId = programIndexMapInfo[i].ProgramId,
|
||||
MainProgramId = programIndexMapInfo[i].MainProgramId,
|
||||
ProgramIndex = programIndexMapInfo[i].ProgramIndex
|
||||
};
|
||||
var entry = new ProgramIndexMapInfo
|
||||
{
|
||||
ProgramId = programIndexMapInfo[i].ProgramId,
|
||||
MainProgramId = programIndexMapInfo[i].MainProgramId,
|
||||
ProgramIndex = programIndexMapInfo[i].ProgramIndex
|
||||
};
|
||||
|
||||
_mapEntries.AddLast(entry);
|
||||
_mapEntries.AddLast(entry);
|
||||
}
|
||||
|
||||
isSuccess = true;
|
||||
return Result.Success;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!isSuccess)
|
||||
ClearImpl();
|
||||
}
|
||||
|
||||
// We skip running ClearImpl() if the allocation failed because we don't need to worry about that in C#
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -116,6 +125,19 @@ public class ProgramIndexMapInfoManager : IDisposable
|
|||
return _mapEntries.Count;
|
||||
}
|
||||
|
||||
public ProgramId GetApplicationProgramId(ProgramId programId)
|
||||
{
|
||||
using ScopedLock<SdkMutexType> scopedLock = ScopedLock.Lock(ref _mutex);
|
||||
|
||||
Optional<ProgramIndexMapInfo> programIndexMapInfo =
|
||||
GetImpl((in ProgramIndexMapInfo x) => x.ProgramId == programId);
|
||||
|
||||
if (!programIndexMapInfo.HasValue)
|
||||
return ProgramId.InvalidId;
|
||||
|
||||
return new ProgramId(programIndexMapInfo.Value.MainProgramId.Value + programIndexMapInfo.Value.ProgramIndex);
|
||||
}
|
||||
|
||||
private delegate bool EntrySelector(in ProgramIndexMapInfo candidate);
|
||||
|
||||
private Optional<ProgramIndexMapInfo> GetImpl(EntrySelector selector)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -19,7 +19,7 @@ internal struct ProgramRegistryImplGlobals
|
|||
/// is stored in a <see cref="ProgramInfo"/> and includes the process' process ID, program ID,
|
||||
/// storage location and file system permissions. This allows FS to resolve the program ID and
|
||||
/// verify the permissions of any process calling it.
|
||||
/// <para>Based on nnSdk 13.4.0 (FS 13.1.0)</para></remarks>
|
||||
/// <para>Based on nnSdk 17.5.0 (FS 17.0.0)</para></remarks>
|
||||
public class ProgramRegistryImpl : IProgramRegistry
|
||||
{
|
||||
private ulong _processId;
|
||||
|
@ -55,8 +55,9 @@ public class ProgramRegistryImpl : IProgramRegistry
|
|||
if (accessControlDescriptorSize > accessControlDescriptor.Size)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
return Globals.ServiceImpl.RegisterProgramInfo(processId, programId, storageId, accessControlData.Buffer,
|
||||
accessControlDescriptor.Buffer);
|
||||
return Globals.ServiceImpl.RegisterProgramInfo(processId, programId, storageId,
|
||||
accessControlData.Buffer.Slice(0, (int)accessControlDataSize),
|
||||
accessControlDescriptor.Buffer.Slice(0, (int)accessControlDescriptorSize)).Ret();
|
||||
}
|
||||
|
||||
/// <returns><see cref="Result.Success"/>: The operation was successful.<br/>
|
||||
|
@ -70,7 +71,7 @@ public class ProgramRegistryImpl : IProgramRegistry
|
|||
if (!_fsServer.IsInitialProgram(_processId))
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
return Globals.ServiceImpl.UnregisterProgramInfo(processId);
|
||||
return Globals.ServiceImpl.UnregisterProgramInfo(processId).Ret();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ProgramRegistryManager.GetProgramInfo"/>
|
||||
|
@ -78,7 +79,7 @@ public class ProgramRegistryImpl : IProgramRegistry
|
|||
{
|
||||
Assert.SdkRequiresNotNull(Globals.ServiceImpl);
|
||||
|
||||
return Globals.ServiceImpl.GetProgramInfo(out programInfo, processId);
|
||||
return Globals.ServiceImpl.GetProgramInfo(out programInfo, processId).Ret();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ProgramRegistryManager.GetProgramInfoByProgramId"/>
|
||||
|
@ -86,7 +87,7 @@ public class ProgramRegistryImpl : IProgramRegistry
|
|||
{
|
||||
Assert.SdkRequiresNotNull(Globals.ServiceImpl);
|
||||
|
||||
return Globals.ServiceImpl.GetProgramInfoByProgramId(out programInfo, programId);
|
||||
return Globals.ServiceImpl.GetProgramInfoByProgramId(out programInfo, programId).Ret();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsSrv.Impl;
|
||||
|
@ -14,7 +13,7 @@ namespace LibHac.FsSrv;
|
|||
/// </summary>
|
||||
/// <remarks>Appropriate methods calls on IFileSystemProxy are forwarded to this class
|
||||
/// which then checks the calling process' permissions and performs the requested operation.
|
||||
/// <para>Based on nnSdk 13.4.0 (FS 13.1.0)</para></remarks>
|
||||
/// <para>Based on nnSdk 17.5.0 (FS 17.0.0)</para></remarks>
|
||||
internal readonly struct ProgramIndexRegistryService
|
||||
{
|
||||
private readonly ProgramRegistryServiceImpl _serviceImpl;
|
||||
|
@ -53,11 +52,14 @@ internal readonly struct ProgramIndexRegistryService
|
|||
return ResultFs.PermissionDenied.Log();
|
||||
}
|
||||
|
||||
// Return early if the program count is 0 so we leave any previously
|
||||
// Return early if the program count is 0, so we leave any previously
|
||||
// registered entries as they were
|
||||
if (programCount == 0)
|
||||
return Result.Success;
|
||||
|
||||
if (programIndexMapInfo.IsNull)
|
||||
return ResultFs.NullptrArgument.Log();
|
||||
|
||||
// Verify that the provided buffer is large enough to hold "programCount" entries
|
||||
ReadOnlySpan<ProgramIndexMapInfo> mapInfo = programIndexMapInfo.AsSpan<ProgramIndexMapInfo>();
|
||||
|
||||
|
@ -65,7 +67,7 @@ internal readonly struct ProgramIndexRegistryService
|
|||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
// Register the map info
|
||||
return _serviceImpl.ResetProgramIndexMapInfo(mapInfo.Slice(0, programCount));
|
||||
return _serviceImpl.ResetProgramIndexMapInfo(mapInfo.Slice(0, programCount)).Ret();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -88,10 +90,10 @@ internal readonly struct ProgramIndexRegistryService
|
|||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
// Try to get map info for this process
|
||||
Optional<ProgramIndexMapInfo> mapInfo = _serviceImpl.GetProgramIndexMapInfo(programInfo.ProgramId);
|
||||
Optional<ProgramIndexMapInfo> programMapInfo = _serviceImpl.GetProgramIndexMapInfo(programInfo.ProgramId);
|
||||
|
||||
// Set the output program index if map info was found
|
||||
programIndex = mapInfo.HasValue ? mapInfo.ValueRo.ProgramIndex : 0;
|
||||
programIndex = programMapInfo.HasValue ? programMapInfo.ValueRo.ProgramIndex : 0;
|
||||
|
||||
// Set the number of programs in the current application
|
||||
programCount = _serviceImpl.GetProgramIndexMapInfoCount();
|
||||
|
@ -110,7 +112,7 @@ internal readonly struct ProgramIndexRegistryService
|
|||
/// <summary>
|
||||
/// Manages the main program registry and the multi-program registry.
|
||||
/// </summary>
|
||||
/// <remarks>Based on nnSdk 13.4.0 (FS 13.1.0)</remarks>
|
||||
/// <remarks>Based on nnSdk 17.5.0 (FS 17.0.0)</remarks>
|
||||
public class ProgramRegistryServiceImpl : IDisposable
|
||||
{
|
||||
// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
|
||||
|
@ -142,37 +144,31 @@ public class ProgramRegistryServiceImpl : IDisposable
|
|||
ReadOnlySpan<byte> accessControlData, ReadOnlySpan<byte> accessControlDescriptor)
|
||||
{
|
||||
return _registryManager.RegisterProgram(processId, programId, storageId, accessControlData,
|
||||
accessControlDescriptor);
|
||||
accessControlDescriptor).Ret();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ProgramRegistryManager.UnregisterProgram" />
|
||||
public Result UnregisterProgramInfo(ulong processId)
|
||||
{
|
||||
return _registryManager.UnregisterProgram(processId);
|
||||
return _registryManager.UnregisterProgram(processId).Ret();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ProgramRegistryManager.GetProgramInfo"/>
|
||||
public Result GetProgramInfo(out ProgramInfo programInfo, ulong processId)
|
||||
{
|
||||
return _registryManager.GetProgramInfo(out programInfo, processId);
|
||||
return _registryManager.GetProgramInfo(out programInfo, processId).Ret();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ProgramRegistryManager.GetProgramInfoByProgramId"/>
|
||||
public Result GetProgramInfoByProgramId(out ProgramInfo programInfo, ulong programId)
|
||||
{
|
||||
return _registryManager.GetProgramInfoByProgramId(out programInfo, programId);
|
||||
return _registryManager.GetProgramInfoByProgramId(out programInfo, programId).Ret();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ProgramIndexMapInfoManager.Reset"/>
|
||||
public Result ResetProgramIndexMapInfo(ReadOnlySpan<ProgramIndexMapInfo> programIndexMapInfo)
|
||||
{
|
||||
return _programIndexManager.Reset(programIndexMapInfo);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ProgramIndexMapInfoManager.GetProgramId"/>
|
||||
public ProgramId GetProgramIdByIndex(ProgramId programId, byte programIndex)
|
||||
{
|
||||
return _programIndexManager.GetProgramId(programId, programIndex);
|
||||
return _programIndexManager.Reset(programIndexMapInfo).Ret();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ProgramIndexMapInfoManager.Get"/>
|
||||
|
@ -181,6 +177,12 @@ public class ProgramRegistryServiceImpl : IDisposable
|
|||
return _programIndexManager.Get(programId);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ProgramIndexMapInfoManager.GetProgramId"/>
|
||||
public ProgramId GetProgramIdByIndex(ProgramId programId, byte programIndex)
|
||||
{
|
||||
return _programIndexManager.GetProgramId(programId, programIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of programs in the currently registered application.
|
||||
/// </summary>
|
||||
|
@ -189,4 +191,14 @@ public class ProgramRegistryServiceImpl : IDisposable
|
|||
{
|
||||
return _programIndexManager.GetProgramCount();
|
||||
}
|
||||
|
||||
public ProgramId GetApplicationProgramProgramIdByPatchProgramProgramId(ProgramId programId)
|
||||
{
|
||||
return _programIndexManager.GetApplicationProgramId(programId);
|
||||
}
|
||||
|
||||
public ProgramId GetApplicationHtmlDocumentProgramIdByPatchProgramProgramId(ProgramId programId)
|
||||
{
|
||||
return GetApplicationProgramProgramIdByPatchProgramProgramId(programId);
|
||||
}
|
||||
}
|
|
@ -1191,7 +1191,7 @@ public class SaveDataFileSystemServiceImpl : IDisposable
|
|||
res = Utility.WrapSubDirectory(ref baseFileSystem.Ref, ref tempFileSystem.Ref, in pathSdRoot, createIfMissing);
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
res = _config.EncryptedFsCreator.Create(ref outFileSystem, ref baseFileSystem.Ref,
|
||||
res = _config.EncryptedFsCreator.Create(ref outFileSystem, in baseFileSystem,
|
||||
IEncryptedFileSystemCreator.KeyId.Save, in _encryptionSeed);
|
||||
if (res.IsFailure()) return res.Miss();
|
||||
|
||||
|
|
|
@ -490,7 +490,7 @@ public class ConcatenationFileSystem : IFileSystem
|
|||
}
|
||||
}
|
||||
|
||||
public static readonly long DefaultInternalFileSize = 0xFFFF0000; // Hard-coded value used by FS
|
||||
public const uint DefaultInternalFileSize = 0xFFFF0000; // Hard-coded value used by FS
|
||||
|
||||
private UniqueRef<IAttributeFileSystem> _baseFileSystem;
|
||||
private long _internalFileSize;
|
||||
|
|
|
@ -204,13 +204,13 @@ public class NcaFileSystemDriver : IDisposable
|
|||
}
|
||||
|
||||
public Result OpenStorage(ref SharedRef<IStorage> outStorage,
|
||||
ref SharedRef<IAsynchronousAccessSplitter> outStorageAccessSplitter, out NcaFsHeaderReader outHeaderReader,
|
||||
ref SharedRef<IAsynchronousAccessSplitter> outStorageAccessSplitter, ref NcaFsHeaderReader outHeaderReader,
|
||||
int fsIndex)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private Result OpenStorageImpl(ref SharedRef<IStorage> outStorage, out NcaFsHeaderReader outHeaderReader,
|
||||
private Result OpenStorageImpl(ref SharedRef<IStorage> outStorage, ref NcaFsHeaderReader outHeaderReader,
|
||||
int fsIndex, ref StorageContext storageContext)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
|
|
@ -33,4 +33,13 @@ public class AddOnContentLocationResolver : IDisposable
|
|||
|
||||
public Result UnregisterApplicationAddOnContent(Ncm.ApplicationId id) =>
|
||||
_interface.Get.UnregisterApplicationAddOnContent(id);
|
||||
|
||||
public Result GetRegisteredAddOnContentPaths(out Path outPath, out Path outPatchPath, DataId id) =>
|
||||
_interface.Get.GetRegisteredAddOnContentPaths(out outPath, out outPatchPath, id);
|
||||
|
||||
public Result RegisterAddOnContentPath(DataId id, ApplicationId applicationId, in Path path) =>
|
||||
_interface.Get.RegisterAddOnContentPath(id, applicationId, in path);
|
||||
|
||||
public Result RegisterAddOnContentPaths(DataId id, ApplicationId applicationId, in Path path, in Path patchPath) =>
|
||||
_interface.Get.RegisterAddOnContentPaths(id, applicationId, in path, in patchPath);
|
||||
}
|
|
@ -6,9 +6,12 @@ namespace LibHac.Lr;
|
|||
|
||||
public interface IAddOnContentLocationResolver : IDisposable
|
||||
{
|
||||
Result ResolveAddOnContentPath(out Path path, DataId id);
|
||||
Result ResolveAddOnContentPath(out Path outPath, DataId id);
|
||||
Result RegisterAddOnContentStorage(DataId id, Ncm.ApplicationId applicationId, StorageId storageId);
|
||||
Result UnregisterAllAddOnContentPath();
|
||||
Result RefreshApplicationAddOnContent(InArray<Ncm.ApplicationId> ids);
|
||||
Result UnregisterApplicationAddOnContent(Ncm.ApplicationId id);
|
||||
Result GetRegisteredAddOnContentPaths(out Path outPath, out Path outPatchPath, DataId id);
|
||||
Result RegisterAddOnContentPath(DataId id, ApplicationId applicationId, in Path path);
|
||||
Result RegisterAddOnContentPaths(DataId id, ApplicationId applicationId, in Path path, in Path patchPath);
|
||||
}
|
|
@ -17,9 +17,9 @@ public class AesXtsFileSystem : IFileSystem
|
|||
private byte[] _kekSource;
|
||||
private byte[] _validationKey;
|
||||
|
||||
public AesXtsFileSystem(ref SharedRef<IFileSystem> fs, byte[] keys, int blockSize)
|
||||
public AesXtsFileSystem(ref readonly SharedRef<IFileSystem> fs, byte[] keys, int blockSize)
|
||||
{
|
||||
_sharedBaseFileSystem = SharedRef<IFileSystem>.CreateMove(ref fs);
|
||||
_sharedBaseFileSystem = SharedRef<IFileSystem>.CreateCopy(in fs);
|
||||
_baseFileSystem = _sharedBaseFileSystem.Get;
|
||||
_kekSource = keys.AsSpan(0, 0x10).ToArray();
|
||||
_validationKey = keys.AsSpan(0x10, 0x10).ToArray();
|
||||
|
|
|
@ -26,9 +26,9 @@ public class RomFsFileSystem : IFileSystem
|
|||
FileTable = new HierarchicalRomFileTable<RomFileInfo>(dirHashTable, dirEntryTable, fileHashTable, fileEntryTable);
|
||||
}
|
||||
|
||||
public RomFsFileSystem(ref SharedRef<IStorage> storage) : this(storage.Get)
|
||||
public RomFsFileSystem(ref readonly SharedRef<IStorage> storage) : this(storage.Get)
|
||||
{
|
||||
_baseStorageShared = SharedRef<IStorage>.CreateMove(ref storage);
|
||||
_baseStorageShared = SharedRef<IStorage>.CreateCopy(in storage);
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="I" Suffix="" Style="AaBb" /></Policy></s:String></wpf:ResourceDictionary>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="I" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=a0b4bc4d_002Dd13b_002D4a37_002Db37e_002Dc9c6864e4302/@EntryIndexedValue"><Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Types and namespaces"><ElementKinds><Kind Name="NAMESPACE" /><Kind Name="CLASS" /><Kind Name="STRUCT" /><Kind Name="ENUM" /><Kind Name="DELEGATE" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="I" Suffix="" Style="AaBb" /></Policy></Policy></s:String>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
Loading…
Reference in a new issue