예제 #1
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);
        }
예제 #2
0
        public override ArcFile TryOpen(ArcView file)
        {
            var first_offset = file.View.ReadUInt32(8);

            if (first_offset <= 0x14 || first_offset >= file.MaxOffset || first_offset > int.MaxValue)
            {
                return(null);
            }
            int index_size = (int)(first_offset - 4);
            var count      = index_size / 0x10;

            if (count * 0x10 != index_size)
            {
                return(null);
            }

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

            for (int i = 0; i < count; ++i)
            {
                var offset = file.View.ReadUInt32(index_offset + 4);
                if (0 == offset)
                {
                    break;
                }
                if (offset <= last_offset)
                {
                    return(null);
                }
                string name  = string.Format("{0}#{1:D4}", base_name, i);
                var    entry = new AutoEntry(name, () => {
                    uint signature = file.View.ReadUInt32(offset);
                    if (0 == signature)
                    {
                        return(null);
                    }
                    return(FormatCatalog.Instance.LookupSignature(signature).FirstOrDefault());
                });
                entry.Offset = offset;
                entry.Size   = file.View.ReadUInt32(index_offset);
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                last_offset   = offset;
                index_offset += 0x10;
            }
            if (0 == dir.Count)
            {
                return(null);
            }
            return(new ArcFile(file, this, dir));
        }
예제 #3
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));
        }
예제 #4
0
파일: ArcMAI.cs 프로젝트: zxc120/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            uint file_size = file.View.ReadUInt32(4);

            if (file_size != file.MaxOffset)
            {
                return(null);
            }
            int count = file.View.ReadInt32(8);

            if (count <= 0 || count > 0xfffff)
            {
                return(null);
            }
            int  dir_level    = file.View.ReadByte(0x0d);
            int  dir_entries  = file.View.ReadUInt16(0x0e);
            uint index_offset = 0x10;
            uint index_size   = (uint)(count * 0x18 + dir_entries * 8);

            if (index_size > file.View.Reserve(index_offset, index_size))
            {
                return(null);
            }
            List <DirEntry> folders = null;

            if (0 != dir_entries && 2 == dir_level)
            {
                folders = new List <DirEntry> (dir_entries);
                uint dir_offset = index_offset + (uint)count * 0x18;
                for (int i = 0; i < dir_entries; ++i)
                {
                    folders.Add(new DirEntry {
                        Name  = file.View.ReadString(dir_offset, 4),
                        Index = file.View.ReadInt32(dir_offset + 4)
                    });
                    dir_offset += 8;
                }
            }
            bool   is_mask_arc    = VFS.IsPathEqualsToFileName(file.Name, "mask.arc");
            var    dir            = new List <Entry> (count);
            int    next_folder    = null == folders ? count : folders[0].Index;
            int    folder         = 0;
            string current_folder = "";

            for (int i = 0; i < count; ++i)
            {
                while (i >= next_folder && folder < folders.Count)
                {
                    current_folder = folders[folder++].Name;
                    if (folders.Count == folder)
                    {
                        next_folder = count;
                    }
                    else
                    {
                        next_folder = folders[folder].Index;
                    }
                }
                string name = file.View.ReadString(index_offset, 0x10);
                if (0 == name.Length)
                {
                    return(null);
                }
                var offset = file.View.ReadUInt32(index_offset + 0x10);
                var entry  = new AutoEntry(Path.Combine(current_folder, name), () => {
                    if (is_mask_arc)
                    {
                        return(s_MskFormat.Value);
                    }
                    uint signature = file.View.ReadUInt32(offset);
                    switch (signature & 0xFFFF)
                    {
                    case 0x4D43: return(s_CmFormat.Value);

                    case 0x4D41: return(s_AmFormat.Value);

                    case 0x4D42: return(ImageFormat.Bmp);

                    default: return(AutoEntry.DetectFileType(signature));
                    }
                });
                entry.Offset = offset;
                entry.Size   = file.View.ReadUInt32(index_offset + 0x14);
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 0x18;
            }
            return(new ArcFile(file, this, dir));
        }
