2019-12-04 15:42:30 -08:00
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Compress.SevenZip.Structure
|
|
|
|
|
|
{
|
|
|
|
|
|
internal class SignatureHeader
|
|
|
|
|
|
{
|
2020-04-03 13:19:21 -07:00
|
|
|
|
private static readonly byte[] Signature = { (byte)'7', (byte)'z', 0xBC, 0xAF, 0x27, 0x1C };
|
2019-12-04 15:42:30 -08:00
|
|
|
|
|
|
|
|
|
|
private byte _major;
|
|
|
|
|
|
private byte _minor;
|
|
|
|
|
|
|
|
|
|
|
|
private uint _startHeaderCRC;
|
|
|
|
|
|
|
|
|
|
|
|
public ulong NextHeaderOffset;
|
|
|
|
|
|
public ulong NextHeaderSize;
|
|
|
|
|
|
public uint NextHeaderCRC;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private long _crcOffset;
|
|
|
|
|
|
public long BaseOffset { get; private set; }
|
|
|
|
|
|
|
|
|
|
|
|
public bool Read(Stream stream)
|
|
|
|
|
|
{
|
|
|
|
|
|
using (BinaryReader br = new BinaryReader(stream, Encoding.UTF8, true))
|
|
|
|
|
|
{
|
|
|
|
|
|
byte[] signatureBytes = br.ReadBytes(6);
|
|
|
|
|
|
if (!signatureBytes.Compare(Signature))
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_major = br.ReadByte();
|
|
|
|
|
|
_minor = br.ReadByte();
|
|
|
|
|
|
|
|
|
|
|
|
_startHeaderCRC = br.ReadUInt32();
|
|
|
|
|
|
|
|
|
|
|
|
long pos = br.BaseStream.Position;
|
|
|
|
|
|
byte[] mainHeader = new byte[8 + 8 + 4];
|
|
|
|
|
|
br.BaseStream.Read(mainHeader, 0, mainHeader.Length);
|
2020-04-03 13:19:21 -07:00
|
|
|
|
if (!Utils.CRC.VerifyDigest(_startHeaderCRC, mainHeader, 0, (uint)mainHeader.Length))
|
2019-12-04 15:42:30 -08:00
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
br.BaseStream.Seek(pos, SeekOrigin.Begin);
|
|
|
|
|
|
|
|
|
|
|
|
NextHeaderOffset = br.ReadUInt64();
|
|
|
|
|
|
NextHeaderSize = br.ReadUInt64();
|
|
|
|
|
|
NextHeaderCRC = br.ReadUInt32();
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Write(BinaryWriter bw)
|
|
|
|
|
|
{
|
|
|
|
|
|
//SignatureHeader
|
|
|
|
|
|
//~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
|
|
bw.Write(Signature);
|
|
|
|
|
|
|
|
|
|
|
|
//ArchiveVersion
|
|
|
|
|
|
//{
|
2020-04-03 13:19:21 -07:00
|
|
|
|
bw.Write((byte)0); // BYTE Major
|
|
|
|
|
|
bw.Write((byte)3); // BYTE Minor
|
2019-12-04 15:42:30 -08:00
|
|
|
|
//};
|
|
|
|
|
|
|
|
|
|
|
|
_crcOffset = bw.BaseStream.Position;
|
2020-04-03 13:19:21 -07:00
|
|
|
|
bw.Write((uint)0); //HeaderCRC
|
2019-12-04 15:42:30 -08:00
|
|
|
|
|
|
|
|
|
|
//StartHeader
|
|
|
|
|
|
//{
|
2020-04-03 13:19:21 -07:00
|
|
|
|
bw.Write((ulong)0); //NextHeaderOffset
|
|
|
|
|
|
bw.Write((ulong)0); //NextHeaderSize
|
|
|
|
|
|
bw.Write((uint)0); //NextHeaderCRC
|
2019-12-04 15:42:30 -08:00
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
BaseOffset = bw.BaseStream.Position;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void WriteFinal(BinaryWriter bw, ulong headerpos, ulong headerLength, uint headerCRC)
|
|
|
|
|
|
{
|
|
|
|
|
|
long fileEnd = bw.BaseStream.Position;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
byte[] sigHeaderBytes;
|
|
|
|
|
|
using (MemoryStream sigHeaderMem = new MemoryStream())
|
|
|
|
|
|
{
|
2020-04-03 13:19:21 -07:00
|
|
|
|
using (BinaryWriter sigHeaderBw = new BinaryWriter(sigHeaderMem, Encoding.UTF8, true))
|
2019-12-04 15:42:30 -08:00
|
|
|
|
{
|
2020-04-03 13:19:21 -07:00
|
|
|
|
sigHeaderBw.Write((ulong)((long)headerpos - BaseOffset)); //NextHeaderOffset
|
2019-12-04 15:42:30 -08:00
|
|
|
|
sigHeaderBw.Write(headerLength); //NextHeaderSize
|
|
|
|
|
|
sigHeaderBw.Write(headerCRC); //NextHeaderCRC
|
|
|
|
|
|
|
|
|
|
|
|
sigHeaderBytes = new byte[sigHeaderMem.Length];
|
|
|
|
|
|
sigHeaderMem.Position = 0;
|
|
|
|
|
|
sigHeaderMem.Read(sigHeaderBytes, 0, sigHeaderBytes.Length);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-04-03 13:19:21 -07:00
|
|
|
|
uint sigHeaderCRC = Utils.CRC.CalculateDigest(sigHeaderBytes, 0, (uint)sigHeaderBytes.Length);
|
2019-12-04 15:42:30 -08:00
|
|
|
|
|
|
|
|
|
|
bw.BaseStream.Position = _crcOffset;
|
|
|
|
|
|
bw.Write(sigHeaderCRC); //Header CRC
|
|
|
|
|
|
bw.Write(sigHeaderBytes);
|
|
|
|
|
|
|
|
|
|
|
|
bw.BaseStream.Seek(fileEnd, SeekOrigin.Begin);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|