public void MountCacheStorage_SdCardIsPreferredOverBis() { var applicationId = new Ncm.ApplicationId(1); FileSystemClient fs = FileSystemServerFactory.CreateClient(true); fs.CreateCacheStorage(applicationId, SaveDataSpaceId.SdCache, applicationId.Value, 0, 0, SaveDataFlags.None); fs.MountCacheStorage("cache".ToU8Span(), applicationId); fs.CreateFile("cache:/sd".ToU8Span(), 0); fs.Commit("cache".ToU8Span()); fs.Unmount("cache".ToU8Span()); // Turn off the SD card so the User save is mounted fs.SetSdCardAccessibility(false); fs.CreateCacheStorage(applicationId, SaveDataSpaceId.User, applicationId.Value, 0, 0, SaveDataFlags.None); fs.MountCacheStorage("cache".ToU8Span(), applicationId); fs.CreateFile("cache:/bis".ToU8Span(), 0); fs.Commit("cache".ToU8Span()); fs.Unmount("cache".ToU8Span()); fs.SetSdCardAccessibility(true); Assert.Success(fs.MountCacheStorage("cache".ToU8String(), applicationId)); Assert.Success(fs.GetEntryType(out _, "cache:/sd".ToU8Span())); Assert.Failure(fs.GetEntryType(out _, "cache:/bis".ToU8Span())); }
public ResultCode DeleteFile() { ResultCode result = (ResultCode)_filesystemClient.DeleteFile(DatabasePath).Value; _filesystemClient.Commit(MountName); return(result); }
private static Result ImportSave(FileSystemClient fs, SaveToImport save) { SaveDataAttribute key = save.Attribute; Result result = fs.CreateSaveData(key.TitleId, key.UserId, key.TitleId, 0, 0, 0); if (result.IsFailure()) { return(result); } bool isOldMounted = false; bool isNewMounted = false; try { result = fs.Register("OldSave".ToU8Span(), new LocalFileSystem(save.Path)); if (result.IsFailure()) { return(result); } isOldMounted = true; result = fs.MountSaveData("NewSave".ToU8Span(), key.TitleId, key.UserId); if (result.IsFailure()) { return(result); } isNewMounted = true; result = fs.CopyDirectory("OldSave:/", "NewSave:/"); if (result.IsFailure()) { return(result); } result = fs.Commit("NewSave"); } finally { if (isOldMounted) { fs.Unmount("OldSave"); } if (isNewMounted) { fs.Unmount("NewSave"); } } return(result); }
public void Commit_MultipleFileSystems_AllFileSystemsAreCommitted() { FileSystemClient fs = FileSystemServerFactory.CreateClient(true); var saveInfo = new List <(int id, string name)> { (1, "Save1"), (3, "Save2"), (2, "Save3") }; foreach ((int id, string name)info in saveInfo) { var applicationId = new Ncm.ApplicationId((uint)info.id); fs.CreateSaveData(applicationId, UserId.InvalidId, 0, 0x4000, 0x4000, SaveDataFlags.None); fs.MountSaveData(info.name.ToU8Span(), applicationId, UserId.InvalidId); } foreach ((int id, string name)info in saveInfo) { fs.CreateFile($"{info.name}:/file{info.id}".ToU8Span(), 0); } var names = new List <U8String>(); foreach ((int id, string name)info in saveInfo) { names.Add(info.name.ToU8String()); } Assert.Success(fs.Commit(names.ToArray())); foreach ((int id, string name)info in saveInfo) { fs.Unmount(info.name.ToU8Span()); } foreach ((int id, string name)info in saveInfo) { var applicationId = new Ncm.ApplicationId((uint)info.id); fs.MountSaveData(info.name.ToU8Span(), applicationId, UserId.InvalidId); } foreach ((int id, string name)info in saveInfo) { Assert.Success(fs.GetEntryType(out _, $"{info.name}:/file{info.id}".ToU8Span())); } }
public void MountCacheStorage_WrittenDataPersists() { var applicationId = new Ncm.ApplicationId(1); FileSystemClient fs = FileSystemServerFactory.CreateClient(true); fs.CreateCacheStorage(applicationId, SaveDataSpaceId.SdCache, applicationId.Value, 0, 0, SaveDataFlags.None); fs.MountCacheStorage("cache".ToU8Span(), applicationId); fs.CreateFile("cache:/file".ToU8Span(), 0); fs.Commit("cache".ToU8Span()); fs.Unmount("cache".ToU8Span()); Assert.Success(fs.MountCacheStorage("cache".ToU8Span(), applicationId)); Assert.Success(fs.GetEntryType(out DirectoryEntryType type, "cache:/file".ToU8Span())); Assert.Equal(DirectoryEntryType.File, type); }
public void MountBcatSaveData_WrittenDataPersists() { var applicationId = new Ncm.ApplicationId(1); FileSystemClient fs = FileSystemServerFactory.CreateClient(true); Assert.Success(fs.CreateBcatSaveData(applicationId, 0x400000)); Assert.Success(fs.MountBcatSaveData("bcat_test".ToU8Span(), applicationId)); // Check that the path doesn't exist Assert.Result(ResultFs.PathNotFound, fs.GetEntryType(out _, "bcat_test:/file".ToU8Span())); fs.CreateFile("bcat_test:/file".ToU8Span(), 0); fs.Commit("bcat_test".ToU8Span()); fs.Unmount("bcat_test".ToU8Span()); Assert.Success(fs.MountBcatSaveData("bcat_test".ToU8Span(), applicationId)); Assert.Success(fs.GetEntryType(out DirectoryEntryType type, "bcat_test:/file".ToU8Span())); Assert.Equal(DirectoryEntryType.File, type); }
public static void Process(Context ctx) { var accessNeeded = FileAccess.Read; if (ctx.Options.SignSave || ctx.Options.ReplaceFileDest != null && ctx.Options.ReplaceFileSource != null || ctx.Options.RepackSource != null || ctx.Options.TrimSave) { accessNeeded = FileAccess.ReadWrite; } using (var file = new LocalStorage(ctx.Options.InFile, accessNeeded)) { bool signNeeded = ctx.Options.SignSave; var save = new SaveDataFileSystem(ctx.KeySet, file, ctx.Options.IntegrityLevel, true); FileSystemClient fs = ctx.FsClient; fs.Register("save".ToU8Span(), save); if (ctx.Options.Validate) { save.Verify(ctx.Logger); } if (ctx.Options.OutDir != null) { fs.Register("output".ToU8Span(), new LocalFileSystem(ctx.Options.OutDir)); FsUtils.CopyDirectoryWithProgress(fs, "save:/".ToU8Span(), "output:/".ToU8Span(), logger: ctx.Logger).ThrowIfFailure(); fs.Unmount("output".ToU8Span()); } if (ctx.Options.DebugOutDir != null) { string dir = ctx.Options.DebugOutDir; ExportSaveDebug(ctx, dir, save); } try { if (ctx.Options.ReplaceFileDest != null && ctx.Options.ReplaceFileSource != null) { string destFilename = ctx.Options.ReplaceFileDest; if (!destFilename.StartsWith("/")) { destFilename = '/' + destFilename; } using (IFile inFile = new LocalFile(ctx.Options.ReplaceFileSource, OpenMode.Read)) { save.OpenFile(out IFile outFile, destFilename.ToU8String(), OpenMode.ReadWrite).ThrowIfFailure(); using (outFile) { inFile.GetSize(out long inFileSize).ThrowIfFailure(); outFile.GetSize(out long outFileSize).ThrowIfFailure(); if (inFileSize != outFileSize) { outFile.SetSize(inFileSize).ThrowIfFailure(); } inFile.CopyTo(outFile, ctx.Logger); ctx.Logger.LogMessage($"Replaced file {destFilename}"); } } signNeeded = true; } if (ctx.Options.RepackSource != null) { fs.Register("input".ToU8Span(), new LocalFileSystem(ctx.Options.RepackSource)); fs.CleanDirectoryRecursively("save:/".ToU8Span()); fs.Commit("save".ToU8Span()); FsUtils.CopyDirectoryWithProgress(fs, "input:/".ToU8Span(), "save:/".ToU8Span(), logger: ctx.Logger).ThrowIfFailure(); fs.Commit("save".ToU8Span()); fs.Unmount("input".ToU8Span()); signNeeded = true; } } finally { if (signNeeded) { if (save.Commit(ctx.KeySet).IsSuccess()) { ctx.Logger.LogMessage( $"Successfully signed save file with key {ctx.KeySet.DeviceUniqueSaveMacKeys[0].ToString()}"); } else { ctx.Logger.LogMessage("Unable to sign save file. Do you have all the required keys?"); } signNeeded = false; } } if (ctx.Options.TrimSave) { save.FsTrim(); signNeeded = true; ctx.Logger.LogMessage("Trimmed save file"); } if (signNeeded) { if (save.Commit(ctx.KeySet).IsSuccess()) { ctx.Logger.LogMessage( $"Successfully signed save file with key {ctx.KeySet.DeviceUniqueSaveMacKeys[0].ToString()}"); } else { ctx.Logger.LogMessage("Unable to sign save file. Do you have all the required keys?"); } fs.Unmount("save".ToU8Span()); return; } if (ctx.Options.ListFiles) { foreach (DirectoryEntryEx entry in save.EnumerateEntries()) { ctx.Logger.LogMessage(entry.FullPath); } } ctx.Logger.LogMessage(save.Print(ctx.KeySet)); //ctx.Logger.LogMessage(PrintFatLayout(save.SaveDataFileSystemCore)); fs.Unmount("save".ToU8Span()); } }