예제 #1
0
파일: ArcBIN.cs 프로젝트: zxc120/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0);

            if (!IsSaneCount(count))
            {
                return(null);
            }

            var base_name    = Path.GetFileNameWithoutExtension(file.Name);
            int index_offset = 4;
            int index_end    = 4 + 8 * count;
            var dir          = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                var entry = new PackedEntry
                {
                    Offset = file.View.ReadUInt32(index_offset),
                    Size   = file.View.ReadUInt32(index_offset + 4),
                };
                if (entry.Offset < index_end || !entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                entry.Name = string.Format("{0}#{1:D5}", base_name, i);
                dir.Add(entry);
                index_offset += 8;
            }
            foreach (PackedEntry entry in dir)
            {
                var n = file.View.ReadInt32(entry.Offset);
                if (n <= 0)
                {
                    return(null);
                }
                var offset = file.View.ReadUInt32(entry.Offset + 4);
                var size   = file.View.ReadUInt32(entry.Offset + 8);
                entry.Offset  += offset;
                entry.Size     = size & 0x3FFFFFFF;
                entry.IsPacked = 2 != (size >> 30);
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                var res = AutoEntry.DetectFileType(file.View.ReadUInt32(entry.Offset));
                if (res != null)
                {
                    entry.ChangeType(res);
                }
            }
            return(new ArcFile(file, this, dir));
        }
예제 #2
0
파일: ArcGPC.cs 프로젝트: tenyuhuang/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(4);

            if (!IsSaneCount(count))
            {
                return(null);
            }

            var  base_name    = Path.GetFileNameWithoutExtension(file.Name);
            var  dir          = new List <Entry> (count);
            int  index_offset = 8;
            long data_offset  = count * 4 + 8;
            uint next_offset  = file.View.ReadUInt32(index_offset);

            for (int i = 0; i < count; ++i)
            {
                index_offset += 4;
                var entry = new PackedEntry {
                    Offset = next_offset
                };
                next_offset = i + 1 < count?file.View.ReadUInt32(index_offset) : (uint)file.MaxOffset;

                entry.Size = next_offset - (uint)entry.Offset;
                if (entry.Offset < data_offset || !entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                entry.Name = string.Format("{0}#{1:D4}", base_name, i);
                dir.Add(entry);
            }
            DetectFileTypes(file, dir);
            return(new ArcFile(file, this, dir));
        }
예제 #3
0
        public override ArcFile TryOpen(ArcView file)
        {
            var arc_name = Path.GetFileName(file.Name);
            var parsed   = ArcNameParser.ParseName(arc_name);

            if (null == parsed)
            {
                return(null);
            }
            var toc_name = VFS.CombinePath(VFS.GetDirectoryName(file.Name), parsed.Item1);
            var toc      = ReadToc(toc_name, 4);

            if (null == toc)
            {
                return(null);
            }

            bool has_images = false;
            var  dir        = new List <Entry>();

            using (var toc_stream = new MemoryStream(toc))
                using (var index = new StreamReader(toc_stream))
                {
                    string line;
                    while ((line = index.ReadLine()) != null)
                    {
                        var fields = line.Split(',');
                        if (fields.Length != 5)
                        {
                            return(null);
                        }
                        var    name = Path.ChangeExtension(fields[0], fields[4]);
                        string type = "";
                        if ("b" == fields[4])
                        {
                            type       = "image";
                            has_images = true;
                        }
                        else if ("k" == fields[4] || "j" == fields[4])
                        {
                            type = "audio";
                        }
                        var entry = new PackedEntry
                        {
                            Name         = name,
                            Type         = type,
                            Offset       = UInt32.Parse(fields[3]),
                            Size         = UInt32.Parse(fields[2]),
                            UnpackedSize = UInt32.Parse(fields[1]),
                        };
                        if (!entry.CheckPlacement(file.MaxOffset))
                        {
                            return(null);
                        }
                        entry.IsPacked = entry.UnpackedSize != entry.Size;
                        dir.Add(entry);
                    }
                }
            return(ArchiveFromDir(file, dir, has_images));
        }
예제 #4
0
            bool ReadV1(Stream input)
            {
                // NOTE CryptoStream will close an input stream
                using (var xored = new CryptoStream(input, new NotTransform(), CryptoStreamMode.Read))
                    using (var lzss = new LzssStream(xored))
                        lzss.Read(m_index, 0, m_index.Length);

                int index_offset = Array.IndexOf(m_index, (byte)0);

                if (-1 == index_offset || 0 == index_offset)
                {
                    return(false);
                }
                Password = m_index.Take(index_offset++).ToArray();
                long base_offset = 0x20 + m_packed_size;

                for (int i = 0; i < m_count; ++i)
                {
                    var entry = new PackedEntry();
                    entry.Offset       = LittleEndian.ToUInt32(m_index, index_offset) + base_offset;
                    entry.Size         = LittleEndian.ToUInt32(m_index, index_offset + 4);
                    entry.UnpackedSize = LittleEndian.ToUInt32(m_index, index_offset + 8);
                    entry.IsPacked     = entry.UnpackedSize != 0;
                    if (!entry.CheckPlacement(m_file.MaxOffset))
                    {
                        return(false);
                    }
                    int name_len = LittleEndian.ToInt32(m_index, index_offset + 0xC);
                    entry.Name = Encodings.cp932.GetString(m_index, index_offset + 0x18, name_len);
                    entry.Type = FormatCatalog.Instance.GetTypeFromName(entry.Name);
                    m_dir.Value.Add(entry);
                    index_offset += 0x18 + name_len;
                }
                return(true);
            }
예제 #5
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0x10);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            uint index_offset = file.View.ReadUInt32(8);

            if (index_offset >= file.MaxOffset)
            {
                return(null);
            }

            var base_name = Path.GetFileNameWithoutExtension(file.Name);
            var dir       = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                var entry = new PackedEntry {
                    Name   = string.Format("{0}#{1:D4}", base_name, i),
                    Size   = file.View.ReadUInt32(index_offset),
                    Offset = file.View.ReadUInt32(index_offset + 4),
                };
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 8;
            }
            DetectFileTypes(dir, file);
            return(new ArcFile(file, this, dir));
        }