예제 #5
0
파일: ArcBIN.cs 프로젝트: Casidi/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            var first_offset = file.View.ReadUInt32 (8);
            if (first_offset <= 0x14 || first_offset >= file.MaxOffset || first_offset > int.MaxValue)
                return null;
            int index_size = (int)(first_offset - 4);
            var count = index_size / 0x10;
            if (count * 0x10 != index_size)
                return null;

            string base_name = Path.GetFileNameWithoutExtension (file.Name);
            uint index_offset = 4;
            uint last_offset = 0;
            var dir = new List<Entry> (count);
            for (int i = 0; i < count; ++i)
            {
                var offset = file.View.ReadUInt32 (index_offset+4);
                if (0 == offset)
                    break;
                if (offset <= last_offset)
                    return null;
                string name = string.Format ("{0}#{1:D4}", base_name, i);
                var entry = new AutoEntry (name, () => {
                    uint signature = file.View.ReadUInt32 (offset);
                    if (0 == signature) return null;
                    return FormatCatalog.Instance.LookupSignature (signature).FirstOrDefault();
                });
                entry.Offset = offset;
                entry.Size = file.View.ReadUInt32 (index_offset);
                if (!entry.CheckPlacement (file.MaxOffset))
                    return null;
                dir.Add (entry);
                last_offset = offset;
                index_offset += 0x10;
            }
            if (0 == dir.Count)
                return null;
            return new ArcFile (file, this, dir);
        }
예제 #6
0
파일: ArcMED.cs 프로젝트: Casidi/GARbro
        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.InvariantCultureIgnoreCase)
                && KnownSchemes.Count > 0)
            {
                var options = Query<MedOptions> (arcStrings.ArcEncryptedNotice);
                if (options.Encryption != null)
                    return new ScrMedArchive (file, this, dir, options.Encryption);
            }
            return new ArcFile (file, this, dir);
        }
예제 #7
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);
             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;
 }
예제 #8
0
        public override ArcFile TryOpen(ArcView file)
        {
            uint file_size = file.View.ReadUInt32(4);

            if (file_size != file.MaxOffset)
            {
                return(null);
            }
            int count = file.View.ReadInt32(8);

            if (count <= 0 || count > 0xfffff)
            {
                return(null);
            }
            int  dir_level    = file.View.ReadByte(0x0d);
            int  dir_entries  = file.View.ReadUInt16(0x0e);
            uint index_offset = 0x10;
            uint index_size   = (uint)(count * 0x18 + dir_entries * 8);

            if (index_size > file.View.Reserve(index_offset, index_size))
            {
                return(null);
            }
            List <DirEntry> folders = null;

            if (0 != dir_entries && 2 == dir_level)
            {
                folders = new List <DirEntry> (dir_entries);
                uint dir_offset = index_offset + (uint)count * 0x18;
                for (int i = 0; i < dir_entries; ++i)
                {
                    folders.Add(new DirEntry {
                        Name  = file.View.ReadString(dir_offset, 4),
                        Index = file.View.ReadInt32(dir_offset + 4)
                    });
                    dir_offset += 8;
                }
            }
            bool   is_mask_arc    = "mask.arc" == Path.GetFileName(file.Name).ToLowerInvariant();
            var    dir            = new List <Entry> (count);
            int    next_folder    = null == folders ? count : folders[0].Index;
            int    folder         = 0;
            string current_folder = "";

            for (int i = 0; i < count; ++i)
            {
                while (i >= next_folder && folder < folders.Count)
                {
                    current_folder = folders[folder++].Name;
                    if (folders.Count == folder)
                    {
                        next_folder = count;
                    }
                    else
                    {
                        next_folder = folders[folder].Index;
                    }
                }
                string name = file.View.ReadString(index_offset, 0x10);
                if (0 == name.Length)
                {
                    return(null);
                }
                var offset = file.View.ReadUInt32(index_offset + 0x10);
                var entry  = new AutoEntry(Path.Combine(current_folder, name), () => {
                    uint signature = file.View.ReadUInt32(offset);
                    if (is_mask_arc)
                    {
                        return(ImageFormat.FindByTag("MSK/MAI"));
                    }
                    else if (0x4d43 == (signature & 0xffff)) // 'CM'
                    {
                        return(ImageFormat.FindByTag("CM/MAI"));
                    }
                    else if (0x4d41 == (signature & 0xffff)) // 'AM'
                    {
                        return(ImageFormat.FindByTag("AM/MAI"));
                    }
                    else if (0x4d42 == (signature & 0xffff)) // 'BM'
                    {
                        return(ImageFormat.Bmp);
                    }
                    else if (signature != 0)
                    {
                        return(FormatCatalog.Instance.LookupSignature(signature).FirstOrDefault());
                    }
                    else
                    {
                        return(null);
                    }
                });
                entry.Offset = offset;
                entry.Size   = file.View.ReadUInt32(index_offset + 0x14);
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 0x18;
            }
            return(new ArcFile(file, this, dir));
        }