예제 #1
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(4);

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

            var  base_name = Path.GetFileNameWithoutExtension(file.Name);
            long offset    = 8;
            var  dir       = new List <Entry>();
            int  i         = 0;

            while (offset < file.MaxOffset)
            {
                uint size = file.View.ReadUInt32(offset);
                offset += 4;
                var entry = new Entry {
                    Name   = string.Format("{0}#{1:D4}", base_name, i++),
                    Offset = offset,
                    Size   = size
                };
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                uint signature = file.View.ReadUInt32(offset);
                var  res       = AutoEntry.DetectFileType(signature);
                entry.ChangeType(res);
                offset += size;
                dir.Add(entry);
            }
            return(new ArcFile(file, this, dir));
        }
예제 #2
0
파일: ArcYOX.cs 프로젝트: zxc120/GARbro
 void DetectFileTypes(Stream file, IList <Entry> dir)
 {
     foreach (PackedEntry entry in dir)
     {
         file.Position = entry.Offset;
         uint      signature = ReadUInt32(file);
         IResource res       = null;
         if (0x584F59 == signature) // 'YOX'
         {
             if (0 != (2 & ReadUInt32(file)))
             {
                 entry.IsPacked     = true;
                 entry.UnpackedSize = ReadUInt32(file);
                 entry.Offset      += 0x10;
                 entry.Size        -= 0x10;
                 file.Position      = entry.Offset;
                 using (var input = new ZLibStream(file, CompressionMode.Decompress, true))
                     signature = ReadUInt32(input);
                 res = AutoEntry.DetectFileType(signature);
             }
         }
         else
         {
             res = AutoEntry.DetectFileType(signature);
         }
         if (res != null)
         {
             entry.Name = Path.ChangeExtension(entry.Name, res.Extensions.FirstOrDefault());
             entry.Type = res.Type;
         }
     }
 }
예제 #3
0
 public void DetectTypes(IEnumerable <Entry> dir, Func <Entry, uint> get_signature)
 {
     foreach (var entry in dir.Where(e => string.IsNullOrEmpty(e.Type)))
     {
         if (entry.Name.HasAnyOfExtensions("txt", "nut"))
         {
             entry.Type = "script";
             continue;
         }
         uint signature = get_signature(entry);
         var  res       = AutoEntry.DetectFileType(signature);
         if (res != null)
         {
             entry.ChangeType(res);
         }
         else if (0x474E4D8A == signature)
         {
             entry.Name = Path.ChangeExtension(entry.Name, "mng");
         }
         else if (entry.Name.StartsWith("script/"))
         {
             entry.Type = "script";
         }
     }
 }
예제 #4
0
 void DetectFileTypes(ArcView file, List <Entry> dir)
 {
     foreach (var entry in dir)
     {
         var offset    = entry.Offset;
         var signature = file.View.ReadUInt32(offset);
         if (entry.Size > 0x10 && 0x4C495243 == signature) // 'CRIL'
         {
             uint packed_size = file.View.ReadUInt32(offset + 12);
             if (packed_size < entry.Size - 0x10)
             {
                 signature = file.View.ReadUInt32(offset + 0x10 + packed_size);
                 if (0x10 == signature)
                 {
                     signature = file.View.ReadUInt32(offset + 0x10 + packed_size + signature);
                 }
             }
         }
         var res = AutoEntry.DetectFileType(signature);
         if (null != res)
         {
             entry.Type = res.Type;
             entry.Name = Path.ChangeExtension(entry.Name, res.Extensions.FirstOrDefault());
         }
     }
 }