예제 #6
0
파일: ArcTactics.cs 프로젝트: zxc120/GARbro
            bool ReadV0(Stream input)
            {
                long current_offset    = 0x20 + m_packed_size;
                uint offset_table_size = (uint)m_count * 0x10;

                if (offset_table_size > m_file.View.Reserve(current_offset, offset_table_size))
                {
                    return(false);
                }

                using (var lzss = new LzssStream(input, LzssMode.Decompress, true))
                    if (m_index.Length != lzss.Read(m_index, 0, m_index.Length))
                    {
                        return(false);
                    }

                for (int i = 0; i < m_index.Length; ++i)
                {
                    m_index[i] = (byte)(~m_index[i] - 5);
                }
                int index_offset = Array.IndexOf <byte> (m_index, 0);

                if (-1 == index_offset || 0 == index_offset)
                {
                    return(false);
                }
                index_offset++;
//                Password = m_index.Take (index_offset++).ToArray();

                for (int i = 0; i < m_count && index_offset < m_index.Length; ++i)
                {
                    int name_end = Array.IndexOf <byte> (m_index, 0, index_offset);
                    if (-1 == name_end)
                    {
                        name_end = m_index.Length;
                    }
                    if (index_offset == name_end)
                    {
                        return(false);
                    }
                    var entry = new PackedEntry();
                    entry.Offset       = m_file.View.ReadUInt32(current_offset);
                    entry.Size         = m_file.View.ReadUInt32(current_offset + 4);
                    entry.UnpackedSize = m_file.View.ReadUInt32(current_offset + 8);
                    entry.IsPacked     = entry.UnpackedSize != 0;
                    if (!entry.CheckPlacement(m_file.MaxOffset))
                    {
                        return(false);
                    }
                    entry.Name = Encodings.cp932.GetString(m_index, index_offset, name_end - index_offset);
                    entry.Type = FormatCatalog.Instance.GetTypeFromName(entry.Name);
                    m_dir.Value.Add(entry);
                    index_offset    = name_end + 1;
                    current_offset += 0x10;
                }
                return(true);
            }
예제 #7
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.View.AsciiEqual(4, "KO ARC20"))
            {
                return(null);
            }
            int count = file.View.ReadInt32(12);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            uint index_size = 0x80 * (uint)count;

            if (index_size > file.View.Reserve(0x10, index_size))
            {
                return(null);
            }
            var  dir          = new List <Entry> (count);
            long index_offset = 0x10;
            long base_offset  = index_offset + index_size;

            for (uint i = 0; i < count; ++i)
            {
                string name   = file.View.ReadString(index_offset, 0x60);
                var    offset = base_offset + file.View.ReadUInt32(index_offset + 0x60);
                var    entry  = new PackedEntry {
                    Name = name, Offset = offset
                };
                entry.Size = file.View.ReadUInt32(index_offset + 0x64);
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 0x80;
            }
            foreach (var entry in dir)
            {
                uint signature = file.View.ReadUInt32(entry.Offset);
                var  res       = AutoEntry.DetectFileType(signature);
                if (res != null)
                {
                    entry.Type = res.Type;
                }
                else if (file.View.AsciiEqual(entry.Offset, "BSE 1."))
                {
                    entry.Type = "image";
                }
                else if (file.View.AsciiEqual(entry.Offset + 4, "bw  "))
                {
                    entry.Type = "audio";
                }
            }
            return(new ArcFile(file, this, dir));
        }
예제 #8
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.View.AsciiEqual(0, "PAC") || 'K' == file.View.ReadByte(3))
            {
                return(null);
            }
            int count = file.View.ReadInt32(4);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            int  pack_type  = file.View.ReadInt32(8);
            uint index_size = file.View.ReadUInt32(file.MaxOffset - 4);

            if (index_size >= file.MaxOffset)
            {
                return(null);
            }

            byte[] index_packed = new byte[index_size];
            file.View.Read(file.MaxOffset - 4 - index_size, index_packed, 0, index_size);
            for (int i = 0; i < index_packed.Length; ++i)
            {
                index_packed[i] = (byte)~index_packed[i];
            }

            var index  = HuffmanDecode(index_packed, count * 0x4c);
            var dir    = new List <Entry> (count);
            int offset = 0;

            for (int i = 0; i < count; ++i, offset += 0x4c)
            {
                var name  = Binary.GetCString(index, offset, 0x40);
                var entry = new PackedEntry
                {
                    Name         = name,
                    Type         = FormatCatalog.Instance.GetTypeFromName(name),
                    Offset       = LittleEndian.ToUInt32(index, offset + 0x40),
                    UnpackedSize = LittleEndian.ToUInt32(index, offset + 0x44),
                    Size         = LittleEndian.ToUInt32(index, offset + 0x48),
                };
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                entry.IsPacked = pack_type != 0 && (pack_type != 4 || entry.Size != entry.UnpackedSize);
                dir.Add(entry);
            }
            if (0 == pack_type)
            {
                return(new ArcFile(file, this, dir));
            }
            return(new PacArchive(file, this, dir, (Compression)pack_type));
        }
예제 #9
0
파일: ArcBIN.cs 프로젝트: zxc120/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0);

            if ((count & 0xFFFF) != 0)
            {
                return(null);
            }
            count = (count >> 16) - 1;
            if (!IsSaneCount(count))
            {
                return(null);
            }

            uint index_offset = 0xC;
            var  dir          = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                var name  = file.View.ReadUInt32(index_offset).ToString("D5");
                var entry = new PackedEntry {
                    Name     = name,
                    Offset   = file.View.ReadUInt32(index_offset + 4) << 11,
                        Size = file.View.ReadUInt32(index_offset + 8),
                };
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 12;
            }
            foreach (PackedEntry entry in dir)
            {
                uint signature;
                if (entry.Size > 13 && file.View.AsciiEqual(entry.Offset + 2, "ike"))
                {
                    int unpacked_size = IkeReader.DecodeSize(file.View.ReadByte(entry.Offset + 10),
                                                             file.View.ReadByte(entry.Offset + 11),
                                                             file.View.ReadByte(entry.Offset + 12));
                    entry.IsPacked     = true;
                    entry.UnpackedSize = (uint)unpacked_size;
                    signature          = file.View.ReadUInt32(entry.Offset + 0xF);
                    entry.Offset      += 13;
                    entry.Size        -= 13;
                }
                else
                {
                    signature = file.View.ReadUInt32(entry.Offset);
                }
                entry.ChangeType(AutoEntry.DetectFileType(signature));
            }
            return(new ArcFile(file, this, dir));
        }
