public void moveAllFiles(PhysicalFile first, int firstOffs) { allFiles.Sort(); Console.Out.WriteLine("Moving file " + first.name); Console.Out.WriteLine("Into " + firstOffs.ToString("X")); int firstStart = first.fileBegin; int diff = (int)firstOffs - (int)firstStart; Console.Out.WriteLine("DIFF " + diff.ToString("X")); //if (diff < 0) //throw new Exception("DOSADJODJOSAJD"); // return; //WARNING: I assume all the aligns are powers of 2 int maxAlign = 4; for (int i = allFiles.IndexOf(first); i < allFiles.Count; i++) { int align = ((PhysicalFile)allFiles[i]).alignment; if (align > maxAlign) { maxAlign = align; } } //To preserve the alignment of all the moved files if (diff % maxAlign != 0) { diff += (int)(maxAlign - diff % maxAlign); } int fsEnd = getFilesystemEnd(); int toCopy = (int)fsEnd - (int)firstStart; byte[] data = new byte[toCopy]; s.Seek(firstStart, SeekOrigin.Begin); s.Read(data, 0, toCopy); s.Seek(firstStart + diff, SeekOrigin.Begin); s.Write(data, 0, toCopy); for (int i = allFiles.IndexOf(first); i < allFiles.Count; i++) { ((PhysicalFile)allFiles[i]).fileBeginP += diff; } for (int i = allFiles.IndexOf(first); i < allFiles.Count; i++) { ((PhysicalFile)allFiles[i]).saveOffsets(); } }
public override void load() { headerFile = new HeaderFile(this, mainDir); fntFile = new PhysicalFile(this, mainDir, -1, "fnt.bin", headerFile, 0x40, 0x44, true); fatFile = new PhysicalFile(this, mainDir, -1, "fat.bin", headerFile, 0x48, 0x4C, true); base.load(); arm9ovFile = new PhysicalFile(this, mainDir, -1, "arm9ovt.bin", headerFile, 0x50, 0x54, true); arm7ovFile = new PhysicalFile(this, mainDir, -1, "arm7ovt.bin", headerFile, 0x58, 0x5C, true); // arm9binFile = new Arm9BinFile(this, mainDir, headerFile); // File arm9binFile2 = new PhysicalFile(this, mainDir, true, -2, "arm9.bin", headerFile, 0x20, 0xC, true); arm9binFile = new PhysicalFile(this, mainDir, -1, "arm9.bin", headerFile, 0x20, 0x2C, true); arm9binFile.alignment = 0x1000; arm9binFile.canChangeOffset = false; arm7binFile = new PhysicalFile(this, mainDir, -1, "arm7.bin", headerFile, 0x30, 0x3C, true); arm7binFile.alignment = 0x200; //Not sure what should be used here... bannerFile = new BannerFile(this, mainDir, headerFile); bannerFile.alignment = 0x200; //Not sure what should be used here... uint rsaOffs = headerFile.getUintAt(0x1000); if (rsaOffs == 0) { rsaOffs = headerFile.getUintAt(0x80); headerFile.setUintAt(0x1000, rsaOffs); } rsaSigFile = new PhysicalFile(this, mainDir, -1, "rsasig.bin", (int)rsaOffs, 136); rsaSigFile.canChangeOffset = false; addFile(headerFile); mainDir.childrenFiles.Add(headerFile); addFile(arm9ovFile); mainDir.childrenFiles.Add(arm9ovFile); addFile(arm7ovFile); mainDir.childrenFiles.Add(arm7ovFile); addFile(arm9binFile); mainDir.childrenFiles.Add(arm9binFile); addFile(arm7binFile); mainDir.childrenFiles.Add(arm7binFile); addFile(bannerFile); mainDir.childrenFiles.Add(bannerFile); addFile(rsaSigFile); mainDir.childrenFiles.Add(rsaSigFile); loadOvTable("overlay7", -99, mainDir, arm7ovFile); loadOvTable("overlay9", -98, mainDir, arm9ovFile); loadNamelessFiles(mainDir); }
public override void load() { //I have to do some tricky offset calculations here ... fatOffset = 0x1C; s.Seek(0x18, SeekOrigin.Begin); //number of files fatSize = (int)readUInt(s) * 8; s.Seek(fatSize + fatOffset + 4, SeekOrigin.Begin); //size of FNTB fntSize = (int)readUInt(s) - 8; //do not include header fntOffset = fatSize + fatOffset + 8; fileDataOffsetP = fntSize + fntOffset + 8; fntFile = new PhysicalFile(this, mainDir, -2, "fnt.bin", fntOffset, fntSize); fatFile = new PhysicalFile(this, mainDir, -3, "fat.bin", fatOffset, fatSize); base.load(); loadNamelessFiles(mainDir); }
public override void load() { //I have to do some tricky offset calculations here ... fatOffset= 0x1C; s.Seek(0x18, SeekOrigin.Begin); //number of files fatSize = (int)readUInt(s) * 8; s.Seek(fatSize + fatOffset + 4, SeekOrigin.Begin); //size of FNTB fntSize = (int)readUInt(s) - 8; //do not include header fntOffset = fatSize + fatOffset + 8; fileDataOffsetP = fntSize + fntOffset + 8; fntFile = new PhysicalFile(this, mainDir, -2, "fnt.bin", fntOffset, fntSize); fatFile = new PhysicalFile(this, mainDir, -3, "fat.bin", fatOffset, fatSize); base.load(); loadNamelessFiles(mainDir); }
//Tries to find LEN bytes of continuous unused space AFTER the freeSpaceDelimiter (usually fat or fnt) public int findFreeSpace(int len, int align) { allFiles.Sort(); //sort by offset PhysicalFile bestSpace = null; int bestSpaceLeft = int.MaxValue; int bestSpaceBegin = -1; for (int i = allFiles.IndexOf(freeSpaceDelimiter); i < allFiles.Count - 1; i++) { PhysicalFile a = (PhysicalFile)allFiles[i]; PhysicalFile b = (PhysicalFile)allFiles[i + 1]; int spBegin = a.fileBegin + a.fileSize; //- 1 + 1; spBegin = alignUp(spBegin, align); int spEnd = b.fileBegin; spEnd = alignDown(spEnd, align); int spSize = spEnd - spBegin; if (spSize >= len) { int spLeft = spSize - len; if (spLeft < bestSpaceLeft) { bestSpaceLeft = spLeft; bestSpace = a; bestSpaceBegin = spBegin; } } } if (bestSpace != null) { return(bestSpaceBegin); } else { PhysicalFile last = (PhysicalFile)allFiles[allFiles.Count - 1]; return(alignUp(last.fileBegin + last.fileSize, align)); } }
public void moveAllFiles(PhysicalFile first, int firstOffs) { allFiles.Sort(); Console.Out.WriteLine("Moving file " + first.name); Console.Out.WriteLine("Into " + firstOffs.ToString("X")); int firstStart = first.fileBegin; int diff = (int)firstOffs - (int)firstStart; Console.Out.WriteLine("DIFF " + diff.ToString("X")); //if (diff < 0) //throw new Exception("DOSADJODJOSAJD"); // return; //WARNING: I assume all the aligns are powers of 2 int maxAlign = 4; for(int i = allFiles.IndexOf(first); i < allFiles.Count; i++) { int align = ((PhysicalFile)allFiles[i]).alignment; if(align > maxAlign) maxAlign = align; } //To preserve the alignment of all the moved files if(diff % maxAlign != 0) diff += (int)(maxAlign - diff % maxAlign); int fsEnd = getFilesystemEnd(); int toCopy = (int)fsEnd - (int)firstStart; byte[] data = new byte[toCopy]; s.Seek(firstStart, SeekOrigin.Begin); s.Read(data, 0, toCopy); s.Seek(firstStart + diff, SeekOrigin.Begin); s.Write(data, 0, toCopy); for (int i = allFiles.IndexOf(first); i < allFiles.Count; i++) ((PhysicalFile)allFiles[i]).fileBeginP += diff; for (int i = allFiles.IndexOf(first); i < allFiles.Count; i++) ((PhysicalFile)allFiles[i]).saveOffsets(); }
//TODO: Clean up this mess. public override void replace(byte[] newFile, object editor) { if (!isAGoodEditor(editor)) { throw new Exception("NOT CORRECT EDITOR " + name); } if (newFile.Length != fileSize && !canChangeSize) { throw new Exception("TRYING TO RESIZE CONSTANT-SIZE FILE: " + name); } int newStart = fileBegin; //if we insert a bigger file it might not fit in the current place if (newFile.Length > fileSize) { if (canChangeOffset && !(parent is NarcFilesystem)) { newStart = ((PhysicalFilesystem)parent).findFreeSpace(newFile.Length, alignment); if (newStart % alignment != 0) { newStart += alignment - newStart % alignment; } } else { //TODO: Keep the list always sorted in order to avoid stupid useless sorts. parent.allFiles.Sort(); if (!(parent.allFiles.IndexOf(this) == parent.allFiles.Count - 1)) { PhysicalFile nextFile = (PhysicalFile)parent.allFiles[parent.allFiles.IndexOf(this) + 1]; ((PhysicalFilesystem)parent).moveAllFiles(nextFile, fileBegin + newFile.Length); } } } //This is for keeping NARC filesystems compact. Sucks. else if (parent is NarcFilesystem) { parent.allFiles.Sort(); if (!(parent.allFiles.IndexOf(this) == parent.allFiles.Count - 1)) { PhysicalFile nextFile = (PhysicalFile)parent.allFiles[parent.allFiles.IndexOf(this) + 1]; ((PhysicalFilesystem)parent).moveAllFiles(nextFile, fileBegin + newFile.Length); } } //Stupid check. if (newStart % alignment != 0) { Console.Out.Write("Warning: File is not being aligned: " + name + ", at " + newStart.ToString("X")); } //write the file filesystemStream.Seek(newStart, SeekOrigin.Begin); filesystemStream.Write(newFile, 0, newFile.Length); //This should be handled in NarcFilesystem instead, in fileMoved (?) if (parent is NarcFilesystem) { PhysicalFile lastFile = (PhysicalFile)parent.allFiles[parent.allFiles.Count - 1]; filesystemStream.SetLength(lastFile.fileBegin + lastFile.fileSize + 16); } //update ending pos fileBeginP = newStart; fileSizeP = newFile.Length; saveOffsets(); //Updates total used rom size in header, and/or other stuff. parent.fileMoved(this); }
protected File loadFile(string fileName, int fileID, Directory parent) { int beginOffs = fileID * 8; int endOffs = fileID * 8 + 4; File f = new PhysicalFile(this, parent, fileID, fileName, fatFile, beginOffs, endOffs); parent.childrenFiles.Add(f); addFile(f); return f; }