Beispiel #1
0
        /// <summary>
        /// Parses the WzDirectory
        /// <paramref name="lazyParse">Only parses the first directory</paramref>
        /// </summary>
        internal void ParseDirectory(bool lazyParse = false)
        {
            //Debug.WriteLine(HexTool.ToString( reader.ReadBytes(20)));
            //reader.BaseStream.Position = reader.BaseStream.Position - 20;
            long available = reader.Available();

            if (available == 0)
            {
                return;
            }

            int entryCount = reader.ReadCompressedInt();

            if (entryCount < 0 || entryCount > 100000) // probably nothing > 100k folders for now.
            {
                throw new Exception("Invalid wz version used for decryption, try parsing other version numbers.");
            }

            for (int i = 0; i < entryCount; i++)
            {
                byte   type  = reader.ReadByte();
                string fname = null;
                int    fsize;
                int    checksum;
                uint   offset;

                long rememberPos = 0;
                switch (type)
                {
                case 1:      //01 XX 00 00 00 00 00 OFFSET (4 bytes)
                {
                    int unknown = reader.ReadInt32();
                    reader.ReadInt16();
                    uint offs = reader.ReadOffset();
                    continue;
                }

                case 2:
                {
                    int stringOffset = reader.ReadInt32();
                    rememberPos = reader.BaseStream.Position;
                    reader.BaseStream.Position = reader.Header.FStart + stringOffset;
                    type  = reader.ReadByte();
                    fname = reader.ReadString();
                    break;
                }

                case 3:
                case 4:
                {
                    fname       = reader.ReadString();
                    rememberPos = reader.BaseStream.Position;
                    break;
                }

                default:
                {
                    throw new Exception("[WzDirectory] Unknown directory. type = " + type);
                }
                }
                reader.BaseStream.Position = rememberPos;
                fsize    = reader.ReadCompressedInt();
                checksum = reader.ReadCompressedInt();
                offset   = reader.ReadOffset(); // IWzArchive::Getposition(pArchive)

                if (type == 3)
                {
                    WzDirectory subDir = new WzDirectory(reader, fname, hash, WzIv, wzFile)
                    {
                        BlockSize = fsize,
                        Checksum  = checksum,
                        Offset    = offset,
                        Parent    = this
                    };
                    subDirs.Add(subDir);

                    if (lazyParse)
                    {
                        break;
                    }
                }
                else
                {
                    WzImage img = new WzImage(fname, reader, checksum)
                    {
                        BlockSize = fsize,
                        Offset    = offset,
                        Parent    = this
                    };
                    images.Add(img);

                    if (lazyParse)
                    {
                        break;
                    }
                }
            }

            foreach (WzDirectory subdir in subDirs)
            {
                if (subdir.Checksum != 0)
                {
                    reader.BaseStream.Position = subdir.offset;
                    subdir.ParseDirectory();
                }
            }
        }