예제 #10
0
파일: ArcDAT.cs 프로젝트: zxc120/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            var  arc_list   = new List <Entry>();
            long max_offset = file.MaxOffset;

            for (int i = 1; i < 100; ++i)
            {
                var part_name = Path.ChangeExtension(file.Name, string.Format("a{0:D02}", i));
                if (!VFS.FileExists(part_name))
                {
                    break;
                }
                var part = VFS.FindFile(part_name);
                arc_list.Add(part);
                max_offset += part.Size;
            }
            uint index_length = file.View.ReadUInt32(8);
            uint data_offset  = file.View.ReadUInt32(0x10);

            using (var zindex = file.CreateStream(0x20, index_length))
                using (var uindex = new ZLibStream(zindex, CompressionMode.Decompress))
                    using (var index = new BinaryStream(uindex, file.Name))
                    {
                        var buffer = new byte[500];
                        var dir    = new List <Entry>();
                        while (index.PeekByte() != -1)
                        {
                            int entry_length = index.ReadInt32();
                            if (entry_length <= 528)
                            {
                                return(null);
                            }
                            bool is_deleted = index.ReadUInt32() != 0;
                            var  entry      = new PackedEntry();
                            entry.Offset = index.ReadInt64() + data_offset;
                            index.ReadUInt32();
                            entry.Size         = index.ReadUInt32();
                            entry.UnpackedSize = index.ReadUInt32();
                            entry.IsPacked     = entry.Size != entry.UnpackedSize;
                            index.Read(buffer, 0, 500);
                            int name_length = index.Read(buffer, 0, entry_length - 528);
                            if (!is_deleted && entry.CheckPlacement(max_offset))
                            {
                                entry.Name = Encoding.Unicode.GetString(buffer, 0, name_length);
                                entry.Type = FormatCatalog.Instance.GetTypeFromName(entry.Name);
                                dir.Add(entry);
                            }
                        }
                        return(new Mpf2Archive(file, this, dir, arc_list));
                    }
        }
예제 #11
0
파일: ArcGRP.cs 프로젝트: uboaa/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            uint first_offset = file.View.ReadUInt32(0);

            if (first_offset < 8 || first_offset >= file.MaxOffset || 0 != (first_offset & 3))
            {
                return(null);
            }
            int count = (int)(first_offset - 4) / 4;

            if (!IsSaneCount(count))
            {
                return(null);
            }

            var  base_name    = Path.GetFileNameWithoutExtension(file.Name);
            uint index_offset = 0;
            uint next_offset  = first_offset;
            var  dir          = new List <Entry> (count);

            for (int i = 0; i < count && next_offset < file.MaxOffset; ++i)
            {
                var entry = new PackedEntry {
                    Offset = next_offset
                };
                index_offset += 4;
                next_offset   = file.View.ReadUInt32(index_offset);
                if (next_offset < entry.Offset)
                {
                    return(null);
                }
                entry.Size         = (uint)(next_offset - entry.Offset);
                entry.UnpackedSize = entry.Size;
                if (entry.Size != 0)
                {
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    entry.Name = string.Format("{0}#{1:D4}", base_name, i);
                    dir.Add(entry);
                }
            }
            if (0 == dir.Count)
            {
                return(null);
            }
            DetectFileTypes(file, dir);
            return(new ArcFile(file, this, dir));
        }
예제 #12
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(4);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            uint index_offset = 8;
            long base_offset  = count * 0x20 + 8;
            var  dir          = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                string name  = file.View.ReadString(index_offset, 0x10);
                uint   size  = file.View.ReadUInt32(index_offset + 0x10);
                var    entry = new PackedEntry {
                    Name = name
                };
                if (name.HasExtension(".scp"))
                {
                    entry.Type     = "script";
                    entry.IsPacked = size > 12 && file.View.AsciiEqual(index_offset + 0x14, "CMP1");
                }
                else
                {
                    entry.Type     = FormatCatalog.Instance.GetTypeFromName(name);
                    entry.IsPacked = false;
                }
                if (entry.IsPacked)
                {
                    entry.UnpackedSize = file.View.ReadUInt32(index_offset + 0x18);
                }
                else
                {
                    entry.UnpackedSize = size;
                }
                entry.Offset = base_offset;
                entry.Size   = size;
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                base_offset  += size;
                index_offset += 0x20;
            }
            return(new ArcFile(file, this, dir));
        }
예제 #13
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.View.AsciiEqual(0, "KOTORI") || 0x1A1A00 != file.View.ReadInt32(6))
            {
                return(null);
            }
            int count = file.View.ReadUInt16(0x14);

            if (0x0100A618 != file.View.ReadInt32(0x10) || !IsSaneCount(count))
            {
                return(null);
            }
            string base_name      = Path.GetFileNameWithoutExtension(file.Name);
            uint   current_offset = 0x18;
            long   next_offset    = file.View.ReadUInt32(current_offset);
            var    dir            = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                var entry = new PackedEntry {
                    Name   = string.Format("{0}#{1:D4}.ogg", base_name, i),
                    Type   = "audio",
                    Offset = next_offset,
                };
                if (i + 1 != count)
                {
                    current_offset += 6;
                    next_offset     = file.View.ReadUInt32(current_offset);
                }
                else
                {
                    next_offset = file.MaxOffset;
                }
                entry.Size = (uint)(next_offset - entry.Offset);
                if (entry.Size >= 0x32)
                {
                    entry.IsPacked     = true;
                    entry.UnpackedSize = entry.Size - 0x32;
                }
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
            }
            return(new ArcFile(file, this, dir));
        }
예제 #14
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0);

            if (!IsSaneCount(count))
            {
                return(null);
            }

            uint first_offset = file.View.ReadUInt32(4);

            if (first_offset != 4 + (uint)count * 12)
            {
                return(null);
            }

            var    base_name    = Path.GetFileNameWithoutExtension(file.Name).ToUpperInvariant();
            string default_type = base_name == "SCR" ? "script" :
                                  base_name == "VOICE" || base_name == "SE" ? "audio" :
                                  base_name == "PICT" ? "image" : "";
            uint index_offset = 4;
            var  dir          = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                uint offset = file.View.ReadUInt32(index_offset);
                var  entry  = new PackedEntry {
                    Name         = string.Format("{0}#{1:D4}", base_name, i),
                    Type         = default_type,
                    Offset       = file.View.ReadUInt32(index_offset),
                    UnpackedSize = file.View.ReadUInt32(index_offset + 4),
                    Size         = file.View.ReadUInt32(index_offset + 8),
                };
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                entry.IsPacked = entry.UnpackedSize != entry.Size;
                dir.Add(entry);
                index_offset += 12;
            }
            if (string.IsNullOrEmpty(default_type))
            {
                DetectFileTypes(file, dir);
            }
            return(new ArcFile(file, this, dir));
        }
예제 #15
0
파일: ArcDDP.cs 프로젝트: zxc120/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(4);

            if (!IsSaneCount(count))
            {
                return(null);
            }

            var index = Him5Opener.ReadIndex(file, 0x20, count);
            var dir   = new List <Entry>();

            foreach (var section in index)
            {
                int index_offset = section.Item1;
                for (int section_size = section.Item2; section_size > 0;)
                {
                    int entry_size = file.View.ReadByte(index_offset);
                    if (entry_size < 17)
                    {
                        break;
                    }
                    var entry = new PackedEntry {
                        Offset       = file.View.ReadUInt32(index_offset + 1),
                        UnpackedSize = file.View.ReadUInt32(index_offset + 5),
                        Size         = file.View.ReadUInt32(index_offset + 9),
                        Name         = file.View.ReadString(index_offset + 17, (uint)entry_size - 17),
                    };
                    entry.IsPacked = entry.Size != 0;
                    if (!entry.IsPacked)
                    {
                        entry.Size = entry.UnpackedSize;
                    }
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    index_offset += entry_size;
                    section_size -= entry_size;
                    dir.Add(entry);
                }
            }
            DetectFileTypes(file, dir);
            return(new ArcFile(file, this, dir));
        }
