Exemple #1
0
        private byte[] getFileZBlock(GrfFile file)
        {
            /* Get new stream */
            var stream = FileManager.Load(filename) as Stream;

            if (stream == null)
            {
                throw new Exception("GE_ERRNO");
            }

            byte[] data;
            using (var br = new System.IO.BinaryReader(stream))
            {
                br.BaseStream.Seek(file.pos, SeekOrigin.Begin);
                data = br.ReadBytes((int)file.compressed_len_aligned);
            }

            byte[] keyschedule = new byte[0x80];

            return(GrfCrypt.GRFProcess(data, file.compressed_len_aligned, file.flags, file.compressed_len, keyschedule));
        }
Exemple #2
0
        public byte[] GetData(GrfFile file)
        {
            //not a file
            if (file.IsDir())
            {
                return(null);
            }

            //empty file
            if (file.real_len == 0)
            {
                return(null);
            }

            //check if data was already extracted
            if (file.data != null)
            {
                return(file.data);
            }

            /* Retrieve the unencrypted block */
            byte[] zbuf = getFileZBlock(file);
            if (zbuf == null)
            {
                return(null);
            }

            using (var stream = new InflaterInputStream(new MemoryStream(zbuf)))
            {
                file.data = new byte[file.real_len];

                stream.Read(file.data, 0, file.data.Length);
            }

            return(file.data);
        }
Exemple #3
0
        /*! \brief Private function to read GRF0x2xx headers
         *
         * Reads the information about files within the archive...
         * for archive versions 0x02xx
         *
         * \todo Find GRF versions other than just 0x200 (do any exist?)
         *
         * \param grf Pointer to the Grf struct to read to
         * \param error Pointer to a GrfErrorType struct/enum for error reporting
         * \param callback Function to call for each read file. It should return 0 if
         *		everything is fine, 1 if everything is fine (but further
         *		reading should stop), or -1 if there has been an error
         * \return 0 if everything went fine, 1 if something went wrong
         */
        static uint GRF_readVer2_info(System.IO.BinaryReader br, Grf grf, GrfOpenCallback callback)
        {
            uint i, offset, len, len2;

            byte[] buf, zbuf;

            /* Check grf */
            if (grf.version != 0x200)
            {
                throw new Exception("GE_NSUP");
            }

            /* Read the original and compressed sizes */
            buf = br.ReadBytes(8);

            /* Allocate memory and read the compressed file table */
            len  = GrfSupport.LittleEndian32(buf, 0);
            zbuf = br.ReadBytes((int)len);

            if (0 == (len2 = GrfSupport.LittleEndian32(buf, 4)))
            {
                return(0);
            }

            /* Allocate memory and uncompress the compressed file table */
            Array.Resize(ref buf, (int)len2);

            var stream = new InflaterInputStream(new MemoryStream(zbuf));

            stream.Read(buf, 0, buf.Length);

            stream.Close();

            /* Read information about each file */
            for (i = offset = 0; i < grf.nfiles; i++)
            {
                /* Grab the filename length */
                len = GrfSupport.getCStringLength(buf, offset) + 1;

                /* Make sure its not too large */
                if (len >= GrfTypes.GRF_NAMELEN)
                {
                    throw new Exception("GE_CORRUPTED");
                }

                /* Grab filename */
                GrfFile file = new GrfFile();
                file.name = GrfSupport.getCString(buf, offset);

                offset += len;

                /* Grab the rest of the information */
                file.compressed_len         = GrfSupport.LittleEndian32(buf, (int)offset);
                file.compressed_len_aligned = GrfSupport.LittleEndian32(buf, (int)offset + 4);
                file.real_len = GrfSupport.LittleEndian32(buf, (int)offset + 8);
                file.flags    = buf[offset + 0xC];
                file.pos      = GrfSupport.LittleEndian32(buf, (int)(offset + 0xD)) + (uint)GRF_HEADER_FULL_LEN;
                file.hash     = GrfSupport.GRF_NameHash(file.name);

                file.name = NormalizePath(file.name);

                grf.files.Add(file.name, file);

                /* Advance to the next file */
                offset += 0x11;

                /* Run the callback, if we have one */
                if (callback != null)
                {
                    callback.doCallback(file);

                    if (!callback.hasReturned())
                    {
                        throw new Exception("NO_RETURN");
                    }

                    if (callback.Response < 0)
                    {
                        /* Callback function had an error, so we
                         * have an error
                         */
                        return(1);
                    }
                    else if (callback.Response > 0)
                    {
                        /* Callback function found the file it needed,
                         * just exit now
                         */
                        return(0);
                    }
                }
            }

            /* Calling functions will set success...
             * GRF_SETERR(error,GE_SUCCESS,GRF_readVer2_info);
             */

            return(0);
        }
 public void doCallback(GrfFile file)
 {
     this.file = file;
     callback.Invoke(this);
 }