예제 #5
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            List <Entry> dir = null;

            foreach (var name_size in NameSizes)
            {
                uint index_size   = (uint)((name_size + 8) * count);
                uint first_offset = file.View.ReadUInt32(4 + name_size + 4);
                if (first_offset == (4 + index_size) && first_offset < file.MaxOffset)
                {
                    if (null == dir)
                    {
                        dir = new List <Entry> (count);
                    }
                    else
                    {
                        dir.Clear();
                    }
                    long index_offset = 4;
                    for (int i = 0; i < count; ++i)
                    {
                        string name = file.View.ReadString(index_offset, name_size);
                        if (string.IsNullOrWhiteSpace(name))
                        {
                            goto CheckNextLength;
                        }
                        index_offset += name_size;
                        uint offset = file.View.ReadUInt32(index_offset + 4);
                        var  entry  = new AutoEntry(name, () => {
                            uint signature = file.View.ReadUInt32(offset);
                            if (1 == signature)
                            {
                                return(s_GraFormat.Value);
                            }
                            return(AutoEntry.DetectFileType(signature));
                        });
                        entry.Offset = offset;
                        entry.Size   = file.View.ReadUInt32(index_offset);
                        if (offset <= index_size || !entry.CheckPlacement(file.MaxOffset))
                        {
                            goto CheckNextLength;
                        }
                        dir.Add(entry);
                        index_offset += 8;
                    }
                    return(new ArcFile(file, this, dir));
                }
CheckNextLength:
                ;
            }
            return(null);
        }
예제 #6
0
        static void SetEntryType(Entry entry, uint signature)
        {
            var res = AutoEntry.DetectFileType(signature);

            if (null != res)
            {
                entry.ChangeType(res);
            }
        }
예제 #7
0
파일: ArcAdvSys3.cs 프로젝트: zxc120/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".dat") ||
                !Path.GetFileName(file.Name).StartsWith("arc", StringComparison.InvariantCultureIgnoreCase))
            {
                return(null);
            }
            long current_offset = 0;
            var  dir            = new List <Entry>();

            while (current_offset < file.MaxOffset)
            {
                uint size = file.View.ReadUInt32(current_offset);
                if (0 == size)
                {
                    break;
                }
                uint name_length = file.View.ReadUInt16(current_offset + 8);
                if (0 == name_length || name_length > 0x100)
                {
                    return(null);
                }
                var name = file.View.ReadString(current_offset + 10, name_length);
                if (0 == name.Length)
                {
                    return(null);
                }
                current_offset += 10 + name_length;
                if (current_offset + size > file.MaxOffset)
                {
                    return(null);
                }
                var entry = new Entry {
                    Name   = name,
                    Offset = current_offset,
                    Size   = size,
                };
                uint signature = file.View.ReadUInt32(current_offset);
                if (file.View.AsciiEqual(current_offset + 4, "GWD"))
                {
                    entry.Type = "image";
                    entry.Name = Path.ChangeExtension(entry.Name, "gwd");
                }
                else
                {
                    var res = AutoEntry.DetectFileType(signature);
                    entry.ChangeType(res);
                }
                dir.Add(entry);
                current_offset += size;
            }
            if (0 == dir.Count)
            {
                return(null);
            }
            return(new ArcFile(file, this, dir));
        }
예제 #8
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (file.View.ReadUInt32(4) != 0)
            {
                return(null);
            }
            int count = file.View.ReadInt32(0xC);

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

            if (index_offset >= file.MaxOffset || index_offset + count * 4 > 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 Entry {
                    Name   = string.Format("{0}#{1:D5}", base_name, i),
                    Offset = file.View.ReadUInt32(index_offset) + 0x20,
                };
                if (entry.Offset > index_offset)
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 4;
            }
            for (int i = 1; i < count; ++i)
            {
                dir[i - 1].Size = (uint)(dir[i].Offset - dir[i - 1].Offset);
            }
            dir[count - 1].Size = (uint)(index_offset - dir[count - 1].Offset);
            foreach (var entry in dir)
            {
                uint signature = file.View.ReadUInt32(entry.Offset);
                if (0x544F48 == signature) // 'HOT'
                {
                    if (0x21 == (file.View.ReadByte(entry.Offset + 7) & 0x21))
                    {
                        entry.Type = "image";
                    }
                }
                else
                {
                    entry.ChangeType(AutoEntry.DetectFileType(signature));
                }
            }
            return(new ArcFile(file, this, dir));
        }