예제 #16
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".arc"))
            {
                return(null);
            }
            var bin_name = Path.ChangeExtension(file.Name, "BIN");

            if (!VFS.FileExists(bin_name))
            {
                return(null);
            }
            using (var bin = VFS.OpenView(bin_name))
            {
                if (!bin.View.AsciiEqual(0, "LSDARC V.100"))
                {
                    return(null);
                }
                int count = bin.View.ReadInt32(0xC);
                if (!IsSaneCount(count))
                {
                    return(null);
                }
                using (var index = bin.CreateStream())
                {
                    index.Position = 0x10;
                    var dir = new List <Entry>(count);
                    for (int i = 0; i < count; ++i)
                    {
                        var entry = new PackedEntry();
                        entry.IsPacked     = index.ReadInt32() != 0;
                        entry.Offset       = index.ReadUInt32();
                        entry.UnpackedSize = index.ReadUInt32();
                        entry.Size         = index.ReadUInt32();
                        entry.Name         = index.ReadCString();
                        if (!entry.CheckPlacement(file.MaxOffset))
                        {
                            return(null);
                        }
                        dir.Add(entry);
                    }
                    return(new ArcFile(file, this, dir));
                }
            }
        }
예제 #17
0
파일: ArcDM.cs 프로젝트: zxc120/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".dm"))
            {
                return(null);
            }
            int count = file.View.ReadInt32(0);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            var    arc_name = Path.GetFileNameWithoutExtension(file.Name).ToLowerInvariant();
            string type     = arc_name == "image" ? "image"
                        : arc_name == "sound" ? "audio" : "";
            uint index_offset = 4;
            uint data_offset  = 4 + (uint)count * 0x2C;
            var  dir          = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                var name = file.View.ReadString(index_offset, 0x20);
                if (string.IsNullOrWhiteSpace(name))
                {
                    return(null);
                }
                var entry = new PackedEntry {
                    Name         = name,
                    Type         = type,
                    UnpackedSize = file.View.ReadUInt32(index_offset + 0x20),
                    Size         = file.View.ReadUInt32(index_offset + 0x24),
                    Offset       = file.View.ReadUInt32(index_offset + 0x28),
                    IsPacked     = true,
                };
                if (entry.Offset < data_offset || !entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 0x2C;
            }
            return(new ArcFile(file, this, dir));
        }
예제 #18
0
파일: ArcYOX.cs 프로젝트: zxc120/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            uint index_offset = file.View.ReadUInt32(8);
            int  count        = file.View.ReadInt32(0xC);

            if (!IsSaneCount(count) || index_offset >= file.MaxOffset)
            {
                return(null);
            }

            var dir = new List <Entry> (count);
            Func <uint, bool> ReadIndex = entry_size => {
                uint current_offset = index_offset;
                for (int i = 0; i < count; ++i)
                {
                    var entry = new PackedEntry {
                        Name = i.ToString("D5")
                    };
                    entry.Offset = file.View.ReadUInt32(current_offset);
                    entry.Size   = file.View.ReadUInt32(current_offset + 4);
                    if (0 == entry.Size || !entry.CheckPlacement(file.MaxOffset))
                    {
                        return(false);
                    }
                    dir.Add(entry);
                    current_offset += entry_size;
                }
                return(true);
            };

            if (!ReadIndex(8))
            {
                dir.Clear();
                if (!ReadIndex(0x10))
                {
                    return(null);
                }
            }
            using (var stream = file.CreateStream())
                DetectFileTypes(stream, dir);
            return(new ArcFile(file, this, dir));
        }
예제 #19
0
파일: ArcTLZ.cs 프로젝트: zxc120/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0xC);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            uint index_offset = file.View.ReadUInt32(4);

            if (index_offset >= file.MaxOffset)
            {
                return(null);
            }
            var dir = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                var entry = new PackedEntry {
                    UnpackedSize = file.View.ReadUInt32(index_offset),
                    Size         = file.View.ReadUInt32(index_offset + 4),
                    Offset       = file.View.ReadUInt32(index_offset + 8),
                };
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                uint name_length = file.View.ReadUInt32(index_offset + 0xC);
                if (0 == name_length || name_length > 0x100)
                {
                    return(null);
                }
                entry.Name     = file.View.ReadString(index_offset + 0x10, name_length);
                entry.Type     = FormatCatalog.Instance.GetTypeFromName(entry.Name);
                entry.IsPacked = entry.UnpackedSize != entry.Size;
                dir.Add(entry);
                index_offset += 0x10 + name_length;
            }
            return(new ArcFile(file, this, dir));
        }
예제 #20
0
파일: VideoAMV.cs 프로젝트: zxc120/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            if (file.View.ReadInt16(4) != 1)
            {
                return(null);
            }
            uint unpacked_size = file.View.ReadUInt32(0x16);
            uint width         = file.View.ReadUInt32(0x1A);
            uint height        = file.View.ReadUInt32(0x1E);
            int  count         = file.View.ReadInt32(0x2A);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            var  base_name = Path.GetFileNameWithoutExtension(file.Name);
            uint offset    = 0x32;
            var  dir       = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                uint size  = file.View.ReadUInt32(offset);
                var  entry = new PackedEntry
                {
                    Name         = string.Format("{0}#{1:D4}.bmp", base_name, i),
                    Type         = "image",
                    Offset       = offset + 4,
                    Size         = size,
                    IsPacked     = true,
                    UnpackedSize = unpacked_size + 0x36,
                };
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                offset += 4 + size;
            }
            return(new ArcFile(file, this, dir));
        }
예제 #21
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0);

            if (!IsSaneCount(count) || !file.Name.HasExtension(".dat"))
            {
                return(null);
            }
            uint first_offset = file.View.ReadUInt32(0x14);

            if (first_offset != 4 + count * 0x14)
            {
                return(null);
            }
            uint index_offset = 4;
            var  dir          = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                var name = file.View.ReadString(index_offset, 0xC);
                if (string.IsNullOrEmpty(name))
                {
                    return(null);
                }
                var entry = new PackedEntry {
                    Name   = name,
                    Size   = file.View.ReadUInt32(index_offset + 0xC),
                    Offset = file.View.ReadUInt32(index_offset + 0x10),
                };
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 0x14;
            }
            DetectFileTypes(file, dir);
            return(new ArcFile(file, this, dir));
        }
