Пример #1
0
        private void romTree_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (e.Node.Tag is NDSFile)
            {
                if (e.Node.Tag is NDSBinary)
                {
                    DataGridView grid = propertyView;
                    NDSBinary    file = e.Node.Tag as NDSBinary;

                    grid.Rows.Clear();
                    string[] row = new string[] { "Name:", file.Name + file.Extension };
                    grid.Rows.Add(row);
                    row = new string[] { "Path:", "Root" };
                    grid.Rows.Add(row);

                    if (file.Name.Contains("9"))
                    {
                        if (!file.Name.Contains("i"))
                        {
                            row = new string[] { "File Type:", "ARM9i Binary", "ARMv5TE Compiled Binary, DSi Extended" };
                        }
                        else
                        {
                            row = new string[] { "File Type:", "ARM7i Binary", "ARMv5TE Compiled Binary." };
                        }
                    }
                    else if (file.Name.Contains("7"))
                    {
                        if (!file.Name.Contains("i"))
                        {
                            row = new string[] { "File Type:", "ARM9 Binary", "ARMv4T Compiled Binary, DSi Extended" };
                        }
                        else
                        {
                            row = new string[] { "File Type:", "ARM7 Binary", "ARMv4T Compiled Binary." };
                        }
                    }
                    else
                    {
                        row = new string[] { "File Type:", "ARM Binary", "ARM Compiled Binary" };
                    }
                    grid.Rows.Add(row);

                    row = new string[] { "Address:", file.Offset.ToString(), "Offset from beginning of ROM to start of the binary." };
                    grid.Rows.Add(row);
                    row = new string[] { "Length:", file.Length.ToString(), "The length of the binary." };
                    grid.Rows.Add(row);
                    row = new string[] { "RAM Address:", file.Load.ToString(), "The RAM address this binary is loaded to." };

                    if (!file.Name.Contains("i"))
                    {
                        grid.Rows.Add(row);
                        row = new string[] { "Hook Address:", file.AutoLoad.ToString(), "The RAM auto-load hook address." };
                        grid.Rows.Add(row);
                        row = new string[] { "Parameters:", file.AutoParams.ToString(), "Offset to auto-load parameter table." };
                    }
                    grid.Rows.Add(row);

                    grid.Refresh();
                }
                else if (e.Node.Tag is NDSOverlay)
                {
                    DataGridView grid = propertyView;
                    NDSOverlay   file = e.Node.Tag as NDSOverlay;

                    grid.Rows.Clear();
                    string[] row = new string[] { "Name:", file.Name + file.Extension };
                    grid.Rows.Add(row);
                    row = new string[] { "Path:", file.Path };
                    grid.Rows.Add(row);

                    if (file.Path.Contains("9"))
                    {
                        row = new string[] { "File Type:", "ARM9 Binary Overlay", "ARMv5TE Compiled Binary Overlay" };
                    }
                    else if (file.Path.Contains("7"))
                    {
                        row = new string[] { "File Type:", "ARM7 Binary Overlay", "ARMv4T Compiled Binary Overlay" };
                    }
                    else
                    {
                        row = new string[] { "File Type:", "ARM Binary Overlay", "ARM Compiled Binary Overlay" };
                    }
                    grid.Rows.Add(row);

                    row = new string[] { "File ID:", file.ID.ToString(), "The ID of the overlay in the file allocation table." };
                    grid.Rows.Add(row);
                    row = new string[] { "Overlay ID:", file.OverlayID.ToString(), "The ID of the overlay in the overlay table." };
                    grid.Rows.Add(row);
                    row = new string[] { "Offset:", "0x" + file.Offset.ToString("X"), "Offset from beginning of ROM to start of the overlay." };
                    grid.Rows.Add(row);
                    row = new string[] { "Size:", file.Length.ToString("N0") + " bytes", "The length of the overlay." };
                    grid.Rows.Add(row);
                    row = new string[] { "RAM Size:", file.SizeRAM.ToString("N0") + " bytes", "The size of the RAM section of the overlay." };
                    grid.Rows.Add(row);
                    row = new string[] { "BSS Size:", file.SizeBSS.ToString("N0") + " bytes", "The size of the BSS section of the overlay." };
                    grid.Rows.Add(row);
                    row = new string[] { "Compressed:", file.Compressed.ToString(), "Flag that indicates a compressed overlay." };
                    grid.Rows.Add(row);
                    if (file.Compressed)
                    {
                        row = new string[] { "Compressed Size:", file.CompressedSize.ToString("N0") + " bytes", "The compressed size of the overlay." };
                        grid.Rows.Add(row);
                        row = new string[] { "Total Size:", (file.SizeRAM + file.SizeBSS).ToString("N0") + " bytes", "The total size of the uncompressed overlay." };
                        grid.Rows.Add(row);
                    }

                    row = new string[] { "RAM Address:", "0x" + file.AddressRAM.ToString("X"), "The overlay transfer desitation address in RAM." };
                    grid.Rows.Add(row);
                    row = new string[] { "Start Address:", "0x" + file.StaticStartAddress.ToString("X"), "The static initializer start address of the overlay." };
                    grid.Rows.Add(row);
                    row = new string[] { "End Address:", "0x" + file.StaticEndAddress.ToString("X"), "The static initializer end address of the overlay." };
                    grid.Rows.Add(row);

                    grid.Refresh();
                }
                else if (e.Node.Tag is NDSBanner)
                {
                    DataGridView grid   = propertyView;
                    NDSBanner    banner = e.Node.Tag as NDSBanner;

                    grid.Rows.Clear();

                    string[] row = new string[] { };
                    grid.Rows.Add(row);
                }
                else
                {
                    DataGridView grid = propertyView;
                    NDSFile      file = e.Node.Tag as NDSFile;

                    grid.Rows.Clear();

                    string[] row = new string[] { "Name:", file.Name + file.Extension };
                    grid.Rows.Add(row);
                    row = new string[] { "Path:", file.Path };
                    grid.Rows.Add(row);
                    row = new string[] { "File Type:", file.Type, file.About };
                    grid.Rows.Add(row);
                    row = new string[] { "Offset:", file.Offset.ToString(), "The length of the file." };
                    grid.Rows.Add(row);
                    row = new string[] { "Size:", file.Length.ToString(), "Offset from beginning of ROM to start of the overlay." };
                    grid.Rows.Add(row);



                    grid.Refresh();
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Reads and breaks down the file tables from the specified stream.<para />
        /// Currently Supports: File Name Table (FNT); File Allocation Table (FAT); Overlay Tables (OVT); NARC.
        /// </summary>
        /// <param name="stream">ROM file to read tables from.</param>
        ///
        public void ReadFileTables(Stream stream)
        {
            if (FATOffset == 0 || FATLength == 0 ||
                FNTOffset == 0 || FNTLength == 0 ||
                ARM9OverlayOffset == 0 || ARM9OverlayLength == 0)
            {
                return;
            }

            // We initiate a BinaryReader with using() and set it to leave the stream open after disposal.
            using (BinaryReader reader = new BinaryReader(stream, new UTF8Encoding(), true))
            {
                // The File Allocation Table contain eight bytes per file entry;
                // a four byte file offset followed by a four byte file length.
                // We start by determining the file count and then dividing the
                // offsets and lenghts into separate indexed arrays.
                int file_count = Convert.ToInt32(FATLength) / 8;
                FileTable = new NDSFile[file_count];

                reader.BaseStream.Position = FATOffset;
                for (int i = 0; i < file_count; i++)
                {
                    FileTable[i]        = new NDSFile();
                    FileTable[i].ID     = i;
                    FileTable[i].Offset = reader.ReadUInt32();
                    FileTable[i].Length = reader.ReadUInt32() - FileTable[i].Offset;
                }

                // The File Name Table contains two sections; the first is the
                // main directory table. It's length is eight bytes per entry.
                // The first four bytes represent an offset to the entry in the
                // second section; the sub-directory table. This is followed by
                // two byte index corresponding to the first file entry in the
                // directory. Finally we have a two byte index corresponding to
                // the parent directory.

                // The first entry in the table is slightly different though.
                // The last two bytes in the first entry actually denote the
                // number of directories in the first section. Let's read that,
                // then use it to iterate through the main directory table and
                // split the table into three seperate indexed arrays.
                reader.BaseStream.Position = FNTOffset + 6;

                int directory_count = reader.ReadUInt16();

                DirectoryTable = new NDSDirectory[directory_count];
                int[] entry_offset = new int[directory_count];
                int[] first_file   = new int[directory_count];
                int[] parent_index = new int[directory_count];

                reader.BaseStream.Position = FNTOffset;
                for (int i = 0; i < directory_count; i++)
                {
                    entry_offset[i] = Convert.ToInt32(reader.ReadUInt32() + FNTOffset);
                    first_file[i]   = reader.ReadUInt16();
                    parent_index[i] = reader.ReadUInt16() - 61440;
                }

                // Setting up the root directory.
                DirectoryTable[0]      = new NDSDirectory();
                DirectoryTable[0].Name = "File Table";
                DirectoryTable[0].Path = "File Table";

                // The second section is the sub-directory table. This table is
                // a bit more complex. We start by iterating through the main
                // directory table and using the entry offset to locate its
                // position in the sub-directory table.
                int file_index = first_file[0];

                for (int i = 0; i < directory_count; i++)
                {
                    // Initialize the directory arrays.
                    reader.BaseStream.Position = entry_offset[i];
                    NDSDirectory parent_directory = DirectoryTable[i];
                    parent_directory.Children = new List <NDSDirectory>();
                    parent_directory.Contents = new List <NDSFile>();

                    while (true)
                    {
                        // A small sanity check to make sure we havent overrun the table.
                        if (reader.BaseStream.Position > FNTOffset + FNTLength)
                        {
                            break;
                        }

                        // The first byte in the sub-directory entry indicates how to continue.
                        byte entry_byte = reader.ReadByte();

                        // 0 indicates the end of a directory.
                        if (entry_byte == 0)
                        {
                            break;
                        }

                        // 128 is actually invalid, and shouldn't be encountered. It would
                        // indicate a directory with no name, which isn't actually valid.
                        else if (entry_byte == 128)
                        {
                            continue;
                        }

                        // The first bit indicates a directory entry, so anything over 128
                        // is a sub-directory. The other seven bits indicate the length of
                        // the sub-directory name. We simply need to subtract 128, and the
                        // next so many bytes are the sub-directory name. The following
                        // two bytes are the sub-directory's ID in the main directory table.
                        else if (entry_byte > 128)
                        {
                            string       name            = System.Text.Encoding.UTF8.GetString(reader.ReadBytes(entry_byte - 128));
                            NDSDirectory child_directory = new NDSDirectory();
                            child_directory.Name   = name;
                            child_directory.Parent = parent_directory;
                            child_directory.Path   = parent_directory.Path + "\\" + child_directory.Name;
                            child_directory.ID     = reader.ReadUInt16() - 61440;

                            DirectoryTable[child_directory.ID] = child_directory;
                            parent_directory.Children.Add(child_directory);
                        }

                        // Anything under 128 indicates a file. Same as the previous, the
                        // other seven bits indicate the length of the file name. Unlike
                        // sub-directories, there is no index proceeding the file name.
                        else
                        {
                            string  name = System.Text.Encoding.UTF8.GetString(reader.ReadBytes(entry_byte));
                            NDSFile file = FileTable[file_index++];
                            file.Name   = name;
                            file.Parent = parent_directory;
                            file.Path   = parent_directory.Path + "\\" + file.Name;

                            parent_directory.Contents.Add(file);
                        }
                    }
                }

                // We run this now so that we don't mess up the memory stream.
                foreach (NDSFile file in FileTable)
                {
                    file.GetExtension(stream);

                    if (file.Extension == ".narc")
                    {
                        file.NARCTables = FileHandler.NARC(stream, file, true);
                    }
                    else if (file.Extension == ".arc")
                    {
                        file.NARCTables = FileHandler.NARC(stream, file, false);
                    }
                }

                // Header Represented As A File
                Header        = new NDSFile();
                Header.Name   = "Header";
                Header.Offset = 0;
                Header.Length = 16384;

                // Header Represented As A File
                Banner        = new NDSBanner();
                Banner.Name   = "Banner";
                Banner.Offset = BannerOffset;
                Banner.Length = 9216;
                Banner.ReadBanner(stream);

                // ARM9 and ARM9 Overlay Table reading.
                ARM9            = new NDSBinary();
                ARM9.Name       = "ARM9";
                ARM9.Extension  = ".bin";
                ARM9.Offset     = ARM9Offset;
                ARM9.Length     = ARM9Length;
                ARM9.Load       = ARM9Load;
                ARM9.AutoLoad   = ARM9AutoLoad;
                ARM9.AutoParams = ARM9AutoParam;

                if (ARM9iLength > 0)
                {
                    ARM9i           = new NDSBinary();
                    ARM9i.Name      = "ARM9i";
                    ARM9i.Extension = ".bin";
                    ARM9i.Offset    = ARM9iOffset;
                    ARM9i.Length    = ARM9iLength;
                }

                int overlay9_count = Convert.ToInt32(ARM9OverlayLength / 32);
                reader.BaseStream.Position = ARM9OverlayOffset;
                OverlayTable9 = new NDSOverlay[overlay9_count];

                for (int i = 0; i < overlay9_count; i++)
                {
                    NDSOverlay overlay = new NDSOverlay();
                    overlay.OverlayID          = reader.ReadUInt32();
                    overlay.AddressRAM         = reader.ReadUInt32();
                    overlay.SizeRAM            = reader.ReadUInt32();
                    overlay.SizeBSS            = reader.ReadUInt32();
                    overlay.StaticStartAddress = reader.ReadUInt32();
                    overlay.StaticEndAddress   = reader.ReadUInt32();
                    overlay.ID     = Convert.ToInt32(reader.ReadUInt32());
                    overlay.Offset = FileTable[overlay.ID].Offset;
                    overlay.Length = FileTable[overlay.ID].Length;
                    uint temp = reader.ReadUInt32();
                    uint flag = temp >> 24;
                    if ((flag & 2) != 0)
                    {
                        overlay.Authenticated = true;
                    }
                    if ((flag & 1) != 0)
                    {
                        overlay.Compressed     = true;
                        overlay.CompressedSize = (temp << 8) >> 8;
                    }

                    overlay.Name      = "Overlay " + overlay.OverlayID;
                    overlay.Path      = "ARM9 Overlay Table\\" + overlay.Name;
                    overlay.Extension = ".bin";

                    OverlayTable9[i]      = overlay;
                    FileTable[overlay.ID] = overlay;
                }

                // ARM7 and ARM7 Overlay Table reading.
                if (ARM7Length > 0)
                {
                    ARM7            = new NDSBinary();
                    ARM7.Name       = "ARM7";
                    ARM7.Extension  = ".bin";
                    ARM7.Offset     = ARM7Offset;
                    ARM7.Length     = ARM7Length;
                    ARM7.Load       = ARM7Load;
                    ARM7.AutoLoad   = ARM7AutoLoad;
                    ARM7.AutoParams = ARM7AutoParam;
                }
                if (ARM7iLength > 0)
                {
                    ARM7i           = new NDSBinary();
                    ARM7i.Name      = "ARM7i";
                    ARM7i.Extension = ".bin";
                    ARM7i.Offset    = ARM7iOffset;
                    ARM7i.Length    = ARM7Length;
                }

                int overlay7_count = Convert.ToInt32(ARM7OverlayLength / 32);
                OverlayTable7 = new NDSOverlay[overlay7_count];
                if (overlay7_count > 0)
                {
                    reader.BaseStream.Position = ARM7OverlayOffset;

                    for (int i = 0; i < overlay7_count; i++)
                    {
                        NDSOverlay overlay = new NDSOverlay();
                        overlay.OverlayID          = reader.ReadUInt32();
                        overlay.AddressRAM         = reader.ReadUInt32();
                        overlay.SizeRAM            = reader.ReadUInt32();
                        overlay.SizeBSS            = reader.ReadUInt32();
                        overlay.StaticStartAddress = reader.ReadUInt32();
                        overlay.StaticEndAddress   = reader.ReadUInt32();
                        overlay.ID     = Convert.ToInt32(reader.ReadUInt32());
                        overlay.Offset = FileTable[overlay.ID].Offset;
                        overlay.Length = FileTable[overlay.ID].Length;
                        uint temp = reader.ReadUInt32();
                        uint flag = temp >> 24;
                        if ((flag & 2) != 0)
                        {
                            overlay.Authenticated = true;
                        }
                        if ((flag & 1) != 0)
                        {
                            overlay.Compressed     = true;
                            overlay.CompressedSize = (temp << 8) >> 8;
                        }

                        overlay.Name      = "Overlay " + overlay.OverlayID;
                        overlay.Path      = "ARM9 Overlay Table\\" + overlay.Name;
                        overlay.Extension = ".bin";

                        OverlayTable7[i]      = overlay;
                        FileTable[overlay.ID] = overlay;
                    }
                }
            }
        }