예제 #9
0
파일: ArcGPC.cs 프로젝트: tenyuhuang/GARbro
 void DetectFileTypes(ArcView file, List <Entry> dir)
 {
     using (var input = file.CreateStream())
         using (var reader = new ArcView.Reader(input))
         {
             var buffer = new byte[0x10];
             foreach (PackedEntry entry in dir)
             {
                 input.Position = entry.Offset;
                 uint packed_size = reader.ReadUInt32();
                 entry.UnpackedSize = reader.ReadUInt32();
                 entry.Offset      += 8;
                 if (0 == packed_size)
                 {
                     entry.Size = entry.UnpackedSize;
                 }
                 else
                 {
                     entry.IsPacked = true;
                     entry.Size     = packed_size;
                 }
                 if (entry.Size < 0x10)
                 {
                     continue;
                 }
                 uint signature;
                 if (entry.IsPacked)
                 {
                     UnpackEntry(input, buffer);
                     signature = LittleEndian.ToUInt32(buffer, 0);
                 }
                 else
                 {
                     signature = reader.ReadUInt32();
                 }
                 IResource res;
                 if (0x020000 == signature || 0x0A0000 == signature)
                 {
                     res = ImageFormat.Tga;
                 }
                 else
                 {
                     res = AutoEntry.DetectFileType(signature);
                 }
                 if (null != res)
                 {
                     entry.Type = res.Type;
                     var ext = res.Extensions.FirstOrDefault();
                     if (!string.IsNullOrEmpty(ext))
                     {
                         entry.Name = Path.ChangeExtension(entry.Name, ext);
                     }
                 }
             }
         }
 }
예제 #10
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));
        }
예제 #11
0
파일: ArcABMP.cs 프로젝트: zxc120/GARbro
        static internal void DetectFileType(ArcView file, Entry entry)
        {
            uint signature = file.View.ReadUInt32(entry.Offset);
            var  res       = AutoEntry.DetectFileType(signature);

            if (null != res)
            {
                entry.ChangeType(res);
            }
        }
예제 #12
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));
        }
예제 #13
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.View.AsciiEqual(0, "MD"))
            {
                return(null);
            }
            uint entry_length = file.View.ReadUInt16(4);
            int  count        = file.View.ReadUInt16(6);

            if (entry_length <= 8 || !IsSaneCount(count))
            {
                return(null);
            }

            uint name_length  = entry_length - 8;
            uint index_offset = 0x10;
            var  dir          = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                var name = file.View.ReadString(index_offset, name_length);
                index_offset += name_length;
                uint offset = file.View.ReadUInt32(index_offset + 4);

                var entry = new AutoEntry(name, () => {
                    uint signature = file.View.ReadUInt32(offset);
                    if (0x4259 == (signature & 0xFFFF)) // 'YB'
                    {
                        return(PrsFormat.Value);
                    }
                    return(AutoEntry.DetectFileType(signature));
                });
                entry.Size   = file.View.ReadUInt32(index_offset);
                entry.Offset = offset;
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 8;
            }
            var base_name = Path.GetFileNameWithoutExtension(file.Name);

            if (base_name.EndsWith("_scr", StringComparison.OrdinalIgnoreCase) &&
                KnownSchemes.Count > 0)
            {
                var encryption = QueryEncryption(file.Name);
                if (encryption != null)
                {
                    return(new ScrMedArchive(file, this, dir, encryption));
                }
            }
            return(new ArcFile(file, this, dir));
        }
예제 #14
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));
        }
예제 #15
0
파일: ArcBMX.cs 프로젝트: zxc120/GARbro
        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);
            }
            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 Entry {
                    Name   = string.Format("{0}#{1:D4}", base_name, i),
                    Offset = offset,
                };
                offset     = file.View.ReadUInt32(index_offset);
                entry.Size = (uint)(offset - entry.Offset);
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
            }
            foreach (var entry in dir)
            {
                uint signature = file.View.ReadUInt32(entry.Offset);
                entry.ChangeType(AutoEntry.DetectFileType(signature));
            }
            return(new ArcFile(file, this, dir));
        }
