Example #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));
    }
Example #2
0
        private void FlushFile(int i)
        {
            if (m_Items[i] is GrfDirectoryInfo)
            {
                return;
            }

            GrfFileInfo gfile = (GrfFileInfo)m_Items[i];

            byte[] buf = ZlibStream.CompressBuffer(gfile.Data);
            gfile.CompressedLength        = buf.Length;
            gfile.AlignedCompressedLength = gfile.CompressedLength;

            if ((gfile.Flags & (GrfFileFlags.MixCrypt | GrfFileFlags.Des_0x14)) != GrfFileFlags.None)
            {
                gfile.AlignedCompressedLength += gfile.CompressedLength % 8;
                Array.Resize <byte>(ref buf, gfile.AlignedCompressedLength);
                buf = GrfCrypt.EncryptFileBuffer(buf, gfile.CompressedLength, gfile.Flags);
            }

            int writeOffset = m_Items.FindUnused(gfile.AlignedCompressedLength);

            if (writeOffset == 0)
            {
                // grf_find_unused returned 0 -> append
                FileStream.Seek(0, SeekOrigin.End);
            }
            else
            {
                FileStream.Seek(writeOffset, SeekOrigin.Begin);
            }

            gfile.Position = (int)FileStream.Position;

            FileStream.Write(buf, 0, buf.Length);
        }
Example #3
0
        private void FlushVer1()
        {
            byte[]      buffer = new byte[m_Items.Count * GRF_ITEM_SIZE];
            int         i, offset, len, writeOffset;
            GrfFileInfo gfile = null;

            try
            {
                m_Items.SortToPosition();

                using (IntPtrEx pBuffer = new IntPtrEx(buffer))
                {
                    for (i = offset = 0; i < Items.Count; i++)
                    {
                        if (m_Items[i] is GrfFileInfo)
                        {
                            gfile = (GrfFileInfo)m_Items[i];

                            if (m_ForceRepack)
                            {
                                gfile.CompressedLength        = 0;
                                gfile.AlignedCompressedLength = 0;
                                gfile.Position = 0;
                            }

                            if (gfile.CompressedLength == 0 &&
                                gfile.AlignedCompressedLength == 0 &&
                                gfile.Position == 0 &&
                                gfile.Length != 0)
                            {
                                if (gfile.CheckExtension())
                                {
                                    gfile.Flags = (gfile.Flags & ~GrfFileFlags.MixCrypt) | GrfFileFlags.Des_0x14;
                                }
                                else
                                {
                                    gfile.Flags = (gfile.Flags & ~GrfFileFlags.Des_0x14) | GrfFileFlags.MixCrypt;
                                }

                                FlushFile(i);
                            }
                        }

                        len = m_Items[i].FullName.Length + 1;
                        if (m_IntVersion < 0x101)
                        {
                            pBuffer.Write <int>(offset, len);
                            SwapNibbles(pBuffer + offset + 4, m_Items[i].FullName, len);
                            offset += 4 + len;
                        }
                        else if (m_IntVersion < 0x104)
                        {
                            pBuffer.Write <int>(offset, len + 6);
                            offset += 4;
                            SwapNibbles(pBuffer + offset + 6, GrfCrypt.EncryptNameVer1(m_Items[i].Name, len), len);
                            offset += len + 6;
                        }

                        if (m_Items[i] is GrfDirectoryInfo)
                        {
                            pBuffer.Write <int>(offset, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_SZSMALL + GrfItem.GRFFILE_DIR_SZORIG + 0x02CB));
                            pBuffer.Write <int>(offset + 4, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_SZFILE + 0x92CB));
                            pBuffer.Write <int>(offset + 8, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_SZORIG));
                            pBuffer.Write <int>(offset + 0xD, EndianConverter.LittleEndian(GrfItem.GRFFILE_DIR_OFFSET - GRF_HEADER_FULL_LEN));
                        }
                        else
                        {
                            pBuffer.Write <int>(offset, EndianConverter.LittleEndian(gfile.CompressedLength + gfile.Length + 0x02CB));
                            pBuffer.Write <int>(offset + 4, EndianConverter.LittleEndian(gfile.AlignedCompressedLength + 0x92CB));
                            pBuffer.Write <int>(offset + 8, EndianConverter.LittleEndian(gfile.Length));
                            pBuffer.Write <int>(offset + 0xD, EndianConverter.LittleEndian(gfile.Position - GRF_HEADER_FULL_LEN));
                        }

                        pBuffer.Write <byte>(offset + 0xC, (byte)(m_Items[i].Flags & GrfFileFlags.File));

                        offset += 0x11;
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            FileStream.Seek(0, SeekOrigin.End);
            writeOffset = (int)FileStream.Position;
            FileStream.Write(buffer, 0, offset);
            FileStream.Seek(GRF_HEADER_MID_LEN, SeekOrigin.End);

            FileStream.Write(BitConverter.GetBytes(EndianConverter.LittleEndian(writeOffset - GRF_HEADER_FULL_LEN)), 0, 4);
            FileStream.Write(BitConverter.GetBytes(0), 0, 4);
            FileStream.Write(BitConverter.GetBytes(EndianConverter.LittleEndian(i + 0 + 7)), 0, 4);
        }
Example #4
0
        private void ReadVer1Info()
        {
            if (m_IntVersion > 0x103)
            {
                throw new GrfException();
            }

            int offset = (int)FileStream.Position;
            int len2, len = (int)FileStream.Length - offset;

            byte[] buffer = new byte[len], namebuf = new byte[GRF_NAMELEN];

            try
            {
                FileStream.Read(buffer, 0, len);

                string  name = null;
                GrfItem item;

                using (IntPtrEx pBuffer = new IntPtrEx(buffer))
                {
                    for (int i = offset = 0; i < m_Items.Capacity; i++)
                    {
                        len     = EndianConverter.LittleEndian(pBuffer.Read <int>(offset));
                        offset += 4;

                        if (m_IntVersion < 0x101)
                        {
                            len2 = pBuffer.Read <string>(offset).Length;
                            if (len2 >= GRF_NAMELEN)
                            {
                                throw new GrfException();
                            }

                            name = SwapNibbles(pBuffer + offset, len2);
                        }
                        else if (m_IntVersion < 0x104)
                        {
                            offset += 2;
                            len2    = len - 6;
                            if (len2 >= GRF_NAMELEN)
                            {
                                throw new GrfException();
                            }

                            SwapNibbles(namebuf, pBuffer + offset, len2);
                            name = GrfCrypt.DecryptNameVer1(namebuf, len2);

                            len -= 2;
                        }

                        offset += len;

                        item = GrfItem.CreateV1
                               (
                            this,
                            name,
                            EndianConverter.LittleEndian(pBuffer.Read <int>(offset)) - EndianConverter.LittleEndian(pBuffer.Read <int>(offset + 8)) - 0x02CB,
                            EndianConverter.LittleEndian(pBuffer.Read <int>(offset + 4)) - 0x92CB,
                            EndianConverter.LittleEndian(pBuffer.Read <int>(offset + 8)),
                            (GrfFileFlags)pBuffer[offset + 0xC],
                            EndianConverter.LittleEndian(pBuffer.Read <int>(offset + 0xD)) + GRF_HEADER_FULL_LEN
                               );

                        m_Items.GrfAdd(item);

                        offset += 0x11;
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }