From ae1e37cde6881d370097ca18167e6c9333e39665 Mon Sep 17 00:00:00 2001 From: benshoof Date: Thu, 7 May 2015 18:20:05 -0800 Subject: [PATCH] Added read support for RARs with Protect Headers Some RARs with recovery records contain Protect Headers, I've added support for parsing them so that RARs containing them can be read, instead of an invalid-header exception being thrown. Parsing logic taken from unrar reference source. --- .../Common/Rar/Headers/ProtectHeader.cs | 22 +++++++++++++++ .../Common/Rar/Headers/RarHeaderFactory.cs | 27 +++++++++++++++++++ SharpCompress/SharpCompress.NET2.csproj | 1 + SharpCompress/SharpCompress.Portable.csproj | 1 + .../SharpCompress.PortableTest.csproj | 1 + .../SharpCompress.WindowsStore.csproj | 1 + SharpCompress/SharpCompress.csproj | 1 + 7 files changed, 54 insertions(+) create mode 100644 SharpCompress/Common/Rar/Headers/ProtectHeader.cs diff --git a/SharpCompress/Common/Rar/Headers/ProtectHeader.cs b/SharpCompress/Common/Rar/Headers/ProtectHeader.cs new file mode 100644 index 00000000..a80802c8 --- /dev/null +++ b/SharpCompress/Common/Rar/Headers/ProtectHeader.cs @@ -0,0 +1,22 @@ +using SharpCompress.IO; + +namespace SharpCompress.Common.Rar.Headers +{ + // ProtectHeader is part of the Recovery Record feature + internal class ProtectHeader : RarHeader + { + protected override void ReadFromReader(MarkingBinaryReader reader) + { + Version = reader.ReadByte(); + RecSectors = reader.ReadUInt16(); + TotalBlocks = reader.ReadUInt32(); + Mark = reader.ReadBytes(8); + } + + internal uint DataSize { get { return AdditionalSize; } } + internal byte Version { get; private set; } + internal ushort RecSectors { get; private set; } + internal uint TotalBlocks { get; private set; } + internal byte[] Mark { get; private set; } + } +} diff --git a/SharpCompress/Common/Rar/Headers/RarHeaderFactory.cs b/SharpCompress/Common/Rar/Headers/RarHeaderFactory.cs index 5e630732..216d8652 100644 --- a/SharpCompress/Common/Rar/Headers/RarHeaderFactory.cs +++ b/SharpCompress/Common/Rar/Headers/RarHeaderFactory.cs @@ -151,6 +151,33 @@ namespace SharpCompress.Common.Rar.Headers { return header.PromoteHeader(reader); } + + case HeaderType.ProtectHeader: + { + ProtectHeader ph = header.PromoteHeader(reader); + + // skip the recovery record data, we do not use it. + switch (StreamingMode) + { + case StreamingMode.Seekable: + { + reader.BaseStream.Position += ph.DataSize; + } + break; + case StreamingMode.Streaming: + { + reader.BaseStream.Skip(ph.DataSize); + } + break; + default: + { + throw new InvalidFormatException("Invalid StreamingMode"); + } + } + + return ph; + } + case HeaderType.NewSubHeader: { FileHeader fh = header.PromoteHeader(reader); diff --git a/SharpCompress/SharpCompress.NET2.csproj b/SharpCompress/SharpCompress.NET2.csproj index c97ecc7d..a8e1cef8 100644 --- a/SharpCompress/SharpCompress.NET2.csproj +++ b/SharpCompress/SharpCompress.NET2.csproj @@ -307,6 +307,7 @@ + diff --git a/SharpCompress/SharpCompress.Portable.csproj b/SharpCompress/SharpCompress.Portable.csproj index 41c4495f..ead5b9b9 100644 --- a/SharpCompress/SharpCompress.Portable.csproj +++ b/SharpCompress/SharpCompress.Portable.csproj @@ -118,6 +118,7 @@ + diff --git a/SharpCompress/SharpCompress.PortableTest.csproj b/SharpCompress/SharpCompress.PortableTest.csproj index 41102c60..f31799e3 100644 --- a/SharpCompress/SharpCompress.PortableTest.csproj +++ b/SharpCompress/SharpCompress.PortableTest.csproj @@ -315,6 +315,7 @@ + diff --git a/SharpCompress/SharpCompress.WindowsStore.csproj b/SharpCompress/SharpCompress.WindowsStore.csproj index 90519b5d..974b4ceb 100644 --- a/SharpCompress/SharpCompress.WindowsStore.csproj +++ b/SharpCompress/SharpCompress.WindowsStore.csproj @@ -104,6 +104,7 @@ + diff --git a/SharpCompress/SharpCompress.csproj b/SharpCompress/SharpCompress.csproj index 6a6a17bc..8873b906 100644 --- a/SharpCompress/SharpCompress.csproj +++ b/SharpCompress/SharpCompress.csproj @@ -307,6 +307,7 @@ +