예제 #16
0
        internal void DetectFileTypes(ArcView file, IEnumerable <Entry> dir)
        {
            var buffer = new byte[4];

            foreach (var entry in dir.Where(e => e.Size > 4))
            {
                file.View.Read(entry.Offset, buffer, 0, 4);
                Decrypt(buffer);
                uint signature = buffer.ToUInt32(0);
                var  res       = AutoEntry.DetectFileType(signature);
                entry.ChangeType(res);
            }
        }
예제 #17
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt16(0);

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

            if (next_offset != count * 4 + 6)
            {
                return(null);
            }
            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 Entry {
                    Name   = string.Format("{0}#{1:D4}", base_name, i),
                    Offset = next_offset,
                };
                next_offset = file.View.ReadUInt32(index_offset);
                if (next_offset < entry.Offset)
                {
                    return(null);
                }
                entry.Size = (uint)(next_offset - entry.Offset);
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
            }
            foreach (var entry in dir)
            {
                uint signature = file.View.ReadUInt32(entry.Offset);
                if ((signature & 0xFFFF) == 0x4246) // 'FB'
                {
                    entry.Type = "image";
                }
                else
                {
                    entry.ChangeType(AutoEntry.DetectFileType(signature));
                }
            }
            return(new ArcFile(file, this, dir));
        }
예제 #18
0
파일: ArcGPC.cs 프로젝트: zxc120/GARbro
 void DetectFileTypes(ArcView file, List <Entry> dir)
 {
     using (var input = file.CreateStream())
     {
         var buffer = new byte[0x10];
         foreach (PackedEntry entry in dir)
         {
             input.Position = entry.Offset;
             uint packed_size = input.ReadUInt32();
             entry.UnpackedSize = input.ReadUInt32();
             entry.Offset      += 8;
             if (0 == packed_size)
             {
                 entry.Size = entry.UnpackedSize;
             }
             else
             {
                 entry.IsPacked = true;
                 entry.Size     = packed_size;
             }
             if (entry.Size < 0x10)
             {
                 continue;
             }
             uint signature;
             if (entry.IsPacked)
             {
                 UnpackEntry(input, buffer);
                 signature = LittleEndian.ToUInt32(buffer, 0);
             }
             else
             {
                 signature = input.ReadUInt32();
             }
             IResource res;
             if (0x020000 == signature || 0x0A0000 == signature)
             {
                 res = ImageFormat.Tga;
             }
             else
             {
                 res = AutoEntry.DetectFileType(signature);
             }
             if (null != res)
             {
                 entry.ChangeType(res);
             }
         }
     }
 }
예제 #19
0
파일: ArcODN.cs 프로젝트: zxc120/GARbro
        void FixupDir()
        {
            for (int i = 0; i < m_dir.Count; ++i)
            {
                var entry = (OdnEntry)m_dir[i];

                long next_offset = i + 1 < m_dir.Count ? m_dir[i + 1].Offset : m_file.MaxOffset;
                entry.Size = (uint)(next_offset - entry.Offset);

                if (OdnOpener.Image24NameRe.IsMatch(entry.Name))
                {
                    entry.Type = "image";
                }
                else if (OdnOpener.ScriptNameRe.IsMatch(entry.Name))
                {
                    entry.Type        = "script";
                    entry.IsEncrypted = m_scripts_encrypted;
                }
                else if (OdnOpener.AudioNameRe.IsMatch(entry.Name))
                {
                    entry.Type = "audio";
                }
                else if (entry.Size > 4)
                {
                    var       signature = m_file.View.ReadUInt32(entry.Offset);
                    IResource res       = null;
                    if (0x5E6A6A42 == signature)
                    {
                        res = OggAudio.Instance;
                    }
                    else if (AudioFormat.Wav.Signature == signature)
                    {
                        res = AudioFormat.Wav;
                    }
                    else
                    {
                        res = AutoEntry.DetectFileType(signature);
                    }
                    if (res != null)
                    {
                        entry.ChangeType(res);
                    }
                    else if (OdnOpener.Image32NameRe.IsMatch(entry.Name))
                    {
                        entry.Type = "image";
                    }
                }
            }
        }
