Ejemplo n.º 1
0
        private long OpenFileSystemFromInternalFile(ServiceCtx context, string fullPath)
        {
            DirectoryInfo archivePath = new DirectoryInfo(fullPath).Parent;

            while (string.IsNullOrWhiteSpace(archivePath.Extension))
            {
                archivePath = archivePath.Parent;
            }

            if (archivePath.Extension == ".nsp" && File.Exists(archivePath.FullName))
            {
                FileStream pfsFile = new FileStream(
                    archivePath.FullName.TrimEnd(Path.DirectorySeparatorChar),
                    FileMode.Open,
                    FileAccess.Read);

                Pfs nsp = new Pfs(pfsFile.AsStorage());

                ImportTitleKeysFromNsp(nsp, context.Device.System.KeySet);

                string filename = fullPath.Replace(archivePath.FullName, string.Empty).TrimStart('\\');

                if (nsp.FileExists(filename))
                {
                    return(OpenNcaFs(context, fullPath, nsp.OpenFile(filename)));
                }
            }

            return(MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist));
        }
Ejemplo n.º 2
0
        private long OpenFileSystemFromInternalFile(ServiceCtx context, string fullPath)
        {
            DirectoryInfo archivePath = new DirectoryInfo(fullPath).Parent;

            while (string.IsNullOrWhiteSpace(archivePath.Extension))
            {
                archivePath = archivePath.Parent;
            }

            if (archivePath.Extension == ".nsp" && File.Exists(archivePath.FullName))
            {
                FileStream pfsFile = new FileStream(
                    archivePath.FullName.TrimEnd(Path.DirectorySeparatorChar),
                    FileMode.Open,
                    FileAccess.Read);

                Pfs          nsp        = new Pfs(pfsFile);
                PfsFileEntry ticketFile = nsp.Files.FirstOrDefault(x => x.Name.EndsWith(".tik"));

                if (ticketFile != null)
                {
                    Ticket ticket = new Ticket(nsp.OpenFile(ticketFile));

                    context.Device.System.KeySet.TitleKeys[ticket.RightsId] =
                        ticket.GetTitleKey(context.Device.System.KeySet);
                }

                string filename = fullPath.Replace(archivePath.FullName, string.Empty).TrimStart('\\');

                if (nsp.FileExists(filename))
                {
                    return(OpenNcaFs(context, fullPath, nsp.OpenFile(filename)));
                }
            }

            return(MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist));
        }
Ejemplo n.º 3
0
        private long OpenFileSystemFromInternalFile(ServiceCtx Context, string FullPath)
        {
            DirectoryInfo ArchivePath = new DirectoryInfo(FullPath).Parent;

            while (string.IsNullOrWhiteSpace(ArchivePath.Extension))
            {
                ArchivePath = ArchivePath.Parent;
            }

            if (ArchivePath.Extension == ".nsp" && File.Exists(ArchivePath.FullName))
            {
                FileStream PfsFile = new FileStream(
                    ArchivePath.FullName.TrimEnd(Path.DirectorySeparatorChar),
                    FileMode.Open,
                    FileAccess.Read);

                Pfs          Nsp        = new Pfs(PfsFile);
                PfsFileEntry TicketFile = Nsp.Files.FirstOrDefault(x => x.Name.EndsWith(".tik"));

                if (TicketFile != null)
                {
                    Ticket Ticket = new Ticket(Nsp.OpenFile(TicketFile));

                    Context.Device.System.KeySet.TitleKeys[Ticket.RightsId] =
                        Ticket.GetTitleKey(Context.Device.System.KeySet);
                }

                string Filename = FullPath.Replace(ArchivePath.FullName, string.Empty).TrimStart('\\');

                if (Nsp.FileExists(Filename))
                {
                    return(OpenNcaFs(Context, FullPath, Nsp.OpenFile(Filename)));
                }
            }

            return(MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist));
        }