예제 #22
0
파일: ArcAil.cs 프로젝트: zxc120/GARbro
        internal List <Entry> ReadIndex(ArcView file, uint index_offset, int count)
        {
            var  base_name = Path.GetFileNameWithoutExtension(file.Name);
            long offset    = index_offset + count * 4;

            if (offset >= file.MaxOffset)
            {
                return(null);
            }
            var dir = new List <Entry> (count / 2);

            for (int i = 0; i < count; ++i)
            {
                uint size = file.View.ReadUInt32(index_offset);
                if (size != 0 && size != uint.MaxValue)
                {
                    var entry = new PackedEntry
                    {
                        Name     = string.Format("{0}#{1:D5}", base_name, i),
                        Offset   = offset,
                        Size     = size,
                        IsPacked = false,
                    };
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                    offset += size;
                }
                index_offset += 4;
            }
            if (0 == dir.Count || (file.MaxOffset - offset) > 0x80000)
            {
                return(null);
            }
            DetectFileTypes(file, dir);
            return(dir);
        }
예제 #23
0
파일: ArcDDP.cs 프로젝트: zxc120/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(4);

            if (!IsSaneCount(count))
            {
                return(null);
            }

            var  base_name    = Path.GetFileNameWithoutExtension(file.Name);
            uint index_offset = 0x20;
            var  dir          = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                var entry = new PackedEntry {
                    Offset       = file.View.ReadUInt32(index_offset),
                    UnpackedSize = file.View.ReadUInt32(index_offset + 4),
                    Size         = file.View.ReadUInt32(index_offset + 8),
                    Name         = string.Format("{0}#{1:D5}", base_name, i),
                };
                entry.IsPacked = entry.Size != 0;
                if (!entry.IsPacked)
                {
                    entry.Size = entry.UnpackedSize;
                }
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                index_offset += 0x10;
                dir.Add(entry);
            }
            DetectFileTypes(file, dir);
            return(new ArcFile(file, this, dir));
        }
예제 #24
0
파일: ArcCCT.cs 프로젝트: zxc120/GARbro
        public List <Entry> ReadIndex()
        {
            uint section_size = ReadSectionSize("Fver");

            m_offset    += section_size;
            section_size = ReadSectionSize("Fcdr");

            /*
             * int Mcdr_size;
             * var Mcdr = ZlibUnpack (m_offset, section_size, out Mcdr_size);
             */
            m_offset += section_size;
            uint abmp_size   = ReadSectionSize("ABMP");
            int  max_count   = m_file.View.Read(m_offset, m_size_buffer, 0, Math.Min(10, abmp_size));
            int  size_offset = 0;

            ReadValue(m_size_buffer, ref size_offset, max_count);
            max_count -= size_offset;

            int bmp_unpacked_size = (int)ReadValue(m_size_buffer, ref size_offset, max_count);

            m_offset  += size_offset;
            abmp_size -= (uint)size_offset;
            int index_size;
            var index = ZlibUnpack(m_offset, abmp_size, out index_size, bmp_unpacked_size);

            m_offset    += abmp_size;
            section_size = ReadSectionSize("FGEI");
            if (0 != section_size)
            {
                throw new NotSupportedException();
            }

            int index_offset = 0;

            ReadValue(index, ref index_offset, index_size - index_offset);
            ReadValue(index, ref index_offset, index_size - index_offset);
            int entry_count = (int)ReadValue(index, ref index_offset, index_size - index_offset);

            if (entry_count <= 0 || entry_count > 0xfffff)
            {
                return(null);
            }

            var type_buf = new char[4];
            var dir      = new List <Entry> (entry_count);

            for (int i = 0; i < entry_count; ++i)
            {
                uint id            = ReadValue(index, ref index_offset, index_size - index_offset);
                uint offset        = ReadValue(index, ref index_offset, index_size - index_offset);
                uint size          = ReadValue(index, ref index_offset, index_size - index_offset);
                uint unpacked_size = ReadValue(index, ref index_offset, index_size - index_offset);
                uint flag          = ReadValue(index, ref index_offset, index_size - index_offset);

                if (index_size - index_offset < 4)
                {
                    return(null);
                }
                uint type_id = LittleEndian.ToUInt32(index, index_offset);
                index_offset += 4;
                if (0 == type_id || uint.MaxValue == offset)
                {
                    continue;
                }

                Encoding.ASCII.GetChars(index, index_offset - 4, 4, type_buf, 0);
                var entry = new PackedEntry
                {
                    Name         = CreateName(id, type_buf),
                    Offset       = (long)m_offset + offset,
                    Size         = size,
                    UnpackedSize = unpacked_size,
                    IsPacked     = 0 == flag,
                };
                if (entry.CheckPlacement(m_file.MaxOffset))
                {
                    dir.Add(entry);
                }
            }
            return(dir);
        }
예제 #25
0
파일: ArcBIN.cs 프로젝트: zxc120/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            uint first_offset = file.View.ReadUInt32(4);

            if (4 + count * 8 != first_offset)
            {
                return(null);
            }

            var  base_name    = Path.GetFileNameWithoutExtension(file.Name);
            bool is_msg       = base_name == "msg";
            uint index_offset = 4;
            var  dir          = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                uint offset = file.View.ReadUInt32(index_offset);
                uint size   = file.View.ReadUInt32(index_offset + 4);
                var  entry  = new PackedEntry {
                    Name   = string.Format("{0}#{1:D5}", base_name, i),
                    Offset = offset,
                    Size   = size,
                };
                if (!is_msg && !entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 8;
            }
            foreach (PackedEntry entry in dir)
            {
                if (is_msg)
                {
                    uint size = file.View.ReadUInt32(entry.Offset);
                    entry.Offset      += 4;
                    entry.UnpackedSize = entry.Size;
                    entry.Size         = size;
                    entry.IsPacked     = true;
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    continue;
                }
                uint pos = file.View.ReadUInt32(entry.Offset + 4);
                if (pos > entry.Size)
                {
                    continue;
                }
                uint unpacked_size = file.View.ReadUInt32(entry.Offset + 8);
                uint flags         = unpacked_size >> 30;
                unpacked_size &= 0x3FFFFFFF;
                entry.IsPacked = 0 == flags;
                uint signature = 0;
                if (entry.IsPacked)
                {
                    entry.UnpackedSize = unpacked_size;
                    entry.Size         = file.View.ReadUInt32(entry.Offset + pos);
                    entry.Offset      += pos + 4;
                    if ((file.View.ReadByte(entry.Offset) & 0xF) == 0xF)
                    {
                        signature = file.View.ReadUInt32(entry.Offset + 1);
                    }
                }
                else
                {
                    entry.Size    = unpacked_size;
                    entry.Offset += pos;
                    signature     = file.View.ReadUInt32(entry.Offset);
                }
                var res = AutoEntry.DetectFileType(signature);
                if (res != null)
                {
                    entry.ChangeType(res);
                }
            }
            return(new ArcFile(file, this, dir));
        }