예제 #20
0
파일: ArcAil.cs 프로젝트: zxc120/GARbro
 static void SetEntryType(Entry entry, uint signature)
 {
     if (0xBA010000 == signature)
     {
         entry.Type = "video";
         entry.Name = Path.ChangeExtension(entry.Name, "mpg");
     }
     else
     {
         var res = AutoEntry.DetectFileType(signature);
         if (null != res)
         {
             entry.ChangeType(res);
         }
     }
 }
예제 #21
0
파일: ArcHXP.cs 프로젝트: zxc120/GARbro
 static protected void DetectFileTypes(ArcView file, List <Entry> dir)
 {
     byte[] signature_buffer = new byte[4];
     foreach (PackedEntry entry in dir)
     {
         uint packed_size   = file.View.ReadUInt32(entry.Offset);
         uint unpacked_size = file.View.ReadUInt32(entry.Offset + 4);
         entry.IsPacked = 0 != packed_size;
         if (!entry.IsPacked)
         {
             packed_size = unpacked_size;
         }
         entry.Size         = packed_size;
         entry.UnpackedSize = unpacked_size;
         entry.Offset      += 8;
         uint signature;
         if (entry.IsPacked)
         {
             using (var input = file.CreateStream(entry.Offset, Math.Min(packed_size, 0x20u)))
                 using (var reader = new ShsCompression(input))
                 {
                     reader.Unpack(signature_buffer);
                     signature = LittleEndian.ToUInt32(signature_buffer, 0);
                 }
         }
         else
         {
             signature = file.View.ReadUInt32(entry.Offset);
         }
         if (0 != signature)
         {
             IResource res;
             if (0x020000 == signature || 0x0A0000 == signature)
             {
                 res = ImageFormat.Tga;
             }
             else
             {
                 res = AutoEntry.DetectFileType(signature);
             }
             if (res != null)
             {
                 entry.ChangeType(res);
             }
         }
     }
 }
예제 #22
0
파일: ArcXARC.cs 프로젝트: zxc120/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(4);

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

            uint index_offset = 8;
            uint first_offset = file.View.ReadUInt32(index_offset);

            if ((uint)count * 4 + 10 != first_offset)
            {
                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 Entry {
                    Offset = file.View.ReadUInt32(index_offset)
                };
                dir.Add(entry);
                index_offset += 4;
            }
            foreach (var entry in dir)
            {
                if (!file.View.AsciiEqual(entry.Offset, "DATA"))
                {
                    return(null);
                }
                uint name_length = file.View.ReadUInt16(entry.Offset + 0x18);
                entry.Size = file.View.ReadUInt32(entry.Offset + 0x1C);
                var name = file.View.ReadBytes(entry.Offset + 0x20, name_length);
                entry.Name    = DecryptName(name);
                entry.Offset += 0x22 + name_length;
                uint signature = file.View.ReadUInt32(entry.Offset);
                var  res       = AutoEntry.DetectFileType(signature);
                if (res != null)
                {
                    entry.Type = res.Type;
                }
            }
            return(new ArcFile(file, this, dir));
        }
예제 #23
0
파일: ArcDDP.cs 프로젝트: zxc120/GARbro
 internal static void DetectFileTypes(ArcView file, List <Entry> dir)
 {
     byte[] signature_buffer = new byte[4];
     foreach (PackedEntry entry in dir)
     {
         uint signature;
         if (entry.IsPacked)
         {
             using (var input = file.CreateStream(entry.Offset, Math.Min(entry.Size, 0x20u)))
                 using (var reader = new ShsCompression(input))
                 {
                     reader.Unpack(signature_buffer);
                     signature = LittleEndian.ToUInt32(signature_buffer, 0);
                 }
         }
         else
         {
             signature = file.View.ReadUInt32(entry.Offset);
         }
         if (0x78534444 == signature) // 'DDSx'
         {
             entry.Type = "script";
             entry.Name = Path.ChangeExtension(entry.Name, "hxb");
         }
         else if (0 != signature)
         {
             IResource res;
             if (0x020000 == signature || 0x0A0000 == signature)
             {
                 res = ImageFormat.Tga;
             }
             else
             {
                 res = AutoEntry.DetectFileType(signature);
             }
             if (res != null)
             {
                 entry.ChangeType(res);
             }
         }
     }
 }
