internal static void ExportSaveDebug(Context ctx, string dir, SaveDataFileSystem save) { Directory.CreateDirectory(dir); FsLayout layout = save.Header.Layout; string mainRemapDir = Path.Combine(dir, "main_remap"); Directory.CreateDirectory(mainRemapDir); save.DataRemapStorage.GetBaseStorage().WriteAllBytes(Path.Combine(mainRemapDir, "Data")); save.DataRemapStorage.GetHeaderStorage().WriteAllBytes(Path.Combine(mainRemapDir, "Header")); save.DataRemapStorage.GetMapEntryStorage().WriteAllBytes(Path.Combine(mainRemapDir, "Map entries")); string metadataRemapDir = Path.Combine(dir, "metadata_remap"); Directory.CreateDirectory(metadataRemapDir); save.MetaRemapStorage.GetBaseStorage().WriteAllBytes(Path.Combine(metadataRemapDir, "Data")); save.MetaRemapStorage.GetHeaderStorage().WriteAllBytes(Path.Combine(metadataRemapDir, "Header")); save.MetaRemapStorage.GetMapEntryStorage().WriteAllBytes(Path.Combine(metadataRemapDir, "Map entries")); string journalDir = Path.Combine(dir, "journal"); Directory.CreateDirectory(journalDir); save.JournalStorage.GetBaseStorage().WriteAllBytes(Path.Combine(journalDir, "Data")); save.JournalStorage.GetHeaderStorage().WriteAllBytes(Path.Combine(journalDir, "Header")); save.JournalStorage.Map.GetHeaderStorage().WriteAllBytes(Path.Combine(journalDir, "Map_header")); save.JournalStorage.Map.GetMapStorage().WriteAllBytes(Path.Combine(journalDir, "Map")); save.JournalStorage.Map.GetModifiedPhysicalBlocksStorage() .WriteAllBytes(Path.Combine(journalDir, "ModifiedPhysicalBlocks")); save.JournalStorage.Map.GetModifiedVirtualBlocksStorage() .WriteAllBytes(Path.Combine(journalDir, "ModifiedVirtualBlocks")); save.JournalStorage.Map.GetFreeBlocksStorage().WriteAllBytes(Path.Combine(journalDir, "FreeBlocks")); string saveDir = Path.Combine(dir, "save"); Directory.CreateDirectory(saveDir); save.SaveDataFileSystemCore.GetHeaderStorage().WriteAllBytes(Path.Combine(saveDir, "Save_Header")); save.SaveDataFileSystemCore.GetBaseStorage().WriteAllBytes(Path.Combine(saveDir, "Save_Data")); save.SaveDataFileSystemCore.AllocationTable.GetHeaderStorage().WriteAllBytes(Path.Combine(saveDir, "FAT_header")); save.SaveDataFileSystemCore.AllocationTable.GetBaseStorage().WriteAllBytes(Path.Combine(saveDir, "FAT_Data")); save.Header.DataIvfcMaster.WriteAllBytes(Path.Combine(saveDir, "Save_MasterHash")); IStorage saveLayer1Hash = save.MetaRemapStorage.Slice(layout.IvfcL1Offset, layout.IvfcL1Size); IStorage saveLayer2Hash = save.MetaRemapStorage.Slice(layout.IvfcL2Offset, layout.IvfcL2Size); IStorage saveLayer3Hash = save.MetaRemapStorage.Slice(layout.IvfcL3Offset, layout.IvfcL3Size); saveLayer1Hash.WriteAllBytes(Path.Combine(saveDir, "Save_Layer1Hash"), ctx.Logger); saveLayer2Hash.WriteAllBytes(Path.Combine(saveDir, "Save_Layer2Hash"), ctx.Logger); saveLayer3Hash.WriteAllBytes(Path.Combine(saveDir, "Save_Layer3Hash"), ctx.Logger); if (layout.Version >= 0x50000) { save.Header.FatIvfcMaster.WriteAllBytes(Path.Combine(saveDir, "Fat_MasterHash")); IStorage fatLayer1Hash = save.MetaRemapStorage.Slice(layout.FatIvfcL1Offset, layout.FatIvfcL1Size); IStorage fatLayer2Hash = save.MetaRemapStorage.Slice(layout.FatIvfcL2Offset, layout.FatIvfcL1Size); fatLayer1Hash.WriteAllBytes(Path.Combine(saveDir, "Fat_Layer1Hash"), ctx.Logger); fatLayer2Hash.WriteAllBytes(Path.Combine(saveDir, "Fat_Layer2Hash"), ctx.Logger); } string duplexDir = Path.Combine(dir, "duplex"); Directory.CreateDirectory(duplexDir); save.Header.DuplexMasterBitmapA.WriteAllBytes(Path.Combine(duplexDir, "MasterBitmapA")); save.Header.DuplexMasterBitmapB.WriteAllBytes(Path.Combine(duplexDir, "MasterBitmapB")); IStorage duplexL1A = save.DataRemapStorage.Slice(layout.DuplexL1OffsetA, layout.DuplexL1Size); IStorage duplexL1B = save.DataRemapStorage.Slice(layout.DuplexL1OffsetB, layout.DuplexL1Size); IStorage duplexDataA = save.DataRemapStorage.Slice(layout.DuplexDataOffsetA, layout.DuplexDataSize); IStorage duplexDataB = save.DataRemapStorage.Slice(layout.DuplexDataOffsetB, layout.DuplexDataSize); duplexL1A.WriteAllBytes(Path.Combine(duplexDir, "L1BitmapA"), ctx.Logger); duplexL1B.WriteAllBytes(Path.Combine(duplexDir, "L1BitmapB"), ctx.Logger); duplexDataA.WriteAllBytes(Path.Combine(duplexDir, "DataA"), ctx.Logger); duplexDataB.WriteAllBytes(Path.Combine(duplexDir, "DataB"), ctx.Logger); }
public static void Process(Context ctx) { using (var file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.ReadWrite)) { var save = new Savefile(ctx.Keyset, file, ctx.Options.IntegrityLevel); if (ctx.Options.Validate) { save.Verify(ctx.Logger); } if (ctx.Options.OutDir != null) { save.Extract(ctx.Options.OutDir, ctx.Logger); } if (ctx.Options.DebugOutDir != null) { string dir = ctx.Options.DebugOutDir; Directory.CreateDirectory(dir); FsLayout layout = save.Header.Layout; File.WriteAllBytes(Path.Combine(dir, "L0_0_MasterHashA"), save.Header.MasterHashA); File.WriteAllBytes(Path.Combine(dir, "L0_1_MasterHashB"), save.Header.MasterHashB); File.WriteAllBytes(Path.Combine(dir, "L0_2_DuplexMasterA"), save.Header.DuplexMasterA); File.WriteAllBytes(Path.Combine(dir, "L0_3_DuplexMasterB"), save.Header.DuplexMasterB); Stream duplexL1A = save.DataRemapStorage.OpenStream(layout.DuplexL1OffsetA, layout.DuplexL1Size); Stream duplexL1B = save.DataRemapStorage.OpenStream(layout.DuplexL1OffsetB, layout.DuplexL1Size); Stream duplexDataA = save.DataRemapStorage.OpenStream(layout.DuplexDataOffsetA, layout.DuplexDataSize); Stream duplexDataB = save.DataRemapStorage.OpenStream(layout.DuplexDataOffsetB, layout.DuplexDataSize); Stream journalData = save.DataRemapStorage.OpenStream(layout.JournalDataOffset, layout.JournalDataSizeB + layout.SizeReservedArea); duplexL1A.WriteAllBytes(Path.Combine(dir, "L0_4_DuplexL1A"), ctx.Logger); duplexL1B.WriteAllBytes(Path.Combine(dir, "L0_5_DuplexL1B"), ctx.Logger); duplexDataA.WriteAllBytes(Path.Combine(dir, "L0_6_DuplexDataA"), ctx.Logger); duplexDataB.WriteAllBytes(Path.Combine(dir, "L0_7_DuplexDataB"), ctx.Logger); journalData.WriteAllBytes(Path.Combine(dir, "L0_9_JournalData"), ctx.Logger); save.DuplexData.WriteAllBytes(Path.Combine(dir, "L1_0_DuplexData"), ctx.Logger); Stream journalTable = save.MetaRemapStorage.OpenStream(layout.JournalTableOffset, layout.JournalTableSize); Stream journalBitmapUpdatedPhysical = save.MetaRemapStorage.OpenStream(layout.JournalBitmapUpdatedPhysicalOffset, layout.JournalBitmapUpdatedPhysicalSize); Stream journalBitmapUpdatedVirtual = save.MetaRemapStorage.OpenStream(layout.JournalBitmapUpdatedVirtualOffset, layout.JournalBitmapUpdatedVirtualSize); Stream journalBitmapUnassigned = save.MetaRemapStorage.OpenStream(layout.JournalBitmapUnassignedOffset, layout.JournalBitmapUnassignedSize); Stream journalLayer1Hash = save.MetaRemapStorage.OpenStream(layout.IvfcL1Offset, layout.IvfcL1Size); Stream journalLayer2Hash = save.MetaRemapStorage.OpenStream(layout.IvfcL2Offset, layout.IvfcL2Size); Stream journalLayer3Hash = save.MetaRemapStorage.OpenStream(layout.IvfcL3Offset, layout.IvfcL3Size); Stream journalFat = save.MetaRemapStorage.OpenStream(layout.FatOffset, layout.FatSize); journalTable.WriteAllBytes(Path.Combine(dir, "L2_0_JournalTable"), ctx.Logger); journalBitmapUpdatedPhysical.WriteAllBytes(Path.Combine(dir, "L2_1_JournalBitmapUpdatedPhysical"), ctx.Logger); journalBitmapUpdatedVirtual.WriteAllBytes(Path.Combine(dir, "L2_2_JournalBitmapUpdatedVirtual"), ctx.Logger); journalBitmapUnassigned.WriteAllBytes(Path.Combine(dir, "L2_3_JournalBitmapUnassigned"), ctx.Logger); journalLayer1Hash.WriteAllBytes(Path.Combine(dir, "L2_4_Layer1Hash"), ctx.Logger); journalLayer2Hash.WriteAllBytes(Path.Combine(dir, "L2_5_Layer2Hash"), ctx.Logger); journalLayer3Hash.WriteAllBytes(Path.Combine(dir, "L2_6_Layer3Hash"), ctx.Logger); journalFat.WriteAllBytes(Path.Combine(dir, "L2_7_FAT"), ctx.Logger); save.IvfcStreamSource.CreateStream().WriteAllBytes(Path.Combine(dir, "L3_0_SaveData"), ctx.Logger); } if (ctx.Options.SignSave) { if (save.CommitHeader(ctx.Keyset)) { ctx.Logger.LogMessage("Successfully signed save file"); } else { ctx.Logger.LogMessage("Unable to sign save file. Do you have all the required keys?"); } } if (ctx.Options.ListFiles) { foreach (FileEntry fileEntry in save.Files) { ctx.Logger.LogMessage(fileEntry.FullPath); } } ctx.Logger.LogMessage(save.Print()); } }
public static void Process(Context ctx) { using (var file = new LocalStorage(ctx.Options.InFile, FileAccess.ReadWrite)) { var save = new SaveDataFileSystem(ctx.Keyset, file, ctx.Options.IntegrityLevel, true); if (ctx.Options.Validate) { save.Verify(ctx.Logger); } if (ctx.Options.OutDir != null) { save.SaveDataFileSystemCore.Extract(ctx.Options.OutDir, ctx.Logger); } if (ctx.Options.DebugOutDir != null) { // todo string dir = ctx.Options.DebugOutDir; Directory.CreateDirectory(dir); FsLayout layout = save.Header.Layout; string mainRemapDir = Path.Combine(dir, "main_remap"); Directory.CreateDirectory(mainRemapDir); save.DataRemapStorage.GetBaseStorage().WriteAllBytes(Path.Combine(mainRemapDir, "Data")); save.DataRemapStorage.GetHeaderStorage().WriteAllBytes(Path.Combine(mainRemapDir, "Header")); save.DataRemapStorage.GetMapEntryStorage().WriteAllBytes(Path.Combine(mainRemapDir, "Map entries")); string metadataRemapDir = Path.Combine(dir, "metadata_remap"); Directory.CreateDirectory(metadataRemapDir); save.MetaRemapStorage.GetBaseStorage().WriteAllBytes(Path.Combine(metadataRemapDir, "Data")); save.MetaRemapStorage.GetHeaderStorage().WriteAllBytes(Path.Combine(metadataRemapDir, "Header")); save.MetaRemapStorage.GetMapEntryStorage().WriteAllBytes(Path.Combine(metadataRemapDir, "Map entries")); string journalDir = Path.Combine(dir, "journal"); Directory.CreateDirectory(journalDir); save.JournalStorage.GetBaseStorage().WriteAllBytes(Path.Combine(journalDir, "Data")); save.JournalStorage.GetHeaderStorage().WriteAllBytes(Path.Combine(journalDir, "Header")); save.JournalStorage.Map.GetHeaderStorage().WriteAllBytes(Path.Combine(journalDir, "Map_header")); save.JournalStorage.Map.GetMapStorage().WriteAllBytes(Path.Combine(journalDir, "Map")); save.JournalStorage.Map.GetModifiedPhysicalBlocksStorage().WriteAllBytes(Path.Combine(journalDir, "ModifiedPhysicalBlocks")); save.JournalStorage.Map.GetModifiedVirtualBlocksStorage().WriteAllBytes(Path.Combine(journalDir, "ModifiedVirtualBlocks")); save.JournalStorage.Map.GetFreeBlocksStorage().WriteAllBytes(Path.Combine(journalDir, "FreeBlocks")); string saveDir = Path.Combine(dir, "save"); Directory.CreateDirectory(saveDir); save.SaveDataFileSystemCore.GetHeaderStorage().WriteAllBytes(Path.Combine(saveDir, "Save_Header")); save.SaveDataFileSystemCore.GetBaseStorage().WriteAllBytes(Path.Combine(saveDir, "Save_Data")); save.SaveDataFileSystemCore.AllocationTable.GetHeaderStorage().WriteAllBytes(Path.Combine(saveDir, "FAT_header")); save.SaveDataFileSystemCore.AllocationTable.GetBaseStorage().WriteAllBytes(Path.Combine(saveDir, "FAT_Data")); save.Header.DataIvfcMaster.WriteAllBytes(Path.Combine(saveDir, "Save_MasterHash")); IStorage saveLayer1Hash = save.MetaRemapStorage.Slice(layout.IvfcL1Offset, layout.IvfcL1Size); IStorage saveLayer2Hash = save.MetaRemapStorage.Slice(layout.IvfcL2Offset, layout.IvfcL2Size); IStorage saveLayer3Hash = save.MetaRemapStorage.Slice(layout.IvfcL3Offset, layout.IvfcL3Size); saveLayer1Hash.WriteAllBytes(Path.Combine(saveDir, "Save_Layer1Hash"), ctx.Logger); saveLayer2Hash.WriteAllBytes(Path.Combine(saveDir, "Save_Layer2Hash"), ctx.Logger); saveLayer3Hash.WriteAllBytes(Path.Combine(saveDir, "Save_Layer3Hash"), ctx.Logger); string duplexDir = Path.Combine(dir, "duplex"); Directory.CreateDirectory(duplexDir); save.Header.DuplexMasterBitmapA.WriteAllBytes(Path.Combine(duplexDir, "MasterBitmapA")); save.Header.DuplexMasterBitmapB.WriteAllBytes(Path.Combine(duplexDir, "MasterBitmapB")); IStorage duplexL1A = save.DataRemapStorage.Slice(layout.DuplexL1OffsetA, layout.DuplexL1Size); IStorage duplexL1B = save.DataRemapStorage.Slice(layout.DuplexL1OffsetB, layout.DuplexL1Size); IStorage duplexDataA = save.DataRemapStorage.Slice(layout.DuplexDataOffsetA, layout.DuplexDataSize); IStorage duplexDataB = save.DataRemapStorage.Slice(layout.DuplexDataOffsetB, layout.DuplexDataSize); duplexL1A.WriteAllBytes(Path.Combine(duplexDir, "L1BitmapA"), ctx.Logger); duplexL1B.WriteAllBytes(Path.Combine(duplexDir, "L1BitmapB"), ctx.Logger); duplexDataA.WriteAllBytes(Path.Combine(duplexDir, "DataA"), ctx.Logger); duplexDataB.WriteAllBytes(Path.Combine(duplexDir, "DataB"), ctx.Logger); } 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)) { using (IFile outFile = save.OpenFile(destFilename, OpenMode.ReadWrite)) { if (inFile.GetSize() != outFile.GetSize()) { ctx.Logger.LogMessage($"Replacement file must be the same size as the original file. ({outFile.GetSize()} bytes)"); return; } inFile.CopyTo(outFile, ctx.Logger); ctx.Logger.LogMessage($"Replaced file {destFilename}"); } } if (save.Commit(ctx.Keyset)) { ctx.Logger.LogMessage("Successfully signed save file"); } else { ctx.Logger.LogMessage("ERROR: Unable to sign save file. Do you have all the required keys?"); } return; } if (ctx.Options.SignSave) { if (save.Commit(ctx.Keyset)) { ctx.Logger.LogMessage("Successfully signed save file"); } else { ctx.Logger.LogMessage("Unable to sign save file. Do you have all the required keys?"); } return; } if (ctx.Options.ListFiles) { IDirectory dir = save.SaveDataFileSystemCore.OpenDirectory("/", OpenDirectoryMode.All); foreach (DirectoryEntry entry in dir.EnumerateEntries()) { ctx.Logger.LogMessage(entry.FullPath); } } ctx.Logger.LogMessage(save.Print()); } }
public static void Process(Context ctx) { using (var file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.ReadWrite)) { var save = new Savefile(ctx.Keyset, file.AsStorage(), ctx.Options.IntegrityLevel, true); if (ctx.Options.Validate) { save.Verify(ctx.Logger); } if (ctx.Options.OutDir != null) { save.Extract(ctx.Options.OutDir, ctx.Logger); } if (ctx.Options.DebugOutDir != null) { // todo string dir = ctx.Options.DebugOutDir; Directory.CreateDirectory(dir); FsLayout layout = save.Header.Layout; string mainRemapDir = Path.Combine(dir, "main_remap"); Directory.CreateDirectory(mainRemapDir); save.DataRemapStorage.GetBaseStorage().WriteAllBytes(Path.Combine(mainRemapDir, "Data")); save.DataRemapStorage.GetHeaderStorage().WriteAllBytes(Path.Combine(mainRemapDir, "Header")); save.DataRemapStorage.GetMapEntryStorage().WriteAllBytes(Path.Combine(mainRemapDir, "Map entries")); string metadataRemapDir = Path.Combine(dir, "metadata_remap"); Directory.CreateDirectory(metadataRemapDir); save.MetaRemapStorage.GetBaseStorage().WriteAllBytes(Path.Combine(metadataRemapDir, "Data")); save.MetaRemapStorage.GetHeaderStorage().WriteAllBytes(Path.Combine(metadataRemapDir, "Header")); save.MetaRemapStorage.GetMapEntryStorage().WriteAllBytes(Path.Combine(metadataRemapDir, "Map entries")); string journalDir = Path.Combine(dir, "journal"); Directory.CreateDirectory(journalDir); save.JournalStorage.GetBaseStorage().WriteAllBytes(Path.Combine(journalDir, "Data")); save.JournalStorage.GetHeaderStorage().WriteAllBytes(Path.Combine(journalDir, "Header")); save.JournalStorage.Map.GetHeaderStorage().WriteAllBytes(Path.Combine(journalDir, "Map_header")); save.JournalStorage.Map.GetMapStorage().WriteAllBytes(Path.Combine(journalDir, "Map")); save.JournalStorage.Map.GetModifiedPhysicalBlocksStorage().WriteAllBytes(Path.Combine(journalDir, "ModifiedPhysicalBlocks")); save.JournalStorage.Map.GetModifiedVirtualBlocksStorage().WriteAllBytes(Path.Combine(journalDir, "ModifiedVirtualBlocks")); save.JournalStorage.Map.GetFreeBlocksStorage().WriteAllBytes(Path.Combine(journalDir, "FreeBlocks")); string saveDir = Path.Combine(dir, "save"); Directory.CreateDirectory(saveDir); save.SaveFs.GetHeaderStorage().WriteAllBytes(Path.Combine(saveDir, "Save_Header")); save.SaveFs.GetBaseStorage().WriteAllBytes(Path.Combine(saveDir, "Save_Data")); save.SaveFs.AllocationTable.GetHeaderStorage().WriteAllBytes(Path.Combine(saveDir, "FAT_header")); save.SaveFs.AllocationTable.GetBaseStorage().WriteAllBytes(Path.Combine(saveDir, "FAT_Data")); save.Header.DataIvfcMaster.WriteAllBytes(Path.Combine(saveDir, "Save_MasterHash")); IStorage saveLayer1Hash = save.MetaRemapStorage.Slice(layout.IvfcL1Offset, layout.IvfcL1Size); IStorage saveLayer2Hash = save.MetaRemapStorage.Slice(layout.IvfcL2Offset, layout.IvfcL2Size); IStorage saveLayer3Hash = save.MetaRemapStorage.Slice(layout.IvfcL3Offset, layout.IvfcL3Size); saveLayer1Hash.WriteAllBytes(Path.Combine(saveDir, "Save_Layer1Hash"), ctx.Logger); saveLayer2Hash.WriteAllBytes(Path.Combine(saveDir, "Save_Layer2Hash"), ctx.Logger); saveLayer3Hash.WriteAllBytes(Path.Combine(saveDir, "Save_Layer3Hash"), ctx.Logger); string duplexDir = Path.Combine(dir, "duplex"); Directory.CreateDirectory(duplexDir); save.Header.DuplexMasterBitmapA.WriteAllBytes(Path.Combine(duplexDir, "MasterBitmapA")); save.Header.DuplexMasterBitmapB.WriteAllBytes(Path.Combine(duplexDir, "MasterBitmapB")); IStorage duplexL1A = save.DataRemapStorage.Slice(layout.DuplexL1OffsetA, layout.DuplexL1Size); IStorage duplexL1B = save.DataRemapStorage.Slice(layout.DuplexL1OffsetB, layout.DuplexL1Size); IStorage duplexDataA = save.DataRemapStorage.Slice(layout.DuplexDataOffsetA, layout.DuplexDataSize); IStorage duplexDataB = save.DataRemapStorage.Slice(layout.DuplexDataOffsetB, layout.DuplexDataSize); duplexL1A.WriteAllBytes(Path.Combine(duplexDir, "L1BitmapA"), ctx.Logger); duplexL1B.WriteAllBytes(Path.Combine(duplexDir, "L1BitmapB"), ctx.Logger); duplexDataA.WriteAllBytes(Path.Combine(duplexDir, "DataA"), ctx.Logger); duplexDataB.WriteAllBytes(Path.Combine(duplexDir, "DataB"), ctx.Logger); } if (ctx.Options.SignSave) { if (save.CommitHeader(ctx.Keyset)) { ctx.Logger.LogMessage("Successfully signed save file"); } else { ctx.Logger.LogMessage("Unable to sign save file. Do you have all the required keys?"); } } if (ctx.Options.ListFiles) { foreach (FileEntry fileEntry in save.Files) { ctx.Logger.LogMessage(fileEntry.FullPath); } } ctx.Logger.LogMessage(save.Print()); } }