Ejemplo n.º 1
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((int)dir.timestamp);
     rdaFile.BinaryFile = mrm == null ? reader : new BinaryReader(mrm.Data);
     return rdaFile;
 }
Ejemplo n.º 2
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);
            }
        }
Ejemplo n.º 3
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;
        }