public NintendoContentArchiveSource(NintendoContentFileSystemInfo fileSystemInfo, KeyConfiguration config, bool needsLogoPartition = false) { this.m_fileSystemInfo = fileSystemInfo; this.m_keyConfig = config; this.SetCryptor(this.m_keyConfig); this.AddDefaultLogoPartitionIfNeeded(needsLogoPartition); fileSystemInfo.fsEntries.Sort((Comparison <NintendoContentFileSystemInfo.EntryInfo>)((x, y) => x.partitionIndex.CompareTo(y.partitionIndex))); NintendoContentFileSystemMeta meta = new NintendoContentFileSystemMeta(); NintendoContentFileSystemEntryInfoContainer fsEntries = new NintendoContentFileSystemEntryInfoContainer(fileSystemInfo.fsEntries); List <ConcatenatedSource.Element> elements1 = new List <ConcatenatedSource.Element>(); NintendoContentArchiveSource.BodySourceElement[] bodySources = new NintendoContentArchiveSource.BodySourceElement[fileSystemInfo.fsEntries.Count]; long offset = (long)meta.GetFsHeaderSize() * 4L; foreach (NintendoContentFileSystemInfo.EntryInfo entryInfo in fsEntries) { if (entryInfo.type != null) { ISource source = NintendoContentArchiveSource.GetDataSource(entryInfo); if (fileSystemInfo.isProdEncryption && fileSystemInfo.contentType == (byte)0 && entryInfo.partitionIndex == 0) { source = this.AcidResignedSource(source); } if (fileSystemInfo.contentType == (byte)0 && entryInfo.partitionIndex == 1) { source = this.NrrSignedSource(source); } int currentIndex = fsEntries.CurrentIndex; bodySources[currentIndex].DataOffset = offset; NintendoContentArchiveSource.BuildDataInfo buildInfo = new NintendoContentArchiveSource.BuildDataInfo(meta, source, offset, currentIndex); fileSystemInfo.fsEntries[currentIndex] = this.BuildData(entryInfo, buildInfo); offset = buildInfo.CurrentOffset; Sha256HierarchicalHashCalculatedSource calculatedSource = new Sha256HierarchicalHashCalculatedSource(buildInfo.HeaderSource, (int)buildInfo.HeaderSource.Size, 1); ConcatenatedSource.Element element1 = new ConcatenatedSource.Element(calculatedSource.GetMasterHashSource(), "fsHeaderHash" + (object)currentIndex, (long)(32 * currentIndex)); elements1.Add(element1); ConcatenatedSource.Element element2 = new ConcatenatedSource.Element((ISource)calculatedSource, "fsHeader" + (object)currentIndex, (long)currentIndex * (long)meta.GetFsHeaderSize()); bodySources[currentIndex].HeaderElement = element2; bodySources[currentIndex].DataSourceElements = buildInfo.DataSourceElements; } } if (fsEntries.IsReverse) { elements1.Reverse(); } NintendoContentArchiveSource.BodyEncryptionKey bodyEncryptionKey = new NintendoContentArchiveSource.BodyEncryptionKey(fileSystemInfo); this.MakeBody(meta, fsEntries, bodySources, bodyEncryptionKey); this.MakeNcaHeader(meta, (ISource) new ConcatenatedSource(elements1), bodyEncryptionKey); List <ConcatenatedSource.Element> elements2 = new List <ConcatenatedSource.Element>(); ConcatenatedSource.Element element3 = new ConcatenatedSource.Element(this.m_headerSource, "header", 0L); ConcatenatedSource.Element element4 = new ConcatenatedSource.Element(this.m_bodySource, "body", element3.Source.Size); elements2.Add(element3); elements2.Add(element4); this.m_source = (ISource) new ConcatenatedSource(elements2); this.Size = this.m_source.Size; }
public static ApplicationControlPropertyModel GetApplicationControlProperty(List <NintendoSubmissionPackageFileSystemInfo.ContentInfo> contentInfos, KeyConfiguration config) { List <NintendoSubmissionPackageFileSystemInfo.ContentInfo> list = contentInfos.Where <NintendoSubmissionPackageFileSystemInfo.ContentInfo>((Func <NintendoSubmissionPackageFileSystemInfo.ContentInfo, bool>)(x => x.ContentType == "Control")).ToList <NintendoSubmissionPackageFileSystemInfo.ContentInfo>(); if (list.Count > 1) { throw new NotImplementedException("Multiple control contents in an Application are not supported."); } NintendoSubmissionPackageFileSystemInfo.ContentInfo contentInfo = list.Single <NintendoSubmissionPackageFileSystemInfo.ContentInfo>(); string fileName = "control.nacp"; byte[] bytes; if (contentInfo.FsInfo != null) { NintendoContentFileSystemInfo.EntryInfo entryInfo = (contentInfo.FsInfo as NintendoContentFileSystemInfo).fsEntries.Single <NintendoContentFileSystemInfo.EntryInfo>(); using (SourceBasedStream sourceBasedStream = new SourceBasedStream(NintendoContentArchiveSource.GetDataSource(entryInfo))) { IFileSystemArchiveReader systemArchiveReader = NintendoSubmissionPackageArchiveUtils.OpenFsReader(entryInfo, (Stream)sourceBasedStream); bytes = systemArchiveReader.ReadFile(fileName, 0L, systemArchiveReader.GetFileSize(fileName)); } } else { if (contentInfo.Source == null) { throw new NotImplementedException(); } byte[][] areaEncryptionKeys = config.GetKeyAreaEncryptionKeys(); using (SourceBasedStream sourceBasedStream = new SourceBasedStream(contentInfo.Source)) { IFileSystemArchiveReader systemArchiveReader = new NintendoContentArchiveReader((Stream)sourceBasedStream, areaEncryptionKeys).OpenFileSystemArchiveReader(0); bytes = systemArchiveReader.ReadFile(fileName, 0L, systemArchiveReader.GetFileSize(fileName)); } } return(ApplicationControlPropertyModel.PropertyBytesToModel(bytes)); }
public static ProgramInfoXml GetProgramInfoXml(List <NintendoSubmissionPackageFileSystemInfo.ContentInfo> contentInfos, KeyConfiguration config) { NintendoSubmissionPackageFileSystemInfo.ContentInfo contentInfo = contentInfos.Where <NintendoSubmissionPackageFileSystemInfo.ContentInfo>((Func <NintendoSubmissionPackageFileSystemInfo.ContentInfo, bool>)(x => x.ContentType == "Program")).ToList <NintendoSubmissionPackageFileSystemInfo.ContentInfo>().Single <NintendoSubmissionPackageFileSystemInfo.ContentInfo>(); string fileName = "main"; string filePath = ""; byte[] data = (byte[])null; bool flag = false; if (contentInfo.FsInfo != null) { NintendoContentFileSystemInfo.EntryInfo entryInfo = (contentInfo.FsInfo as NintendoContentFileSystemInfo).fsEntries.Where <NintendoContentFileSystemInfo.EntryInfo>((Func <NintendoContentFileSystemInfo.EntryInfo, bool>)(x => x.partitionIndex == 0)).Single <NintendoContentFileSystemInfo.EntryInfo>(); PartitionFileSystemInfo fileSystemInfo = (PartitionFileSystemInfo)entryInfo.fileSystemInfo; if (fileSystemInfo != null && fileSystemInfo.entries.Where <PartitionFileSystemInfo.EntryInfo>((Func <PartitionFileSystemInfo.EntryInfo, bool>)(x => x.name == fileName)).Count <PartitionFileSystemInfo.EntryInfo>() == 1) { flag = true; filePath = fileSystemInfo.entries.Where <PartitionFileSystemInfo.EntryInfo>((Func <PartitionFileSystemInfo.EntryInfo, bool>)(x => x.name == fileName)).Single <PartitionFileSystemInfo.EntryInfo>().path; using (SourceBasedStream sourceBasedStream = new SourceBasedStream(NintendoContentArchiveSource.GetDataSource(entryInfo))) { IFileSystemArchiveReader systemArchiveReader = NintendoSubmissionPackageArchiveUtils.OpenFsReader(entryInfo, (Stream)sourceBasedStream); data = systemArchiveReader.ReadFile(fileName, 0L, systemArchiveReader.GetFileSize(fileName)); } } } else { if (contentInfo.Source == null) { throw new NotImplementedException(); } byte[][] areaEncryptionKeys = config.GetKeyAreaEncryptionKeys(); using (SourceBasedStream sourceBasedStream = new SourceBasedStream(contentInfo.Source)) { IFileSystemArchiveReader systemArchiveReader = new NintendoContentArchiveReader((Stream)sourceBasedStream, areaEncryptionKeys).OpenFileSystemArchiveReader(0); if (systemArchiveReader.ListFileInfo().Where <Tuple <string, long> >((Func <Tuple <string, long>, bool>)(x => x.Item1 == fileName)).Count <Tuple <string, long> >() == 1) { flag = true; filePath = systemArchiveReader.ListFileInfo().Where <Tuple <string, long> >((Func <Tuple <string, long>, bool>)(x => x.Item1 == fileName)).Single <Tuple <string, long> >().Item1; data = systemArchiveReader.ReadFile(fileName, 0L, systemArchiveReader.GetFileSize(fileName)); } } } if (!flag) { Log.Warning("\"main\" was not found in code region."); data = new byte[0]; } return(new ProgramInfoXml(new SymbolExtract(data, filePath))); }