mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Fix method signatures in IFileSystemProxy
This commit is contained in:
parent
882e6bc937
commit
a3220cc8df
20 changed files with 404 additions and 208 deletions
|
@ -3,6 +3,7 @@ using System.Runtime.CompilerServices;
|
|||
using LibHac.Common;
|
||||
using LibHac.Fs.Accessors;
|
||||
using LibHac.FsSrv;
|
||||
using LibHac.Sf;
|
||||
|
||||
namespace LibHac.Fs
|
||||
{
|
||||
|
@ -187,7 +188,7 @@ namespace LibHac.Fs
|
|||
string logString = AccessLogHelpers.BuildDefaultLogLine(result, startTime, endTime, handleId, message, caller);
|
||||
|
||||
IFileSystemProxy fsProxy = GetFileSystemProxyServiceObject();
|
||||
fsProxy.OutputAccessLogToSdCard(logString.ToU8Span());
|
||||
fsProxy.OutputAccessLogToSdCard(new InBuffer(logString.ToU8Span())).IgnoreResult();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs.Impl;
|
||||
using LibHac.FsSrv;
|
||||
|
@ -137,8 +138,7 @@ namespace LibHac.Fs.Shim
|
|||
// todo: Decide how to handle SetBisRootForHost since it allows mounting any directory on the user's computer
|
||||
public static Result SetBisRootForHost(this FileSystemClient fs, BisPartitionId partitionId, U8Span rootPath)
|
||||
{
|
||||
FsPath sfPath;
|
||||
unsafe { _ = &sfPath; } // workaround for CS0165
|
||||
Unsafe.SkipInit(out FsPath path);
|
||||
|
||||
int pathLen = StringUtils.GetLength(rootPath, PathTools.MaxPathLength + 1);
|
||||
if (pathLen > PathTools.MaxPathLength)
|
||||
|
@ -150,18 +150,20 @@ namespace LibHac.Fs.Shim
|
|||
? StringTraits.NullTerminator
|
||||
: StringTraits.DirectorySeparator;
|
||||
|
||||
var sb = new U8StringBuilder(sfPath.Str);
|
||||
var sb = new U8StringBuilder(path.Str);
|
||||
Result rc = sb.Append(rootPath).Append(endingSeparator).ToSfPath();
|
||||
if (rc.IsFailure()) return rc;
|
||||
}
|
||||
else
|
||||
{
|
||||
sfPath.Str[0] = StringTraits.NullTerminator;
|
||||
path.Str[0] = StringTraits.NullTerminator;
|
||||
}
|
||||
|
||||
FspPath.FromSpan(out FspPath sfPath, path.Str);
|
||||
|
||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||
|
||||
return fsProxy.SetBisRootForHost(partitionId, ref sfPath);
|
||||
return fsProxy.SetBisRootForHost(partitionId, in sfPath);
|
||||
}
|
||||
|
||||
public static Result OpenBisPartition(this FileSystemClient fs, out IStorage partitionStorage, BisPartitionId partitionId)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
using System;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Fs.Impl;
|
||||
using LibHac.FsSrv;
|
||||
using LibHac.FsSrv.Sf;
|
||||
|
||||
namespace LibHac.Fs.Shim
|
||||
{
|
||||
|
@ -12,12 +13,22 @@ namespace LibHac.Fs.Shim
|
|||
Result rc = MountHelpers.CheckMountName(mountName);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
ReferenceCountedDisposable<IFileSystemSf> customFs = null;
|
||||
try
|
||||
{
|
||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||
|
||||
rc = fsProxy.OpenCustomStorageFileSystem(out IFileSystem customFs, storageId);
|
||||
rc = fsProxy.OpenCustomStorageFileSystem(out customFs, storageId);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return fs.Register(mountName, customFs);
|
||||
var adapter = new FileSystemServiceObjectAdapter(customFs);
|
||||
|
||||
return fs.Register(mountName, adapter);
|
||||
}
|
||||
finally
|
||||
{
|
||||
customFs?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetCustomStorageDirectoryName(CustomStorageId storageId)
|
||||
|
|
|
@ -12,33 +12,63 @@ namespace LibHac.Fs.Shim
|
|||
{
|
||||
handle = default;
|
||||
|
||||
ReferenceCountedDisposable<IDeviceOperator> deviceOperator = null;
|
||||
try
|
||||
{
|
||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||
|
||||
Result rc = fsProxy.OpenDeviceOperator(out IDeviceOperator deviceOperator);
|
||||
Result rc = fsProxy.OpenDeviceOperator(out deviceOperator);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return deviceOperator.GetGameCardHandle(out handle);
|
||||
return deviceOperator.Target.GetGameCardHandle(out handle);
|
||||
}
|
||||
finally
|
||||
{
|
||||
deviceOperator?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsGameCardInserted(this FileSystemClient fs)
|
||||
{
|
||||
ReferenceCountedDisposable<IDeviceOperator> deviceOperator = null;
|
||||
try
|
||||
{
|
||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||
|
||||
Result rc = fsProxy.OpenDeviceOperator(out IDeviceOperator deviceOperator);
|
||||
Result rc = fsProxy.OpenDeviceOperator(out deviceOperator);
|
||||
if (rc.IsFailure()) throw new LibHacException("Abort");
|
||||
|
||||
rc = deviceOperator.IsGameCardInserted(out bool isInserted);
|
||||
rc = deviceOperator.Target.IsGameCardInserted(out bool isInserted);
|
||||
if (rc.IsFailure()) throw new LibHacException("Abort");
|
||||
|
||||
return isInserted;
|
||||
}
|
||||
finally
|
||||
{
|
||||
deviceOperator?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public static Result OpenGameCardPartition(this FileSystemClient fs, out IStorage storage,
|
||||
GameCardHandle handle, GameCardPartitionRaw partitionType)
|
||||
{
|
||||
storage = default;
|
||||
|
||||
ReferenceCountedDisposable<IStorageSf> sfStorage = null;
|
||||
try
|
||||
{
|
||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||
|
||||
return fsProxy.OpenGameCardStorage(out storage, handle, partitionType);
|
||||
Result rc = fsProxy.OpenGameCardStorage(out sfStorage, handle, partitionType);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
storage = new StorageServiceObjectAdapter(sfStorage);
|
||||
return Result.Success;
|
||||
}
|
||||
finally
|
||||
{
|
||||
sfStorage?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public static Result MountGameCardPartition(this FileSystemClient fs, U8Span mountName, GameCardHandle handle,
|
||||
|
|
|
@ -3,7 +3,9 @@ using System.Diagnostics;
|
|||
using System.Runtime.CompilerServices;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Fs.Impl;
|
||||
using LibHac.FsSrv;
|
||||
using LibHac.FsSrv.Sf;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.Util;
|
||||
using static LibHac.Fs.CommonPaths;
|
||||
|
@ -76,12 +78,11 @@ namespace LibHac.Fs.Shim
|
|||
public static Result MountHostRoot(this FileSystemClient fs)
|
||||
{
|
||||
IFileSystem hostFileSystem = default;
|
||||
var path = new FsPath();
|
||||
path.Str[0] = 0;
|
||||
FspPath.CreateEmpty(out FspPath path);
|
||||
|
||||
static string LogMessageGenerator() => $", name: \"{HostRootFileSystemMountName.ToString()}\"";
|
||||
|
||||
Result OpenHostFs() => OpenHostFileSystemImpl(fs, out hostFileSystem, ref path, MountHostOption.None);
|
||||
Result OpenHostFs() => OpenHostFileSystemImpl(fs, out hostFileSystem, in path, MountHostOption.None);
|
||||
|
||||
Result MountHostFs() => fs.Register(HostRootFileSystemMountName, hostFileSystem,
|
||||
new HostRootCommonMountNameGenerator());
|
||||
|
@ -110,13 +111,12 @@ namespace LibHac.Fs.Shim
|
|||
public static Result MountHostRoot(this FileSystemClient fs, MountHostOption option)
|
||||
{
|
||||
IFileSystem hostFileSystem = default;
|
||||
var path = new FsPath();
|
||||
path.Str[0] = 0;
|
||||
FspPath.CreateEmpty(out FspPath path);
|
||||
|
||||
string LogMessageGenerator() =>
|
||||
$", name: \"{HostRootFileSystemMountName.ToString()}, mount_host_option: {option}\"";
|
||||
|
||||
Result OpenHostFs() => OpenHostFileSystemImpl(fs, out hostFileSystem, ref path, option);
|
||||
Result OpenHostFs() => OpenHostFileSystemImpl(fs, out hostFileSystem, in path, option);
|
||||
|
||||
Result MountHostFs() => fs.Register(HostRootFileSystemMountName, hostFileSystem,
|
||||
new HostRootCommonMountNameGenerator());
|
||||
|
@ -318,8 +318,7 @@ namespace LibHac.Fs.Shim
|
|||
if (pathLength + 1 > PathTools.MaxPathLength)
|
||||
return ResultFs.TooLongPath.Log();
|
||||
|
||||
FsPath fullPath;
|
||||
unsafe { _ = &fullPath; } // workaround for CS0165
|
||||
Unsafe.SkipInit(out FsPath fullPath);
|
||||
|
||||
var sb = new U8StringBuilder(fullPath.Str);
|
||||
sb.Append(StringTraits.DirectorySeparator).Append(path);
|
||||
|
@ -341,7 +340,9 @@ namespace LibHac.Fs.Shim
|
|||
}
|
||||
}
|
||||
|
||||
return OpenHostFileSystemImpl(fs, out fileSystem, ref fullPath, option);
|
||||
FspPath.FromSpan(out FspPath sfPath, fullPath.Str);
|
||||
|
||||
return OpenHostFileSystemImpl(fs, out fileSystem, in sfPath, option);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -352,26 +353,34 @@ namespace LibHac.Fs.Shim
|
|||
/// <param name="path">The path on the host computer to open. e.g. /C:\Windows\System32/</param>
|
||||
/// <param name="option">Options for opening the host file system.</param>
|
||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||
private static Result OpenHostFileSystemImpl(FileSystemClient fs, out IFileSystem fileSystem, ref FsPath path, MountHostOption option)
|
||||
private static Result OpenHostFileSystemImpl(FileSystemClient fs, out IFileSystem fileSystem, in FspPath path,
|
||||
MountHostOption option)
|
||||
{
|
||||
fileSystem = default;
|
||||
|
||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||
IFileSystem hostFs;
|
||||
ReferenceCountedDisposable<IFileSystemSf> hostFs = null;
|
||||
|
||||
try
|
||||
{
|
||||
if (option == MountHostOption.None)
|
||||
{
|
||||
Result rc = fsProxy.OpenHostFileSystem(out hostFs, ref path);
|
||||
Result rc = fsProxy.OpenHostFileSystem(out hostFs, in path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result rc = fsProxy.OpenHostFileSystemWithOption(out hostFs, ref path, option);
|
||||
Result rc = fsProxy.OpenHostFileSystemWithOption(out hostFs, in path, option);
|
||||
if (rc.IsFailure()) return rc;
|
||||
}
|
||||
|
||||
fileSystem = hostFs;
|
||||
fileSystem = new FileSystemServiceObjectAdapter(hostFs);
|
||||
return Result.Success;
|
||||
}
|
||||
finally
|
||||
{
|
||||
hostFs?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -212,7 +212,7 @@ namespace LibHac.Fs.Shim
|
|||
SpaceId = spaceId
|
||||
};
|
||||
|
||||
return fsProxy.CreateSaveDataFileSystemBySystemSaveDataId(ref attribute, ref createInfo);
|
||||
return fsProxy.CreateSaveDataFileSystemBySystemSaveDataId(in attribute, in createInfo);
|
||||
},
|
||||
() => $", savedataspaceid: {spaceId}, savedataid: 0x{saveDataId:X}, userid: 0x{userId.Id.High:X16}{userId.Id.Low:X16}, save_data_owner_id: 0x{ownerId:X}, save_data_size: {size}, save_data_journal_size: {journalSize}, save_data_flags: 0x{(int)flags:x8}");
|
||||
}
|
||||
|
|
|
@ -55,17 +55,25 @@ namespace LibHac.Fs.Shim
|
|||
}
|
||||
|
||||
public static bool IsSdCardInserted(this FileSystemClient fs)
|
||||
{
|
||||
ReferenceCountedDisposable<IDeviceOperator> deviceOperator = null;
|
||||
try
|
||||
{
|
||||
IFileSystemProxy fsProxy = fs.GetFileSystemProxyServiceObject();
|
||||
|
||||
Result rc = fsProxy.OpenDeviceOperator(out IDeviceOperator deviceOperator);
|
||||
Result rc = fsProxy.OpenDeviceOperator(out deviceOperator);
|
||||
if (rc.IsFailure()) throw new HorizonResultException(rc, "Abort");
|
||||
|
||||
rc = deviceOperator.IsSdCardInserted(out bool isInserted);
|
||||
rc = deviceOperator.Target.IsSdCardInserted(out bool isInserted);
|
||||
if (rc.IsFailure()) throw new HorizonResultException(rc, "Abort");
|
||||
|
||||
return isInserted;
|
||||
}
|
||||
finally
|
||||
{
|
||||
deviceOperator?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public static Result SetSdCardEncryptionSeed(this FileSystemClient fs, in EncryptionSeed seed)
|
||||
{
|
||||
|
|
|
@ -110,12 +110,12 @@ namespace LibHac.FsSrv.Creators
|
|||
var partitionPath = GetPartitionPath(partitionId).ToU8String();
|
||||
|
||||
ReferenceCountedDisposable<IFileSystem> partitionFileSystem = null;
|
||||
ReferenceCountedDisposable<IFileSystem> sharedRootFs = null;
|
||||
try
|
||||
{
|
||||
// Todo: Store shared file systems
|
||||
using var sharedRootFs = new ReferenceCountedDisposable<IFileSystem>(Config.RootFileSystem);
|
||||
sharedRootFs = new ReferenceCountedDisposable<IFileSystem>(Config.RootFileSystem);
|
||||
|
||||
Result rc = Utility.WrapSubDirectory(out partitionFileSystem, sharedRootFs, partitionPath, true);
|
||||
Result rc = Utility.WrapSubDirectory(out partitionFileSystem, ref sharedRootFs, partitionPath, true);
|
||||
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
|
@ -125,11 +125,12 @@ namespace LibHac.FsSrv.Creators
|
|||
return Result.Success;
|
||||
}
|
||||
|
||||
return Utility.CreateSubDirectoryFileSystem(out fileSystem, partitionFileSystem, rootPath);
|
||||
return Utility.CreateSubDirectoryFileSystem(out fileSystem, ref partitionFileSystem, rootPath);
|
||||
}
|
||||
finally
|
||||
{
|
||||
partitionFileSystem?.Dispose();
|
||||
sharedRootFs?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,11 +5,7 @@ namespace LibHac.FsSrv.Creators
|
|||
{
|
||||
public interface ISubDirectoryFileSystemCreator
|
||||
{
|
||||
// Todo: Remove the raw IFileSystem overloads
|
||||
Result Create(out IFileSystem subDirFileSystem, IFileSystem baseFileSystem, U8Span path);
|
||||
Result Create(out IFileSystem subDirFileSystem, IFileSystem baseFileSystem, U8Span path, bool preserveUnc);
|
||||
|
||||
Result Create(out ReferenceCountedDisposable<IFileSystem> subDirFileSystem, ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path);
|
||||
Result Create(out ReferenceCountedDisposable<IFileSystem> subDirFileSystem, ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path, bool preserveUnc);
|
||||
Result Create(out ReferenceCountedDisposable<IFileSystem> subDirFileSystem, ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path);
|
||||
Result Create(out ReferenceCountedDisposable<IFileSystem> subDirFileSystem, ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path, bool preserveUnc);
|
||||
}
|
||||
}
|
|
@ -6,31 +6,14 @@ namespace LibHac.FsSrv.Creators
|
|||
{
|
||||
public class SubDirectoryFileSystemCreator : ISubDirectoryFileSystemCreator
|
||||
{
|
||||
public Result Create(out IFileSystem subDirFileSystem, IFileSystem baseFileSystem, U8Span path)
|
||||
public Result Create(out ReferenceCountedDisposable<IFileSystem> subDirFileSystem,
|
||||
ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path)
|
||||
{
|
||||
return Create(out subDirFileSystem, baseFileSystem, path, false);
|
||||
}
|
||||
|
||||
public Result Create(out IFileSystem subDirFileSystem, IFileSystem baseFileSystem, U8Span path, bool preserveUnc)
|
||||
{
|
||||
subDirFileSystem = default;
|
||||
|
||||
Result rc = baseFileSystem.OpenDirectory(out IDirectory _, path, OpenDirectoryMode.Directory);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = SubdirectoryFileSystem.CreateNew(out SubdirectoryFileSystem fs, baseFileSystem, path.ToU8String(), preserveUnc);
|
||||
subDirFileSystem = fs;
|
||||
return rc;
|
||||
return Create(out subDirFileSystem, ref baseFileSystem, path, false);
|
||||
}
|
||||
|
||||
public Result Create(out ReferenceCountedDisposable<IFileSystem> subDirFileSystem,
|
||||
ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path)
|
||||
{
|
||||
return Create(out subDirFileSystem, baseFileSystem, path, false);
|
||||
}
|
||||
|
||||
public Result Create(out ReferenceCountedDisposable<IFileSystem> subDirFileSystem,
|
||||
ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path, bool preserveUnc)
|
||||
ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path, bool preserveUnc)
|
||||
{
|
||||
subDirFileSystem = default;
|
||||
|
||||
|
@ -39,7 +22,7 @@ namespace LibHac.FsSrv.Creators
|
|||
if (rc.IsFailure()) return rc;
|
||||
|
||||
// Initialize the SubdirectoryFileSystem
|
||||
var subDir = new SubdirectoryFileSystem(baseFileSystem, preserveUnc);
|
||||
var subDir = new SubdirectoryFileSystem(ref baseFileSystem, preserveUnc);
|
||||
using var subDirShared = new ReferenceCountedDisposable<SubdirectoryFileSystem>(subDir);
|
||||
|
||||
rc = subDirShared.Target.Initialize(path);
|
||||
|
|
|
@ -13,6 +13,8 @@ namespace LibHac.FsSrv
|
|||
SdCard = sdCard;
|
||||
}
|
||||
|
||||
public void Dispose() { }
|
||||
|
||||
public Result IsSdCardInserted(out bool isInserted)
|
||||
{
|
||||
isInserted = SdCard.IsSdCardInserted();
|
||||
|
|
|
@ -4,6 +4,8 @@ using LibHac.Fs;
|
|||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Fs.Shim;
|
||||
using LibHac.FsSrv.Creators;
|
||||
using LibHac.FsSrv.Impl;
|
||||
using LibHac.FsSrv.Sf;
|
||||
|
||||
namespace LibHac.FsSrv
|
||||
{
|
||||
|
@ -13,7 +15,7 @@ namespace LibHac.FsSrv
|
|||
private FileSystemCreators FsCreators => Config.FsCreatorInterfaces;
|
||||
internal ProgramRegistryImpl ProgramRegistry { get; }
|
||||
|
||||
private IDeviceOperator DeviceOperator { get; }
|
||||
private ReferenceCountedDisposable<IDeviceOperator> DeviceOperator { get; }
|
||||
|
||||
private byte[] SdEncryptionSeed { get; } = new byte[0x10];
|
||||
|
||||
|
@ -27,31 +29,57 @@ namespace LibHac.FsSrv
|
|||
{
|
||||
Config = config;
|
||||
ProgramRegistry = new ProgramRegistryImpl(Config.ProgramRegistryService);
|
||||
DeviceOperator = deviceOperator;
|
||||
DeviceOperator = new ReferenceCountedDisposable<IDeviceOperator>(deviceOperator);
|
||||
}
|
||||
|
||||
public Result OpenGameCardStorage(out IStorage storage, GameCardHandle handle, GameCardPartitionRaw partitionId)
|
||||
public Result OpenGameCardStorage(out ReferenceCountedDisposable<IStorageSf> storage, GameCardHandle handle,
|
||||
GameCardPartitionRaw partitionId)
|
||||
{
|
||||
storage = default;
|
||||
|
||||
Result rc;
|
||||
IStorage gcStorage = null;
|
||||
ReferenceCountedDisposable<IStorage> sharedGcStorage = null;
|
||||
try
|
||||
{
|
||||
switch (partitionId)
|
||||
{
|
||||
case GameCardPartitionRaw.NormalReadOnly:
|
||||
return FsCreators.GameCardStorageCreator.CreateNormal(handle, out storage);
|
||||
rc = FsCreators.GameCardStorageCreator.CreateNormal(handle, out gcStorage);
|
||||
break;
|
||||
case GameCardPartitionRaw.SecureReadOnly:
|
||||
return FsCreators.GameCardStorageCreator.CreateSecure(handle, out storage);
|
||||
rc = FsCreators.GameCardStorageCreator.CreateSecure(handle, out gcStorage);
|
||||
break;
|
||||
case GameCardPartitionRaw.RootWriteOnly:
|
||||
return FsCreators.GameCardStorageCreator.CreateWritable(handle, out storage);
|
||||
rc = FsCreators.GameCardStorageCreator.CreateWritable(handle, out gcStorage);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(partitionId), partitionId, null);
|
||||
}
|
||||
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
sharedGcStorage = new ReferenceCountedDisposable<IStorage>(gcStorage);
|
||||
gcStorage = null;
|
||||
|
||||
storage = StorageInterfaceAdapter.CreateShared(ref sharedGcStorage);
|
||||
return Result.Success;
|
||||
}
|
||||
finally
|
||||
{
|
||||
gcStorage?.Dispose();
|
||||
sharedGcStorage?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public Result OpenDeviceOperator(out IDeviceOperator deviceOperator)
|
||||
public Result OpenDeviceOperator(out ReferenceCountedDisposable<IDeviceOperator> deviceOperator)
|
||||
{
|
||||
deviceOperator = DeviceOperator;
|
||||
deviceOperator = DeviceOperator.AddReference();
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
public Result OpenCustomStorageFileSystem(out IFileSystem fileSystem, CustomStorageId storageId)
|
||||
public Result OpenCustomStorageFileSystem(out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
||||
CustomStorageId storageId)
|
||||
{
|
||||
fileSystem = default;
|
||||
|
||||
|
@ -72,7 +100,7 @@ namespace LibHac.FsSrv
|
|||
EncryptedFsKeyId.CustomStorage, SdEncryptionSeed);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
fileSystem = encryptedFs;
|
||||
fileSystem = new ReferenceCountedDisposable<IFileSystem>(encryptedFs);
|
||||
return Result.Success;
|
||||
}
|
||||
case CustomStorageId.System:
|
||||
|
@ -87,7 +115,8 @@ namespace LibHac.FsSrv
|
|||
rc = Util.CreateSubFileSystem(out IFileSystem subFs, userFs, subDirName, true);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
fileSystem = subFs;
|
||||
// Todo: Get shared object from earlier functions
|
||||
fileSystem = new ReferenceCountedDisposable<IFileSystem>(subFs);
|
||||
return Result.Success;
|
||||
}
|
||||
default:
|
||||
|
@ -95,7 +124,8 @@ namespace LibHac.FsSrv
|
|||
}
|
||||
}
|
||||
|
||||
public Result OpenHostFileSystem(out IFileSystem fileSystem, U8Span path, bool openCaseSensitive)
|
||||
public Result OpenHostFileSystem(out ReferenceCountedDisposable<IFileSystem> fileSystem, U8Span path,
|
||||
bool openCaseSensitive)
|
||||
{
|
||||
fileSystem = default;
|
||||
Result rc;
|
||||
|
@ -106,28 +136,43 @@ namespace LibHac.FsSrv
|
|||
if (rc.IsFailure()) return rc;
|
||||
}
|
||||
|
||||
// Todo: Return shared fs from Create
|
||||
rc = FsCreators.TargetManagerFileSystemCreator.Create(out IFileSystem hostFs, openCaseSensitive);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
ReferenceCountedDisposable<IFileSystem> sharedHostFs = null;
|
||||
ReferenceCountedDisposable<IFileSystem> subDirFs = null;
|
||||
|
||||
try
|
||||
{
|
||||
sharedHostFs = new ReferenceCountedDisposable<IFileSystem>(hostFs);
|
||||
|
||||
if (path.IsEmpty())
|
||||
{
|
||||
ReadOnlySpan<byte> rootHostPath = new[] { (byte)'C', (byte)':', (byte)'/' };
|
||||
rc = hostFs.GetEntryType(out _, new U8Span(rootHostPath));
|
||||
rc = sharedHostFs.Target.GetEntryType(out _, new U8Span(rootHostPath));
|
||||
|
||||
// Nintendo ignores all results other than this one
|
||||
if (ResultFs.TargetNotFound.Includes(rc))
|
||||
return rc;
|
||||
|
||||
fileSystem = hostFs;
|
||||
Shared.Move(out fileSystem, ref sharedHostFs);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
rc = FsCreators.SubDirectoryFileSystemCreator.Create(out IFileSystem subDirFs, hostFs, path, preserveUnc: true);
|
||||
rc = FsCreators.SubDirectoryFileSystemCreator.Create(out subDirFs, ref sharedHostFs, path,
|
||||
preserveUnc: true);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
fileSystem = subDirFs;
|
||||
return Result.Success;
|
||||
}
|
||||
finally
|
||||
{
|
||||
sharedHostFs?.Dispose();
|
||||
subDirFs?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public Result SetSdCardEncryptionSeed(in EncryptionSeed seed)
|
||||
{
|
||||
|
|
|
@ -254,8 +254,8 @@ namespace LibHac.FsSrv
|
|||
in hashSalt);
|
||||
}
|
||||
|
||||
public Result CreateSaveDataFileSystemBySystemSaveDataId(ref SaveDataAttribute attribute,
|
||||
ref SaveDataCreationInfo creationInfo)
|
||||
public Result CreateSaveDataFileSystemBySystemSaveDataId(in SaveDataAttribute attribute,
|
||||
in SaveDataCreationInfo creationInfo)
|
||||
{
|
||||
Result rc = GetSaveDataFileSystemService(out SaveDataFileSystemService saveFsService);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
@ -399,17 +399,44 @@ namespace LibHac.FsSrv
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result OpenHostFileSystem(out IFileSystem fileSystem, ref FsPath path)
|
||||
public Result OpenHostFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, in FspPath path)
|
||||
{
|
||||
return OpenHostFileSystemWithOption(out fileSystem, ref path, MountHostOption.None);
|
||||
return OpenHostFileSystemWithOption(out fileSystem, in path, MountHostOption.None);
|
||||
}
|
||||
|
||||
public Result OpenHostFileSystemWithOption(out IFileSystem fileSystem, ref FsPath path, MountHostOption option)
|
||||
public Result OpenHostFileSystemWithOption(out ReferenceCountedDisposable<IFileSystemSf> fileSystem,
|
||||
in FspPath path, MountHostOption option)
|
||||
{
|
||||
// Missing permission check
|
||||
fileSystem = default;
|
||||
|
||||
return FsProxyCore.OpenHostFileSystem(out fileSystem, new U8Span(path.Str),
|
||||
Result rc = GetProgramInfo(out ProgramInfo programInfo);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
Accessibility accessibility = programInfo.AccessControl.GetAccessibilityFor(AccessibilityType.MountHost);
|
||||
|
||||
if (!accessibility.CanRead || !accessibility.CanWrite)
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
ReferenceCountedDisposable<IFileSystem> hostFs = null;
|
||||
try
|
||||
{
|
||||
rc = FsProxyCore.OpenHostFileSystem(out hostFs, new U8Span(path.Str),
|
||||
option.HasFlag(MountHostOption.PseudoCaseSensitive));
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
bool isRootPath = path.Str[0] == 0;
|
||||
|
||||
fileSystem = FileSystemInterfaceAdapter.CreateShared(ref hostFs, isRootPath);
|
||||
|
||||
if (fileSystem is null)
|
||||
return ResultFs.AllocationFailureInCreateShared.Log();
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
finally
|
||||
{
|
||||
hostFs?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public Result OpenSdCardFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem)
|
||||
|
@ -432,20 +459,31 @@ namespace LibHac.FsSrv
|
|||
return GetBaseFileSystemService().IsExFatSupported(out isSupported);
|
||||
}
|
||||
|
||||
public Result OpenGameCardStorage(out IStorage storage, GameCardHandle handle, GameCardPartitionRaw partitionId)
|
||||
public Result OpenGameCardStorage(out ReferenceCountedDisposable<IStorageSf> storage, GameCardHandle handle,
|
||||
GameCardPartitionRaw partitionId)
|
||||
{
|
||||
// Missing permission check and StorageInterfaceAdapter
|
||||
|
||||
return FsProxyCore.OpenGameCardStorage(out storage, handle, partitionId);
|
||||
}
|
||||
|
||||
public Result OpenDeviceOperator(out IDeviceOperator deviceOperator)
|
||||
public Result OpenDeviceOperator(out ReferenceCountedDisposable<IDeviceOperator> deviceOperator)
|
||||
{
|
||||
// Missing permission check
|
||||
|
||||
return FsProxyCore.OpenDeviceOperator(out deviceOperator);
|
||||
}
|
||||
|
||||
public Result OpenSdCardDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result OpenGameCardDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result OpenSystemDataUpdateEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier)
|
||||
{
|
||||
Result rc = GetNcaFileSystemService(out NcaFileSystemService ncaFsService);
|
||||
|
@ -659,11 +697,37 @@ namespace LibHac.FsSrv
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Result OpenCustomStorageFileSystem(out IFileSystem fileSystem, CustomStorageId storageId)
|
||||
public Result OpenCustomStorageFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, CustomStorageId storageId)
|
||||
{
|
||||
// Missing permission check, speed emulation storage type wrapper, and FileSystemInterfaceAdapter
|
||||
fileSystem = default;
|
||||
var storageFlag = StorageType.NonGameCard;
|
||||
using var scopedLayoutType = new ScopedStorageLayoutTypeSetter(storageFlag);
|
||||
|
||||
return FsProxyCore.OpenCustomStorageFileSystem(out fileSystem, storageId);
|
||||
Result rc = GetProgramInfo(out ProgramInfo programInfo);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
AccessibilityType accessType = storageId > CustomStorageId.SdCard
|
||||
? AccessibilityType.NotMount
|
||||
: AccessibilityType.MountCustomStorage;
|
||||
|
||||
Accessibility accessibility = programInfo.AccessControl.GetAccessibilityFor(accessType);
|
||||
|
||||
if (!accessibility.CanRead || !accessibility.CanWrite)
|
||||
return ResultFs.PermissionDenied.Log();
|
||||
|
||||
ReferenceCountedDisposable<IFileSystem> customFs = null;
|
||||
try
|
||||
{
|
||||
customFs = StorageLayoutTypeSetFileSystem.CreateShared(ref customFs, storageFlag);
|
||||
customFs = AsynchronousAccessFileSystem.CreateShared(ref customFs);
|
||||
fileSystem = FileSystemInterfaceAdapter.CreateShared(ref customFs);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
finally
|
||||
{
|
||||
customFs?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public Result OpenGameCardFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem,
|
||||
|
@ -766,7 +830,7 @@ namespace LibHac.FsSrv
|
|||
.RegisterProgramIndexMapInfo(programIndexMapInfoBuffer, programCount);
|
||||
}
|
||||
|
||||
public Result SetBisRootForHost(BisPartitionId partitionId, ref FsPath path)
|
||||
public Result SetBisRootForHost(BisPartitionId partitionId, in FspPath path)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
@ -839,7 +903,7 @@ namespace LibHac.FsSrv
|
|||
return GetProgramIndexRegistryService().GetProgramIndex(out programIndex, out programCount);
|
||||
}
|
||||
|
||||
public Result OutputAccessLogToSdCard(U8Span logString)
|
||||
public Result OutputAccessLogToSdCard(InBuffer logString)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
namespace LibHac.FsSrv
|
||||
using System;
|
||||
|
||||
namespace LibHac.FsSrv
|
||||
{
|
||||
public interface IDeviceOperator
|
||||
public interface IDeviceOperator : IDisposable
|
||||
{
|
||||
Result IsSdCardInserted(out bool isInserted);
|
||||
Result IsGameCardInserted(out bool isInserted);
|
||||
|
|
|
@ -20,24 +20,24 @@ namespace LibHac.FsSrv
|
|||
Result OpenBisFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, in FspPath rootPath, BisPartitionId partitionId);
|
||||
Result OpenBisStorage(out ReferenceCountedDisposable<IStorageSf> storage, BisPartitionId partitionId);
|
||||
Result InvalidateBisCache();
|
||||
Result OpenHostFileSystemWithOption(out IFileSystem fileSystem, ref FsPath path, MountHostOption option);
|
||||
Result OpenHostFileSystem(out IFileSystem fileSystem, ref FsPath path);
|
||||
Result OpenHostFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, in FspPath path);
|
||||
Result OpenSdCardFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem);
|
||||
Result FormatSdCardFileSystem();
|
||||
Result DeleteSaveDataFileSystem(ulong saveDataId);
|
||||
Result CreateSaveDataFileSystem(in SaveDataAttribute attribute, in SaveDataCreationInfo creationInfo, in SaveDataMetaInfo metaInfo);
|
||||
Result CreateSaveDataFileSystemBySystemSaveDataId(ref SaveDataAttribute attribute, ref SaveDataCreationInfo creationInfo);
|
||||
Result CreateSaveDataFileSystemBySystemSaveDataId(in SaveDataAttribute attribute, in SaveDataCreationInfo creationInfo);
|
||||
Result RegisterSaveDataFileSystemAtomicDeletion(InBuffer saveDataIds);
|
||||
Result DeleteSaveDataFileSystemBySaveDataSpaceId(SaveDataSpaceId spaceId, ulong saveDataId);
|
||||
Result FormatSdCardDryRun();
|
||||
Result IsExFatSupported(out bool isSupported);
|
||||
Result DeleteSaveDataFileSystemBySaveDataAttribute(SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
||||
Result OpenGameCardStorage(out IStorage storage, GameCardHandle handle, GameCardPartitionRaw partitionId);
|
||||
Result OpenGameCardStorage(out ReferenceCountedDisposable<IStorageSf> storage, GameCardHandle handle, GameCardPartitionRaw partitionId);
|
||||
Result OpenGameCardFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, GameCardHandle handle, GameCardPartition partitionId);
|
||||
Result ExtendSaveDataFileSystem(SaveDataSpaceId spaceId, ulong saveDataId, long dataSize, long journalSize);
|
||||
Result DeleteCacheStorage(ushort index);
|
||||
Result GetCacheStorageSize(out long dataSize, out long journalSize, ushort index);
|
||||
Result CreateSaveDataFileSystemWithHashSalt(in SaveDataAttribute attribute, in SaveDataCreationInfo creationInfo, in SaveDataMetaInfo metaInfo, in HashSalt hashSalt);
|
||||
Result OpenHostFileSystemWithOption(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, in FspPath path, MountHostOption option);
|
||||
Result OpenSaveDataFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
||||
Result OpenSaveDataFileSystemBySystemSaveDataId(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
||||
Result OpenReadOnlySaveDataFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, SaveDataSpaceId spaceId, in SaveDataAttribute attribute);
|
||||
|
@ -62,15 +62,17 @@ namespace LibHac.FsSrv
|
|||
Result OpenImageDirectoryFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, ImageDirectoryId directoryId);
|
||||
Result OpenContentStorageFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, ContentStorageId storageId);
|
||||
Result OpenCloudBackupWorkStorageFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, CloudBackupWorkStorageId storageId);
|
||||
Result OpenCustomStorageFileSystem(out IFileSystem fileSystem, CustomStorageId storageId);
|
||||
Result OpenCustomStorageFileSystem(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, CustomStorageId storageId);
|
||||
Result OpenDataStorageByCurrentProcess(out ReferenceCountedDisposable<IStorageSf> storage);
|
||||
Result OpenDataStorageByProgramId(out ReferenceCountedDisposable<IStorageSf> storage, ProgramId programId);
|
||||
Result OpenDataStorageByDataId(out ReferenceCountedDisposable<IStorageSf> storage, DataId dataId, StorageId storageId);
|
||||
Result OpenPatchDataStorageByCurrentProcess(out ReferenceCountedDisposable<IStorageSf> storage);
|
||||
Result OpenDataFileSystemWithProgramIndex(out ReferenceCountedDisposable<IFileSystemSf> fileSystem, byte programIndex);
|
||||
Result OpenDataStorageWithProgramIndex(out ReferenceCountedDisposable<IStorageSf> storage, byte programIndex);
|
||||
Result OpenDeviceOperator(out IDeviceOperator deviceOperator);
|
||||
Result OpenDeviceOperator(out ReferenceCountedDisposable<IDeviceOperator> deviceOperator);
|
||||
|
||||
Result OpenSdCardDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier);
|
||||
Result OpenGameCardDetectionEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier);
|
||||
Result OpenSystemDataUpdateEventNotifier(out ReferenceCountedDisposable<IEventNotifier> eventNotifier);
|
||||
Result NotifySystemDataUpdateEvent();
|
||||
|
||||
|
@ -96,13 +98,13 @@ namespace LibHac.FsSrv
|
|||
Result IsSdCardAccessible(out bool isAccessible);
|
||||
|
||||
Result RegisterProgramIndexMapInfo(InBuffer programIndexMapInfoBuffer, int programCount);
|
||||
Result SetBisRootForHost(BisPartitionId partitionId, ref FsPath path);
|
||||
Result SetBisRootForHost(BisPartitionId partitionId, in FspPath path);
|
||||
Result SetSaveDataSize(long saveDataSize, long saveDataJournalSize);
|
||||
Result SetSaveDataRootPath(in FspPath path);
|
||||
Result DisableAutoSaveDataCreation();
|
||||
Result SetGlobalAccessLogMode(GlobalAccessLogMode mode);
|
||||
Result GetGlobalAccessLogMode(out GlobalAccessLogMode mode);
|
||||
Result OutputAccessLogToSdCard(U8Span logString);
|
||||
Result OutputAccessLogToSdCard(InBuffer logString);
|
||||
Result RegisterUpdatePartition();
|
||||
Result OpenRegisteredUpdatePartition(out ReferenceCountedDisposable<IFileSystemSf> fileSystem);
|
||||
|
||||
|
|
|
@ -10,9 +10,21 @@ namespace LibHac.FsSrv.Impl
|
|||
{
|
||||
private ReferenceCountedDisposable<IStorage> BaseStorage { get; }
|
||||
|
||||
public StorageInterfaceAdapter(ReferenceCountedDisposable<IStorage> baseStorage)
|
||||
private StorageInterfaceAdapter(ref ReferenceCountedDisposable<IStorage> baseStorage)
|
||||
{
|
||||
BaseStorage = baseStorage.AddReference();
|
||||
BaseStorage = Shared.Move(ref baseStorage);
|
||||
}
|
||||
|
||||
public static ReferenceCountedDisposable<IStorageSf> CreateShared(
|
||||
ref ReferenceCountedDisposable<IStorage> baseStorage)
|
||||
{
|
||||
var adapter = new StorageInterfaceAdapter(ref baseStorage);
|
||||
return new ReferenceCountedDisposable<IStorageSf>(adapter);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
BaseStorage?.Dispose();
|
||||
}
|
||||
|
||||
public Result Read(long offset, Span<byte> destination)
|
||||
|
@ -47,7 +59,7 @@ namespace LibHac.FsSrv.Impl
|
|||
if (source.Length < 0)
|
||||
return ResultFs.InvalidSize.Log();
|
||||
|
||||
// Note: Thread priority is temporarily when writing in FS
|
||||
// Note: Thread priority is temporarily increased when writing in FS
|
||||
|
||||
return BaseStorage.Target.Write(offset, source);
|
||||
}
|
||||
|
@ -93,9 +105,5 @@ namespace LibHac.FsSrv.Impl
|
|||
|
||||
return Result.Success;
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
BaseStorage?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ namespace LibHac.FsSrv.Impl
|
|||
}
|
||||
|
||||
public static Result CreateSubDirectoryFileSystem(out ReferenceCountedDisposable<IFileSystem> subDirFileSystem,
|
||||
ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span subPath, bool preserveUnc = false)
|
||||
ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span subPath, bool preserveUnc = false)
|
||||
{
|
||||
subDirFileSystem = default;
|
||||
|
||||
|
@ -132,7 +132,7 @@ namespace LibHac.FsSrv.Impl
|
|||
|
||||
dir.Dispose();
|
||||
|
||||
var fs = new SubdirectoryFileSystem(baseFileSystem, preserveUnc);
|
||||
var fs = new SubdirectoryFileSystem(ref baseFileSystem, preserveUnc);
|
||||
using (var subDirFs = new ReferenceCountedDisposable<SubdirectoryFileSystem>(fs))
|
||||
{
|
||||
rc = subDirFs.Target.Initialize(subPath);
|
||||
|
@ -144,7 +144,7 @@ namespace LibHac.FsSrv.Impl
|
|||
}
|
||||
|
||||
public static Result WrapSubDirectory(out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
||||
ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path, bool createIfMissing)
|
||||
ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path, bool createIfMissing)
|
||||
{
|
||||
fileSystem = default;
|
||||
|
||||
|
@ -159,7 +159,7 @@ namespace LibHac.FsSrv.Impl
|
|||
Result rc = EnsureDirectory(baseFileSystem.Target, path);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return CreateSubDirectoryFileSystem(out fileSystem, baseFileSystem, path);
|
||||
return CreateSubDirectoryFileSystem(out fileSystem, ref baseFileSystem, path);
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<byte> FileSystemRootPath => // /
|
||||
|
|
|
@ -100,17 +100,29 @@ namespace LibHac.FsSrv
|
|||
|
||||
if (type == FileSystemProxyType.Manual)
|
||||
{
|
||||
rc = TryOpenCaseSensitiveContentDirectory(
|
||||
out ReferenceCountedDisposable<IFileSystem> manualFileSystem, baseFileSystem, currentPath);
|
||||
ReferenceCountedDisposable<IFileSystem> manualFileSystem = null;
|
||||
ReferenceCountedDisposable<IFileSystem> readOnlyFileSystem = null;
|
||||
try
|
||||
{
|
||||
rc = TryOpenCaseSensitiveContentDirectory(out manualFileSystem, ref baseFileSystem,
|
||||
currentPath);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
var readOnlyFs = new ReadOnlyFileSystem(manualFileSystem);
|
||||
fileSystem = new ReferenceCountedDisposable<IFileSystem>(readOnlyFs);
|
||||
readOnlyFileSystem = ReadOnlyFileSystem.CreateShared(ref manualFileSystem);
|
||||
if (readOnlyFileSystem?.Target is null)
|
||||
return ResultFs.AllocationFailureInAllocateShared.Log();
|
||||
|
||||
Shared.Move(out fileSystem, ref readOnlyFileSystem);
|
||||
return Result.Success;
|
||||
}
|
||||
finally
|
||||
{
|
||||
manualFileSystem?.Dispose();
|
||||
readOnlyFileSystem?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
return TryOpenContentDirectory(currentPath, out fileSystem, baseFileSystem, type, true);
|
||||
return TryOpenContentDirectory(currentPath, out fileSystem, ref baseFileSystem, type, true);
|
||||
}
|
||||
|
||||
rc = TryOpenNsp(ref currentPath, out ReferenceCountedDisposable<IFileSystem> nspFileSystem, baseFileSystem);
|
||||
|
@ -371,20 +383,27 @@ namespace LibHac.FsSrv
|
|||
|
||||
private Result TryOpenContentDirectory(U8Span path,
|
||||
out ReferenceCountedDisposable<IFileSystem> contentFileSystem,
|
||||
ReferenceCountedDisposable<IFileSystem> baseFileSystem, FileSystemProxyType fsType, bool preserveUnc)
|
||||
ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, FileSystemProxyType fsType, bool preserveUnc)
|
||||
{
|
||||
contentFileSystem = default;
|
||||
|
||||
Result rc = _config.SubDirectoryFsCreator.Create(out ReferenceCountedDisposable<IFileSystem> subDirFs,
|
||||
baseFileSystem, path, preserveUnc);
|
||||
ReferenceCountedDisposable<IFileSystem> subDirFs = null;
|
||||
try
|
||||
{
|
||||
Result rc = _config.SubDirectoryFsCreator.Create(out subDirFs, ref baseFileSystem, path, preserveUnc);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return OpenSubDirectoryForFsType(out contentFileSystem, subDirFs, fsType);
|
||||
return OpenSubDirectoryForFsType(out contentFileSystem, ref subDirFs, fsType);
|
||||
}
|
||||
finally
|
||||
{
|
||||
subDirFs?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private Result TryOpenCaseSensitiveContentDirectory(
|
||||
out ReferenceCountedDisposable<IFileSystem> contentFileSystem,
|
||||
ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path)
|
||||
ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, U8Span path)
|
||||
{
|
||||
contentFileSystem = default;
|
||||
Unsafe.SkipInit(out FsPath fullPath);
|
||||
|
@ -408,11 +427,11 @@ namespace LibHac.FsSrv
|
|||
if (rc.IsFailure()) return rc;
|
||||
}
|
||||
|
||||
return _config.SubDirectoryFsCreator.Create(out contentFileSystem, baseFileSystem, fullPath);
|
||||
return _config.SubDirectoryFsCreator.Create(out contentFileSystem, ref baseFileSystem, fullPath);
|
||||
}
|
||||
|
||||
private Result OpenSubDirectoryForFsType(out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
||||
ReferenceCountedDisposable<IFileSystem> baseFileSystem, FileSystemProxyType fsType)
|
||||
ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, FileSystemProxyType fsType)
|
||||
{
|
||||
fileSystem = default;
|
||||
ReadOnlySpan<byte> dirName;
|
||||
|
@ -442,9 +461,11 @@ namespace LibHac.FsSrv
|
|||
return ResultFs.InvalidArgument.Log();
|
||||
}
|
||||
|
||||
ReferenceCountedDisposable<IFileSystem> subDirFs = null;
|
||||
try
|
||||
{
|
||||
// Open the subdirectory filesystem
|
||||
Result rc = _config.SubDirectoryFsCreator.Create(out ReferenceCountedDisposable<IFileSystem> subDirFs,
|
||||
baseFileSystem, new U8Span(dirName));
|
||||
Result rc = _config.SubDirectoryFsCreator.Create(out subDirFs, ref baseFileSystem, new U8Span(dirName));
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (fsType == FileSystemProxyType.Code)
|
||||
|
@ -453,9 +474,14 @@ namespace LibHac.FsSrv
|
|||
if (rc.IsFailure()) return rc;
|
||||
}
|
||||
|
||||
fileSystem = subDirFs;
|
||||
Shared.Move(out fileSystem, ref subDirFs);
|
||||
return Result.Success;
|
||||
}
|
||||
finally
|
||||
{
|
||||
subDirFs?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private Result TryOpenNsp(ref U8Span path, out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
||||
ReferenceCountedDisposable<IFileSystem> baseFileSystem)
|
||||
|
@ -659,8 +685,11 @@ namespace LibHac.FsSrv
|
|||
if (rc.IsFailure()) return rc;
|
||||
}
|
||||
|
||||
rc = _config.TargetManagerFsCreator.Create(out ReferenceCountedDisposable<IFileSystem> hostFs,
|
||||
openCaseSensitive);
|
||||
ReferenceCountedDisposable<IFileSystem> hostFs = null;
|
||||
ReferenceCountedDisposable<IFileSystem> subDirFs = null;
|
||||
try
|
||||
{
|
||||
rc = _config.TargetManagerFsCreator.Create(out hostFs, openCaseSensitive);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
if (path.IsEmpty())
|
||||
|
@ -672,17 +701,22 @@ namespace LibHac.FsSrv
|
|||
if (ResultFs.TargetNotFound.Includes(rc))
|
||||
return rc;
|
||||
|
||||
fileSystem = hostFs;
|
||||
Shared.Move(out fileSystem, ref hostFs);
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
rc = _config.SubDirectoryFsCreator.Create(out ReferenceCountedDisposable<IFileSystem> subDirFs, hostFs,
|
||||
path, preserveUnc: true);
|
||||
rc = _config.SubDirectoryFsCreator.Create(out subDirFs, ref hostFs, path, preserveUnc: true);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
fileSystem = subDirFs;
|
||||
Shared.Move(out fileSystem, ref subDirFs);
|
||||
return Result.Success;
|
||||
}
|
||||
finally
|
||||
{
|
||||
hostFs?.Dispose();
|
||||
subDirFs?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public Result OpenFileSystemWithPatch(out ReferenceCountedDisposable<IFileSystem> fileSystem,
|
||||
ProgramId programId, FileSystemProxyType fsType)
|
||||
|
@ -746,7 +780,7 @@ namespace LibHac.FsSrv
|
|||
rc = Utility.EnsureDirectory(baseFileSystem.Target, new U8Span(contentStoragePath));
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
rc = _config.SubDirectoryFsCreator.Create(out subDirFileSystem, baseFileSystem,
|
||||
rc = _config.SubDirectoryFsCreator.Create(out subDirFileSystem, ref baseFileSystem,
|
||||
new U8Span(contentStoragePath));
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
|
@ -754,8 +788,7 @@ namespace LibHac.FsSrv
|
|||
if (contentStorageId != ContentStorageId.SdCard)
|
||||
{
|
||||
// Move the shared reference to the out variable
|
||||
fileSystem = subDirFileSystem;
|
||||
subDirFileSystem = null;
|
||||
Shared.Move(out fileSystem, ref subDirFileSystem);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
@ -765,8 +798,7 @@ namespace LibHac.FsSrv
|
|||
EncryptedFsKeyId.Content, in _encryptionSeed);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
fileSystem = encryptedFileSystem;
|
||||
encryptedFileSystem = null;
|
||||
Shared.Move(out fileSystem, ref encryptedFileSystem);
|
||||
|
||||
return Result.Success;
|
||||
}
|
||||
|
|
|
@ -437,7 +437,7 @@ namespace LibHac.FsSrv
|
|||
rc = _config.TargetManagerFsCreator.Create(out tmFs, isTargetFsCaseSensitive);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return Utility.CreateSubDirectoryFileSystem(out fileSystem, tmFs, new U8Span(path.Str), true);
|
||||
return Utility.CreateSubDirectoryFileSystem(out fileSystem, ref tmFs, new U8Span(path.Str), true);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -482,14 +482,14 @@ namespace LibHac.FsSrv
|
|||
rc = _config.BaseFsService.OpenBisFileSystem(out tempFs, U8Span.Empty, BisPartitionId.System, true);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return Utility.WrapSubDirectory(out fileSystem, tempFs, basePath, createIfMissing);
|
||||
return Utility.WrapSubDirectory(out fileSystem, ref tempFs, basePath, createIfMissing);
|
||||
|
||||
case SaveDataSpaceId.User:
|
||||
case SaveDataSpaceId.Temporary:
|
||||
rc = _config.BaseFsService.OpenBisFileSystem(out tempFs, U8Span.Empty, BisPartitionId.User, true);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return Utility.WrapSubDirectory(out fileSystem, tempFs, basePath, createIfMissing);
|
||||
return Utility.WrapSubDirectory(out fileSystem, ref tempFs, basePath, createIfMissing);
|
||||
|
||||
case SaveDataSpaceId.SdSystem:
|
||||
case SaveDataSpaceId.SdCache:
|
||||
|
@ -503,7 +503,7 @@ namespace LibHac.FsSrv
|
|||
.Append((byte)'/')
|
||||
.Append(CommonPaths.SdCardNintendoRootDirectoryName);
|
||||
|
||||
rc = Utility.WrapSubDirectory(out tempSubFs, tempFs, path, createIfMissing);
|
||||
rc = Utility.WrapSubDirectory(out tempSubFs, ref tempFs, path, createIfMissing);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return _config.EncryptedFsCreator.Create(out fileSystem, tempSubFs, EncryptedFsKeyId.Save,
|
||||
|
@ -513,13 +513,13 @@ namespace LibHac.FsSrv
|
|||
rc = _config.BaseFsService.OpenBisFileSystem(out tempFs, U8Span.Empty, BisPartitionId.SystemProperPartition, true);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return Utility.WrapSubDirectory(out fileSystem, tempFs, basePath, createIfMissing);
|
||||
return Utility.WrapSubDirectory(out fileSystem, ref tempFs, basePath, createIfMissing);
|
||||
|
||||
case SaveDataSpaceId.SafeMode:
|
||||
rc = _config.BaseFsService.OpenBisFileSystem(out tempFs, U8Span.Empty, BisPartitionId.SafeMode, true);
|
||||
if (rc.IsFailure()) return rc;
|
||||
|
||||
return Utility.WrapSubDirectory(out fileSystem, tempFs, basePath, createIfMissing);
|
||||
return Utility.WrapSubDirectory(out fileSystem, ref tempFs, basePath, createIfMissing);
|
||||
|
||||
default:
|
||||
return ResultFs.InvalidArgument.Log();
|
||||
|
|
|
@ -36,9 +36,9 @@ namespace LibHac.FsSystem
|
|||
PreserveUnc = preserveUnc;
|
||||
}
|
||||
|
||||
public SubdirectoryFileSystem(ReferenceCountedDisposable<IFileSystem> baseFileSystem, bool preserveUnc = false)
|
||||
public SubdirectoryFileSystem(ref ReferenceCountedDisposable<IFileSystem> baseFileSystem, bool preserveUnc = false)
|
||||
{
|
||||
BaseFileSystemShared = baseFileSystem.AddReference();
|
||||
BaseFileSystemShared = Shared.Move(ref baseFileSystem);
|
||||
BaseFileSystem = BaseFileSystemShared.Target;
|
||||
PreserveUnc = preserveUnc;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue