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();
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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));
            }
        }
예제 #7
0
        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();
        }
예제 #8
0
        //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);
        }
예제 #9
0
        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;

        }