This repository has been archived on 2025-05-24. You can view files and clone it, but cannot push or open issues or pull requests.
Files
RomVault/ROMVault2/SupportedFiles/SevenZip/SevenZip.cs

783 lines
29 KiB
C#
Raw Normal View History

2015-03-18 08:48:48 -05:00
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography;
using ROMVault2.SupportedFiles.SevenZip.Common;
using ROMVault2.SupportedFiles.SevenZip.Compress.LZMA;
using ROMVault2.SupportedFiles.SevenZip.Filters;
using ROMVault2.SupportedFiles.SevenZip.Structure;
namespace ROMVault2.SupportedFiles.SevenZip
{
public class SevenZ : ICompress
{
public class LocalFile
{
public string FileName;
public ulong UncompressedSize;
public bool isDirectory;
public byte[] crc;
public byte[] sha1;
public byte[] md5;
public int StreamIndex;
public ulong StreamOffset;
public ZipReturn FileStatus = ZipReturn.ZipUntested;
}
private List<LocalFile> _localFiles = new List<LocalFile>();
private IO.FileInfo _zipFileInfo;
private Stream _zipFs;
private ZipOpenType _zipOpen;
private ZipStatus _pZipStatus;
SignatureHeader _signatureHeader;
private bool _compressed = true;
private Stream _tmpOutStream;
private Stream _streamNow;
private int _streamIndex = -1;
public string ZipFilename
{
get { return _zipFileInfo != null ? _zipFileInfo.FullName : ""; }
}
public long TimeStamp
{
get { return _zipFileInfo != null ? _zipFileInfo.LastWriteTime : 0; }
}
public ZipOpenType ZipOpen { get { return _zipOpen; } }
public ZipStatus ZipStatus { get { return _pZipStatus; } }
public int LocalFilesCount() { return _localFiles.Count; }
public string Filename(int i) { return _localFiles[i].FileName; }
public ulong? LocalHeader(int i) { return 0; }
public ulong UncompressedSize(int i) { return _localFiles[i].UncompressedSize; }
public ZipReturn FileStatus(int i) { return _localFiles[i].FileStatus; }
public byte[] CRC32(int i) { return _localFiles[i].crc; }
public byte[] MD5(int i) { return _localFiles[i].md5; }
public byte[] SHA1(int i) { return _localFiles[i].sha1; }
public bool IsDirectory(int i) { return _localFiles[i].isDirectory; }
private long _baseOffset;
#region open 7z files
public ZipReturn ZipFileOpen(string filename, long timestamp,bool readHeaders)
{
Debug.WriteLine(filename);
#region open file stream
try
{
if (!IO.File.Exists(filename))
{
ZipFileClose();
return ZipReturn.ZipErrorFileNotFound;
}
_zipFileInfo = new IO.FileInfo(filename);
if (timestamp != -1 && _zipFileInfo.LastWriteTime != timestamp)
{
ZipFileClose();
return ZipReturn.ZipErrorTimeStamp;
}
int errorCode = IO.FileStream.OpenFileRead(filename, out _zipFs);
if (errorCode != 0)
{
ZipFileClose();
return ZipReturn.ZipErrorOpeningFile;
}
}
catch (PathTooLongException)
{
ZipFileClose();
return ZipReturn.ZipFileNameToLong;
}
catch (IOException)
{
ZipFileClose();
return ZipReturn.ZipErrorOpeningFile;
}
#endregion
_zipOpen = ZipOpenType.OpenRead;
_pZipStatus = ZipStatus.None;
SignatureHeader signatureHeader = new SignatureHeader();
if (!signatureHeader.Read(new BinaryReader(_zipFs)))
return ZipReturn.ZipSignatureError;
_baseOffset = _zipFs.Position; Util.log("BaseOffset : " + _baseOffset);
Util.log("Loading Stream : " + (_baseOffset + (long)signatureHeader.NextHeaderOffset) + " , Size : " + signatureHeader.NextHeaderSize);
//_zipFs.Seek(_baseOffset + (long)signatureHeader.NextHeaderOffset, SeekOrigin.Begin);
//byte[] mainHeader = new byte[signatureHeader.NextHeaderSize];
//_zipFs.Read(mainHeader, 0, (int)signatureHeader.NextHeaderSize);
//if (!CRC.VerifyDigest(signatureHeader.NextHeaderCRC, mainHeader, 0, (uint)signatureHeader.NextHeaderSize))
// return ZipReturn.Zip64EndOfCentralDirError;
_zipFs.Seek(_baseOffset + (long)signatureHeader.NextHeaderOffset, SeekOrigin.Begin);
ZipReturn zr = Header.ReadHeaderOrPackedHeader(_zipFs, _baseOffset, out _header);
if (zr != ZipReturn.ZipGood)
return zr;
_zipFs.Seek(_baseOffset + (long)(signatureHeader.NextHeaderOffset + signatureHeader.NextHeaderSize), SeekOrigin.Begin);
_pZipStatus = Istorrent7Z() ? ZipStatus.TrrntZip : ZipStatus.None;
PopulateLocalFiles(out _localFiles);
return ZipReturn.ZipGood;
}
private void PopulateLocalFiles(out List<LocalFile> localFiles)
{
int emptyFileIndex = 0;
int folderIndex = 0;
int unpackedStreamsIndex = 0;
ulong streamOffset = 0;
localFiles = new List<LocalFile>();
for (int i = 0; i < _header.FileInfo.Names.Length; i++)
{
LocalFile lf = new LocalFile { FileName = _header.FileInfo.Names[i] };
if (_header.FileInfo.EmptyStreamFlags == null || !_header.FileInfo.EmptyStreamFlags[i])
{
lf.StreamIndex = folderIndex;
lf.StreamOffset = streamOffset;
lf.UncompressedSize = _header.StreamsInfo.Folders[folderIndex].UnpackedStreamInfo[unpackedStreamsIndex].UnpackedSize;
lf.crc = Util.uinttobytes(_header.StreamsInfo.Folders[folderIndex].UnpackedStreamInfo[unpackedStreamsIndex].Crc);
streamOffset += lf.UncompressedSize;
unpackedStreamsIndex++;
if (unpackedStreamsIndex >= _header.StreamsInfo.Folders[folderIndex].UnpackedStreamInfo.Length)
{
folderIndex++;
unpackedStreamsIndex = 0;
streamOffset = 0;
}
}
else
{
lf.UncompressedSize = 0;
lf.crc = new byte[] { 0, 0, 0, 0 };
lf.isDirectory = _header.FileInfo.EmptyFileFlags == null || !_header.FileInfo.EmptyFileFlags[emptyFileIndex++];
if (lf.isDirectory)
if (lf.FileName.Substring(lf.FileName.Length - 1, 1) != "/")
lf.FileName += "/";
}
localFiles.Add(lf);
}
}
public void ZipFileClose()
{
ZipFileClose(null);
}
public void ZipFileClose(ICodeProgress p)
{
if (_zipOpen == ZipOpenType.Closed)
return;
if (_zipOpen == ZipOpenType.OpenRead)
{
ZipFileCloseReadStream();
if (_zipFs != null)
{
_zipFs.Close();
_zipFs.Dispose();
}
_zipOpen = ZipOpenType.Closed;
return;
}
CloseWriting7Zip(p);
_zipFileInfo = new IO.FileInfo(_zipFileInfo.FullName);
_zipOpen = ZipOpenType.Closed;
}
private Header _header;
private bool Istorrent7Z()
{
const int crcsz = 128;
const int t7ZsigSize = 16 + 1 + 9 + 4 + 4;
byte[] kSignature = { (byte)'7', (byte)'z', 0xBC, 0xAF, 0x27, 0x1C };
int kSignatureSize = kSignature.Length;
const string sig = "\xa9\x9f\xd1\x57\x08\xa9\xd7\xea\x29\x64\xb2\x36\x1b\x83\x52\x33\x01torrent7z_0.9beta";
byte[] t7Zid = Util.Enc.GetBytes(sig);
int t7ZidSize = t7Zid.Length;
const int tmpbufsize = 256 + t7ZsigSize + 8 + 4;
byte[] buffer = new byte[tmpbufsize];
// read fist 128 bytes, pad with zeros if less bytes
int offs = 0;
_zipFs.Seek(0, SeekOrigin.Begin);
int ar = _zipFs.Read(buffer, offs, crcsz);
if (ar < crcsz)
Util.memset(buffer, offs + ar, 0, crcsz - ar);
offs = crcsz;
long foffs = _zipFs.Length;
foffs = foffs < (crcsz + t7ZsigSize + 4) ? 0 : foffs - (crcsz + t7ZsigSize + 4);
_zipFs.Seek(foffs, SeekOrigin.Begin);
ar = _zipFs.Read(buffer, offs, (crcsz + t7ZsigSize + 4));
if (ar < (crcsz + t7ZsigSize + 4))
{
if (ar >= t7ZsigSize + 4)
{
ar -= t7ZsigSize + 4;
}
if (ar < kSignatureSize)
{
ar = kSignatureSize;
}
Util.memset(buffer, offs + ar, 0, crcsz - ar);
Util.memcpyr(buffer, crcsz * 2 + 8, buffer, offs + ar, t7ZsigSize + 4);
}
else
Util.memcpyr(buffer, crcsz * 2 + 8, buffer, crcsz * 2, t7ZsigSize + 4);
foffs = _zipFs.Length;
foffs -= t7ZsigSize + 4;
//memcpy(buffer, crcsz * 2, &foffs, 8);
buffer[crcsz * 2 + 0] = (byte)((foffs >> 0) & 0xff);
buffer[crcsz * 2 + 1] = (byte)((foffs >> 8) & 0xff);
buffer[crcsz * 2 + 2] = (byte)((foffs >> 16) & 0xff);
buffer[crcsz * 2 + 3] = (byte)((foffs >> 24) & 0xff);
buffer[crcsz * 2 + 4] = 0;
buffer[crcsz * 2 + 5] = 0;
buffer[crcsz * 2 + 6] = 0;
buffer[crcsz * 2 + 7] = 0;
if (Util.memcmp(buffer, 0, kSignature, kSignatureSize))
{
t7Zid[16] = buffer[crcsz * 2 + 4 + 8 + 16];
if (Util.memcmp(buffer, crcsz * 2 + 4 + 8, t7Zid, t7ZidSize))
{
UInt32 inCrc32 = (UInt32)((buffer[crcsz * 2 + 8 + 0]) +
(buffer[crcsz * 2 + 8 + 1] << 8) +
(buffer[crcsz * 2 + 8 + 2] << 16) +
(buffer[crcsz * 2 + 8 + 3] << 24));
buffer[crcsz * 2 + 8 + 0] = 0xff;
buffer[crcsz * 2 + 8 + 1] = 0xff;
buffer[crcsz * 2 + 8 + 2] = 0xff;
buffer[crcsz * 2 + 8 + 3] = 0xff;
uint calcCrc32 = CRC.CalculateDigest(buffer, 0, crcsz * 2 + 8 + t7ZsigSize + 4);
if (inCrc32 == calcCrc32) return true;
}
}
return false;
}
#endregion
public void DeepScan()
{
const int bufferSize = 4096 * 128;
byte[] buffer = new byte[bufferSize];
for (int index = 0; index < _localFiles.Count; index++)
{
if (_localFiles[index].isDirectory || _localFiles[index].UncompressedSize == 0)
{
_localFiles[index].md5 = new byte[] { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e };
_localFiles[index].sha1 = new byte[] { 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09 };
_localFiles[index].FileStatus = ZipReturn.ZipGood;
continue;
}
ulong sizetogo;
Stream inStream;
ZipReturn zr = ZipFileOpenReadStream(index, out inStream, out sizetogo);
if (zr != ZipReturn.ZipGood)
continue;
if (inStream == null)
continue;
CRC crc32 = new CRC();
MD5 lmd5 = System.Security.Cryptography.MD5.Create();
SHA1 lsha1 = System.Security.Cryptography.SHA1.Create();
while (sizetogo > 0)
{
int sizenow = sizetogo > (ulong)bufferSize ? bufferSize : (int)sizetogo;
inStream.Read(buffer, 0, sizenow);
crc32.Update(buffer, 0, (uint)sizenow);
lmd5.TransformBlock(buffer, 0, sizenow, null, 0);
lsha1.TransformBlock(buffer, 0, sizenow, null, 0);
sizetogo = sizetogo - (ulong)sizenow;
}
lmd5.TransformFinalBlock(buffer, 0, 0);
lsha1.TransformFinalBlock(buffer, 0, 0);
byte[] testcrc = Util.uinttobytes(crc32.GetDigest());
_localFiles[index].md5 = lmd5.Hash;
_localFiles[index].sha1 = lsha1.Hash;
_localFiles[index].FileStatus = Util.ByteArrCompare(_localFiles[index].crc, testcrc) ? ZipReturn.ZipGood : ZipReturn.ZipCRCDecodeError;
}
}
#region read 7z file
public ZipReturn ZipFileOpenReadStream(int index, out Stream stream, out ulong unCompressedSize)
{
Debug.WriteLine("Opening File " + _localFiles[index].FileName);
stream = null;
unCompressedSize = 0;
if (_zipOpen != ZipOpenType.OpenRead)
return ZipReturn.ZipErrorGettingDataStream;
if (IsDirectory(index))
return ZipReturn.ZipTryingToAccessADirectory;
unCompressedSize = _localFiles[index].UncompressedSize;
int thisStreamIndex = _localFiles[index].StreamIndex;
// first see if we can re-use the current open stream
if (_streamIndex == thisStreamIndex)
{
stream = _streamNow;
if (_streamNow is BCJFilter) // it is a BCJ + Decoder stream but need to check the position in the stream can be used.
{
if ((long)_localFiles[index].StreamOffset >= _streamNow.Position)
{
stream.Seek((long)_localFiles[index].StreamOffset - _streamNow.Position, SeekOrigin.Current);
return ZipReturn.ZipGood;
}
}
else if (_streamNow is Decoder) // it is a Decoder stream but need to check the position in the stream can be used.
{
if ((long)_localFiles[index].StreamOffset >= _streamNow.Position)
{
stream.Seek((long)_localFiles[index].StreamOffset - _streamNow.Position, SeekOrigin.Current);
return ZipReturn.ZipGood;
}
}
else // it is an uncompressed stream
{
if (stream != null)
stream.Seek((long)_localFiles[index].StreamOffset - _streamNow.Position, SeekOrigin.Current);
return ZipReturn.ZipGood;
}
}
// need to open a new stream
// first close the old streams
ZipFileCloseReadStream();
// open new stream
_streamIndex = thisStreamIndex;
_zipFs.Seek(_baseOffset + (long)_header.StreamsInfo.PackedStreams[thisStreamIndex].StreamPosition, SeekOrigin.Begin);
byte[] method = _header.StreamsInfo.Folders[_localFiles[index].StreamIndex].Coders[0].Method;
if (method.Length == 3 && method[0] == 3 && method[1] == 1 && method[2] == 1) // LZMA
{
Decoder decoder = new Decoder();
decoder.SetDecoderProperties(_header.StreamsInfo.Folders[_localFiles[index].StreamIndex].Coders[0].Properties);
decoder.SetUpStream(_zipFs);
stream = decoder;
_streamNow = stream;
if (_header.StreamsInfo.Folders[_localFiles[index].StreamIndex].Coders.Length > 1) // BCJ
{
method = _header.StreamsInfo.Folders[_localFiles[index].StreamIndex].Coders[1].Method;
if (method.Length == 4 && method[0] == 3 && method[1] == 3 && method[2] == 1 && method[3] == 3)
{
BCJFilter filter = new BCJFilter(false, stream);
stream = filter;
_streamNow = stream;
stream.Seek((long)_localFiles[index].StreamOffset, SeekOrigin.Current);
return ZipReturn.ZipGood;
}
return ZipReturn.ZipUnsupportedCompression;
}
stream.Seek((long)_localFiles[index].StreamOffset, SeekOrigin.Current);
return ZipReturn.ZipGood;
}
if (method.Length == 1 && method[0] == 33) // lzma2
{
return ZipReturn.ZipUnsupportedCompression;
}
if (method.Length == 1 && method[0] == 0) // uncompressed
{
stream = _zipFs;
_streamNow = stream;
stream.Seek((long)_localFiles[index].StreamOffset, SeekOrigin.Current);
return ZipReturn.ZipGood;
}
if (method.Length == 3 && method[0] == 4 && method[1] == 2 && method[2] == 2) // BZip2
{
return ZipReturn.ZipUnsupportedCompression;
}
if (method.Length == 1 && method[0] == 33) // LZMA2
{
return ZipReturn.ZipUnsupportedCompression;
}
return ZipReturn.ZipUnsupportedCompression;
}
public ZipReturn ZipFileCloseReadStream()
{
if (_streamNow is BCJFilter)
{
Stream baseStream = ((BCJFilter)_streamNow).BaseStream;
_streamNow.Dispose();
_streamNow = baseStream;
}
if (_streamNow is Decoder)
{
_streamNow.Close();
_streamNow.Dispose();
}
_streamNow = null;
return ZipReturn.ZipGood;
}
#endregion
#region write 7z File
public void ZipFileAddDirectory()
{
// do nothing here for 7zip
}
public ZipReturn ZipFileCreate(string newFilename)
{
return ZipFileCreate(newFilename, true);
}
public ZipReturn ZipFileCreate(string newFilename, bool compressOutput)
{
if (_zipOpen != ZipOpenType.Closed)
return ZipReturn.ZipFileAlreadyOpen;
DirUtil.CreateDirForFile(newFilename);
_zipFileInfo = new IO.FileInfo(newFilename);
int errorCode = IO.FileStream.OpenFileWrite(newFilename, out _zipFs);
if (errorCode != 0)
{
ZipFileClose();
return ZipReturn.ZipErrorOpeningFile;
}
_zipOpen = ZipOpenType.OpenWrite;
_signatureHeader = new SignatureHeader();
_header = new Header();
BinaryWriter bw = new BinaryWriter(_zipFs);
_signatureHeader.Write(bw);
_compressed = compressOutput;
_tmpOutStream = compressOutput ? new FileStream(_zipFileInfo.FullName + ".tmp", FileMode.Create, FileAccess.Write) : null;
return ZipReturn.ZipGood;
}
public ZipReturn ZipFileOpenWriteStream(bool raw, bool trrntzip, string filename, ulong uncompressedSize, ushort compressionMethod, out Stream stream)
{
return ZipFileOpenWriteStream(filename, uncompressedSize, out stream);
}
public ZipReturn ZipFileOpenWriteStream(string filename, ulong uncompressedSize, out Stream stream)
{
LocalFile lf = new LocalFile
{
FileName = filename,
UncompressedSize = uncompressedSize,
StreamOffset = (ulong)(_zipFs.Position - _signatureHeader.BaseOffset)
};
_localFiles.Add(lf);
stream = _tmpOutStream ?? _zipFs;
return ZipReturn.ZipGood;
}
public ZipReturn ZipFileCloseWriteStream(byte[] crc32)
{
_localFiles[_localFiles.Count - 1].crc = new[] { crc32[3], crc32[2], crc32[1], crc32[0] };
return ZipReturn.ZipGood;
}
private void Create7ZStructure()
{
int fileCount = _localFiles.Count;
//FileInfo
_header.FileInfo = new Structure.FileInfo
{
Names = new string[fileCount]
};
ulong emptyStreamCount = 0;
ulong emptyFileCount = 0;
for (int i = 0; i < fileCount; i++)
{
_header.FileInfo.Names[i] = _localFiles[i].FileName;
if (_localFiles[i].UncompressedSize != 0)
continue;
if (!_localFiles[i].isDirectory)
emptyFileCount += 1;
emptyStreamCount += 1;
}
ulong outFileCount = (ulong)_localFiles.Count - emptyStreamCount;
_header.FileInfo.EmptyStreamFlags = null;
_header.FileInfo.EmptyFileFlags = null;
_header.FileInfo.Attributes = null;
if (emptyStreamCount > 0)
{
if (emptyStreamCount != emptyFileCount) //then we found directories and need to set the attributes
_header.FileInfo.Attributes = new uint[fileCount];
if (emptyFileCount > 0)
_header.FileInfo.EmptyFileFlags = new bool[emptyStreamCount];
emptyStreamCount = 0;
_header.FileInfo.EmptyStreamFlags = new bool[fileCount];
for (int i = 0; i < fileCount; i++)
{
if (_localFiles[i].UncompressedSize != 0)
continue;
if (_localFiles[i].isDirectory)
_header.FileInfo.Attributes[i] = 0x10; // set attributes to directory
else
_header.FileInfo.EmptyFileFlags[emptyStreamCount] = true; // set empty file flag
_header.FileInfo.EmptyStreamFlags[i] = true;
emptyStreamCount += 1;
}
}
//StreamsInfo
_header.StreamsInfo = new StreamsInfo { PackPosition = 0 };
//StreamsInfo.PackedStreamsInfo
if (_compressed)
{
_header.StreamsInfo.PackedStreams = new PackedStreamInfo[1];
_header.StreamsInfo.PackedStreams[0] = new PackedStreamInfo { PackedSize = _packStreamSize };
}
else
{
_header.StreamsInfo.PackedStreams = new PackedStreamInfo[outFileCount];
int fileIndex = 0;
for (int i = 0; i < fileCount; i++)
{
if (_localFiles[i].UncompressedSize == 0)
continue;
_header.StreamsInfo.PackedStreams[fileIndex++] = new PackedStreamInfo { PackedSize = _localFiles[i].UncompressedSize };
}
}
//StreamsInfo.PackedStreamsInfo, no CRC or StreamPosition required
if (_compressed)
{
//StreamsInfo.Folders
_header.StreamsInfo.Folders = new Folder[1];
Folder folder = new Folder { Coders = new Coder[1] };
//StreamsInfo.Folders.Coder
// flags 0x23
folder.Coders[0] = new Coder
{
Method = new byte[] { 3, 1, 1 },
NumInStreams = 1,
NumOutStreams = 1,
Properties = _codeMSbytes
};
folder.BindPairs = null;
folder.PackedStreamIndices = new[] { (ulong)0 };
folder.UnpackedStreamSizes = new[] { _unpackedStreamSize };
folder.UnpackCRC = null;
folder.UnpackedStreamInfo = new UnpackedStreamInfo[outFileCount];
int fileIndex = 0;
for (int i = 0; i < fileCount; i++)
{
if (_localFiles[i].UncompressedSize == 0)
continue;
UnpackedStreamInfo unpackedStreamInfo = new UnpackedStreamInfo
{
UnpackedSize = _localFiles[i].UncompressedSize,
Crc = Util.bytestouint(_localFiles[i].crc)
};
folder.UnpackedStreamInfo[fileIndex++] = unpackedStreamInfo;
}
_header.StreamsInfo.Folders[0] = folder;
}
else
{
_header.StreamsInfo.Folders = new Folder[outFileCount];
int fileIndex = 0;
for (int i = 0; i < fileCount; i++)
{
if (_localFiles[i].UncompressedSize == 0)
continue;
Folder folder = new Folder { Coders = new Coder[1] };
//StreamsInfo.Folders.Coder
// flags 0x01
folder.Coders[0] = new Coder
{
Method = new byte[] { 0 },
NumInStreams = 1,
NumOutStreams = 1,
Properties = null
};
folder.BindPairs = null;
folder.PackedStreamIndices = new[] { (ulong)i };
folder.UnpackedStreamSizes = new[] { _localFiles[i].UncompressedSize };
folder.UnpackCRC = null;
folder.UnpackedStreamInfo = new UnpackedStreamInfo[1];
UnpackedStreamInfo unpackedStreamInfo = new UnpackedStreamInfo
{
UnpackedSize = _localFiles[i].UncompressedSize,
Crc = Util.bytestouint(_localFiles[i].crc)
};
folder.UnpackedStreamInfo[0] = unpackedStreamInfo;
_header.StreamsInfo.Folders[fileIndex++] = folder;
}
}
}
ulong _packStreamSize;
ulong _unpackedStreamSize;
byte[] _codeMSbytes;
private void CloseWriting7Zip(ICodeProgress p = null)
{
if (_compressed)
{
_unpackedStreamSize = (ulong)_tmpOutStream.Length;
_tmpOutStream.Close();
_tmpOutStream.Dispose();
UInt64 packStreamStart = (UInt64)_zipFs.Position;
using (Stream inStream = new FileStream(_zipFileInfo.FullName + ".tmp", FileMode.Open, FileAccess.Read))
{
LZMACompressFile.CompressFile(inStream, _zipFs, out _codeMSbytes, p);
}
_packStreamSize = (UInt64)_zipFs.Position - packStreamStart;
File.Delete(_zipFileInfo.FullName + ".tmp");
}
Create7ZStructure();
byte[] newHeaderByte;
using (Stream headerMem = new MemoryStream())
{
using (BinaryWriter headerBw = new BinaryWriter(headerMem))
{
_header.WriteHeader(headerBw);
newHeaderByte = new byte[headerMem.Length];
headerMem.Position = 0;
headerMem.Read(newHeaderByte, 0, newHeaderByte.Length);
}
}
CRC mainHeadercrc = new CRC();
mainHeadercrc.Update(newHeaderByte, 0, (uint)newHeaderByte.Length);
UInt32 mainHeaderCRC = mainHeadercrc.GetDigest();
UInt64 headerpos = (UInt64)_zipFs.Position;
BinaryWriter bw = new BinaryWriter(_zipFs);
bw.Write(newHeaderByte);
_signatureHeader.WriteFinal(bw, headerpos, (ulong)newHeaderByte.Length, mainHeaderCRC);
_zipFs.Flush();
_zipFs.Close();
_zipFs.Dispose();
}
#endregion
public void ZipFileAddDirectory(string filename)
{
LocalFile lf = new LocalFile
{
FileName = filename,
UncompressedSize = 0,
isDirectory = true,
StreamOffset = 0
};
_localFiles.Add(lf);
}
public ZipReturn ZipFileRollBack()
{
throw new NotImplementedException();
}
public void ZipFileCloseFailed()
{
throw new NotImplementedException();
}
}
}