Example #1
0
        public static Title processFile(string filename)
        {
            log?.WriteLine("\nProcessing file {0}", filename);

            try
            {
                Title title = processXci(filename) ?? processNsp(filename) ?? processNro(filename);

                title.filename = filename;
                title.filesize = new FileInfo(filename).Length;

                return(title);
            }
            catch (MissingKeyException ex)
            {
                log?.WriteLine("Missing {0}: {1}", ex.Type == KeyType.Title ? "Title Key" : "Key", ex.Name.Replace("key_area_key_application", "master_key"));
            }
            catch (NullReferenceException ex)
            {
                log?.WriteLine(ex.StackTrace);

                log?.WriteLine("\nFile {0} has failed to process", filename);
            }

            return(null);
        }
Example #2
0
        public static Title processNro(string filename)
        {
            Title title = new Title();

            using (var filestream = new FileStream(filename, FileMode.Open, FileAccess.Read))
            {
                Nro nro;

                try
                {
                    nro = new Nro(filestream.AsStorage());

                    title.distribution = Title.Distribution.Homebrew;

                    log?.WriteLine("Processing NRO {0}", filename);

                    using (var control = nro.OpenNacp().AsStream())
                    {
                        processControlNacp(control, ref title);
                    }
                }
                catch (InvalidDataException)
                {
                    return(null);
                }
            }

            log?.WriteLine("NRO information for {0}: [{1}] {2}", filename, title.titleName, title.displayVersion);

            return(title);
        }
Example #3
0
        private static void processControlNacp(Stream controlNacp, ref Title title)
        {
            log?.WriteLine("Processing Control NACP");

            Nacp nacp = new Nacp(controlNacp);

            bool first = true;

            foreach (NacpDescription description in nacp.Descriptions)
            {
                if (!String.IsNullOrEmpty(description.Title))
                {
                    if (first)
                    {
                        title.titleName = description.Title;
                        title.publisher = description.Developer;
                        first           = false;
                    }

                    title.languages.Add(Title.LanguageCode.ElementAtOrDefault((int)description.Language));
                }
            }

            title.displayVersion = nacp.DisplayVersion;
        }
Example #4
0
        static List <Title> openSDCard(string pathSd)
        {
            Process.log?.WriteLine("\nOpen SD Card");

            List <FsTitle> fsTitles = Process.processSd(pathSd);

            List <Title> titles = new List <Title>();

            if (fsTitles != null)
            {
                foreach (var fsTitle in fsTitles)
                {
                    Title title = Process.processTitle(fsTitle);
                    if (title != null)
                    {
                        titles.Add(title);
                    }
                }

                Process.log?.WriteLine("\n{0} titles processed", titles.Count);
            }
            else
            {
                string error = "SD card \"Contents\" directory could not be found";
                Process.log?.WriteLine(error);

                Console.ForegroundColor = ConsoleColor.DarkYellow;
                Console.Error.WriteLine(error);
                Console.ResetColor();
            }

            return(titles);
        }
Example #5
0
        static List <Title> openDirectory(string path)
        {
            Process.log?.WriteLine("\nOpen Directory");

            List <string> filenames = Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)
                                      .Where(filename => filename.ToLower().EndsWith(".xci") || filename.ToLower().EndsWith(".nsp") || filename.ToLower().EndsWith(".nro") ||
                                             (Common.Settings.Default.NszExtension && (filename.ToLower().EndsWith(".xcz") || filename.ToLower().EndsWith(".nsz")))).ToList();

            filenames.Sort();

            Process.log?.WriteLine("{0} files selected", filenames.Count);
            Console.Error.WriteLine("Opening {0} files from directory {1}", filenames.Count, path);

            List <Title> titles = new List <Title>();

            foreach (string filename in filenames)
            {
                Title title = Process.processFile(filename);
                if (title != null)
                {
                    titles.Add(title);
                }
            }

            Process.log?.WriteLine("\n{0} titles processed", titles.Count);

            return(titles);
        }
Example #6
0
        private static void processBiggestNca(Nca nca, ref Title title)
        {
            log?.WriteLine("Processing Biggest NCA");

            if (((title.type == TitleType.Application || title.type == TitleType.Patch) && nca.Header.ContentType == ContentType.Program) ||
                (title.type == TitleType.Patch && nca.Header.ContentType == ContentType.Data) ||
                (title.type == TitleType.AddOnContent && nca.Header.ContentType == ContentType.AocData))
            {
                title.signature = (nca.Header.FixedSigValidity == Validity.Valid);
            }

            if (nca.HasRightsId)
            {
                if (keyset.TitleNames.TryGetValue(nca.Header.RightsId, out string titleName))
                {
                    title.titleName = titleName;
                }
                if (keyset.TitleVersions.TryGetValue(nca.Header.RightsId, out uint titleVersion))
                {
                    title.latestVersion = titleVersion;
                }
            }
            else
            {
                if (titleNames.TryGetValue(title.titleID, out string titleName))
                {
                    title.titleName = titleName;
                }
                else if (titleNames.TryGetValue(title.titleIDApplication, out titleName))
                {
                    title.titleName = titleName;

                    if (title.type == TitleType.AddOnContent)
                    {
                        title.titleName += " [DLC]";
                    }
                }
                if (titleVersions.TryGetValue(title.titleID, out uint titleVersion))
                {
                    title.latestVersion = titleVersion;
                }
            }

            if (((title.type == TitleType.Application || title.type == TitleType.Patch) && nca.Header.ContentType == ContentType.Program) ||
                (title.type == TitleType.Patch && nca.Header.ContentType == ContentType.Data) ||
                (title.type == TitleType.AddOnContent && nca.Header.ContentType == ContentType.AocData))
            {
                title.masterkey = (uint)nca.Header.CryptoType == 2 ? (uint)Math.Max(nca.Header.CryptoType2 - 1, 0) : 0;

                if (nca.Header.ContentType == ContentType.Program)
                {
                    processNpdm(nca, ref title);
                }
            }
        }
