Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
 public static IStorage OpenStorage(this Nca nca, NcaSectionType type, IntegrityCheckLevel integrityCheckLevel,
                                    bool openRaw)
 {
     if (openRaw)
     {
         return(nca.OpenRawStorage(type));
     }
     return(nca.OpenStorage(type, integrityCheckLevel));
 }
Beispiel #5
0
        public bool CanOpenSection(NcaSectionType type)
        {
            if (!TryGetSectionIndexFromType(type, Header.ContentType, out int index))
            {
                return(false);
            }

            return(CanOpenSection(index));
        }
Beispiel #6
0
        public bool SectionExists(NcaSectionType type)
        {
            if (!TryGetSectionIndexFromType(type, Header.ContentType, out int index))
            {
                return(false);
            }

            return(SectionExists(index));
        }
Beispiel #7
0
 public IFileSystem TryOpenFileSystemSection(NcaSectionType section)
 {
     try
     {
         return(Nca.OpenFileSystem(section, IntegrityCheckLevel.ErrorOnInvalid));
     }
     catch (System.ArgumentException)
     {
         return(null);
     }
 }
Beispiel #8
0
        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);
        }
Beispiel #9
0
 private int GetSectionIndexFromType(NcaSectionType type)
 {
     return(GetSectionIndexFromType(type, Header.ContentType));
 }
Beispiel #10
0
 public IStorage OpenStorageWithPatch(Nca patchNca, NcaSectionType type, IntegrityCheckLevel integrityCheckLevel)
 {
     return(OpenStorageWithPatch(patchNca, GetSectionIndexFromType(type), integrityCheckLevel));
 }
Beispiel #11
0
 public IStorage OpenStorage(NcaSectionType type, IntegrityCheckLevel integrityCheckLevel)
 {
     return(OpenStorage(GetSectionIndexFromType(type), integrityCheckLevel));
 }
Beispiel #12
0
 public IStorage OpenRawStorageWithPatch(Nca patchNca, NcaSectionType type)
 {
     return(OpenRawStorageWithPatch(patchNca, GetSectionIndexFromType(type)));
 }
Beispiel #13
0
 public IFileSystem OpenFileSystem(NcaSectionType type, IntegrityCheckLevel integrityCheckLevel)
 {
     return(OpenFileSystem(GetSectionIndexFromType(type), integrityCheckLevel));
 }
Beispiel #14
0
 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);
 }
Beispiel #15
0
 public IFileSystem OpenFileSystemWithPatch(Nca patchNca, NcaSectionType type, IntegrityCheckLevel integrityCheckLevel)
 {
     return(OpenFileSystemWithPatch(patchNca, GetSectionIndexFromType(type), integrityCheckLevel));
 }
Beispiel #16
0
        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);
            }
        }
Beispiel #17
0
 public IStorage OpenRawStorage(NcaSectionType type)
 {
     return(OpenRawStorage(GetSectionIndexFromType(type)));
 }
Beispiel #18
0
        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;
            }
        }