예제 #26
0
파일: ArcAil.cs 프로젝트: y111303tut/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            long offset = 4 + count * 4;

            if (offset >= file.MaxOffset)
            {
                return(null);
            }
            uint index_offset = 4;
            var  dir          = new List <Entry>();

            for (int i = 0; i < count; ++i)
            {
                uint size = file.View.ReadUInt32(index_offset);
                if (0 != size)
                {
                    var entry = new PackedEntry
                    {
                        Name     = i.ToString("D5"),
                        Offset   = offset,
                        Size     = size,
                        IsPacked = false,
                    };
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                    offset += size;
                }
                index_offset += 4;
            }
            if (offset != file.MaxOffset || 0 == dir.Count)
            {
                return(null);
            }
            byte[] preview  = new byte[16];
            byte[] sign_buf = new byte[4];
            foreach (PackedEntry entry in dir)
            {
                uint extra = 6;
                if (extra > entry.Size)
                {
                    continue;
                }
                int label = file.View.ReadUInt16(entry.Offset);
                if (1 == label)
                {
                    entry.IsPacked     = true;
                    entry.UnpackedSize = file.View.ReadUInt32(entry.Offset + 2);
                }
                entry.Offset += extra;
                entry.Size   -= extra;
                uint signature;
                if (entry.IsPacked)
                {
                    file.View.Read(entry.Offset, preview, 0, (uint)preview.Length);
                    using (var input = new MemoryStream(preview))
                    {
                        LzssUnpack(input, sign_buf);
                        signature = LittleEndian.ToUInt32(sign_buf, 0);
                    }
                }
                else
                {
                    signature = file.View.ReadUInt32(entry.Offset);
                }
                if (0 != signature)
                {
                    SetEntryType(entry, signature);
                }
            }
            return(new ArcFile(file, this, dir));
        }
예제 #27
0
파일: ArcGRP.cs 프로젝트: Casidi/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            uint first_offset = file.View.ReadUInt32 (0);
            if (first_offset < 8 || first_offset >= file.MaxOffset)
                return null;
            int count = (int)(first_offset - 8) / 4;
            if (!IsSaneCount (count))
                return null;

            var base_name = Path.GetFileNameWithoutExtension (file.Name);
            uint index_offset = 0;
            uint next_offset = first_offset;
            var dir = new List<Entry> (count);
            for (int i = 0; i < count; ++i)
            {
                var entry = new PackedEntry { Offset = next_offset };
                index_offset += 4;
                next_offset = file.View.ReadUInt32 (index_offset);
                if (next_offset < entry.Offset)
                    return null;
                entry.Size = (uint)(next_offset - entry.Offset);
                entry.UnpackedSize = entry.Size;
                if (entry.Size != 0)
                {
                    if (!entry.CheckPlacement (file.MaxOffset))
                        return null;
                    entry.Name = string.Format ("{0}#{1:D4}", base_name, i);
                    dir.Add (entry);
                }
            }
            if (0 == dir.Count)
                return null;
            foreach (PackedEntry entry in dir)
            {
                if (entry.Size < 4)
                    continue;
                uint unpacked_size = file.View.ReadUInt32 (entry.Offset);
                if (entry.Size > 8 && file.View.AsciiEqual (entry.Offset+4, "HDJ\0"))
                {
                    if (file.View.AsciiEqual (entry.Offset+12, "BM"))
                    {
                        entry.Name = Path.ChangeExtension (entry.Name, "bmp");
                        entry.Type = "image";
                    }
                    entry.UnpackedSize = unpacked_size;
                    entry.IsPacked = true;
                }
                else if (entry.Size > 12 && file.View.AsciiEqual (entry.Offset+8, "RIFF"))
                {
                    entry.Name = Path.ChangeExtension (entry.Name, "wav");
                    entry.Type = "audio";
                    entry.UnpackedSize = unpacked_size;
                    entry.IsPacked = true;
                }
                else if (0x4D42 == (unpacked_size & 0xFFFF))
                {
                    entry.Name = Path.ChangeExtension (entry.Name, "bmp");
                    entry.Type = "image";
                }
            }
            return new ArcFile (file, this, dir);
        }
예제 #28
0
파일: ArcBIN.cs 프로젝트: y111303tut/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.View.AsciiEqual(4, "OFST"))
            {
                return(null);
            }
            int index_size = file.View.ReadInt32(8);
            int count      = index_size / 4;

            if (!IsSaneCount(count))
            {
                return(null);
            }
            var    base_name = Path.GetFileNameWithoutExtension(file.Name);
            string content_ext = "", content_type = "";

            if (base_name.EndsWith("flac", StringComparison.InvariantCultureIgnoreCase))
            {
                content_ext  = "flac";
                content_type = "audio";
                base_name    = base_name.Substring(0, base_name.Length - 4);
            }
            else if (base_name.EndsWith("ogg", StringComparison.InvariantCultureIgnoreCase))
            {
                content_ext  = "ogg";
                content_type = "audio";
                base_name    = base_name.Substring(0, base_name.Length - 3);
            }

            var filenames = GetFileNames(VFS.GetDirectoryName(file.Name), base_name);

            if (null == filenames)
            {
                filenames = new List <string> (count);
            }
            for (int i = filenames.Count; i < count; ++i)
            {
                filenames.Add(string.Format("{0}#{1:D5}", base_name, i));
            }

            uint index_offset = 0xC;
            var  dir          = new List <Entry> (count);
            uint next_offset  = file.View.ReadUInt32(index_offset);

            for (int i = 0; i < count; ++i)
            {
                index_offset += 4;
                var entry = new PackedEntry {
                    Name = filenames[i]
                };
                entry.Offset = next_offset;
                next_offset  = i + 1 < count?file.View.ReadUInt32(index_offset) : (uint)file.MaxOffset;

                entry.Size = next_offset - (uint)entry.Offset;
                if (entry.Size > 0 && !entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                if (!string.IsNullOrEmpty(content_type))
                {
                    entry.Type = content_type;
                    entry.Name = Path.ChangeExtension(entry.Name, content_ext);
                }
                dir.Add(entry);
            }
            foreach (PackedEntry entry in dir.Where(e => e.Size > 4))
            {
                entry.IsPacked = file.View.AsciiEqual(entry.Offset, "DFLT");
                if (entry.IsPacked)
                {
                    entry.Size         = file.View.ReadUInt32(entry.Offset + 4);
                    entry.UnpackedSize = file.View.ReadUInt32(entry.Offset + 8);
                    entry.Offset      += 12;
                }
                else if (file.View.AsciiEqual(entry.Offset, "DATA"))
                {
                    entry.Size         = file.View.ReadUInt32(entry.Offset + 4);
                    entry.UnpackedSize = entry.Size;
                    entry.Offset      += 8;
                    if (string.IsNullOrEmpty(entry.Type))
                    {
                        uint signature = file.View.ReadUInt32(entry.Offset);
                        if (0x43614C66 == signature) // 'fLaC'
                        {
                            entry.Type = "audio";
                            entry.Name = Path.ChangeExtension(entry.Name, "flac");
                        }
                        else
                        {
                            var res = AutoEntry.DetectFileType(signature);
                            if (null != res)
                            {
                                entry.ChangeType(res);
                            }
                        }
                    }
                }
            }
            return(new ArcFile(file, this, dir));
        }