Example #7
0
        static Title openFile(string filename)
        {
            Process.log?.WriteLine("\nOpen File");

            Process.log?.WriteLine("File selected");
            Console.Error.WriteLine("Opening file {0}", filename);

            Title title = Process.processFile(filename);

            Process.log?.WriteLine("\nTitle processed");

            return(title);
        }
Example #8
0
        private static void processControlNacp(Stream controlNacp, ref Title title)
        {
            log?.WriteLine("Processing Control NACP");

            Nacp nacp = new Nacp(controlNacp);

            foreach (NacpDescription description in nacp.Descriptions)
            {
                if (!String.IsNullOrEmpty(description.Title))
                {
                    title.titleName = description.Title;
                    break;
                }
            }

            title.displayVersion = nacp.DisplayVersion;
        }
Example #9
0
        private static void processNpdm(Nca nca, ref Title title)
        {
            log?.WriteLine("Processing NPDM");

            try
            {
                nca.ParseNpdm();
            }
            catch (MissingKeyException ex)
            {
                title.error = String.Format("Missing {0}: {1}", ex.Type == KeyType.Title ? "Title Key" : "Key", ex.Name.Replace("key_area_key_application", "master_key"));

                log?.WriteLine(title.error);
            }
            catch { }

            if (nca.Npdm != null)
            {
                if (nca.Npdm.AciD.ServiceAccess.Services.Count == 0 || nca.Npdm.AciD.ServiceAccess.Services.Keys.Any(key => key.StartsWith("fsp-")))
                {
                    log?.WriteLine("Permissions Bitmask 0x{0:x16}", nca.Npdm.AciD.FsAccess.PermissionsBitmask);

                    if (nca.Npdm.AciD.FsAccess.PermissionsBitmask == 0xffffffffffffffff)
                    {
                        title.permission = Title.Permission.Dangerous;
                    }
                    else if ((nca.Npdm.AciD.FsAccess.PermissionsBitmask & 0x8000000000000000) != 0)
                    {
                        title.permission = Title.Permission.Unsafe;
                    }
                    else
                    {
                        title.permission = Title.Permission.Safe;
                    }
                }
                else
                {
                    title.permission = Title.Permission.Safe;
                }
            }
        }
Example #10
0
        public static Title processFile(string filename)
        {
            log?.WriteLine("\nProcessing file {0}", filename);

            try
            {
                Title title = processXci(filename) ?? processNsp(filename) ?? processNro(filename);

                title.filename = filename;
                title.filesize = new FileInfo(filename).Length;

                string titleID = title.type == TitleType.AddOnContent ? title.titleID : title.baseTitleID ?? "";

                if (latestVersions.TryGetValue(titleID, out uint version))
                {
                    if (title.version > version)
                    {
                        latestVersions[titleID] = title.version;
                    }
                }
                else
                {
                    latestVersions.Add(titleID, title.version);
                }

                return(title);
            }
            catch (MissingKeyException ex)
            {
                log?.WriteLine("Missing {0}: {1}", ex.Type == KeyType.Title ? "Title Key" : "Key", ex.Name.Replace("key_area_key_application", "master_key"));
            }
            catch (SystemException ex) when(ex is NullReferenceException || ex is ArgumentException)
            {
                log?.WriteLine(ex.StackTrace);

                log?.WriteLine("\nFile {0} has failed to process", filename);
            }

            return(null);
        }
Example #11
0
        private static void processNacpXml(IStorage nacpXml, ref Title title)
        {
            log?.WriteLine("Processing NACP XML");

            Stream stream = nacpXml.AsStream();

            byte[] buffer = new byte[stream.Length];
            stream.Read(buffer, 0, buffer.Length);
            stream.Close();

            byte[] bom = Encoding.UTF8.GetPreamble();
            if (buffer.Take(bom.Length).SequenceEqual(bom))
            {
                Array.Copy(buffer, bom.Length, buffer, 0, buffer.Length - bom.Length);
                Array.Resize(ref buffer, buffer.Length - bom.Length);
            }

            XDocument xml = XDocument.Parse(Encoding.UTF8.GetString(buffer).Replace("&", "&amp;"));

            title.titleName      = xml.Element("Application").Element("Title").Element("Name").Value;
            title.displayVersion = xml.Element("Application").Element("DisplayVersion").Value;
        }
Example #12
0
        public void reloadData()
        {
            uint index = 0, count = (uint)titles.Count;

            objectListView.SetObjects(titles);

            foreach (OLVListItem listItem in objectListView.Items)
            {
                Title title = listItem.RowObject as Title;

                progressDialog?.SetLine(2, title.titleName, true, IntPtr.Zero);
                progressDialog?.SetProgress(index++, count);

                string titleID = title.type == TitleType.AddOnContent ? title.titleID : title.baseTitleID ?? "";

                Process.latestVersions.TryGetValue(titleID, out uint latestVersion);
                Process.versionList.TryGetValue(titleID, out uint version);
                Process.titleVersions.TryGetValue(titleID, out uint titleVersion);

                if (latestVersion < version || latestVersion < titleVersion)
                {
                    listItem.BackColor = title.signature != true ? Color.OldLace : Color.LightYellow;
                }
                else if (title.signature != true)
                {
                    listItem.BackColor = Color.WhiteSmoke;
                }

                if (title.permission == Title.Permission.Dangerous)
                {
                    listItem.ForeColor = Color.DarkRed;
                }
                else if (title.permission == Title.Permission.Unsafe)
                {
                    listItem.ForeColor = Color.Indigo;
                }
            }
        }
Example #13
0
        private static void processControlNca(Nca nca, ref Title title)
        {
            log?.WriteLine("Processing Control NCA");

            if (nca.Header.ContentType == ContentType.Control)
            {
                title.titleID = String.Format("{0:X16}", nca.Header.TitleId);

                if (title.type == TitleType.Patch)
                {
                    title.titleID = title.titleID.Substring(0, Math.Min(title.titleID.Length, 13)) + "800";
                }

                try
                {
                    Romfs romfs = new Romfs(nca.OpenSection(0, false, IntegrityCheckLevel.ErrorOnInvalid, true));

                    RomfsFile[] romfsFiles = romfs.Files.ToArray();
                    foreach (RomfsFile romfsFile in romfsFiles)
                    {
                        if (romfsFile.Name.Equals("control.nacp"))
                        {
                            using (var control = romfs.OpenFile(romfsFile).AsStream())
                            {
                                processControlNacp(control, ref title);
                            }
                        }
                    }
                }
                catch (MissingKeyException ex)
                {
                    title.error = String.Format("Missing {0}: {1}", ex.Type == KeyType.Title ? "Title Key" : "Key", ex.Name.Replace("key_area_key_application", "master_key"));

                    log?.WriteLine(title.error);
                }
                catch (FileNotFoundException) { }
            }
        }
