Exemplo n.º 1
0
        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));
        }
Exemplo n.º 2
0
        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));
        }
Exemplo n.º 3
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 (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));
        }
Exemplo n.º 4
0
        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));
        }
Exemplo n.º 5
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));
        }