public static void ExtractSection(this Nca nca, NcaSectionType type, string outputDir, IntegrityCheckLevel integrityCheckLevel = IntegrityCheckLevel.None, IProgressReport logger = null) { IFileSystem fs = nca.OpenFileSystem(type, integrityCheckLevel); fs.Extract(outputDir, logger); }
public static bool TryGetSectionIndexFromType(NcaSectionType type, NcaContentType contentType, out int index) { switch (type) { case NcaSectionType.Code when contentType == NcaContentType.Program: index = 0; return(true); case NcaSectionType.Data when contentType == NcaContentType.Program: index = 1; return(true); case NcaSectionType.Logo when contentType == NcaContentType.Program: index = 2; return(true); case NcaSectionType.Data: index = 0; return(true); default: index = 0; return(false); } }
public static int GetSectionIndexFromType(NcaSectionType type, NcaContentType contentType) { if (!TryGetSectionIndexFromType(type, contentType, out int index)) { throw new ArgumentOutOfRangeException(nameof(type), "NCA does not contain this section type."); } return(index); }
public static IStorage OpenStorage(this Nca nca, NcaSectionType type, IntegrityCheckLevel integrityCheckLevel, bool openRaw) { if (openRaw) { return(nca.OpenRawStorage(type)); } return(nca.OpenStorage(type, integrityCheckLevel)); }
public bool CanOpenSection(NcaSectionType type) { if (!TryGetSectionIndexFromType(type, Header.ContentType, out int index)) { return(false); } return(CanOpenSection(index)); }
public bool SectionExists(NcaSectionType type) { if (!TryGetSectionIndexFromType(type, Header.ContentType, out int index)) { return(false); } return(SectionExists(index)); }
public IFileSystem TryOpenFileSystemSection(NcaSectionType section) { try { return(Nca.OpenFileSystem(section, IntegrityCheckLevel.ErrorOnInvalid)); } catch (System.ArgumentException) { return(null); } }
public int Extract(string outDir) { int res = 0; Console.WriteLine($"--- {FormatName} ---"); for (NcaSectionType section = NcaSectionType.Code; section <= NcaSectionType.Logo; section++) { using (IFileSystem currentIFs = TryOpenFileSystemSection(section)) { if (currentIFs != null) { string basePath = $"{outDir}/{FormatName}/{section}/"; Console.WriteLine(); List <string> dirEntList = EnumerateDir(currentIFs); if (dirEntList.Count <= 0) { continue; } Directory.CreateDirectory(basePath); foreach (string dirEnt in dirEntList) { string name = dirEnt; string filePath = $"{basePath}{name}".TrimEnd('\x00'); currentIFs.OpenFile(out IFile OpenFile, name.ToU8Span(), OpenMode.Read); if (OpenFile != null) { Console.WriteLine($"{filePath}"); using (FileStream fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write)) { OpenFile.AsStream().CopyTo(fileStream); } } } Console.WriteLine("\n"); } } } return(res); }
private int GetSectionIndexFromType(NcaSectionType type) { return(GetSectionIndexFromType(type, Header.ContentType)); }
public IStorage OpenStorageWithPatch(Nca patchNca, NcaSectionType type, IntegrityCheckLevel integrityCheckLevel) { return(OpenStorageWithPatch(patchNca, GetSectionIndexFromType(type), integrityCheckLevel)); }
public IStorage OpenStorage(NcaSectionType type, IntegrityCheckLevel integrityCheckLevel) { return(OpenStorage(GetSectionIndexFromType(type), integrityCheckLevel)); }
public IStorage OpenRawStorageWithPatch(Nca patchNca, NcaSectionType type) { return(OpenRawStorageWithPatch(patchNca, GetSectionIndexFromType(type))); }
public IFileSystem OpenFileSystem(NcaSectionType type, IntegrityCheckLevel integrityCheckLevel) { return(OpenFileSystem(GetSectionIndexFromType(type), integrityCheckLevel)); }
public static void ExportSection(this Nca nca, NcaSectionType type, string filename, bool raw = false, IntegrityCheckLevel integrityCheckLevel = IntegrityCheckLevel.None, IProgressReport logger = null) { nca.OpenStorage(type, integrityCheckLevel, raw) .WriteAllBytes(filename, logger); }
public IFileSystem OpenFileSystemWithPatch(Nca patchNca, NcaSectionType type, IntegrityCheckLevel integrityCheckLevel) { return(OpenFileSystemWithPatch(patchNca, GetSectionIndexFromType(type), integrityCheckLevel)); }
public static bool TryGetSectionTypeFromIndex(int index, NcaContentType contentType, out NcaSectionType type) { switch (index) { case 0 when contentType == NcaContentType.Program: type = NcaSectionType.Code; return(true); case 1 when contentType == NcaContentType.Program: type = NcaSectionType.Data; return(true); case 2 when contentType == NcaContentType.Program: type = NcaSectionType.Logo; return(true); case 0: type = NcaSectionType.Data; return(true); default: type = default; return(false); } }
public IStorage OpenRawStorage(NcaSectionType type) { return(OpenRawStorage(GetSectionIndexFromType(type))); }
private void ExtractSection(NcaSectionType ncaSectionType) { FileChooserDialog fileChooser = new FileChooserDialog("Choose the folder to extract into", null, FileChooserAction.SelectFolder, "Cancel", ResponseType.Cancel, "Extract", ResponseType.Accept); fileChooser.SetPosition(WindowPosition.Center); int response = fileChooser.Run(); string destination = fileChooser.Filename; fileChooser.Dispose(); if (response == (int)ResponseType.Accept) { Thread extractorThread = new Thread(() => { string sourceFile = _gameTableStore.GetValue(_rowIter, 9).ToString(); Gtk.Application.Invoke(delegate { _dialog = new MessageDialog(null, DialogFlags.DestroyWithParent, MessageType.Info, ButtonsType.Cancel, null) { Title = "Ryujinx - NCA Section Extractor", Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png"), SecondaryText = $"Extracting {ncaSectionType} section from {System.IO.Path.GetFileName(sourceFile)}...", WindowPosition = WindowPosition.Center }; int dialogResponse = _dialog.Run(); if (dialogResponse == (int)ResponseType.Cancel || dialogResponse == (int)ResponseType.DeleteEvent) { _cancel = true; _dialog.Dispose(); } }); using (FileStream file = new FileStream(sourceFile, FileMode.Open, FileAccess.Read)) { Nca mainNca = null; Nca patchNca = null; if ((System.IO.Path.GetExtension(sourceFile).ToLower() == ".nsp") || (System.IO.Path.GetExtension(sourceFile).ToLower() == ".pfs0") || (System.IO.Path.GetExtension(sourceFile).ToLower() == ".xci")) { PartitionFileSystem pfs; if (System.IO.Path.GetExtension(sourceFile) == ".xci") { Xci xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage()); pfs = xci.OpenPartition(XciPartitionType.Secure); } else { pfs = new PartitionFileSystem(file.AsStorage()); } foreach (DirectoryEntryEx fileEntry in pfs.EnumerateEntries("/", "*.nca")) { pfs.OpenFile(out IFile ncaFile, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure(); Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage()); if (nca.Header.ContentType == NcaContentType.Program) { int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program); if (nca.Header.GetFsHeader(dataIndex).IsPatchSection()) { patchNca = nca; } else { mainNca = nca; } } } } else if (System.IO.Path.GetExtension(sourceFile).ToLower() == ".nca") { mainNca = new Nca(_virtualFileSystem.KeySet, file.AsStorage()); } if (mainNca == null) { Logger.PrintError(LogClass.Application, "Extraction failed. The main NCA was not present in the selected file."); Gtk.Application.Invoke(delegate { GtkDialog.CreateErrorDialog("Extraction failed. The main NCA was not present in the selected file."); }); return; } int index = Nca.GetSectionIndexFromType(ncaSectionType, mainNca.Header.ContentType); IFileSystem ncaFileSystem = patchNca != null ? mainNca.OpenFileSystemWithPatch(patchNca, index, IntegrityCheckLevel.ErrorOnInvalid) : mainNca.OpenFileSystem(index, IntegrityCheckLevel.ErrorOnInvalid); FileSystemClient fsClient = _virtualFileSystem.FsClient; string source = DateTime.Now.ToFileTime().ToString().Substring(10); string output = DateTime.Now.ToFileTime().ToString().Substring(10); fsClient.Register(source.ToU8Span(), ncaFileSystem); fsClient.Register(output.ToU8Span(), new LocalFileSystem(destination)); (Result? resultCode, bool canceled) = CopyDirectory(fsClient, $"{source}:/", $"{output}:/"); if (!canceled) { if (resultCode.Value.IsFailure()) { Logger.PrintError(LogClass.Application, $"LibHac returned error code: {resultCode.Value.ErrorCode}"); Gtk.Application.Invoke(delegate { _dialog?.Dispose(); GtkDialog.CreateErrorDialog("Extraction failed. Read the log file for further information."); }); } else if (resultCode.Value.IsSuccess()) { Gtk.Application.Invoke(delegate { _dialog?.Dispose(); MessageDialog dialog = new MessageDialog(null, DialogFlags.DestroyWithParent, MessageType.Info, ButtonsType.Ok, null) { Title = "Ryujinx - NCA Section Extractor", Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png"), SecondaryText = "Extraction has completed successfully.", WindowPosition = WindowPosition.Center }; dialog.Run(); dialog.Dispose(); }); } } fsClient.Unmount(source.ToU8Span()); fsClient.Unmount(output.ToU8Span()); } }); extractorThread.Name = "GUI.NcaSectionExtractorThread"; extractorThread.IsBackground = true; extractorThread.Start(); } }
public void ShowNcaInfo() { Window.RemoveAll(); string NcaPath = (string)Utils.FirmwareUtils.OpenNcaStorageByTitleName(Path, FwTui.NcaNames[FwTui.FirmwareListView.SelectedItem], true); NcaInfo ncaInfo = new NcaInfo(new LocalStorage(NcaPath, FileAccess.Read)); List <string> NcaInfoLines = new List <string>(); string FormattedTid = $"{ncaInfo.Nca.Header.TitleId:X16}"; string FormattedName = $"{ncaInfo.TitleName}"; NcaInfoLines.Add($"Title ID: {FormattedTid}"); if (FormattedName != FormattedTid) { NcaInfoLines.Add($"Title Name: {FormattedName}"); } NcaInfoLines.Add($"Content Type: {ncaInfo.Nca.Header.ContentType}"); string ncaID = NcaPath.Split("/").Last(); if (ncaID == "00.nca") { ncaID = NcaPath.Split("/")[NcaPath.Split("/").Length - 2]; } else { ncaID = ncaID.Replace(".nca", ""); } NcaInfoLines.Add($"Nca ID: {ncaID}"); for (NcaSectionType section = NcaSectionType.Code; section <= NcaSectionType.Logo; section++) { if (ncaInfo.Nca.SectionExists(section)) { NcaInfoLines.Add($"\n{section}"); try { using (PartitionFileSystem pfs = new PartitionFileSystem(ncaInfo.TryOpenStorageSection(section))) { foreach (DirectoryEntryEx dirEnt in pfs.EnumerateEntries()) { NcaInfoLines.Add($"{dirEnt.Name} - {dirEnt.Size} bytes"); } } } catch (LibHac.HorizonResultException) { } } } //Actually draw them int Y = 1; foreach (string content in NcaInfoLines) { int lines = System.Text.RegularExpressions.Regex.Matches(content, "\n").Count + 1; Window.Add(new Label(1, Y, content)); Y += lines; } }