Example #1
0
        private void ReadDirEntries(byte[] buffer, BlockInfo block, RDAMemoryResidentHelper mrm)
        {
            MemoryStream memoryStream = new MemoryStream(buffer);
            BinaryReader reader       = new BinaryReader(memoryStream);

            for (uint fileId = 0; fileId < block.fileCount; ++fileId)
            {
                byte[] fileNameBytes  = reader.ReadBytes((int)DirEntry.GetFilenameSize());
                string fileNameString = Encoding.Unicode.GetString(fileNameBytes).Replace("\0", "");

                DirEntry dirEntry = new DirEntry
                {
                    filename   = fileNameString,
                    offset     = ReadUIntVersionAware(reader),
                    compressed = ReadUIntVersionAware(reader),
                    filesize   = ReadUIntVersionAware(reader),
                    timestamp  = ReadUIntVersionAware(reader),
                    unknown    = ReadUIntVersionAware(reader),
                };

                RDAFile rdaFile = RDAFile.FromUnmanaged(fileHeader.version, dirEntry, block, read, mrm);
                rdaFileEntries.Add(rdaFile);
            }
        }
Example #2
0
        private ulong ReadBlock(ulong Offset, ulong beginningOfDataSection)
        {
            UpdateOutput("----- Reading Block at " + Offset);
            read.BaseStream.Position = (long)Offset;

            BlockInfo blockInfo = new BlockInfo
            {
                flags            = read.ReadUInt32(),
                fileCount        = read.ReadUInt32(),
                directorySize    = ReadUIntVersionAware(read),
                decompressedSize = ReadUIntVersionAware(read),
                nextBlock        = ReadUIntVersionAware(read),
            };

            if ((blockInfo.flags & 8) != 8)
            {
                bool isMemoryResident = false;
                bool isEncrypted      = false;
                bool isCompressed     = false;
                if ((blockInfo.flags & 4) == 4)
                {
                    UpdateOutput("MemoryResident");
                    isMemoryResident = true;
                }
                if ((blockInfo.flags & 2) == 2)
                {
                    UpdateOutput("Encrypted");
                    isEncrypted = true;
                }
                if ((blockInfo.flags & 1) == 1)
                {
                    UpdateOutput("Compressed");
                    isCompressed = true;
                }
                if (blockInfo.flags == 0)
                {
                    UpdateOutput("No Flags");
                }

                int decryptionSeed = 0;
                if (isEncrypted)
                {
                    try {
                        decryptionSeed = BinaryExtension.GetDecryptionSeed(fileHeader.version);
                    } catch (ArgumentException e) {
                        UpdateOutput("Skipping (" + blockInfo.fileCount + " files) -- " + e.Message);
                        skippedDataSections.Add(new RDASkippedDataSection()
                        {
                            blockInfo = blockInfo,
                            offset    = beginningOfDataSection,
                            size      = (Offset - beginningOfDataSection),
                        });
                        return(blockInfo.nextBlock);
                    }
                }
                read.BaseStream.Position = (long)(Offset - blockInfo.directorySize);
                if (isMemoryResident)
                {
                    read.BaseStream.Position -= GetUIntSizeVersionAware() * 2;
                }
                byte[] numArray2 = read.ReadBytes((int)blockInfo.directorySize);
                if (isEncrypted)
                {
                    numArray2 = BinaryExtension.Decrypt(numArray2, decryptionSeed);
                }
                if (isCompressed)
                {
                    numArray2 = ZLib.ZLib.Uncompress(numArray2, (int)blockInfo.decompressedSize);
                }

                RDAMemoryResidentHelper mrm = null;
                if (isMemoryResident)
                {
                    ulong beginningOfHeader = (ulong)read.BaseStream.Position;
                    ulong compressedSize    = ReadUIntVersionAware(read);
                    ulong uncompressedSize  = ReadUIntVersionAware(read);
                    mrm = new RDAMemoryResidentHelper(beginningOfHeader - blockInfo.directorySize - compressedSize, uncompressedSize, compressedSize, read.BaseStream, blockInfo, fileHeader.version);
                }

                uint dirEntrySize = DirEntry.GetSize(fileHeader.version);
                if (blockInfo.fileCount * dirEntrySize != blockInfo.decompressedSize)
                {
                    throw new Exception("Unexpected directory entry size or count");
                }

                ++rdaReadBlocks;
                UpdateOutput("-- DirEntries:");
                ReadDirEntries(numArray2, blockInfo, mrm);
            }

            return(blockInfo.nextBlock);
        }
Example #3
0
        public static RDAFile FromUnmanaged(FileHeader.Version version, DirEntry dir, BlockInfo block, BinaryReader reader, RDAMemoryResidentHelper mrm)
        {
            RDAFile rdaFile = new RDAFile();

            rdaFile.FileName = dir.filename;
            rdaFile.Version  = version;
            if ((block.flags & 4) != 4)
            {
                if ((block.flags & 1) == 1)
                {
                    rdaFile.Flags |= Flag.Compressed;
                }
                if ((block.flags & 2) == 2)
                {
                    rdaFile.Flags |= Flag.Encrypted;
                }
            }
            if ((block.flags & 4) == 4)
            {
                rdaFile.Flags |= Flag.MemoryResident;
            }
            if ((block.flags & 8) == 8)
            {
                rdaFile.Flags |= Flag.Deleted;
            }
            rdaFile.Offset           = dir.offset;
            rdaFile.UncompressedSize = dir.filesize;
            rdaFile.CompressedSize   = dir.compressed;
            rdaFile.TimeStamp        = DateTimeExtension.FromTimeStamp(dir.timestamp);
            rdaFile.BinaryFile       = mrm == null ? reader : new BinaryReader(mrm.Data);
            return(rdaFile);
        }