コード例 #1
0
        ArcFile Open(byte[] basename, ArcView file, EncryptionScheme scheme, Key key)
        {
            uint key1 = scheme.BaseKey.Key1;
            uint key2 = scheme.BaseKey.Key2;

            for (int b = 0, e = basename.Length - 1; e >= 0; ++b, --e)
            {
                key1 ^= basename[e];
                key2 ^= basename[b];
                key1  = Binary.RotR(key1, 7);
                key2  = Binary.RotL(key2, 7);
            }
            if (null != key)
            {
                key1 ^= key.Key1;
                key2 ^= key.Key2;
            }
            uint code       = file.View.ReadUInt32(4) ^ key2;
            int  index_size = (int)(code & 0xffffff);
            byte flags      = (byte)(code >> 24);

            if (0 != (flags & 1))
            {
                index_size = (index_size << 11) - 8;
            }
            if (index_size < 5 || index_size >= file.MaxOffset)
            {
                return(null);
            }
            var index = new byte[index_size];

            if (index_size != file.View.Read(8, index, 0, (uint)index_size))
            {
                return(null);
            }
            scheme.DecryptIndex(index, index_size, key2);
            var lpk_info = new LpkInfo
            {
                AlignedOffset = 0 != (flags & 1),
                Flag1         = 0 != (flags & 2),
                IsEncrypted   = 0 != (flags & 4),
                PackedEntries = 0 != (flags & 8),
                WholeCrypt    = 0 != (flags & 0x10),
                Key           = key1
            };
            var reader = new IndexReader(lpk_info);
            var dir    = reader.Read(index);

            if (null == dir)
            {
                return(null);
            }
            // this condition is fishy, probably patch files have additional bitflag set
            if (lpk_info.WholeCrypt && Binary.AsciiEqual(basename, "PATCH"))
            {
                lpk_info.WholeCrypt = false;
            }
            return(new LuciArchive(file, this, dir, scheme, reader.Info));
        }