예제 #29
0
파일: ArcTactics.cs 프로젝트: Casidi/GARbro
            bool ReadV1(Stream input)
            {
                // NOTE CryptoStream will close an input stream
                using (var xored = new CryptoStream (input, new NotTransform(), CryptoStreamMode.Read))
                using (var lzss = new LzssStream (xored))
                    lzss.Read (m_index, 0, m_index.Length);

                int index_offset = Array.IndexOf (m_index, (byte)0);
                if (-1 == index_offset || 0 == index_offset)
                    return false;
                Password = m_index.Take (index_offset++).ToArray();
                long base_offset = 0x20 + m_packed_size;

                for (int i = 0; i < m_count; ++i)
                {
                    var entry = new PackedEntry();
                    entry.Offset = LittleEndian.ToUInt32 (m_index, index_offset) + base_offset;
                    entry.Size   = LittleEndian.ToUInt32 (m_index, index_offset + 4);
                    entry.UnpackedSize = LittleEndian.ToUInt32 (m_index, index_offset + 8);
                    entry.IsPacked = entry.UnpackedSize != 0;
                    if (!entry.CheckPlacement (m_file.MaxOffset))
                        return false;
                    int name_len = LittleEndian.ToInt32 (m_index, index_offset + 0xC);
                    entry.Name = Encodings.cp932.GetString (m_index, index_offset+0x18, name_len);
                    entry.Type = FormatCatalog.Instance.GetTypeFromName (entry.Name);
                    m_dir.Value.Add (entry);
                    index_offset += 0x18 + name_len;
                }
                return true;
            }
예제 #30
0
        public override ArcFile TryOpen(ArcView file)
        {
            int version = file.View.ReadByte(3) - 0x30;
            int count   = file.View.ReadInt32(4);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            var  name_buf     = new byte[32];
            var  dir          = new List <Entry> (count);
            long index_offset = 8;
            uint next_offset  = file.View.ReadUInt32(index_offset);

            for (int i = 0; i < count; ++i)
            {
                uint offset      = next_offset;
                uint size        = file.View.ReadUInt32(index_offset + 4);
                int  name_length = file.View.ReadByte(index_offset + 8);
                if (name_length > name_buf.Length)
                {
                    name_buf = new byte[name_length];
                }
                file.View.Read(index_offset + 9, name_buf, 0, (uint)name_length);
                if (i + 1 == count)
                {
                    next_offset = (uint)file.MaxOffset;
                }
                else
                {
                    next_offset = file.View.ReadUInt32(index_offset + 9 + name_length);
                }
                if (0 != offset && offset != file.MaxOffset)
                {
                    if (2 == version)
                    {
                        for (int j = 0; j < name_length; ++j)
                        {
                            name_buf[j] ^= 0xff;
                        }
                    }
                    uint packed_size;
                    if (0 == next_offset)
                    {
                        packed_size = size;
                    }
                    else if (next_offset >= offset)
                    {
                        packed_size = next_offset - offset;
                    }
                    else
                    {
                        return(null);
                    }
                    string name  = Encodings.cp932.GetString(name_buf, 0, name_length);
                    var    entry = new PackedEntry
                    {
                        Name         = name,
                        Type         = FormatCatalog.Instance.GetTypeFromName(name),
                        Offset       = offset,
                        Size         = packed_size,
                        UnpackedSize = size,
                        IsPacked     = packed_size != size,
                    };
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                }
                index_offset += 9 + name_length;
            }
            if (2 == version)
            {
                return(new AstArchive(file, this, dir));
            }
            else
            {
                return(new ArcFile(file, this, dir));
            }
        }
예제 #31
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            uint index_size = (uint)count * 4 + 8;

            if (index_size > file.View.Reserve(0, index_size))
            {
                return(null);
            }
            uint index_offset = 4;
            uint offset       = file.View.ReadUInt32(index_offset);

            if (offset != index_size)
            {
                return(null);
            }
            uint last_offset = file.View.ReadUInt32(index_size - 4);

            if (last_offset != file.MaxOffset)
            {
                return(null);
            }
            string default_type = "";

            if (file.Name.HasExtension("fx"))
            {
                default_type = "audio";
            }
            else if (file.Name.HasExtension("gx"))
            {
                default_type = "image";
            }
            var base_name = Path.GetFileNameWithoutExtension(file.Name);
            var dir       = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                index_offset += 4;
                var entry = new PackedEntry {
                    Name   = string.Format("{0}#{1:D4}", base_name, i),
                    Type   = default_type,
                    Offset = offset,
                };
                offset     = file.View.ReadUInt32(index_offset);
                entry.Size = (uint)(offset - entry.Offset);
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
            }
            if (string.IsNullOrEmpty(default_type))
            {
                foreach (var entry in dir)
                {
                    uint signature = file.View.ReadUInt32(entry.Offset);
                    entry.ChangeType(AutoEntry.DetectFileType(signature));
                }
            }
            return(new ArcFile(file, this, dir));
        }
예제 #32
0
파일: ArcAil.cs 프로젝트: Casidi/GARbro
 public override ArcFile TryOpen(ArcView file)
 {
     int count = file.View.ReadInt32 (0);
     if (!IsSaneCount (count))
         return null;
     long offset = 4+count*4;
     if (offset >= file.MaxOffset)
         return null;
     uint index_offset = 4;
     var dir = new List<Entry>();
     for (int i = 0; i < count; ++i)
     {
         uint size = file.View.ReadUInt32 (index_offset);
         if (0 != size)
         {
             var entry = new PackedEntry
             {
                 Name = i.ToString ("D5"),
                 Offset = offset,
                 Size = size,
                 IsPacked = false,
             };
             if (!entry.CheckPlacement (file.MaxOffset))
                 return null;
             dir.Add (entry);
             offset += size;
         }
         index_offset += 4;
     }
     if (offset != file.MaxOffset || 0 == dir.Count)
         return null;
     byte[] preview = new byte[16];
     byte[] sign_buf = new byte[4];
     foreach (PackedEntry entry in dir)
     {
         uint extra = 6;
         if (extra > entry.Size)
             continue;
         int label = file.View.ReadUInt16 (entry.Offset);
         if (1 == label)
         {
             entry.IsPacked = true;
             entry.UnpackedSize = file.View.ReadUInt32 (entry.Offset+2);
         }
         entry.Offset += extra;
         entry.Size   -= extra;
         uint signature;
         if (entry.IsPacked)
         {
             file.View.Read (entry.Offset, preview, 0, (uint)preview.Length);
             using (var input = new MemoryStream (preview))
             {
                 LzssUnpack (input, sign_buf);
                 signature = LittleEndian.ToUInt32 (sign_buf, 0);
             }
         }
         else
         {
             signature = file.View.ReadUInt32 (entry.Offset);
         }
         if (0 != signature)
             SetEntryType (entry, signature);
     }
     return new ArcFile (file, this, dir);
 }
