public void Initialize(FileStream fs, long offset, bool isRawDump) { long absoluteOffset; this.FormatDescription = Nintendo3dsCtr.FORMAT_DESCRIPTION_STRING_DECRYPTED; this.VolumeBaseOffset = offset; this.IsRawDump = isRawDump; this.VolumeType = VolumeDataType.Data; this.DirectoryStructureArray = new ArrayList(); // parse NCCH header this.ParseNcchHeader(fs, offset); // set volume name this.VolumeIdentifier = this.ProductCode; // parse File Systems Nintendo3dsCtrDirectory dummyRoot = new Nintendo3dsCtrDirectory(); dummyRoot.SubDirectoryArray = new ArrayList(); dummyRoot.FileArray = new ArrayList(); if (this.ExeFsOffset > 0) { absoluteOffset = offset + ((long)this.ExeFsOffset * Nintendo3dsCtr.MEDIA_UNIT_SIZE); Nintendo3dsCtrDirectory ExeFs = new Nintendo3dsCtrDirectory(fs, fs.Name, this.VolumeIdentifier, absoluteOffset, Nintendo3dsCtr.FileSystemType.ExeFS, null); dummyRoot.SubDirectoryArray.Add((IDirectoryStructure)ExeFs); } if (this.RomFsOffset > 0) { absoluteOffset = offset + ((long)this.RomFsOffset * Nintendo3dsCtr.MEDIA_UNIT_SIZE); try { Nintendo3dsCtrDirectory RomFs = new Nintendo3dsCtrDirectory(fs, fs.Name, this.VolumeIdentifier, absoluteOffset, Nintendo3dsCtr.FileSystemType.RomFS, null); dummyRoot.SubDirectoryArray.Add((IDirectoryStructure)RomFs); } catch (Exception ex) { if (ex is FormatException) { MessageBox.Show(String.Format("IVFC magic bytes not found at expected RomFS offset for Volume '{0}, are you sure it is decrypted?' Note: System Volume, {1}, has not been tested due to unavailability of decrypted samples.", this.VolumeIdentifier, Nintendo3dsCtr.CTR_SYSTEM_PARTITION), "Error Processing 3DS CTR"); } else { throw ex; } } } if (dummyRoot.SubDirectoryArray.Count > 0) { this.DirectoryStructureArray.Add((IDirectoryStructure)dummyRoot); } }
public int CompareTo(object obj) { if ((obj is Nintendo3dsCtrDirectory)) { Nintendo3dsCtrDirectory o = (Nintendo3dsCtrDirectory)obj; return(this.DirectoryName.CompareTo(o.DirectoryName)); } throw new ArgumentException("object is not an Nintendo3dsCtrDirectory"); }
private void BuildDirectory(FileStream isoStream, long ivfcOffset, long directoryEntryOffset, long directoryBlockOffset, long fileBlockOffset) { RomFsDirEntry dir = new RomFsDirEntry(); RomFsFileEntry file = new RomFsFileEntry(); Nintendo3dsCtrDirectory tempDir; Nintendo3dsCtrFile tempFile; byte[] nameBytes; string nextDirectory; // load dir dir.ParentOffset = ParseFile.ReadUintLE(isoStream, ivfcOffset + directoryBlockOffset + directoryEntryOffset); dir.SiblingOffset = ParseFile.ReadInt32LE(isoStream, ivfcOffset + directoryBlockOffset + directoryEntryOffset + 4); dir.ChildOffset = ParseFile.ReadInt32LE(isoStream, ivfcOffset + directoryBlockOffset + directoryEntryOffset + 8); dir.FileOffset = ParseFile.ReadInt32LE(isoStream, ivfcOffset + directoryBlockOffset + directoryEntryOffset + 0xC); dir.WeirdOffset = ParseFile.ReadInt32LE(isoStream, ivfcOffset + directoryBlockOffset + directoryEntryOffset + 0x10); dir.NameSize = ParseFile.ReadUintLE(isoStream, ivfcOffset + directoryBlockOffset + directoryEntryOffset + 0x14); // build directory name if (dir.NameSize > 0) { nameBytes = ParseFile.ParseSimpleOffset(isoStream, ivfcOffset + directoryBlockOffset + directoryEntryOffset + 0x18, (int)dir.NameSize); dir.Name = ByteConversion.GetUtf16LeText(nameBytes); } else // this is root { dir.Name = "RomFS"; // @TODO Make this a constant } this.DirectoryName = dir.Name; nextDirectory = this.ParentDirectoryName + Path.DirectorySeparatorChar + this.DirectoryName; // add files if (dir.FileOffset != -1) { tempFile = new Nintendo3dsCtrFile(isoStream, nextDirectory, isoStream.Name, null, ivfcOffset, -1, Nintendo3dsCtr.FileSystemType.RomFS, this.IvfcLevels[2], dir.FileOffset, fileBlockOffset, this.RomFsDataOffset); this.FileArray.Add(tempFile); while (tempFile.SiblingOffset != -1) { tempFile = new Nintendo3dsCtrFile(isoStream, nextDirectory, isoStream.Name, null, ivfcOffset, -1, Nintendo3dsCtr.FileSystemType.RomFS, this.IvfcLevels[2], tempFile.SiblingOffset, fileBlockOffset, this.RomFsDataOffset); this.FileArray.Add(tempFile); } } // get sibling dir if (dir.SiblingOffset != -1) { tempDir = new Nintendo3dsCtrDirectory(isoStream, isoStream.Name, this.ParentDirectoryName, ivfcOffset, Nintendo3dsCtr.FileSystemType.RomFS, this.IvfcLevels, dir.SiblingOffset, directoryBlockOffset, fileBlockOffset, this.RomFsDataOffset); this.SiblingDirectory = tempDir; } // add subdirs if (dir.ChildOffset != -1) { tempDir = new Nintendo3dsCtrDirectory(isoStream, isoStream.Name, nextDirectory, ivfcOffset, Nintendo3dsCtr.FileSystemType.RomFS, this.IvfcLevels, dir.ChildOffset, directoryBlockOffset, fileBlockOffset, this.RomFsDataOffset); this.SubDirectoryArray.Add(tempDir); while (tempDir.SiblingDirectory != null) { this.SubDirectoryArray.Add(tempDir.SiblingDirectory); tempDir = tempDir.SiblingDirectory; } } }