예제 #24
0
파일: ArcARC2.cs 프로젝트: ziyuejun/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(4);

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

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

            for (int i = 0; i < count; ++i)
            {
                var name = file.View.ReadString(index_offset, 0x10);
                if (names.Add(name))
                {
                    var entry = Create <Arc2Entry> (name);
                    entry.Offset = file.View.ReadUInt32(index_offset + 0x10);
                    entry.Size   = file.View.ReadUInt32(index_offset + 0x14);
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    entry.Key1 = file.View.ReadUInt32(index_offset + 0x18);
                    entry.Key2 = file.View.ReadUInt32(index_offset + 0x1C);
                    dir.Add(entry);
                }
                index_offset += 0x20;
            }
            foreach (Arc2Entry entry in dir)
            {
                uint signature = file.View.ReadUInt32(entry.Offset) - (entry.Key1 + entry.Key2);
                entry.ChangeType(AutoEntry.DetectFileType(signature));
            }
            return(new ArcFile(file, this, dir));
        }
예제 #25
0
파일: ArcCLS.cs 프로젝트: zxc120/GARbro
 void DetectFileTypes(ArcView file, IEnumerable <Entry> dir)
 {
     foreach (var entry in dir)
     {
         uint signature = file.View.ReadUInt32(entry.Offset);
         if (0x5F534C43 == signature) // 'CLS_'
         {
             if (file.View.AsciiEqual(entry.Offset + 4, "TEXFILE"))
             {
                 entry.Type = "image";
             }
         }
         else
         {
             var res = AutoEntry.DetectFileType(signature);
             if (res != null)
             {
                 entry.ChangeType(res);
             }
         }
     }
 }
예제 #26
0
        void DetectFileTypes(List <Entry> dir, ArcView file)
        {
            var type = new byte[3];

            foreach (PackedEntry entry in dir)
            {
                uint signature = file.View.ReadUInt32(entry.Offset);
                if (signature != 0x34655A4C) // 'LZe4'
                {
                    entry.ChangeType(AutoEntry.DetectFileType(signature));
                }
                else if (entry.Size > 0x40)
                {
                    entry.IsPacked     = true;
                    entry.UnpackedSize = file.View.ReadUInt32(entry.Offset + 8);
                    file.View.Read(entry.Offset + 0xC, type, 0, 3);
                    if (type.AsciiEqual("000"))
                    {
                        entry.Type = "audio"; // either WAV or MIDI
                    }
                    else
                    {
                        DecryptType(type);
                        if (type.AsciiEqual("BMP"))
                        {
                            entry.ChangeType(ImageFormat.Bmp);
                        }
                        else if (type.AsciiEqual("WAV"))
                        {
                            entry.ChangeType(AudioFormat.Wav);
                        }
                        else if (type.AsciiEqual("MID"))
                        {
                            entry.Name = Path.ChangeExtension(entry.Name, "mid");
                        }
                    }
                }
            }
        }