예제 #33
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (0 != file.View.ReadInt32(4))
            {
                return(null);
            }
            long index_offset = file.View.ReadInt64(8);

            if (index_offset >= file.MaxOffset)
            {
                return(null);
            }
            if (!file.View.AsciiEqual(index_offset, "GCE3"))
            {
                return(null);
            }
            int count = file.View.ReadInt32(index_offset + 0x18);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            bool index_packed = 0x11 == file.View.ReadInt32(index_offset + 4);
            uint index_size   = file.View.ReadUInt32(index_offset + 8);

            byte[] index = null;
            if (index_packed)
            {
                index_size -= 0x28;
                int unpacked_size = file.View.ReadInt32(index_offset + 0x20);
                using (var input = file.CreateStream(index_offset + 0x28, index_size))
                    using (var reader = new GceReader(input, unpacked_size))
                        index = reader.Data;
            }
            else
            {
                index_size -= 0x20;
                index       = new byte[index_size];
                if (index.Length != file.View.Read(index_offset + 0x20, index, 0, index_size))
                {
                    return(null);
                }
            }
            int  current_index    = 0;
            int  current_filename = 0x20 * count;
            long current_offset   = 0x10;
            var  dir = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                int name_length = LittleEndian.ToUInt16(index, current_filename);
                if (current_filename + 2 + name_length > index.Length)
                {
                    return(null);
                }
                uint size = LittleEndian.ToUInt32(index, current_index + 0x18);
                if (size != 0)
                {
                    string name  = Encodings.cp932.GetString(index, current_filename + 2, name_length);
                    var    entry = new PackedEntry
                    {
                        Name         = name,
                        Type         = FormatCatalog.Instance.GetTypeFromName(name),
                        Offset       = current_offset,
                        Size         = size,
                        UnpackedSize = LittleEndian.ToUInt32(index, current_index + 0x10),
                    };
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    entry.IsPacked  = entry.Size != entry.UnpackedSize;
                    current_offset += entry.Size;
                    dir.Add(entry);
                }
                current_index    += 0x20;
                current_filename += 2 + name_length;
            }
            return(new ArcFile(file, this, dir));
        }
예제 #34
0
파일: ArcGPC.cs 프로젝트: Casidi/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32 (4);
            if (!IsSaneCount (count))
                return null;

            var base_name = Path.GetFileNameWithoutExtension (file.Name);
            var dir = new List<Entry> (count);
            int index_offset = 8;
            long data_offset = count * 4 + 8;
            uint next_offset = file.View.ReadUInt32 (index_offset);
            for (int i = 0; i < count; ++i)
            {
                index_offset += 4;
                var entry = new PackedEntry { Offset = next_offset };
                next_offset = i + 1 < count ? file.View.ReadUInt32 (index_offset) : (uint)file.MaxOffset;
                entry.Size = next_offset - (uint)entry.Offset;
                if (entry.Offset < data_offset || !entry.CheckPlacement (file.MaxOffset))
                    return null;
                entry.Name = string.Format ("{0}#{1:D4}", base_name, i);
                dir.Add (entry);
            }
            DetectFileTypes (file, dir);
            return new ArcFile (file, this, dir);
        }
예제 #35
0
파일: ArcTactics.cs 프로젝트: Casidi/GARbro
            bool ReadV0(Stream input)
            {
                long current_offset = 0x20 + m_packed_size;
                uint offset_table_size = (uint)m_count * 0x10;
                if (offset_table_size > m_file.View.Reserve (current_offset, offset_table_size))
                    return false;

                using (var lzss = new LzssStream (input, LzssMode.Decompress, true))
                    lzss.Read (m_index, 0, m_index.Length);

                for (int i = 0; i < m_index.Length; ++i)
                {
                    m_index[i] = (byte)(~m_index[i] - 5);
                }
                int index_offset = Array.IndexOf (m_index, (byte)0);
                if (-1 == index_offset || 0 == index_offset)
                    return false;
                index_offset++;
                //                Password = m_index.Take (index_offset++).ToArray();

                for (int i = 0; i < m_count && index_offset < m_index.Length; ++i)
                {
                    int name_end = Array.IndexOf (m_index, (byte)0, index_offset);
                    if (-1 == name_end)
                        name_end = m_index.Length;
                    if (index_offset == name_end)
                        return false;
                    var entry = new PackedEntry();
                    entry.Offset = m_file.View.ReadUInt32 (current_offset);
                    entry.Size   = m_file.View.ReadUInt32 (current_offset+4);
                    entry.UnpackedSize = m_file.View.ReadUInt32 (current_offset+8);
                    entry.IsPacked = entry.UnpackedSize != 0;
                    if (!entry.CheckPlacement (m_file.MaxOffset))
                        return false;
                    entry.Name = Encodings.cp932.GetString (m_index, index_offset, name_end-index_offset);
                    entry.Type = FormatCatalog.Instance.GetTypeFromName (entry.Name);
                    m_dir.Value.Add (entry);
                    index_offset = name_end+1;
                    current_offset += 0x10;
                }
                return true;
            }
예제 #36
0
파일: ArcXuse.cs 프로젝트: Casidi/GARbro
 public override ArcFile TryOpen(ArcView file)
 {
     if (!file.View.AsciiEqual (0, "KOTORI") || 0x1A1A00 != file.View.ReadInt32 (6))
         return null;
     int count = file.View.ReadUInt16 (0x14);
     if (0x0100A618 != file.View.ReadInt32 (0x10) || !IsSaneCount (count))
         return null;
     string base_name = Path.GetFileNameWithoutExtension (file.Name);
     uint current_offset = 0x18;
     long next_offset = file.View.ReadUInt32 (current_offset);
     var dir = new List<Entry> (count);
     for (int i = 0; i < count; ++i)
     {
         var entry = new PackedEntry {
             Name = string.Format ("{0}#{1:D4}.ogg", base_name, i),
             Type = "audio",
             Offset = next_offset,
         };
         if (i+1 != count)
         {
             current_offset += 6;
             next_offset = file.View.ReadUInt32 (current_offset);
         }
         else
             next_offset = file.MaxOffset;
         entry.Size = (uint)(next_offset - entry.Offset);
         if (entry.Size >= 0x32)
         {
             entry.IsPacked = true;
             entry.UnpackedSize = entry.Size - 0x32;
         }
         if (!entry.CheckPlacement (file.MaxOffset))
             return null;
         dir.Add (entry);
     }
     return new ArcFile (file, this, dir);
 }