public Result Create(out ReferenceCountedDisposable <IFileSystem> subDirFileSystem, ref ReferenceCountedDisposable <IFileSystem> baseFileSystem, U8Span path, bool preserveUnc) { UnsafeHelpers.SkipParamInit(out subDirFileSystem); // Verify the sub-path exists Result rc = baseFileSystem.Target.OpenDirectory(out IDirectory _, path, OpenDirectoryMode.Directory); if (rc.IsFailure()) { return(rc); } // Initialize the SubdirectoryFileSystem var subDir = new SubdirectoryFileSystem(ref baseFileSystem, preserveUnc); using var subDirShared = new ReferenceCountedDisposable <SubdirectoryFileSystem>(subDir); rc = subDirShared.Target.Initialize(path); if (rc.IsFailure()) { return(rc); } subDirFileSystem = subDirShared.AddReference <IFileSystem>(); return(Result.Success); }
public static Result CreateSubDirectoryFileSystem(out ReferenceCountedDisposable <IFileSystem> subDirFileSystem, ref ReferenceCountedDisposable <IFileSystem> baseFileSystem, U8Span subPath, bool preserveUnc = false) { UnsafeHelpers.SkipParamInit(out subDirFileSystem); // Check if the directory exists Result rc = baseFileSystem.Target.OpenDirectory(out IDirectory dir, subPath, OpenDirectoryMode.Directory); if (rc.IsFailure()) { return(rc); } dir.Dispose(); var fs = new SubdirectoryFileSystem(ref baseFileSystem, preserveUnc); using (var subDirFs = new ReferenceCountedDisposable <SubdirectoryFileSystem>(fs)) { rc = subDirFs.Target.Initialize(subPath); if (rc.IsFailure()) { return(rc); } subDirFileSystem = subDirFs.AddReference <IFileSystem>(); return(Result.Success); } }
public static SwitchFs OpenNandPartition(Keyset keyset, IAttributeFileSystem fileSystem) { var concatFs = new ConcatenationFileSystem(fileSystem); var saveDirFs = new SubdirectoryFileSystem(concatFs, "/save"); var contentDirFs = new SubdirectoryFileSystem(concatFs, "/Contents"); return(new SwitchFs(keyset, contentDirFs, saveDirFs)); }
protected override IFileSystem CreateFileSystem() { var baseFs = new InMemoryFileSystem(); var subFs = new SubdirectoryFileSystem(baseFs); subFs.Initialize("/".ToU8String()).ThrowIfFailure(); return(subFs); }
public Result Create(out IFileSystem fileSystem, out ISaveDataExtraDataAccessor extraDataAccessor, IFileSystem sourceFileSystem, ulong saveDataId, bool allowDirectorySaveData, bool useDeviceUniqueMac, SaveDataType type, ITimeStampGenerator timeStampGenerator) { fileSystem = default; extraDataAccessor = default; string saveDataPath = $"/{saveDataId:x16}"; Result rc = sourceFileSystem.GetEntryType(out DirectoryEntryType entryType, saveDataPath); if (rc.IsFailure()) { return(rc == ResultFs.PathNotFound ? ResultFs.TargetNotFound : rc); } switch (entryType) { case DirectoryEntryType.Directory: // Actual FS does this check // if (!allowDirectorySaveData) return ResultFs.InvalidSaveDataEntryType.Log(); var subDirFs = new SubdirectoryFileSystem(sourceFileSystem, saveDataPath); rc = DirectorySaveDataFileSystem.CreateNew(out DirectorySaveDataFileSystem saveFs, subDirFs); if (rc.IsFailure()) { return(rc); } fileSystem = saveFs; // Todo: Dummy ISaveDataExtraDataAccessor return(Result.Success); case DirectoryEntryType.File: rc = sourceFileSystem.OpenFile(out IFile saveDataFile, saveDataPath, OpenMode.ReadWrite); if (rc.IsFailure()) { return(rc); } var saveDataStorage = new DisposingFileStorage(saveDataFile); fileSystem = new SaveDataFileSystem(Keyset, saveDataStorage, IntegrityCheckLevel.ErrorOnInvalid, false); // Todo: ISaveDataExtraDataAccessor return(Result.Success); default: throw new ArgumentOutOfRangeException(); } }
public static SwitchFs OpenSdCard(Keyset keyset, IAttributeFileSystem fileSystem) { var concatFs = new ConcatenationFileSystem(fileSystem); var saveDirFs = new SubdirectoryFileSystem(concatFs, "/Nintendo/save"); var contentDirFs = new SubdirectoryFileSystem(concatFs, "/Nintendo/Contents"); var encSaveFs = new AesXtsFileSystem(saveDirFs, keyset.SdCardKeys[0], 0x4000); var encContentFs = new AesXtsFileSystem(contentDirFs, keyset.SdCardKeys[1], 0x4000); return(new SwitchFs(keyset, encContentFs, encSaveFs)); }
private (IFileSystem baseFs, IFileSystem subDirFs) CreateFileSystemInternal() { var baseFs = new InMemoryFileSystem(); baseFs.CreateDirectory("/sub".ToU8Span()); baseFs.CreateDirectory("/sub/path".ToU8Span()); var subFs = new SubdirectoryFileSystem(baseFs); subFs.Initialize("/sub/path".ToU8String()).ThrowIfFailure(); return(baseFs, subFs); }
public static SwitchFs OpenNandPartition(KeySet keySet, IAttributeFileSystem fileSystem) { var concatFs = new ConcatenationFileSystem(fileSystem); SubdirectoryFileSystem saveDirFs = null; if (concatFs.DirectoryExists("/save")) { SubdirectoryFileSystem.CreateNew(out saveDirFs, concatFs, "/save".ToU8String()).ThrowIfFailure(); } SubdirectoryFileSystem.CreateNew(out SubdirectoryFileSystem contentDirFs, concatFs, "/Contents".ToU8String()).ThrowIfFailure(); return(new SwitchFs(keySet, contentDirFs, saveDirFs)); }
public Result Create(out IFileSystem subDirFileSystem, IFileSystem baseFileSystem, string path) { subDirFileSystem = default; Result rc = baseFileSystem.OpenDirectory(out IDirectory _, path, OpenDirectoryMode.Directory); if (rc.IsFailure()) { return(rc); } subDirFileSystem = new SubdirectoryFileSystem(baseFileSystem, path); return(Result.Success); }
public static Result CreateSubFileSystemImpl(out IFileSystem subFileSystem, IFileSystem baseFileSystem, string path) { subFileSystem = default; if (path == null) { return(ResultFs.NullArgument.Log()); } Result rc = baseFileSystem.OpenDirectory(out IDirectory _, path, OpenDirectoryMode.Directory); if (rc.IsFailure()) { return(rc); } subFileSystem = new SubdirectoryFileSystem(baseFileSystem, path); return(Result.Success); }
public static SwitchFs OpenSdCard(KeySet keySet, IAttributeFileSystem fileSystem) { var concatFs = new ConcatenationFileSystem(fileSystem); var contentDirFs = new SubdirectoryFileSystem(concatFs); contentDirFs.Initialize("/Nintendo/Contents".ToU8String()).ThrowIfFailure(); AesXtsFileSystem encSaveFs = null; if (fileSystem.DirectoryExists("/Nintendo/save")) { var saveDirFs = new SubdirectoryFileSystem(concatFs); saveDirFs.Initialize("/Nintendo/save".ToU8String()).ThrowIfFailure(); encSaveFs = new AesXtsFileSystem(saveDirFs, keySet.SdCardEncryptionKeys[0].DataRo.ToArray(), 0x4000); } var encContentFs = new AesXtsFileSystem(contentDirFs, keySet.SdCardEncryptionKeys[1].DataRo.ToArray(), 0x4000); return(new SwitchFs(keySet, encContentFs, encSaveFs)); }
public Result Create(out ReferenceCountedDisposable <IFileSystem> fileSystem, out ReferenceCountedDisposable <ISaveDataExtraDataAccessor> extraDataAccessor, ISaveDataFileSystemCacheManager cacheManager, ref ReferenceCountedDisposable <IFileSystem> baseFileSystem, SaveDataSpaceId spaceId, ulong saveDataId, bool allowDirectorySaveData, bool useDeviceUniqueMac, bool isJournalingSupported, bool isMultiCommitSupported, bool openReadOnly, bool openShared, ISaveDataCommitTimeStampGetter timeStampGetter) { Span <byte> saveImageName = stackalloc byte[0x12]; UnsafeHelpers.SkipParamInit(out fileSystem, out extraDataAccessor); Assert.SdkRequiresNotNull(cacheManager); var sb = new U8StringBuilder(saveImageName); sb.Append((byte)'/').AppendFormat(saveDataId, 'x', 16); Result rc = baseFileSystem.Target.GetEntryType(out DirectoryEntryType type, new U8Span(saveImageName)); if (rc.IsFailure()) { return(ResultFs.PathNotFound.Includes(rc) ? ResultFs.TargetNotFound.LogConverted(rc) : rc); } if (type == DirectoryEntryType.Directory) { if (!allowDirectorySaveData) { return(ResultFs.InvalidSaveDataEntryType.Log()); } SubdirectoryFileSystem subDirFs = null; ReferenceCountedDisposable <DirectorySaveDataFileSystem> saveFs = null; try { subDirFs = new SubdirectoryFileSystem(ref baseFileSystem); rc = subDirFs.Initialize(new U8Span(saveImageName)); if (rc.IsFailure()) { return(rc); } saveFs = DirectorySaveDataFileSystem.CreateShared(Shared.Move(ref subDirFs), _fsServer.Hos.Fs); rc = saveFs.Target.Initialize(timeStampGetter, _randomGenerator, isJournalingSupported, isMultiCommitSupported, !openReadOnly); if (rc.IsFailure()) { return(rc); } fileSystem = saveFs.AddReference <IFileSystem>(); extraDataAccessor = saveFs.AddReference <ISaveDataExtraDataAccessor>(); return(Result.Success); } finally { subDirFs?.Dispose(); saveFs?.Dispose(); } } ReferenceCountedDisposable <IStorage> fileStorage = null; try { Optional <OpenType> openType = openShared ? new Optional <OpenType>(OpenType.Normal) : new Optional <OpenType>(); rc = _fsServer.OpenSaveDataStorage(out fileStorage, ref baseFileSystem, spaceId, saveDataId, OpenMode.ReadWrite, openType); if (rc.IsFailure()) { return(rc); } if (!isJournalingSupported) { throw new NotImplementedException(); } // Todo: Properly handle shared storage fileSystem = new ReferenceCountedDisposable <IFileSystem>(new SaveDataFileSystem(_keySet, fileStorage.Target, IntegrityCheckLevel.ErrorOnInvalid, false)); // Todo: ISaveDataExtraDataAccessor return(Result.Success); } finally { fileStorage?.Dispose(); } }