예제 #27
0
 void DetectFileTypes(ArcView file, List <Entry> dir)
 {
     foreach (var entry in dir.Where(e => string.IsNullOrEmpty(e.Type)))
     {
         uint signature = file.View.ReadUInt32(entry.Offset);
         if (0x05304148 == signature)
         {
             entry.Type = "image";
             continue;
         }
         else if (0x304148 == (signature & 0xFFFFFF))
         {
             uint encryption = file.View.ReadUInt32(entry.Offset + 8);
             long offset     = entry.Offset + 0x10 + (signature >> 24);
             if (0 != encryption)
             {
                 if (4 == encryption)
                 {
                     uint bits = Binary.BigEndian(file.View.ReadUInt32(offset + 8));
                     if (bits > entry.Size)
                     {
                         continue;
                     }
                     if (file.View.AsciiEqual(offset + 12 + bits, "BM"))
                     {
                         entry.ChangeType(ImageFormat.Bmp);
                     }
                     else if (file.View.AsciiEqual(entry.Offset + entry.Size - 0x12, "TRUEVISION"))
                     {
                         entry.ChangeType(ImageFormat.Tga);
                     }
                 }
                 continue;
             }
             signature = file.View.ReadUInt32(offset);
         }
         entry.ChangeType(AutoEntry.DetectFileType(signature));
     }
 }
예제 #28
0
        void DetectTypes(ArcView file, List <Entry> dir, NekoXCode dec)
        {
            byte[] buffer = new byte[8];
            foreach (var entry in dir.Where(e => string.IsNullOrEmpty(e.Type)))
            {
                if (entry.Name.EndsWith(".txt", StringComparison.InvariantCultureIgnoreCase))
                {
                    entry.Type = "script";
                    continue;
                }
                uint key = file.View.ReadUInt32(entry.Offset);
                file.View.Read(entry.Offset + 12, buffer, 0, 8);
                dec.Decrypt(key, buffer, 0, 8);
                uint   signature = LittleEndian.ToUInt32(buffer, 0);
                var    res       = AutoEntry.DetectFileType(signature);
                string ext       = "";
                if (res != null)
                {
                    ext        = res.Extensions.FirstOrDefault();
                    entry.Type = res.Type;
                }
                else if (0x474e4d8a == signature)
                {
                    ext = "mng";
                }
                else if (entry.Name.StartsWith("script/"))
                {
                    entry.Type = "script";
                }

                if (!string.IsNullOrEmpty(ext))
                {
                    entry.Name = Path.ChangeExtension(entry.Name, ext);
                }
            }
        }
예제 #29
0
        public override ArcFile TryOpen(ArcView file)
        {
            int version;

            if (file.View.AsciiEqual(4, "1.00"))
            {
                version = 100;
            }
            else if (file.View.AsciiEqual(4, "1.10"))
            {
                version = 110;
            }
            else
            {
                return(null);
            }
            int count = file.View.ReadInt32(0x14);

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

            int  bucket_count = file.View.ReadInt32(0x18);
            uint index_size   = file.View.ReadUInt32(0x1C);
            uint arc_seed     = file.View.ReadUInt32(0x20);
            long index_offset = version >= 110 ? 0x2C : 0x24;
            long base_offset  = index_offset + index_size;
            var  blowfish     = new Blowfish(IndexKey);
            var  packed_bytes = file.View.ReadBytes(index_offset, index_size);

            blowfish.Decipher(packed_bytes, packed_bytes.Length & ~7);

            using (var input = new MemoryStream(packed_bytes))
                using (var unpacked = new ZLibStream(input, CompressionMode.Decompress))
                    using (var index = new BinaryReader(unpacked))
                    {
                        var file_map  = BuildFileNameMap(arc_seed);
                        var dir_table = new List <TacBucket> (bucket_count);
                        for (int i = 0; i < bucket_count; ++i)
                        {
                            var entry = new TacBucket();
                            entry.Hash  = index.ReadUInt16();
                            entry.Count = index.ReadUInt16();
                            entry.Index = index.ReadInt32();
                            dir_table.Add(entry);
                        }
                        var dir = new List <Entry> (count);
                        for (int i = 0; i < count; ++i)
                        {
                            var entry = new TacEntry();
                            entry.Hash         = index.ReadUInt64();
                            entry.IsPacked     = index.ReadInt32() != 0;
                            entry.UnpackedSize = index.ReadUInt32();
                            entry.Offset       = base_offset + index.ReadUInt32();
                            entry.Size         = index.ReadUInt32();
                            if (!entry.CheckPlacement(file.MaxOffset))
                            {
                                return(null);
                            }
                            dir.Add(entry);
                        }
                        var buffer = new byte[8];
                        foreach (var bucket in dir_table)
                        {
                            for (int i = 0; i < bucket.Count; ++i)
                            {
                                var entry = dir[bucket.Index + i] as TacEntry;
                                entry.Hash = entry.Hash << 16 | bucket.Hash;
                                bool known_name = file_map.ContainsKey(entry.Hash);
                                if (known_name)
                                {
                                    entry.Name = file_map[entry.Hash];
                                    entry.Type = FormatCatalog.Instance.GetTypeFromName(entry.Name);
                                }
                                else
                                {
                                    entry.Name = string.Format("{0:X16}", entry.Hash);
                                }
                                if (entry.IsPacked)
                                {
                                    continue;
                                }
                                entry.Key = Encoding.ASCII.GetBytes(string.Format("{0}_tlib_secure_", entry.Hash));
                                if (!known_name)
                                {
                                    var bf = new Blowfish(entry.Key);
                                    file.View.Read(entry.Offset, buffer, 0, 8);
                                    bf.Decipher(buffer, 8);
                                    var res = AutoEntry.DetectFileType(buffer.ToUInt32(0));
                                    if (res != null)
                                    {
                                        entry.ChangeType(res);
                                    }
                                }
                                if ("image" == entry.Type)
                                {
                                    entry.EncryptedSize = Math.Min(10240, entry.Size);
                                }
                                else
                                {
                                    entry.EncryptedSize = entry.Size;
                                }
                            }
                        }
                        return(new ArcFile(file, this, dir));
                    }
        }
