Beispiel #1
0
        public RarPackedFileBlock(SrrBlockHeader srrBlockHeader, long startOffset, ref BinaryReader reader) : base(srrBlockHeader, startOffset, ref reader)
        {
            //this.PackedSize = reader.ReadUInt32(); //already read when reading "addsize"
            this.PackedSize = this.SrrBlockHeader.AddSize;

            this.UnpackedSize = reader.ReadUInt32();
            reader.ReadByte();   //os (skip)
            this.FileCrc = reader.ReadUInt32();
            reader.ReadUInt32(); //datetime (skip)
            reader.ReadByte();   //unpackVersion (skip)
            this.CompressionMethod = reader.ReadByte();
            ushort nameLength = reader.ReadUInt16();

            reader.ReadUInt32(); //file attributes (skip)

            // if large file flag is set, next are 4 bytes each for high order bits of file sizes
            if ((this.SrrBlockHeader.Flags & 0x100) != 0)
            {
                //read additional bytes
                this.PackedSize   += reader.ReadUInt32() * 0x100000000ul;
                this.UnpackedSize += reader.ReadUInt32() * 0x100000000ul;
            }

            this.FileName = new string(reader.ReadChars(nameLength));

            // the file name can be null-terminated, especially in the case of utf-encoded ones. cut it off if necessary
            if (this.FileName.IndexOf('\0') >= 0)
            {
                this.FileName = this.FileName.Substring(0, this.FileName.IndexOf('\0'));
            }
        }
Beispiel #2
0
        //public SrrHeaderBlock(byte[] blockBytes, long filePos) : base(blockBytes, filePos)
        public SrrHeaderBlock(SrrBlockHeader srrBlockHeader, long startOffset, ref BinaryReader reader) : base(srrBlockHeader, startOffset, ref reader)
        {
            this.AppName = new string(reader.ReadChars(reader.ReadUInt16()));

            //ushort fileNameLength = BitConverter.ToUInt16(blockBytes, 7);
            //byte[] fileName = new byte[fileNameLength];
            //Buffer.BlockCopy(blockBytes, 9, fileName, 0, fileNameLength);
            //this.AppName = Encoding.UTF8.GetString(fileName);
        }
Beispiel #3
0
        public RarOldRecoveryBlock(SrrBlockHeader srrBlockHeader, long startOffset, ref BinaryReader reader) : base(srrBlockHeader, startOffset, ref reader)
        {
            this.PackedSize = reader.ReadUInt32();

            reader.BaseStream.Seek(1, SeekOrigin.Current); //rar version

            this.RecoverySectors = reader.ReadUInt16();
            this.DataSectors     = reader.ReadUInt32();
        }
Beispiel #4
0
 public RarVolumeHeaderBlock(SrrBlockHeader srrBlockHeader, long startOffset, ref BinaryReader reader) : base(srrBlockHeader, startOffset, ref reader)
 {
 }
Beispiel #5
0
 public SrrRarFileBlock(SrrBlockHeader srrBlockHeader, long startOffset, ref BinaryReader reader) : base(srrBlockHeader, startOffset, ref reader)
 {
     this.FileName = new string(reader.ReadChars(reader.ReadUInt16()));
 }
Beispiel #6
0
 public SrrStoredFileBlock(SrrBlockHeader srrBlockHeader, long startOffset, ref BinaryReader reader) : base(srrBlockHeader, startOffset, ref reader)
 {
     this.FileName   = new string(reader.ReadChars(reader.ReadUInt16()));
     this.FileOffset = reader.BaseStream.Position;
     this.FileLength = this.SrrBlockHeader.AddSize;
 }
Beispiel #7
0
 public RarRecoveryBlock(SrrBlockHeader srrBlockHeader, long startOffset, ref BinaryReader reader) : base(srrBlockHeader, startOffset, ref reader)
 {
     this.FileName        = new string(reader.ReadChars(8)); //'Protect+', overwrites 'RR'
     this.RecoverySectors = reader.ReadUInt32();
     this.DataSectors     = reader.ReadUInt64();
 }
Beispiel #8
0
 public Block(SrrBlockHeader srrBlockHeader, long startOffset, ref BinaryReader reader)
 {
     this.BlockPosition  = startOffset;
     this.SrrBlockHeader = srrBlockHeader;
 }
