예제 #1
0
파일: arch.cs 프로젝트: bsv798/p3fes
        private int GetArchType(sio.BinaryReader br, long len, out int fileCount)
        {
            sio.MemoryStream ms;
            long prevPos;
            long lastPos;
            byte b;
            byte[] bb;
            int size;
            int i;
            bool tru;

            bb = new byte[0xfc];

            ms = (sio.MemoryStream)br.BaseStream;
            fileCount = 0;
            prevPos = ms.Position;
            lastPos = prevPos + len;
            if (lastPos < 0x4)
                return 0;

            if (br.ReadInt32() == 0x64)
            {
                fileCount = br.ReadInt32();
                size = (fileCount + 1) << 3;
                if (fileCount > 0)
                    if (br.ReadInt32() == size)
                    {
                        ms.Position += size - 0xc - 0x8;
                        size = br.ReadInt32() + br.ReadInt32();
                        if (size <= lastPos)
                            return 1;
                    }
            }

            fileCount = 0;
            ms.Position = prevPos;
            if (lastPos > 0xff)
            {
                while (ms.Position < lastPos)
                {
                    for (i = 0; i < bb.Length; i++)
                    {
                        b = br.ReadByte();
                        if (b == 0)
                            break;
                        else if ((b < 0x20) || (b > 0x7f))
                        {
                            i = 0;
                            break;
                        }
                        bb[i] = b;
                    }
                    if (i > 0)
                    {
                        if (!stre.Regex.IsMatch(ste.ASCII.GetString(bb, 0, i), "^(\\w*[/.]*){1,}.\\w+$"))
                            break;
                    }
                    else if (fileCount == 0)
                        break;
                    ms.Position += bb.Length - i - 1;
                    size = br.ReadInt32();
                    if (size < 0 || size > lastPos)
                        break;
                    ms.Position += size;
                    ms.AlignPos(0x40);
                    if (size == 0)
                        if (fileCount == 0)
                            break;
                        else
                            if (lastPos - ms.Position < 0x800)
                                return 2;
                    fileCount++;
                }
                if (fileCount > 0)
                    if (ms.Position == lastPos)
                        return 2;
            }

            fileCount = 0;
            ms.Position = prevPos;
            if (br.ReadInt32() == 1)
                if (br.ReadInt32() == 0)
                    if (br.ReadInt32() == 0x30525053)
                        if (br.ReadInt32() == 0x20)
                            if (br.ReadInt32() - len - 0x4 < 0x40)
                            {
                                fileCount = br.ReadInt16();
                                return 3;
                            }
            #if DEBUG
                            else
                                throw new ArgumentException("spr0 size mismatch!");
                        else
                            throw new ArgumentException("spr0 header size mismatch!");
            #endif

            fileCount = 0;
            ms.Position = prevPos;
            if (br.ReadInt32() == 0)
                if (br.ReadInt32() - len - 0x4 < 0x40)
                    if (br.ReadInt32() == 0x31444D50) //pmd1
                        if (br.ReadInt32() == 0)
                        {
                            fileCount = br.ReadInt32();
                            if (br.ReadInt32() == 0x3)
                                return 4;
            #if DEBUG
                            else
                                throw new ArgumentException("pmd1 flag mismatch!");
            #endif
                        }

            fileCount = 0;
            ms.Position = prevPos;
            if (br.ReadInt32() == 0x9)
                if (br.ReadInt32() - len - 0x4 < 0x40)
                    if (br.ReadInt32() == 0x30505854) //txp0
                        if (br.ReadInt32() == 0)
                        {
                            fileCount = br.ReadInt32();
                            return 5;
                        }

            fileCount = 0;
            ms.Position = prevPos;
            if (br.ReadInt32() == 1)
            {
                br.ReadInt32();
                if (br.ReadInt32() == 0x30424950) //pib0
                    if (br.ReadInt32() == 0)
                        return 6;
            }

            if (len > 0x80)
            {
                fileCount = 0; //epl
                ms.Position = prevPos + 0x44;
                tru = (br.ReadInt32() & 0x40a00000) == 0x40a00000;
                ms.Position += 0x4;
                tru &= br.ReadInt32() == 0x3f800000;
                ms.Position += 0xc;
                tru &= br.ReadInt32() == 0x3f800000;
                ms.Position += 0x28;
                tru &= br.ReadInt32() == 0x90;
                if (tru)
                    return 7;
            }

            fileCount = 0; //rmd
            ms.Position = prevPos;
            if (br.ReadUInt32() == 0xf0f000f0)
            {
                if (br.ReadInt32() == 0x2)
                    if (br.ReadInt32() == 0x40000000)
                        return 7;
            }
            else
            {
                ms.Position = prevPos;
                tru = br.ReadInt32() == 0x16;
                ms.Position += 0x8;
                tru &= br.ReadInt32() == 1;
                i = br.ReadInt32();
                if ((i > -1) && ((i + ms.Position + 0x4) < lastPos))
                {
                    ms.Position += 0x4 + i;
                    if (ms.Position < lastPos)
                        tru &= br.ReadInt32() == 0x15;
                    else
                        tru = false;
                    if (tru)
                        return 7;
                }
            }

            fileCount = 0;
            ms.Position = prevPos;
            if (br.ReadInt32() == 0x34444542) //bed4
                if (br.ReadInt32() == 0x3030)
                {
                    br.ReadInt32();
                    if (br.ReadInt32() == 0)
                        return 7;
                }

            fileCount = 0;
            ms.Position = prevPos;
            if (br.ReadInt32() == 0x004E4943)
                if (br.ReadInt32() == 1)
                    return 8;

            return 0;
        }