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)); }
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)); }
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)); }
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()); }
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); }
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(); }
public bool FileExists(string name) { name = name.TrimStart('/'); return(_pfs.FileExists(name)); }
public bool FileExists(string Name) { Name = Name.TrimStart('/'); return(Pfs.FileExists(Name)); }