Example #14
0
        private void backgroundWorkerProcess_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            if (e.Result is List <Title> titles)
            {
                objectListView.SetObjects(titles);

                foreach (OLVListItem listItem in objectListView.Items)
                {
                    Title title = listItem.RowObject as Title;

                    if (title.signature != true)
                    {
                        listItem.BackColor = Color.WhiteSmoke;
                    }

                    if (title.permission == Title.Permission.Dangerous)
                    {
                        listItem.ForeColor = Color.DarkRed;
                    }
                    else if (title.permission == Title.Permission.Unsafe)
                    {
                        listItem.ForeColor = Color.Indigo;
                    }
                }

                toolStripStatusLabel.Text = String.Format("{0} files", titles.Count);

                progressDialog.StopProgressDialog();
                Activate();
            }
            else if (e.Result is string error)
            {
                progressDialog.StopProgressDialog();

                MessageBox.Show(String.Format("{0}.", error), Application.ProductName);
            }
        }
Example #15
0
        private static void processBiggestNca(IStorage biggestNca, ref Title title)
        {
            Nca nca = new Nca(keyset, biggestNca, false);

            processBiggestNca(nca, ref title);
        }
Example #16
0
        private static (string, string) processCnmtNca(Nca nca, ref Title title, bool cnmtContent = true)
        {
            string biggestNca = null, controlNca = null;

            log?.WriteLine("Processing CNMT NCA");

            try
            {
                Pfs ncaPfs = new Pfs(nca.OpenSection(0, false, IntegrityCheckLevel.ErrorOnInvalid, true));

                PfsFileEntry[] ncaFileEntries = ncaPfs.Files;
                foreach (PfsFileEntry pfsEntry in ncaFileEntries)
                {
                    Cnmt cnmt = new Cnmt(ncaPfs.OpenFile(pfsEntry).AsStream());

                    if (title.version == unchecked ((uint)-1) || cnmt.TitleVersion?.Version > title.version)
                    {
                        title.type = cnmt.Type;

                        title.titleID     = String.Format("{0:X16}", cnmt.TitleId);
                        title.baseTitleID = String.Format("{0:X16}", cnmt.ApplicationTitleId);
                        title.version     = cnmt.TitleVersion?.Version ?? title.version;

                        title.systemVersion      = cnmt.MinimumSystemVersion?.Version ?? unchecked ((uint)-1);
                        title.applicationVersion = cnmt.MinimumApplicationVersion?.Version ?? unchecked ((uint)-1);

                        if (cnmtContent)
                        {
                            CnmtContentEntry[] contentEntries = cnmt.ContentEntries;
                            foreach (CnmtContentEntry contentEntry in contentEntries)
                            {
                                if (title.type == TitleType.Application || title.type == TitleType.Patch)
                                {
                                    if (contentEntry.Type == CnmtContentType.Program)
                                    {
                                        biggestNca = BitConverter.ToString(contentEntry.NcaId).Replace("-", "").ToLower() + ".nca";

                                        log?.WriteLine("Found Biggest NCA {0}", biggestNca);
                                    }
                                    else if (contentEntry.Type == CnmtContentType.Control)
                                    {
                                        controlNca = BitConverter.ToString(contentEntry.NcaId).Replace("-", "").ToLower() + ".nca";

                                        log?.WriteLine("Found Control NCA {0}", controlNca);
                                    }
                                }
                                else if (title.type == TitleType.AddOnContent)
                                {
                                    if (contentEntry.Type == CnmtContentType.Data)
                                    {
                                        biggestNca = BitConverter.ToString(contentEntry.NcaId).Replace("-", "").ToLower() + ".nca";

                                        log?.WriteLine("Found Biggest NCA {0}", biggestNca);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (MissingKeyException ex)
            {
                title.error = String.Format("Missing {0}: {1}", ex.Type == KeyType.Title ? "Title Key" : "Key", ex.Name.Replace("key_area_key_application", "master_key"));

                log?.WriteLine(title.error);
            }
            catch (FileNotFoundException) { }

            return(biggestNca, controlNca);
        }
Example #17
0
        private static (string, string) processCnmtNca(IStorage cnmtNca, ref Title title)
        {
            Nca nca = new Nca(keyset, cnmtNca, false);

            return(processCnmtNca(nca, ref title));
        }
Example #18
0
        public static Title processTitle(FsTitle fsTitle)
        {
            log?.WriteLine("\nProcessing title [{0:X16}] {1}", fsTitle.Id, fsTitle.Name);

            Title title = new Title
            {
                titleID      = String.Format("{0:X16}", fsTitle.Id),
                type         = fsTitle.Metadata.Type,
                filesize     = fsTitle.GetSize(),
                distribution = Title.Distribution.Filesystem
            };

            foreach (Nca nca in fsTitle.Ncas)
            {
                if (nca.Header.ContentType == ContentType.Program)
                {
                    title.filename = nca.Filename;

                    log?.WriteLine("Found Biggest NCA {0}", nca.Filename);

                    processBiggestNca(nca, ref title);
                }
                if (nca.Header.ContentType == ContentType.Data)
                {
                    title.filename = nca.Filename;

                    log?.WriteLine("Found Biggest NCA {0}", nca.Filename);

                    processBiggestNca(nca, ref title);
                }
                else if (nca.Header.ContentType == ContentType.Meta)
                {
                    processCnmtNca(nca, ref title, false);
                }
                else if (nca.Header.ContentType == ContentType.Control)
                {
                    log?.WriteLine("Found Control NCA {0}", nca.Filename);

                    processControlNca(nca, ref title);
                }
                else if (nca.Header.ContentType == ContentType.AocData)
                {
                    title.filename = nca.Filename;

                    log?.WriteLine("Found Biggest NCA {0}", nca.Filename);

                    processBiggestNca(nca, ref title);
                }
            }

            if (title.type == TitleType.Application || title.type == TitleType.Patch)
            {
                if (versionList.TryGetValue(title.baseTitleID, out uint version))
                {
                    title.latestVersion = version;
                }
            }

            if (title.type == TitleType.Patch)
            {
                title.titleID = title.titleID.Substring(0, Math.Min(title.titleID.Length, 13)) + "800";
            }

            if (title.version > 0)
            {
                string titleID = title.type == TitleType.AddOnContent ? title.titleID : title.baseTitleID ?? "";

                if (latestVersions.TryGetValue(titleID, out uint version))
                {
                    if (title.version > version)
                    {
                        latestVersions[titleID] = title.version;
                    }
                }
                else
                {
                    latestVersions.Add(titleID, title.version);
                }
            }

            log?.WriteLine("Title information for {0}: [{1}] {2}", title.filename, title.titleID, title.titleName);

            return(title);
        }
Example #19
0
        private static (string, string) processCnmtXml(IStorage cnmtXml, ref Title title)
        {
            string biggestNca = null, controlNca = null;

            log?.WriteLine("Processing CNMT XML");

            Stream stream = cnmtXml.AsStream();

            byte[] buffer = new byte[stream.Length];
            stream.Read(buffer, 0, buffer.Length);
            stream.Close();

            byte[] bom = Encoding.UTF8.GetPreamble();
            if (buffer.Take(bom.Length).SequenceEqual(bom))
            {
                Array.Copy(buffer, bom.Length, buffer, 0, buffer.Length - bom.Length);
                Array.Resize(ref buffer, buffer.Length - bom.Length);
            }

            XDocument xml = XDocument.Parse(Encoding.UTF8.GetString(buffer).Replace("&", "&amp;"));

            Enum.TryParse(xml.Element("ContentMeta").Element("Type").Value, true, out TitleType titleType);
            title.type = titleType;

            title.titleID     = xml.Element("ContentMeta").Element("Id").Value.Remove(1, 2).ToUpper();
            title.baseTitleID = String.IsNullOrEmpty(title.titleID) ? "" : title.titleID.Substring(0, Math.Min(title.titleID.Length, 13)) + "000";
            title.version     = Convert.ToUInt32(xml.Element("ContentMeta").Element("Version").Value);

            title.systemUpdate = (uint)(Convert.ToUInt64(xml.Element("ContentMeta").Element("RequiredSystemVersion").Value) % 0x100000000);
            title.masterkey    = (uint)Math.Max(Convert.ToInt32(xml.Element("ContentMeta").Element("KeyGenerationMin").Value) - 1, 0);

            foreach (XElement element in xml.Descendants("Content"))
            {
                if (title.type == TitleType.Application || title.type == TitleType.Patch)
                {
                    if (element.Element("Type").Value == "Program")
                    {
                        biggestNca = element.Element("Id").Value + ".nca";

                        log?.WriteLine("Found Biggest NCA {0}", biggestNca);
                    }
                    else if (element.Element("Type").Value == "Control")
                    {
                        controlNca = element.Element("Id").Value + ".nca";

                        log?.WriteLine("Found Control NCA {0}", controlNca);
                    }
                }
                else if (title.type == TitleType.AddOnContent)
                {
                    if (element.Element("Type").Value == "Data")
                    {
                        biggestNca = element.Element("Id").Value + ".nca";

                        log?.WriteLine("Found Biggest NCA {0}", biggestNca);
                    }
                }
            }

            return(biggestNca, controlNca);
        }
Example #20
0
        public static Title processNsp(string filename)
        {
            Title title = new Title();

            using (var filestream = new FileStream(filename, FileMode.Open, FileAccess.Read))
            {
                Pfs    pfs;
                string biggestNca = null, controlNca = null;

                try
                {
                    pfs = new Pfs(filestream.AsStorage());

                    title.distribution = Title.Distribution.Digital;

                    log?.WriteLine("Processing NSP {0}", filename);

                    PfsFileEntry[] fileEntries = pfs.Files;
                    foreach (PfsFileEntry entry in fileEntries)
                    {
                        if (entry.Name.EndsWith(".cnmt.xml"))
                        {
                            try
                            {
                                using (var cnmtXml = pfs.OpenFile(entry))
                                {
                                    (biggestNca, controlNca) = processCnmtXml(cnmtXml, ref title);
                                }
                            }
                            catch (FileNotFoundException) { }

                            title.structure.Add(Title.Structure.CnmtXml);
                        }
                        else if (entry.Name.EndsWith(".cnmt.nca"))
                        {
                            try
                            {
                                using (var cnmtNca = pfs.OpenFile(entry))
                                {
                                    var nca = processCnmtNca(cnmtNca, ref title);
                                    if (nca.Item1 != null && (nca.Item2 != null || title.type == TitleType.AddOnContent))
                                    {
                                        (biggestNca, controlNca) = nca;
                                    }
                                }
                            }
                            catch (FileNotFoundException)
                            {
                                if (pfs.FileExists(entry.Name.Replace(".nca", ".ncz")))
                                {
                                    title.error = "Unsupported Format: Compressed NCA";
                                }
                            }

                            title.structure.Add(Title.Structure.CnmtNca);
                        }
                        else if (entry.Name.EndsWith(".cert"))
                        {
                            title.structure.Add(Title.Structure.Cert);
                        }
                        else if (entry.Name.EndsWith(".tik"))
                        {
                            try
                            {
                                using (var tik = pfs.OpenFile(entry))
                                {
                                    if (entry.Name.Split('.')[0].TryToBytes(out byte[] rightsId))
                                    {
                                        processTik(tik, rightsId, ref keyset, out byte[] titleKey);

                                        title.titleKey = BitConverter.ToString(titleKey).Replace("-", "").ToUpper();
                                    }
                                }
                            }
                            catch (FileNotFoundException)
                            {
                                if (pfs.FileExists(entry.Name.Replace(".nca", ".ncz")))
                                {
                                    title.error = "Unsupported Format: Compressed NCA";
                                }
                            }

                            title.structure.Add(Title.Structure.Tik);
                        }
                        else if (entry.Name.EndsWith(".legalinfo.xml"))
                        {
                            title.structure.Add(Title.Structure.LegalinfoXml);
                        }
                        else if (entry.Name.EndsWith(".nacp.xml"))
                        {
                            try
                            {
                                using (var nacpXml = pfs.OpenFile(entry))
                                {
                                    processNacpXml(nacpXml, ref title);
                                }
                            }
                            catch (FileNotFoundException) { }

                            title.structure.Add(Title.Structure.NacpXml);
                        }
                        else if (entry.Name.EndsWith(".programinfo.xml"))
                        {
                            title.structure.Add(Title.Structure.PrograminfoXml);
                        }
                        else if (entry.Name.Equals("cardspec.xml"))
                        {
                            title.structure.Add(Title.Structure.CardspecXml);
                        }
                        else if (entry.Name.Equals("authoringtoolinfo.xml"))
                        {
                            title.structure.Add(Title.Structure.AuthoringtoolinfoXml);
                        }
                    }

                    if (!String.IsNullOrEmpty(biggestNca))
                    {
                        try
                        {
                            using (var biggest = pfs.OpenFile(biggestNca))
                            {
                                processBiggestNca(biggest, ref title);
                            }
                        }
                        catch (FileNotFoundException)
                        {
                            if (pfs.FileExists(biggestNca.Replace(".nca", ".ncz")))
                            {
                                title.error = "Unsupported Format: Compressed NCA";
                            }
                        }
                    }

                    if (!String.IsNullOrEmpty(controlNca))
                    {
                        try
                        {
                            using (var control = pfs.OpenFile(controlNca))
                            {
                                processControlNca(control, ref title);
                            }
                        }
                        catch (FileNotFoundException)
                        {
                            if (pfs.FileExists(controlNca.Replace(".nca", ".ncz")))
                            {
                                title.error = "Unsupported Format: Compressed NCA";
                            }
                        }
                    }
                }
                catch (InvalidDataException)
                {
                    return(null);
                }
            }

            if (title.type == TitleType.Application || title.type == TitleType.Patch)
            {
                if (versionList.TryGetValue(title.baseTitleID, out uint version))
                {
                    title.latestVersion = version;
                }
            }

            log?.WriteLine("NSP information for {0}: [{1}] {2}", filename, title.titleID, title.titleName);

            return(title);
        }
Example #21
0
        static void processPaths(List <string> paths, string sort, bool sdcard)
        {
            List <Title> titles = new List <Title>();

            foreach (string path in paths)
            {
                if (Directory.Exists(path))
                {
                    if (sdcard)
                    {
                        titles.AddRange(openSDCard(path));
                    }
                    else
                    {
                        titles.AddRange(openDirectory(path));
                    }
                }
                else if (File.Exists(path) && (Common.Settings.Default.NszExtension ? new string[] { ".xci", ".nsp", ".xcz", ".nsz", ".nro" } : new string[] { ".xci", ".nsp", ".nro" }).Any(ext => ext.Equals(Path.GetExtension(path).ToLower())) && !sdcard)
                {
                    Title title = openFile(path);
                    if (title != null)
                    {
                        titles.Add(title);
                    }
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.DarkYellow;
                    Console.Error.WriteLine("{0} is not supported or not a valid path", path);
                    Console.ResetColor();
                }
            }

            titles = titles.Distinct().OrderBy(x => sort.Equals("titleid") ? x.titleID : sort.Equals("titlename") ? x.titleName : x.filename).ToList();

            foreach (Title title in titles)
            {
                if (title.permission == Title.Permission.Dangerous)
                {
                    Console.ForegroundColor = ConsoleColor.DarkRed;
                }
                else if (title.permission == Title.Permission.Unsafe)
                {
                    Console.ForegroundColor = ConsoleColor.DarkMagenta;
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                }

                Console.WriteLine("\n{0}", title.filename);
                Console.ResetColor();

                Console.WriteLine(@"โ”œ {0}: {1}
โ”œ {2}: {3}
โ”œ {4}: {5}
โ”œ {6}: {7}
โ”œ {8}: {9}
โ”œ {10}: {11}
โ”œ {12}: {13}
โ”œ {14}: {15}
โ”œ {16}: {17}
โ”œ {18}: {19}
โ”œ {20}: {21}
โ”œ {22}: {23}
โ”œ {24}: {25}
โ”œ {26}: {27}
โ”œ {28}: {29}
โ”œ {30}: {31}
โ”œ {32}: {33}
โ”œ {34}: {35}
โ”œ {36}: {37}
โ”œ {38}: {39}
โ”” {40}: {41}",
                                  Title.Properties[0], title.titleID,
                                  Title.Properties[1], title.baseTitleID,
                                  Title.Properties[2], title.titleName,
                                  Title.Properties[3], title.displayVersion,
                                  Title.Properties[4], title.versionString,
                                  Title.Properties[5], title.latestVersionString,
                                  Title.Properties[6], title.systemUpdateString,
                                  Title.Properties[7], title.systemVersionString,
                                  Title.Properties[8], title.applicationVersionString,
                                  Title.Properties[9], title.masterkeyString,
                                  Title.Properties[10], title.titleKey,
                                  Title.Properties[11], title.publisher,
                                  Title.Properties[12], title.languagesString,
                                  Title.Properties[13], title.filename,
                                  Title.Properties[14], title.filesizeString,
                                  Title.Properties[15], title.typeString,
                                  Title.Properties[16], title.distribution,
                                  Title.Properties[17], title.structureString,
                                  Title.Properties[18], title.signatureString,
                                  Title.Properties[19], title.permissionString,
                                  Title.Properties[20], title.error
                                  );
            }

            Process.log?.WriteLine("\n{0} titles processed", titles.Count);
            Console.Error.WriteLine("\n{0} titles processed", titles.Count);
        }
Example #22
0
        void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            titles.Clear();

            if (e.Argument is List <string> filenames)
            {
                int count = filenames.Count, index = 0;

                foreach (var filename in filenames)
                {
                    if (worker.CancellationPending)
                    {
                        break;
                    }

                    worker.ReportProgress(100 * index++ / count, filename);

                    Title title = Process.processFile(filename);
                    if (title != null)
                    {
                        titles.Add(title);
                    }
                }

                if (!worker.CancellationPending)
                {
                    worker.ReportProgress(100, "");
                }

                Process.log?.WriteLine("\n{0} titles processed", titles.Count);
            }
            else if (e.Argument is string path)
            {
                List <FsTitle> fsTitles = Process.processSd(path);

                if (fsTitles != null)
                {
                    int count = fsTitles.Count, index = 0;

                    foreach (var fsTitle in fsTitles)
                    {
                        if (worker.CancellationPending)
                        {
                            break;
                        }

                        worker.ReportProgress(100 * index++ / count, fsTitle.MainNca?.Filename);

                        Title title = Process.processTitle(fsTitle);
                        if (title != null)
                        {
                            titles.Add(title);
                        }
                    }

                    if (!worker.CancellationPending)
                    {
                        worker.ReportProgress(100, "");
                    }

                    Process.log?.WriteLine("\n{0} titles processed", titles.Count);
                }
                else
                {
                    string error = "SD card \"Contents\" directory could not be found";
                    Process.log?.WriteLine(error);

                    e.Result = error;
                    return;
                }
            }

            e.Result = titles;
        }
Example #23
0
        public static Title processXci(string filename)
        {
            Title title = new Title();

            using (var filestream = new FileStream(filename, FileMode.Open, FileAccess.Read))
            {
                Xci    xci;
                string biggestNca = null, controlNca = null;

                try
                {
                    xci = new Xci(keyset, filestream.AsStorage());

                    title.distribution = Title.Distribution.Cartridge;

                    log?.WriteLine("Processing XCI {0}", filename);

                    if (xci.RootPartition?.Files.Length > 0)
                    {
                        title.structure.Add(Title.Structure.RootPartition);
                    }

                    if (xci.UpdatePartition?.Files.Length > 0)
                    {
                        PfsFileEntry[] fileEntries = xci.UpdatePartition.Files;

                        List <string> cnmtNca = fileEntries.Select(x => x.Name).Where(x => x.EndsWith(".cnmt.nca")).Intersect(Title.SystemUpdate.Keys).ToList();
                        if (cnmtNca.Any())
                        {
                            uint systemUpdate = unchecked ((uint)-1);
                            Title.SystemUpdate.TryGetValue(cnmtNca.First(), out systemUpdate);
                            title.systemUpdate = systemUpdate;
                        }

                        title.structure.Add(Title.Structure.UpdatePartition);
                    }

                    if (xci.NormalPartition?.Files.Length > 0)
                    {
                        title.structure.Add(Title.Structure.NormalPartition);
                    }

                    if (xci.SecurePartition?.Files.Length > 0)
                    {
                        PfsFileEntry[] fileEntries = xci.SecurePartition.Files;
                        foreach (PfsFileEntry entry in fileEntries)
                        {
                            if (entry.Name.EndsWith(".cnmt.nca"))
                            {
                                try
                                {
                                    using (var cnmtNca = xci.SecurePartition.OpenFile(entry))
                                    {
                                        var nca = processCnmtNca(cnmtNca, ref title);
                                        if (nca.Item1 != null && (nca.Item2 != null || title.type == TitleType.AddOnContent))
                                        {
                                            (biggestNca, controlNca) = nca;
                                        }
                                    }
                                }
                                catch (FileNotFoundException)
                                {
                                    if (xci.SecurePartition.FileExists(entry.Name.Replace(".nca", ".ncz")))
                                    {
                                        title.error = "Unsupported Format: Compressed NCA";
                                    }
                                }

                                title.structure.Add(Title.Structure.CnmtNca);
                            }
                            else if (entry.Name.EndsWith(".cert"))
                            {
                                title.structure.Add(Title.Structure.Cert);
                            }
                            else if (entry.Name.EndsWith(".tik"))
                            {
                                try
                                {
                                    using (var tik = xci.SecurePartition.OpenFile(entry))
                                    {
                                        if (entry.Name.Split('.')[0].TryToBytes(out byte[] rightsId))
                                        {
                                            processTik(tik, rightsId, ref keyset, out byte[] titleKey);

                                            title.titleKey = BitConverter.ToString(titleKey).Replace("-", "").ToUpper();
                                        }
                                    }
                                }
                                catch (FileNotFoundException)
                                {
                                    if (xci.SecurePartition.FileExists(entry.Name.Replace(".nca", ".ncz")))
                                    {
                                        title.error = "Unsupported Format: Compressed NCA";
                                    }
                                }

                                title.structure.Add(Title.Structure.Tik);
                            }
                        }

                        if (!String.IsNullOrEmpty(biggestNca))
                        {
                            try
                            {
                                using (var biggest = xci.SecurePartition.OpenFile(biggestNca))
                                {
                                    processBiggestNca(biggest, ref title);
                                }
                            }
                            catch (FileNotFoundException)
                            {
                                if (xci.SecurePartition.FileExists(biggestNca.Replace(".nca", ".ncz")))
                                {
                                    title.error = "Unsupported Format: Compressed NCA";
                                }
                            }
                        }

                        if (!String.IsNullOrEmpty(controlNca))
                        {
                            try
                            {
                                using (var control = xci.SecurePartition.OpenFile(controlNca))
                                {
                                    processControlNca(control, ref title);
                                }
                            }
                            catch (FileNotFoundException)
                            {
                                if (xci.SecurePartition.FileExists(controlNca.Replace(".nca", ".ncz")))
                                {
                                    title.error = "Unsupported Format: Compressed NCA";
                                }
                            }
                        }

                        title.structure.Add(Title.Structure.SecurePartition);
                    }

                    if (xci.LogoPartition?.Files.Length > 0)
                    {
                        title.structure.Add(Title.Structure.LogoPartition);
                    }
                }
                catch (InvalidDataException)
                {
                    return(null);
                }
            }

            if (title.type == TitleType.Application || title.type == TitleType.Patch)
            {
                if (versionList.TryGetValue(title.baseTitleID, out uint version))
                {
                    title.latestVersion = version;
                }
            }

            log?.WriteLine("XCI information for {0}: [{1}] {2}", filename, title.titleID, title.titleName);

            return(title);
        }
Example #24
0
        public override NSView GetViewForItem(NSTableView tableView, NSTableColumn tableColumn, nint row)
        {
            NSTextField textField = (NSTextField)tableView.MakeView("TextField", null);

            if (textField == null)
            {
                textField = new NSTextField
                {
                    BackgroundColor = NSColor.Clear,
                    Bordered        = false,
                    Editable        = false,
                };
            }

            Title title = dataSource.Titles[(int)row];

            switch (tableColumn.Identifier)
            {
            case "TitleID":
                textField.StringValue = title.titleID ?? "";
                break;

            case "TitleName":
                textField.StringValue = title.titleName ?? "";
                break;

            case "DisplayVersion":
                textField.StringValue = title.displayVersion ?? "";
                break;

            case "Version":
                textField.StringValue = title.versionString ?? "";
                break;

            case "LatestVersion":
                textField.StringValue = title.latestVersionString ?? "";
                break;

            case "Firmware":
                textField.StringValue = title.firmware ?? "";
                break;

            case "MasterKey":
                textField.StringValue = title.masterkeyString ?? "";
                break;

            case "FileName":
                textField.StringValue = title.filename ?? "";
                break;

            case "FileSize":
                textField.StringValue = NSByteCountFormatter.Format(title.filesize, NSByteCountFormatterCountStyle.File) ?? "";
                break;

            case "Type":
                textField.StringValue = title.typeString ?? "";
                break;

            case "Distribution":
                textField.StringValue = title.distribution.ToString() ?? "";
                break;

            case "Structure":
                textField.StringValue = title.structureString ?? "";
                break;

            case "Signature":
                textField.StringValue = title.signatureString ?? "";
                break;

            case "Permission":
                textField.StringValue = title.permissionString ?? "";
                break;

            case "Error":
                textField.StringValue = title.error ?? "";
                break;
            }

            if (title.signature != true)
            {
                textField.BackgroundColor = NSColor.Gray.ColorWithAlphaComponent((nfloat)0.1);
            }

            if (title.permission == Title.Permission.Dangerous)
            {
                textField.TextColor = NSColor.Red;
            }
            else if (title.permission == Title.Permission.Unsafe)
            {
                textField.TextColor = NSColor.Purple;
            }

            textField.Cell.LineBreakMode = NSLineBreakMode.CharWrapping;

            return(textField);
        }
Example #25
0
        public static Title processXci(string filename)
        {
            Title title = new Title();

            using (var filestream = new FileStream(filename, FileMode.Open, FileAccess.Read))
            {
                Xci    xci;
                string biggestNca = null, controlNca = null;

                try
                {
                    xci = new Xci(keyset, filestream.AsStorage());

                    title.distribution = Title.Distribution.Cartridge;
                }
                catch (InvalidDataException)
                {
                    return(null);
                }

                log?.WriteLine("Processing XCI {0}", filename);

                if (xci.RootPartition?.Files.Length > 0)
                {
                    title.structure.Add(Title.Structure.RootPartition);
                }

                if (xci.UpdatePartition?.Files.Length > 0)
                {
                    title.structure.Add(Title.Structure.UpdatePartition);
                }

                if (xci.NormalPartition?.Files.Length > 0)
                {
                    title.structure.Add(Title.Structure.NormalPartition);
                }

                if (xci.SecurePartition?.Files.Length > 0)
                {
                    PfsFileEntry[] fileEntries = xci.SecurePartition.Files;
                    foreach (PfsFileEntry entry in fileEntries)
                    {
                        if (entry.Name.EndsWith(".cnmt.nca"))
                        {
                            using (var cnmtNca = xci.SecurePartition.OpenFile(entry))
                            {
                                var nca = processCnmtNca(cnmtNca, ref title);
                                if (nca.Item1 != null && (nca.Item2 != null || title.type == TitleType.AddOnContent))
                                {
                                    (biggestNca, controlNca) = nca;
                                }
                            }

                            title.structure.Add(Title.Structure.CnmtNca);
                        }
                    }

                    if (!String.IsNullOrEmpty(biggestNca))
                    {
                        using (var biggest = xci.SecurePartition.OpenFile(biggestNca))
                        {
                            processBiggestNca(biggest, ref title);
                        }
                    }

                    if (!String.IsNullOrEmpty(controlNca))
                    {
                        using (var control = xci.SecurePartition.OpenFile(controlNca))
                        {
                            processControlNca(control, ref title);
                        }
                    }

                    title.structure.Add(Title.Structure.SecurePartition);
                }

                if (xci.LogoPartition?.Files.Length > 0)
                {
                    title.structure.Add(Title.Structure.LogoPartition);
                }
            }

            if (title.type == TitleType.Application || title.type == TitleType.Patch)
            {
                if (versionList.TryGetValue(title.titleIDApplication, out uint version))
                {
                    title.latestVersion = version;
                }
            }

            log?.WriteLine("XCI information for {0}: [{1}] {2}", filename, title.titleID, title.titleName);

            return(title);
        }
Example #26
0
        private static void processControlNca(IStorage controlNca, ref Title title)
        {
            Nca nca = new Nca(keyset, controlNca, false);

            processControlNca(nca, ref title);
        }
Example #27
0
        public static Title processNsp(string filename)
        {
            Title title = new Title();

            using (var filestream = new FileStream(filename, FileMode.Open, FileAccess.Read))
            {
                Pfs    pfs;
                string biggestNca = null, controlNca = null;

                try
                {
                    pfs = new Pfs(filestream.AsStorage());

                    title.distribution = Title.Distribution.Digital;
                }
                catch (InvalidDataException)
                {
                    return(null);
                }

                log?.WriteLine("Processing NSP {0}", filename);

                PfsFileEntry[] fileEntries = pfs.Files;
                foreach (PfsFileEntry entry in fileEntries)
                {
                    if (entry.Name.EndsWith(".cnmt.xml"))
                    {
                        using (var cnmtXml = pfs.OpenFile(entry))
                        {
                            (biggestNca, controlNca) = processCnmtXml(cnmtXml, ref title);
                        }

                        title.structure.Add(Title.Structure.CnmtXml);
                    }
                    else if (entry.Name.EndsWith(".cnmt.nca"))
                    {
                        using (var cnmtNca = pfs.OpenFile(entry))
                        {
                            var nca = processCnmtNca(cnmtNca, ref title);
                            if (nca.Item1 != null && (nca.Item2 != null || title.type == TitleType.AddOnContent))
                            {
                                (biggestNca, controlNca) = nca;
                            }
                        }

                        title.structure.Add(Title.Structure.CnmtNca);
                    }
                    else if (entry.Name.EndsWith(".cert"))
                    {
                        title.structure.Add(Title.Structure.Cert);
                    }
                    else if (entry.Name.EndsWith(".tik"))
                    {
                        title.structure.Add(Title.Structure.Tik);
                    }
                    else if (entry.Name.EndsWith(".legalinfo.xml"))
                    {
                        title.structure.Add(Title.Structure.LegalinfoXml);
                    }
                    else if (entry.Name.EndsWith(".nacp.xml"))
                    {
                        using (var nacpXml = pfs.OpenFile(entry))
                        {
                            processNacpXml(nacpXml, ref title);
                        }

                        title.structure.Add(Title.Structure.NacpXml);
                    }
                    else if (entry.Name.EndsWith(".programinfo.xml"))
                    {
                        title.structure.Add(Title.Structure.PrograminfoXml);
                    }
                    else if (entry.Name.Equals("cardspec.xml"))
                    {
                        title.structure.Add(Title.Structure.CardspecXml);
                    }
                    else if (entry.Name.Equals("authoringtoolinfo.xml"))
                    {
                        title.structure.Add(Title.Structure.AuthoringtoolinfoXml);
                    }
                }

                if (!String.IsNullOrEmpty(biggestNca))
                {
                    using (var biggest = pfs.OpenFile(biggestNca))
                    {
                        processBiggestNca(biggest, ref title);
                    }
                }

                if (!String.IsNullOrEmpty(controlNca))
                {
                    using (var control = pfs.OpenFile(controlNca))
                    {
                        processControlNca(control, ref title);
                    }
                }
            }

            if (title.type == TitleType.Application || title.type == TitleType.Patch)
            {
                if (versionList.TryGetValue(title.titleIDApplication, out uint version))
                {
                    title.latestVersion = version;
                }
            }

            log?.WriteLine("NSP information for {0}: [{1}] {2}", filename, title.titleID, title.titleName);

            return(title);
        }
Example #28
0
        private void backgroundWorkerProcess_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            titles.Clear();
            Process.latestVersions.Clear();

            if (e.Argument is ValueTuple <Worker, string[]> argumentFile)
            {
                if (argumentFile.Item1 == Worker.File && argumentFile.Item2 is string[] files)
                {
                    List <string> filenames = files.ToList();
                    filenames.Sort();

                    Process.log?.WriteLine("{0} files selected", filenames.Count);

                    worker.ReportProgress(-1, String.Format("Opening {0} files", filenames.Count));

                    int count = filenames.Count, index = 0;

                    foreach (var filename in filenames)
                    {
                        if (worker.CancellationPending)
                        {
                            break;
                        }

                        worker.ReportProgress(100 * index++ / count, filename);

                        Title title = Process.processFile(filename);
                        if (title != null)
                        {
                            titles.Add(title);
                        }
                    }

                    if (!worker.CancellationPending)
                    {
                        worker.ReportProgress(100, "");
                    }

                    Process.log?.WriteLine("\n{0} titles processed", titles.Count);
                }
            }
            else if (e.Argument is ValueTuple <Worker, string> argumentPath)
            {
                if (argumentPath.Item1 == Worker.Directory && argumentPath.Item2 is string path)
                {
                    List <string> filenames = Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)
                                              .Where(filename => filename.ToLower().EndsWith(".xci") || filename.ToLower().EndsWith(".nsp") || filename.ToLower().EndsWith(".nro") ||
                                                     (Common.Settings.Default.NszExtension && (filename.ToLower().EndsWith(".xcz") || filename.ToLower().EndsWith(".nsz")))).ToList();
                    filenames.Sort();

                    Process.log?.WriteLine("{0} files selected", filenames.Count);

                    worker.ReportProgress(-1, String.Format("Opening {0} files from directory {1}", filenames.Count, path));

                    int count = filenames.Count, index = 0;

                    foreach (var filename in filenames)
                    {
                        if (worker.CancellationPending)
                        {
                            break;
                        }

                        worker.ReportProgress(100 * index++ / count, filename);

                        Title title = Process.processFile(filename);
                        if (title != null)
                        {
                            titles.Add(title);
                        }
                    }

                    if (!worker.CancellationPending)
                    {
                        worker.ReportProgress(100, "");
                    }

                    Process.log?.WriteLine("\n{0} titles processed", titles.Count);
                }
                else if (argumentPath.Item1 == Worker.SDCard && argumentPath.Item2 is string pathSd)
                {
                    List <FsTitle> fsTitles = Process.processSd(pathSd);

                    if (fsTitles != null)
                    {
                        int count = fsTitles.Count, index = 0;

                        foreach (var fsTitle in fsTitles)
                        {
                            if (worker.CancellationPending)
                            {
                                break;
                            }

                            worker.ReportProgress(100 * index++ / count, fsTitle.MainNca?.Filename);

                            Title title = Process.processTitle(fsTitle);
                            if (title != null)
                            {
                                titles.Add(title);
                            }
                        }

                        if (!worker.CancellationPending)
                        {
                            worker.ReportProgress(100, "");
                        }

                        Process.log?.WriteLine("\n{0} titles processed", titles.Count);
                    }
                    else
                    {
                        worker.ReportProgress(0, "");

                        string error = "SD card \"Contents\" directory could not be found";
                        Process.log?.WriteLine(error);

                        e.Result = error;
                        return;
                    }
                }
            }

            e.Result = titles;
        }