public void Open() { OpenFileDialog ofd = new OpenFileDialog(); ofd.CheckFileExists = true; ofd.Filter = "LedMusic project files (*.lmp)|*.lmp"; if (ofd.ShowDialog() == true) { Stream fs = ofd.OpenFile(); IFormatter f = new BinaryFormatter(); Savefile s = (Savefile)f.Deserialize(fs); fs.Close(); GlobalProperties.Instance.CurrentProjectFile = ofd.FileName; GlobalProperties.Instance.LedCount = s.ledCount; GlobalProperties.Instance.BPM = s.bpm; GlobalProperties.Instance.BeatOffset = s.beatOffset; GlobalProperties.Instance.FPS = s.fps; BassEngine.Instance.OpenFile(s.musicFile); Layers = new ObservableCollection <Layer>(s.layers); } }
public void ToggleRecording() { if (m_Text == null) { Debug.Log("No text Textmesh Pro Text object specified"); return; } if (m_IsRecording) { // stop m_Text.text = "Record"; m_Time = 0f; WriteFile(); } else { // start m_Text.text = "Stop Recording"; //init savefile m_Time = 0f; m_SaveFile = new Savefile(); } m_IsRecording = !m_IsRecording; }
private void OpenAllSaves() { if (SaveDir == null) { return; } string[] files = Fs.GetFileSystemEntries(SaveDir, "*"); foreach (string file in files) { Savefile save = null; string saveName = Path.GetFileNameWithoutExtension(file); try { IStorage storage = Fs.OpenFile(file, FileMode.Open).AsStorage(); string sdPath = "/" + Util.GetRelativePath(file, SaveDir).Replace('\\', '/'); var nax0 = new Nax0(Keyset, storage, sdPath, false); save = new Savefile(Keyset, nax0.BaseStorage, IntegrityCheckLevel.None, true); } catch (Exception ex) { Console.WriteLine($"{ex.Message} File: {file}"); } if (save != null && saveName != null) { Saves[saveName] = save; } } }
public void LoadContents() { string dataPath = Path.Combine(Application.persistentDataPath, "nodes.json"); try { Savefile loadFile = JsonUtility.FromJson <Savefile>(File.ReadAllText(dataPath)); List <Node> newNodes = new List <Node>(); foreach (NodeHierarchy nh in loadFile.nodes) { GameObject go = Instantiate(m_NodePrefab, m_ArSpace.transform); Node n = go.GetComponent <Node>(); go.transform.position = nh.parentPosition; n.position = nh.parentPosition; go.name = nh.parentName; n.nodeName = nh.parentName; newNodes.Add(n); } for (int i = 0; i < newNodes.Count; i++) { List <Node> c = new List <Node>(); foreach (string s in loadFile.nodes[i].childrenNames) { GameObject go = GameObject.Find(s); if (go) { Node n = go.GetComponent <Node>(); if (n != null) { c.Add(n); } } } newNodes[i].neighbours = c; } } catch (FileNotFoundException e) { Debug.LogError(dataPath + " not found\nNo objects loaded: " + e.Message); } }
public void Save() { if (GlobalProperties.Instance.CurrentProjectFile == null || GlobalProperties.Instance.CurrentProjectFile == "") { SaveAs(); return; } List <Layer> layersList = new List <Layer>(_layers); FileStream fs = new FileStream(GlobalProperties.Instance.CurrentProjectFile, FileMode.Create); Savefile s = new Savefile(layersList); IFormatter f = new BinaryFormatter(); f.Serialize(fs, s); fs.Close(); }
public void SaveNodes(List <Node> nodes) { Savefile savefile = new Savefile(); List <NodeHierarchy> nodeHierarchies = new List <NodeHierarchy>(); List <string> names = new List <string>(); List <Vector3> positions = new List <Vector3>(); foreach (Node node in nodes) { if (node.includeInSave) { NodeHierarchy nh = new NodeHierarchy(); nh.parent = node; nh.children = node.neighbours; List <string> neighbourNames = new List <string>(); foreach (Node n in node.neighbours) { if (n != null) { neighbourNames.Add(n.nodeName); } } nh.childrenNames = neighbourNames; nh.parentName = node.nodeName; nh.parentPosition = node.position; nodeHierarchies.Add(nh); names.Add(node.nodeName); positions.Add(node.position); } } savefile.nodes = nodeHierarchies; string jsonstring = JsonUtility.ToJson(savefile, true); string dataPath = Path.Combine(Application.persistentDataPath, "nodes.json"); File.WriteAllText(dataPath, jsonstring); Debug.Log(Application.persistentDataPath); }
public void LoadContents() { string dataPath = Path.Combine(Application.persistentDataPath, m_Filename); try { Savefile loadFile = JsonUtility.FromJson <Savefile>(File.ReadAllText(dataPath)); foreach (Vector3 pos in loadFile.positions) { GameObject go = Instantiate(m_ContentPrefab, m_ARSpace.transform); go.transform.localPosition = pos; } } catch (FileNotFoundException e) { Debug.LogError(dataPath + " not found\nNo objects loaded: " + e.Message); } }
private static List <Ticket> ReadTickets(Keyset keyset, Stream savefile) { var tickets = new List <Ticket>(); var save = new Savefile(keyset, savefile, false); var ticketList = new BinaryReader(save.OpenFile("/ticket_list.bin")); var ticketFile = new BinaryReader(save.OpenFile("/ticket.bin")); var titleId = ticketList.ReadUInt64(); while (titleId != ulong.MaxValue) { ticketList.BaseStream.Position += 0x18; var start = ticketFile.BaseStream.Position; tickets.Add(new Ticket(ticketFile)); ticketFile.BaseStream.Position = start + 0x400; titleId = ticketList.ReadUInt64(); } return(tickets); }
private static List <Ticket> ReadTickets(Keyset keyset, Stream savefile) { var tickets = new List <Ticket>(); var save = new Savefile(keyset, savefile.AsStorage(), IntegrityCheckLevel.None, true); var ticketList = new BinaryReader(save.OpenFile("/ticket_list.bin").AsStream()); var ticketFile = new BinaryReader(save.OpenFile("/ticket.bin").AsStream()); ulong titleId = ticketList.ReadUInt64(); while (titleId != ulong.MaxValue) { ticketList.BaseStream.Position += 0x18; long start = ticketFile.BaseStream.Position; tickets.Add(new Ticket(ticketFile)); ticketFile.BaseStream.Position = start + 0x400; titleId = ticketList.ReadUInt64(); } return(tickets); }
public void LoadContents() { string dataPath = Path.Combine(Application.persistentDataPath, m_Filename); Debug.Log(string.Format("Trying to load file: {0}", dataPath)); try { Savefile loadFile = JsonUtility.FromJson <Savefile>(File.ReadAllText(dataPath)); foreach (Vector3 pos in loadFile.positions) { GameObject go = Instantiate(m_ContentPrefab, m_ARSpace.transform); go.transform.localPosition = pos; } Debug.Log("Successfully loaded file!"); } catch (FileNotFoundException e) { Debug.Log(e.Message + "\n.json file for content storage not found. Created a new file!"); File.WriteAllText(dataPath, ""); } }
private static string Print(this Savefile save) { int colLen = 25; var sb = new StringBuilder(); sb.AppendLine(); sb.AppendLine("Savefile:"); PrintItem(sb, colLen, $"CMAC Signature{save.Header.SignatureValidity.GetValidityString()}:", save.Header.Cmac); PrintItem(sb, colLen, "Title ID:", $"{save.Header.ExtraData.TitleId:x16}"); PrintItem(sb, colLen, "User ID:", save.Header.ExtraData.UserId); PrintItem(sb, colLen, "Save ID:", $"{save.Header.ExtraData.SaveId:x16}"); PrintItem(sb, colLen, "Save Type:", $"{save.Header.ExtraData.Type}"); PrintItem(sb, colLen, "Owner ID:", $"{save.Header.ExtraData.SaveOwnerId:x16}"); PrintItem(sb, colLen, "Timestamp:", $"{DateTimeOffset.FromUnixTimeSeconds(save.Header.ExtraData.Timestamp):yyyy-MM-dd HH:mm:ss} UTC"); PrintItem(sb, colLen, "Save Data Size:", $"0x{save.Header.ExtraData.DataSize:x16} ({Util.GetBytesReadable(save.Header.ExtraData.DataSize)})"); PrintItem(sb, colLen, "Journal Size:", $"0x{save.Header.ExtraData.JournalSize:x16} ({Util.GetBytesReadable(save.Header.ExtraData.JournalSize)})"); PrintItem(sb, colLen, $"Header Hash{save.Header.HeaderHashValidity.GetValidityString()}:", save.Header.Layout.Hash); PrintItem(sb, colLen, "Number of Files:", save.Files.Length); PrintIvfcHash(sb, colLen, 4, save.Header.Ivfc, IntegrityStreamType.Save); return(sb.ToString()); }
private void OnNandFound() { Nand nand = NANDService.NAND; Stream NANDSource = NANDService.NANDSource; NANDSource.Seek(0x804000, SeekOrigin.Begin); // BCPKG2-1-Normal-Main offset + length of BootConfig FileStream pkg2stream = HACGUIKeyset.TempPkg2FileInfo.Create(); NANDSource.CopyToNew(pkg2stream, 0x7FC000); // rest of BCPPKG2-Normal-Main partition pkg2stream.Seek(0, SeekOrigin.Begin); byte[] pkg2raw = new byte[pkg2stream.Length]; pkg2stream.Read(pkg2raw, 0, pkg2raw.Length); Package2 pkg2 = new Package2(HACGUIKeyset.Keyset, new MemoryStream(pkg2raw)); HACGUIKeyset.RootTempPkg2FolderInfo.Create(); FileStream kernelstream = HACGUIKeyset.TempKernelFileInfo.Create(); FileStream INI1stream = HACGUIKeyset.TempINI1FileInfo.Create(); pkg2.OpenKernel().CopyTo(kernelstream); pkg2.OpenIni1().CopyTo(INI1stream); kernelstream.Close(); INI1stream.Close(); Ini1 INI1 = new Ini1(pkg2.OpenIni1()); List <HashSearchEntry> hashes = new List <HashSearchEntry>(); Dictionary <byte[], byte[]> keys = new Dictionary <byte[], byte[]>(); HACGUIKeyset.RootTempINI1Folder.Create(); foreach (Kip kip in INI1.Kips) { Stream rodatastream, datastream; switch (kip.Header.Name) { case "FS": hashes.Add(new HashSearchEntry(NintendoKeys.KeyAreaKeyApplicationSourceHash, 0x10)); hashes.Add(new HashSearchEntry(NintendoKeys.KeyAreaKeyOceanSourceHash, 0x10)); hashes.Add(new HashSearchEntry(NintendoKeys.KeyAreaKeySystemSourceHash, 0x10)); hashes.Add(new HashSearchEntry(NintendoKeys.HeaderKekSourceHash, 0x10)); hashes.Add(new HashSearchEntry(NintendoKeys.SaveMacKekSourceHash, 0x10)); hashes.Add(new HashSearchEntry(NintendoKeys.SaveMacKeySourceHash, 0x10)); rodatastream = new MemoryStream(kip.DecompressSection(1)); keys = rodatastream.FindKeyViaHash(hashes, new SHA256Managed(), 0x10); Array.Copy(keys[NintendoKeys.KeyAreaKeyApplicationSourceHash], HACGUIKeyset.Keyset.KeyAreaKeyApplicationSource, 0x10); Array.Copy(keys[NintendoKeys.KeyAreaKeyOceanSourceHash], HACGUIKeyset.Keyset.KeyAreaKeyOceanSource, 0x10); Array.Copy(keys[NintendoKeys.KeyAreaKeySystemSourceHash], HACGUIKeyset.Keyset.KeyAreaKeySystemSource, 0x10); Array.Copy(keys[NintendoKeys.HeaderKekSourceHash], HACGUIKeyset.Keyset.HeaderKekSource, 0x10); Array.Copy(keys[NintendoKeys.SaveMacKekSourceHash], HACGUIKeyset.Keyset.SaveMacKekSource, 0x10); Array.Copy(keys[NintendoKeys.SaveMacKeySourceHash], HACGUIKeyset.Keyset.SaveMacKeySource, 0x10); hashes.Clear(); rodatastream.Seek(0, SeekOrigin.Begin); bool sdWarn = false; hashes.Add(new HashSearchEntry(NintendoKeys.SDCardKekSourceHash, 0x10)); try { keys = rodatastream.FindKeyViaHash(hashes, new SHA256Managed(), 0x10); Array.Copy(keys[NintendoKeys.SDCardKekSourceHash], HACGUIKeyset.Keyset.SdCardKekSource, 0x10); } catch (EndOfStreamException) { MessageBox.Show("Failed to find SD card kek source! The NAND is probably from 1.0.0."); sdWarn = true; } if (!sdWarn) // don't try to find the rest of the keys if the other one couldn't be found { hashes.Clear(); rodatastream.Seek(0, SeekOrigin.Begin); hashes.Add(new HashSearchEntry(NintendoKeys.SDCardSaveKeySourceHash, 0x20)); hashes.Add(new HashSearchEntry(NintendoKeys.SDCardNcaKeySourceHash, 0x20)); keys = rodatastream.FindKeyViaHash(hashes, new SHA256Managed(), 0x20); Array.Copy(keys[NintendoKeys.SDCardSaveKeySourceHash], HACGUIKeyset.Keyset.SdCardKeySources[0], 0x20); Array.Copy(keys[NintendoKeys.SDCardNcaKeySourceHash], HACGUIKeyset.Keyset.SdCardKeySources[1], 0x20); } hashes.Clear(); rodatastream.Close(); hashes.Add(new HashSearchEntry(NintendoKeys.HeaderKeySourceHash, 0x20)); datastream = new MemoryStream(kip.DecompressSection(2)); keys = datastream.FindKeyViaHash(hashes, new SHA256Managed(), 0x20); Array.Copy(keys[NintendoKeys.HeaderKeySourceHash], HACGUIKeyset.Keyset.HeaderKeySource, 0x20); datastream.Close(); hashes.Clear(); break; case "spl": hashes.Add(new HashSearchEntry(NintendoKeys.AesKeyGenerationSourceHash, 0x10)); rodatastream = new MemoryStream(kip.DecompressSection(1)); keys = rodatastream.FindKeyViaHash(hashes, new SHA256Managed(), 0x10); Array.Copy(keys[NintendoKeys.AesKeyGenerationSourceHash], HACGUIKeyset.Keyset.AesKeyGenerationSource, 0x10); rodatastream.Close(); hashes.Clear(); break; } FileStream kipstream = HACGUIKeyset.RootTempINI1Folder.GetFile(kip.Header.Name + ".kip").Create(); kip.OpenRawFile().CopyTo(kipstream); kipstream.Close(); } pkg2stream.Close(); INI1stream.Close(); HACGUIKeyset.Keyset.DeriveKeys(); SwitchFs fs = new SwitchFs(HACGUIKeyset.Keyset, NANDService.NAND.OpenSystemPartition()); foreach (KeyValuePair <string, Nca> kv in fs.Ncas) { Nca nca = kv.Value; switch (nca.Header.TitleId) { case 0x0100000000000033: // es switch (nca.Header.ContentType) { case ContentType.Program: NcaSection exefsSection = nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Pfs0); Stream pfsStream = nca.OpenSection(exefsSection.SectionNum, false, false); Pfs pfs = new Pfs(pfsStream); Nso nso = new Nso(pfs.OpenFile("main")); NsoSection section = nso.Sections[1]; Stream data = new MemoryStream(section.DecompressSection()); hashes.Clear(); hashes.Add(new HashSearchEntry(NintendoKeys.EticketRsaKekSourceHash, 0x10)); hashes.Add(new HashSearchEntry(NintendoKeys.EticketRsaKekekSourceHash, 0x10)); keys = data.FindKeyViaHash(hashes, new SHA256Managed(), 0x10, data.Length); byte[] EticketRsaKekSource = new byte[0x10]; byte[] EticketRsaKekekSource = new byte[0x10]; Array.Copy(keys[NintendoKeys.EticketRsaKekSourceHash], EticketRsaKekSource, 0x10); Array.Copy(keys[NintendoKeys.EticketRsaKekekSourceHash], EticketRsaKekekSource, 0x10); byte[] RsaOaepKekGenerationSource; XOR(NintendoKeys.KekMasks[0], NintendoKeys.KekSeeds[3], out RsaOaepKekGenerationSource); byte[] key1 = new byte[0x10]; Crypto.DecryptEcb(HACGUIKeyset.Keyset.MasterKeys[0], RsaOaepKekGenerationSource, key1, 0x10); byte[] key2 = new byte[0x10]; Crypto.DecryptEcb(key1, EticketRsaKekekSource, key2, 0x10); byte[] key3 = new byte[0x10]; Crypto.DecryptEcb(key2, EticketRsaKekSource, HACGUIKeyset.Keyset.EticketRsaKek, 0x10); break; } break; } } Stream prodinfo = nand.OpenProdInfo(); Stream prodinfoFile = HACGUIKeyset.TempPRODINFOFileInfo.Create(); prodinfo.CopyTo(prodinfoFile); prodinfo.Close(); prodinfoFile.Seek(0, SeekOrigin.Begin); Calibration cal0 = new Calibration(prodinfoFile); HACGUIKeyset.Keyset.EticketExtKeyRsa = Crypto.DecryptRsaKey(cal0.EticketExtKeyRsa, HACGUIKeyset.Keyset.EticketRsaKek); prodinfoFile.Close(); List <Ticket> tickets = new List <Ticket>(); NandPartition system = nand.OpenSystemPartition(); Stream e1Stream = system.OpenFile("save\\80000000000000E1", FileMode.Open, FileAccess.Read); tickets.AddRange(ReadTickets(HACGUIKeyset.Keyset, e1Stream)); Stream e2Stream = system.OpenFile("save\\80000000000000E2", FileMode.Open, FileAccess.Read); tickets.AddRange(ReadTickets(HACGUIKeyset.Keyset, e2Stream)); Stream nsAppmanStream = system.OpenFile("save\\8000000000000043", FileMode.Open, FileAccess.Read); Savefile save = new Savefile(HACGUIKeyset.Keyset, nsAppmanStream, false); Stream privateStream = save.OpenFile("/private"); byte[] sdSeed = new byte[0x10]; privateStream.Read(sdSeed, 0, 0x10); // Seek doesn't work so i just read twice privateStream.Read(sdSeed, 0, 0x10); HACGUIKeyset.Keyset.SetSdSeed(sdSeed); foreach (Ticket ticket in tickets) { HACGUIKeyset.Keyset.TitleKeys[ticket.RightsId] = new byte[0x10]; Array.Copy(ticket.TitleKeyBlock, HACGUIKeyset.Keyset.TitleKeys[ticket.RightsId], 0x10); } NANDService.Stop(); HACGUIKeyset.ProductionKeysFileInfo.Create().WriteString(HACGUIKeyset.PrintCommonKeys(HACGUIKeyset.Keyset, true)); HACGUIKeyset.ExtraKeysFileInfo.Create().WriteString(HACGUIKeyset.PrintCommonWithoutFriendlyKeys(HACGUIKeyset.Keyset)); HACGUIKeyset.ConsoleKeysFileInfo.Create().WriteString(ExternalKeys.PrintUniqueKeys(HACGUIKeyset.Keyset)); HACGUIKeyset.GetConsoleKeysFileInfoByName(PickConsole.ConsoleName).Create().WriteString(ExternalKeys.PrintUniqueKeys(HACGUIKeyset.Keyset)); HACGUIKeyset.TitleKeysFileInfo.Create().WriteString(ExternalKeys.PrintTitleKeys(HACGUIKeyset.Keyset)); }
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 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()); } }