Ejemplo n.º 4
0
        public void LoadNca(Nca mainNca, Nca controlNca)
        {
            if (mainNca.Header.ContentType != ContentType.Program)
            {
                Logger.PrintError(LogClass.Loader, "Selected NCA is not a \"Program\" NCA");

                return;
            }

            Stream romfsStream = mainNca.OpenSection(ProgramPartitionType.Data, false, FsIntegrityCheckLevel);
            Stream exefsStream = mainNca.OpenSection(ProgramPartitionType.Code, false, FsIntegrityCheckLevel);

            if (exefsStream == null)
            {
                Logger.PrintError(LogClass.Loader, "No ExeFS found in NCA");

                return;
            }

            if (romfsStream == null)
            {
                Logger.PrintWarning(LogClass.Loader, "No RomFS found in NCA");
            }
            else
            {
                Device.FileSystem.SetRomFs(romfsStream);
            }

            Pfs exefs = new Pfs(exefsStream);

            Npdm metaData = null;

            if (exefs.FileExists("main.npdm"))
            {
                Logger.PrintInfo(LogClass.Loader, "Loading main.npdm...");

                metaData = new Npdm(exefs.OpenFile("main.npdm"));
            }
            else
            {
                Logger.PrintWarning(LogClass.Loader, $"NPDM file not found, using default values!");

                metaData = GetDefaultNpdm();
            }

            List <IExecutable> staticObjects = new List <IExecutable>();

            void LoadNso(string filename)
            {
                foreach (PfsFileEntry file in exefs.Files.Where(x => x.Name.StartsWith(filename)))
                {
                    if (Path.GetExtension(file.Name) != string.Empty)
                    {
                        continue;
                    }

                    Logger.PrintInfo(LogClass.Loader, $"Loading {filename}...");

                    NxStaticObject staticObject = new NxStaticObject(exefs.OpenFile(file));

                    staticObjects.Add(staticObject);
                }
            }

            Nacp ReadControlData()
            {
                Romfs controlRomfs = new Romfs(controlNca.OpenSection(0, false, FsIntegrityCheckLevel));

                byte[] controlFile = controlRomfs.GetFile("/control.nacp");

                BinaryReader reader = new BinaryReader(new MemoryStream(controlFile));

                Nacp controlData = new Nacp(reader);

                CurrentTitle = controlData.Languages[(int)State.DesiredTitleLanguage].Title;

                if (string.IsNullOrWhiteSpace(CurrentTitle))
                {
                    CurrentTitle = controlData.Languages.ToList().Find(x => !string.IsNullOrWhiteSpace(x.Title)).Title;
                }

                return(controlData);
            }

            if (controlNca != null)
            {
                ReadControlData();
            }
            else
            {
                CurrentTitle = metaData.Aci0.TitleId.ToString("x16");
            }

            if (!metaData.Is64Bits)
            {
                throw new NotImplementedException("32-bit titles are not supported!");
            }

            LoadNso("rtld");
            LoadNso("main");
            LoadNso("subsdk");
            LoadNso("sdk");

            ContentManager.LoadEntries();

            ProgramLoader.LoadStaticObjects(this, metaData, staticObjects.ToArray());
        }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 6
0
        public void LoadNca(Nca MainNca, Nca ControlNca)
        {
            NcaSection RomfsSection = MainNca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs || x?.Type == SectionType.Bktr);
            NcaSection ExefsSection = MainNca.Sections.FirstOrDefault(x => x?.IsExefs == true);

            if (ExefsSection == null)
            {
                Logger.PrintError(LogClass.Loader, "No ExeFS found in NCA");

                return;
            }

            if (RomfsSection == null)
            {
                Logger.PrintWarning(LogClass.Loader, "No RomFS found in NCA");
            }
            else
            {
                Stream RomfsStream = MainNca.OpenSection(RomfsSection.SectionNum, false, EnableFsIntegrityChecks);

                Device.FileSystem.SetRomFs(RomfsStream);
            }

            Stream ExefsStream = MainNca.OpenSection(ExefsSection.SectionNum, false, EnableFsIntegrityChecks);

            Pfs Exefs = new Pfs(ExefsStream);

            Npdm MetaData = null;

            if (Exefs.FileExists("main.npdm"))
            {
                Logger.PrintInfo(LogClass.Loader, "Loading main.npdm...");

                MetaData = new Npdm(Exefs.OpenFile("main.npdm"));
            }
            else
            {
                Logger.PrintWarning(LogClass.Loader, $"NPDM file not found, using default values!");
            }

            Process MainProcess = MakeProcess(MetaData);

            void LoadNso(string Filename)
            {
                foreach (PfsFileEntry File in Exefs.Files.Where(x => x.Name.StartsWith(Filename)))
                {
                    if (Path.GetExtension(File.Name) != string.Empty)
                    {
                        continue;
                    }

                    Logger.PrintInfo(LogClass.Loader, $"Loading {Filename}...");

                    string Name = Path.GetFileNameWithoutExtension(File.Name);

                    Nso Program = new Nso(Exefs.OpenFile(File), Name);

                    MainProcess.LoadProgram(Program);
                }
            }

            Nacp ReadControlData()
            {
                Romfs ControlRomfs = new Romfs(ControlNca.OpenSection(0, false, EnableFsIntegrityChecks));

                byte[] ControlFile = ControlRomfs.GetFile("/control.nacp");

                BinaryReader Reader = new BinaryReader(new MemoryStream(ControlFile));

                Nacp ControlData = new Nacp(Reader);

                CurrentTitle = ControlData.Languages[(int)State.DesiredTitleLanguage].Title;

                if (string.IsNullOrWhiteSpace(CurrentTitle))
                {
                    CurrentTitle = ControlData.Languages.ToList().Find(x => !string.IsNullOrWhiteSpace(x.Title)).Title;
                }

                return(ControlData);
            }

            if (ControlNca != null)
            {
                MainProcess.ControlData = ReadControlData();
            }
            else
            {
                CurrentTitle = MainProcess.MetaData.ACI0.TitleId.ToString("x16");
            }

            if (!MainProcess.MetaData.Is64Bits)
            {
                throw new NotImplementedException("32-bit titles are unsupported!");
            }

            LoadNso("rtld");

            MainProcess.SetEmptyArgs();

            LoadNso("main");
            LoadNso("subsdk");
            LoadNso("sdk");

            MainProcess.Run();
        }
Ejemplo n.º 7
0
        public bool FileExists(string name)
        {
            name = name.TrimStart('/');

            return(_pfs.FileExists(name));
        }
Ejemplo n.º 8
0
        public bool FileExists(string Name)
        {
            Name = Name.TrimStart('/');

            return(Pfs.FileExists(Name));
        }