Beispiel #9
0
        private void ReadSrr_New(BinaryReader reader)
        {
            this.FileSize = reader.BaseStream.Length;

            SrrRarFileBlock currentRarFile = null;

            while (reader.BaseStream.Position < reader.BaseStream.Length)
            {
                long startOffset = reader.BaseStream.Position;

                byte[] header = reader.ReadBytes(HEADERLENGTH);

                SrrBlockHeader srrBlockHeader = new SrrBlockHeader
                {
                    HeaderCrc  = BitConverter.ToUInt16(header, 0),
                    BlockType  = Enum.IsDefined(typeof(RarBlockType), header[2]) ? (RarBlockType)header[2] : RarBlockType.Unknown,
                    Flags      = BitConverter.ToUInt16(header, 3),
                    HeaderSize = BitConverter.ToUInt16(header, 5)
                };

                int addSizeFlag = srrBlockHeader.Flags & 0x8000;

                if (addSizeFlag > 0 || srrBlockHeader.BlockType == RarBlockType.RarPackedFile || srrBlockHeader.BlockType == RarBlockType.RarNewSub)
                {
                    srrBlockHeader.AddSize = reader.ReadUInt32();
                }

                //calculate rar file size
                if (currentRarFile != null && srrBlockHeader.BlockType != RarBlockType.SrrRarFile)
                {
                    currentRarFile.FileLength += srrBlockHeader.FullSize;
                }

                switch (srrBlockHeader.BlockType)
                {
                case RarBlockType.SrrHeader:
                    this.BlockList.Add(new SrrHeaderBlock(srrBlockHeader, startOffset, ref reader));
                    break;

                case RarBlockType.SrrStoredFile:
                    SrrStoredFileBlock srrStoredFileBlock = new SrrStoredFileBlock(srrBlockHeader, startOffset, ref reader);
                    this.BlockList.Add(srrStoredFileBlock);

                    reader.ReadBytes((int)srrBlockHeader.AddSize);     //skip stored file data
                    break;

                case RarBlockType.SrrRarFile:
                    currentRarFile = new SrrRarFileBlock(srrBlockHeader, startOffset, ref reader);
                    this.BlockList.Add(currentRarFile);
                    break;

                case RarBlockType.RarVolumeHeader:
                    this.BlockList.Add(new RarVolumeHeaderBlock(srrBlockHeader, startOffset, ref reader));
                    reader.ReadBytes((int)srrBlockHeader.HeaderSize - HEADERLENGTH);     //this skip block?
                    break;

                case RarBlockType.RarPackedFile:
                    RarPackedFileBlock rarPackedFileBlock = new RarPackedFileBlock(srrBlockHeader, startOffset, ref reader);

                    this.BlockList.Add(rarPackedFileBlock);

                    reader.BaseStream.Seek(startOffset + rarPackedFileBlock.SrrBlockHeader.HeaderSize, SeekOrigin.Begin);
                    break;

                case RarBlockType.RarOldRecovery:
                    this.BlockList.Add(new RarOldRecoveryBlock(srrBlockHeader, startOffset, ref reader));
                    break;

                case RarBlockType.RarNewSub:
                    //if (isRecovery)
                    if (true)
                    {
                        RarRecoveryBlock rarRecoveryBlock = new RarRecoveryBlock(srrBlockHeader, startOffset, ref reader);     //BROKEN 2020-11-22 04:18:00

                        this.BlockList.Add(rarRecoveryBlock);

                        reader.BaseStream.Seek(startOffset + rarRecoveryBlock.SrrBlockHeader.HeaderSize, SeekOrigin.Begin);
                    }
                    else
                    {
                        this.BlockList.Add(new Block(srrBlockHeader, startOffset, ref reader));
                    }
                    break;

                case RarBlockType.Unknown:     //TODO: fix
                    break;

                case RarBlockType.SrrOsoHash:     //wont implement
                case RarBlockType.RarMin:
                case RarBlockType.RarMax:
                case RarBlockType.OldComment:
                case RarBlockType.OldAuthenticity1:
                case RarBlockType.OldSubblock:
                case RarBlockType.OldAuthenticity2:
                    //case RarBlockType.SrrRarPadding:
                    reader.ReadBytes(srrBlockHeader.HeaderSize - 7);     //skip block
                    break;

                default:
                    //new Block(srrBlockHeader, startOffset, ref reader);
                    reader.BaseStream.Seek(startOffset + srrBlockHeader.FullSize, SeekOrigin.Begin);
                    break;
                }
            }

            //sfv processing
            foreach (SrrFileInfo sfvFile in this.StoredFileInfos.Where(x => x.FileName.ToLower().EndsWith(".sfv")))
            {
                byte[] sfvData = this.GetStoredFileData(sfvFile.FileName);
                this.ProcessSfv(Encoding.UTF8.GetString(sfvData));
            }
        }