예제 #30
0
        public override ArcFile TryOpen(ArcView file)
        {
            if ('H' != file.View.ReadByte(4))
            {
                return(null);
            }
            uint index_offset = 0x10;
            uint data_offset  = file.View.ReadUInt32(index_offset);
            var  base_name    = Path.GetFileNameWithoutExtension(file.Name).ToUpperInvariant();

            if (0 == data_offset && "TP" == base_name)
            {
                var ext = Path.GetExtension(file.Name).TrimStart('.');
                int version;
                if (int.TryParse(ext, out version) && version >= 55)
                {
                    return(OpenTp055Arc(file));
                }
                else
                {
                    return(OpenTpArc(file));
                }
            }
            if (data_offset < index_offset || data_offset >= file.MaxOffset)
            {
                return(null);
            }
            int count = (int)(data_offset - index_offset) / 4;

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

            uint next_offset = data_offset;
            bool is_bgm      = "BGM" == base_name;
            bool is_pic      = "PIC" == base_name;
            var  dir         = new List <Entry> (count);

            for (int i = 0; next_offset != file.MaxOffset && i < count; ++i)
            {
                index_offset += 4;
                var name   = string.Format("{0}#{1:D5}", base_name, i);
                var offset = next_offset;
                next_offset = index_offset == data_offset ? 0 : file.View.ReadUInt32(index_offset);
                if (uint.MaxValue == next_offset || next_offset < offset)
                {
                    break;
                }
                uint size = next_offset - offset;
                if (size < 4)
                {
                    continue;
                }
                Entry entry;
                if (is_pic)
                {
                    entry = new Entry {
                        Name = name, Type = "image"
                    }
                }
                ;
                else if (is_bgm)
                {
                    entry = new Entry {
                        Name = name + ".wav", Type = "audio"
                    }
                }
                ;
                else
                {
                    entry = new AutoEntry(name, () => {
                        uint signature = file.View.ReadUInt32(offset);
                        uint s16       = signature & 0xFFFF;
                        if (1 == s16 || 3 == s16 || 4 == s16)
                        {
                            return(s_PicFormat.Value);
                        }
                        if (size > 0x200 && (size >> 9) == (signature >> 9))
                        {
                            return(AudioFormat.Wav);
                        }
                        return(AutoEntry.DetectFileType(signature));
                    });
                }

                entry.Offset = offset;
                entry.Size   = size;
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
            }
            if (0 == dir.Count)
            {
                return(null);
            }
            return(new ArcFile(file, this, dir));
        }