Как добавить папку в Zip архив через ZipStorer?

Пробую добавить папку в .zip архив но она добавляется не правильно

static string mydir = @"C:\Boba\bin\Release\ZipTest";
static string zipfile = string.Concat(mydir, ".zip");

var d = new DirectoryInfo(mydir);
using (var archive = ZipStorer.Create(zipfile, comment))
{ 
   archive.AddDirectory(ZipStorer.Compression.Deflate, Path.GetFileName(d.FullName), Path.GetFileName(d.FullName), "");
}

При архивации внутри папка становиться ZipTestZipTest -> тут все файлы из папки и внутри лежит архив .zip пустой.
Как правильно добавить папку со всеми файлами в .zip ?


Класс ZipStorer.cs

// System.IO.Compression.ZipStorer
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Text;

public class ZipStorer : IDisposable
{
    public enum Compression : ushort
    {
        Store = 0,
        Deflate = 8
    }

    public class ZipFileEntry
    {
        public Compression Method;

        public string FilenameInZip;

        public long FileSize;

        public long CompressedSize;

        public long HeaderOffset;

        public long FileOffset;

        public uint HeaderSize;

        public uint Crc32;

        public DateTime ModifyTime;

        public DateTime CreationTime;

        public DateTime AccessTime;

        public string Comment;

        public bool EncodeUTF8;

        public override string ToString()
        {
            return FilenameInZip;
        }
    }

    public bool EncodeUTF8 = false;

    public bool ForceDeflating = false;

    private List<ZipFileEntry> Files = new List<ZipFileEntry>();

    private string FileName;

    private Stream ZipFileStream;

    private string Comment = string.Empty;

    private byte[] CentralDirImage = null;

    private long ExistingFiles = 0L;

    private FileAccess Access;

    private bool leaveOpen;

    private bool isDisposed = false;

    private static uint[] CrcTable;

    private static Encoding DefaultEncoding;

    static ZipStorer()
    {
        CrcTable = null;
        DefaultEncoding = Encoding.GetEncoding(437);
        CrcTable = new uint[256];
        for (int i = 0; i < CrcTable.Length; i++)
        {
            uint c = (uint)i;
            for (int j = 0; j < 8; j++)
            {
                c = (((c & 1) == 0) ? (c >> 1) : (0xEDB88320u ^ (c >> 1)));
            }
            CrcTable[i] = c;
        }
    }

    public static ZipStorer Create(string _filename, string _comment = null)
    {
        Stream stream = new FileStream(_filename, FileMode.Create, FileAccess.ReadWrite);
        ZipStorer zip = Create(stream, _comment);
        zip.Comment = _comment ?? string.Empty;
        zip.FileName = _filename;
        return zip;
    }

    public static ZipStorer Create(Stream _stream, string _comment = null, bool _leaveOpen = false)
    {
        return new ZipStorer
        {
            Comment = (_comment ?? string.Empty),
            ZipFileStream = _stream,
            Access = FileAccess.Write,
            leaveOpen = _leaveOpen
        };
    }

    public static ZipStorer Open(string _filename, FileAccess _access)
    {
        Stream stream = new FileStream(_filename, FileMode.Open, (_access == FileAccess.Read) ? FileAccess.Read : FileAccess.ReadWrite);
        ZipStorer zip = Open(stream, _access);
        zip.FileName = _filename;
        return zip;
    }

    public static ZipStorer Open(Stream _stream, FileAccess _access, bool _leaveOpen = false)
    {
        if (!_stream.CanSeek && _access != FileAccess.Read)
        {
            throw new InvalidOperationException("Stream cannot seek");
        }
        ZipStorer zip = new ZipStorer
        {
            ZipFileStream = _stream,
            Access = _access,
            leaveOpen = _leaveOpen
        };
        if (zip.ReadFileInfo())
        {
            return zip;
        }
        if (!_leaveOpen)
        {
            zip.Close();
        }
        throw new InvalidDataException();
    }

    public ZipFileEntry AddFile(Compression _method, string _pathname, string _filenameInZip, string _comment = null)
    {
        if (Access == FileAccess.Read)
        {
            throw new InvalidOperationException("Writing is not alowed");
        }
        using FileStream stream = new FileStream(_pathname, FileMode.Open, FileAccess.Read);
        return AddStream(_method, _filenameInZip, stream, File.GetLastWriteTime(_pathname), _comment);
    }

    public ZipFileEntry AddStream(Compression _method, string _filenameInZip, Stream _source, DateTime _modTime, string _comment = null)
    {
        return AddStreamAsync(_method, _filenameInZip, _source, _modTime, _comment);
    }

    private ZipFileEntry AddStreamAsync(Compression _method, string _filenameInZip, Stream _source, DateTime _modTime, string _comment = null)
    {
        if (Access == FileAccess.Read)
        {
            throw new InvalidOperationException("Writing is not alowed");
        }
        ZipFileEntry zfe = new ZipFileEntry
        {
            Method = _method,
            EncodeUTF8 = EncodeUTF8,
            FilenameInZip = NormalizedFilename(_filenameInZip),
            Comment = (_comment ?? string.Empty),
            Crc32 = 0u,
            HeaderOffset = (uint)ZipFileStream.Position,
            CreationTime = _modTime,
            ModifyTime = _modTime,
            AccessTime = _modTime
        };
        WriteLocalHeader(zfe);
        zfe.FileOffset = (uint)ZipFileStream.Position;
        Store(zfe, _source);
        _source.Close();
        UpdateCrcAndSizes(zfe);
        Files.Add(zfe);
        return zfe;
    }

    public void AddDirectory(Compression _method, string _pathname, string _pathnameInZip, string _comment = null)
    {
        if (Access == FileAccess.Read)
        {
            throw new InvalidOperationException("Writing is not allowed");
        }
        int pos = _pathname.LastIndexOf(Path.DirectorySeparatorChar);
        string separator = Path.DirectorySeparatorChar.ToString();
        string foldername = ((pos < 0) ? _pathname : _pathname.Remove(0, pos + 1));
        if (!string.IsNullOrEmpty(_pathnameInZip))
        {
            foldername = _pathnameInZip + foldername;
        }
        if (!foldername.EndsWith(separator, StringComparison.CurrentCulture))
        {
            foldername += separator;
        }
        string[] fileEntries = Directory.GetFiles(_pathname);
        string[] array = fileEntries;
        foreach (string fileName in array)
        {
            AddFile(_method, fileName, foldername + Path.GetFileName(fileName), "");
        }
        string[] subdirectoryEntries = Directory.GetDirectories(_pathname);
        string[] array2 = subdirectoryEntries;
        foreach (string subdirectory in array2)
        {
            AddDirectory(_method, subdirectory, foldername, "");
        }
    }

    public void Close()
    {
        if (Access != FileAccess.Read)
        {
            uint centralOffset = (uint)ZipFileStream.Position;
            uint centralSize = 0u;
            if (CentralDirImage != null)
            {
                ZipFileStream.Write(CentralDirImage, 0, CentralDirImage.Length);
            }
            for (int i = 0; i < Files.Count; i++)
            {
                long pos = ZipFileStream.Position;
                WriteCentralDirRecord(Files[i]);
                centralSize += (uint)(int)(ZipFileStream.Position - pos);
            }
            if (CentralDirImage != null)
            {
                WriteEndRecord((uint)((int)centralSize + CentralDirImage.Length), centralOffset);
            }
            else
            {
                WriteEndRecord(centralSize, centralOffset);
            }
        }
        if (ZipFileStream != null && !leaveOpen)
        {
            ZipFileStream.Flush();
            ZipFileStream.Dispose();
            ZipFileStream = null;
        }
    }

    public List<ZipFileEntry> ReadCentralDir()
    {
        if (CentralDirImage == null)
        {
            throw new InvalidOperationException("Central directory currently does not exist");
        }
        List<ZipFileEntry> result = new List<ZipFileEntry>();
        ushort filenameSize;
        ushort extraSize;
        ushort commentSize;
        for (int pointer = 0; pointer < CentralDirImage.Length; pointer += 46 + filenameSize + extraSize + commentSize)
        {
            uint signature = BitConverter.ToUInt32(CentralDirImage, pointer);
            if (signature != 33639248)
            {
                break;
            }
            bool encodeUTF8 = (BitConverter.ToUInt16(CentralDirImage, pointer + 8) & 0x800) != 0;
            ushort method = BitConverter.ToUInt16(CentralDirImage, pointer + 10);
            uint modifyTime = BitConverter.ToUInt32(CentralDirImage, pointer + 12);
            uint crc32 = BitConverter.ToUInt32(CentralDirImage, pointer + 16);
            long comprSize = BitConverter.ToUInt32(CentralDirImage, pointer + 20);
            long fileSize = BitConverter.ToUInt32(CentralDirImage, pointer + 24);
            filenameSize = BitConverter.ToUInt16(CentralDirImage, pointer + 28);
            extraSize = BitConverter.ToUInt16(CentralDirImage, pointer + 30);
            commentSize = BitConverter.ToUInt16(CentralDirImage, pointer + 32);
            uint headerOffset = BitConverter.ToUInt32(CentralDirImage, pointer + 42);
            uint headerSize = (uint)(46 + filenameSize + extraSize + commentSize);
            DateTime modifyTimeDT = DosTimeToDateTime(modifyTime) ?? DateTime.Now;
            Encoding encoder = (encodeUTF8 ? Encoding.UTF8 : DefaultEncoding);
            ZipFileEntry zfe = new ZipFileEntry
            {
                Method = (Compression)method,
                FilenameInZip = encoder.GetString(CentralDirImage, pointer + 46, filenameSize),
                FileOffset = GetFileOffset(headerOffset),
                FileSize = fileSize,
                CompressedSize = comprSize,
                HeaderOffset = headerOffset,
                HeaderSize = headerSize,
                Crc32 = crc32,
                ModifyTime = modifyTimeDT,
                CreationTime = modifyTimeDT,
                AccessTime = DateTime.Now
            };
            if (commentSize > 0)
            {
                zfe.Comment = encoder.GetString(CentralDirImage, pointer + 46 + filenameSize + extraSize, commentSize);
            }
            if (extraSize > 0)
            {
                ReadExtraInfo(CentralDirImage, pointer + 46 + filenameSize, zfe);
            }
            result.Add(zfe);
        }
        return result;
    }

    public bool ExtractFile(ZipFileEntry _zfe, string _filename)
    {
        string path = Path.GetDirectoryName(_filename);
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }
        if (Directory.Exists(_filename))
        {
            return true;
        }
        bool result;
        using (FileStream output = new FileStream(_filename, FileMode.Create, FileAccess.Write))
        {
            result = ExtractFile(_zfe, output);
        }
        if (result)
        {
            File.SetCreationTime(_filename, _zfe.CreationTime);
            File.SetLastWriteTime(_filename, _zfe.ModifyTime);
            File.SetLastAccessTime(_filename, _zfe.AccessTime);
        }
        return result;
    }

    public bool ExtractFile(ZipFileEntry _zfe, Stream _stream)
    {
        return ExtractFileAsync(_zfe, _stream);
    }

    private bool ExtractFileAsync(ZipFileEntry _zfe, Stream _stream)
    {
        if (!_stream.CanWrite)
        {
            throw new InvalidOperationException("Stream cannot be written");
        }
        byte[] signature = new byte[4];
        ZipFileStream.Seek(_zfe.HeaderOffset, SeekOrigin.Begin);
        ZipFileStream.Read(signature, 0, 4);
        if (BitConverter.ToUInt32(signature, 0) != 67324752)
        {
            return false;
        }
        Stream inStream;
        if (_zfe.Method == Compression.Store)
        {
            inStream = ZipFileStream;
        }
        else
        {
            if (_zfe.Method != Compression.Deflate)
            {
                return false;
            }
            inStream = new DeflateStream(ZipFileStream, CompressionMode.Decompress, leaveOpen: true);
        }
        byte[] buffer = new byte[65535];
        ZipFileStream.Seek(_zfe.FileOffset, SeekOrigin.Begin);
        long bytesPending = _zfe.FileSize;
        while (bytesPending > 0)
        {
            int bytesRead = inStream.Read(buffer, 0, (int)Math.Min(bytesPending, buffer.Length));
            _stream.Write(buffer, 0, bytesRead);
            bytesPending -= (uint)bytesRead;
        }
        _stream.Flush();
        if (_zfe.Method == Compression.Deflate)
        {
            inStream.Dispose();
        }
        return true;
    }

    public bool ExtractFile(ZipFileEntry _zfe, out byte[] _file)
    {
        using MemoryStream ms = new MemoryStream();
        if (ExtractFile(_zfe, ms))
        {
            _file = ms.ToArray();
            return true;
        }
        _file = null;
        return false;
    }

    public static bool RemoveEntries(ref ZipStorer _zip, List<ZipFileEntry> _zfes)
    {
        if (!(_zip.ZipFileStream is FileStream))
        {
            throw new InvalidOperationException("RemoveEntries is allowed just over streams of type FileStream");
        }
        List<ZipFileEntry> fullList = _zip.ReadCentralDir();
        string tempZipName = Path.GetTempFileName();
        string tempEntryName = Path.GetTempFileName();
        try
        {
            ZipStorer tempZip = Create(tempZipName, string.Empty);
            foreach (ZipFileEntry zfe in fullList)
            {
                if (!_zfes.Contains(zfe) && _zip.ExtractFile(zfe, tempEntryName))
                {
                    tempZip.AddFile(zfe.Method, tempEntryName, zfe.FilenameInZip, zfe.Comment);
                }
            }
            _zip.Close();
            tempZip.Close();
            File.Delete(_zip.FileName);
            File.Move(tempZipName, _zip.FileName);
            _zip = Open(_zip.FileName, _zip.Access);
        }
        catch
        {
            return false;
        }
        finally
        {
            if (File.Exists(tempZipName))
            {
                File.Delete(tempZipName);
            }
            if (File.Exists(tempEntryName))
            {
                File.Delete(tempEntryName);
            }
        }
        return true;
    }

    private uint GetFileOffset(uint _headerOffset)
    {
        byte[] buffer = new byte[2];
        ZipFileStream.Seek(_headerOffset + 26, SeekOrigin.Begin);
        ZipFileStream.Read(buffer, 0, 2);
        ushort filenameSize = BitConverter.ToUInt16(buffer, 0);
        ZipFileStream.Read(buffer, 0, 2);
        ushort extraSize = BitConverter.ToUInt16(buffer, 0);
        return (uint)(30 + filenameSize + extraSize + _headerOffset);
    }

    private void WriteLocalHeader(ZipFileEntry _zfe)
    {
        long pos = ZipFileStream.Position;
        Encoding encoder = (_zfe.EncodeUTF8 ? Encoding.UTF8 : DefaultEncoding);
        byte[] encodedFilename = encoder.GetBytes(_zfe.FilenameInZip);
        byte[] extraInfo = CreateExtraInfo(_zfe);
        ZipFileStream.Write(new byte[6] { 80, 75, 3, 4, 20, 0 }, 0, 6);
        ZipFileStream.Write(BitConverter.GetBytes((ushort)(_zfe.EncodeUTF8 ? 2048u : 0u)), 0, 2);
        ZipFileStream.Write(BitConverter.GetBytes((ushort)_zfe.Method), 0, 2);
        ZipFileStream.Write(BitConverter.GetBytes(DateTimeToDosTime(_zfe.ModifyTime)), 0, 4);
        ZipFileStream.Write(new byte[12], 0, 12);
        ZipFileStream.Write(BitConverter.GetBytes((ushort)encodedFilename.Length), 0, 2);
        ZipFileStream.Write(BitConverter.GetBytes((ushort)extraInfo.Length), 0, 2);
        ZipFileStream.Write(encodedFilename, 0, encodedFilename.Length);
        ZipFileStream.Write(extraInfo, 0, extraInfo.Length);
        _zfe.HeaderSize = (uint)(ZipFileStream.Position - pos);
    }

    private void WriteCentralDirRecord(ZipFileEntry _zfe)
    {
        Encoding encoder = (_zfe.EncodeUTF8 ? Encoding.UTF8 : DefaultEncoding);
        byte[] encodedFilename = encoder.GetBytes(_zfe.FilenameInZip);
        byte[] encodedComment = encoder.GetBytes(_zfe.Comment);
        byte[] extraInfo = CreateExtraInfo(_zfe);
        ZipFileStream.Write(new byte[8] { 80, 75, 1, 2, 23, 11, 20, 0 }, 0, 8);
        ZipFileStream.Write(BitConverter.GetBytes((ushort)(_zfe.EncodeUTF8 ? 2048u : 0u)), 0, 2);
        ZipFileStream.Write(BitConverter.GetBytes((ushort)_zfe.Method), 0, 2);
        ZipFileStream.Write(BitConverter.GetBytes(DateTimeToDosTime(_zfe.ModifyTime)), 0, 4);
        ZipFileStream.Write(BitConverter.GetBytes(_zfe.Crc32), 0, 4);
        ZipFileStream.Write(BitConverter.GetBytes(get32bitSize(_zfe.CompressedSize)), 0, 4);
        ZipFileStream.Write(BitConverter.GetBytes(get32bitSize(_zfe.FileSize)), 0, 4);
        ZipFileStream.Write(BitConverter.GetBytes((ushort)encodedFilename.Length), 0, 2);
        ZipFileStream.Write(BitConverter.GetBytes((ushort)extraInfo.Length), 0, 2);
        ZipFileStream.Write(BitConverter.GetBytes((ushort)encodedComment.Length), 0, 2);
        ZipFileStream.Write(BitConverter.GetBytes((ushort)0), 0, 2);
        ZipFileStream.Write(BitConverter.GetBytes((ushort)0), 0, 2);
        ZipFileStream.Write(BitConverter.GetBytes((ushort)0), 0, 2);
        ZipFileStream.Write(BitConverter.GetBytes((ushort)33024), 0, 2);
        ZipFileStream.Write(BitConverter.GetBytes(get32bitSize(_zfe.HeaderOffset)), 0, 4);
        ZipFileStream.Write(encodedFilename, 0, encodedFilename.Length);
        ZipFileStream.Write(extraInfo, 0, extraInfo.Length);
        ZipFileStream.Write(encodedComment, 0, encodedComment.Length);
    }

    private uint get32bitSize(long size)
    {
        return (uint)((size >= uint.MaxValue) ? uint.MaxValue : size);
    }

    private void WriteEndRecord(long _size, long _offset)
    {
        long dirOffset = ZipFileStream.Length;
        ZipFileStream.Position = dirOffset;
        ZipFileStream.Write(new byte[4] { 80, 75, 6, 6 }, 0, 4);
        ZipFileStream.Write(BitConverter.GetBytes(44L), 0, 8);
        ZipFileStream.Write(BitConverter.GetBytes((ushort)45), 0, 2);
        ZipFileStream.Write(BitConverter.GetBytes((ushort)45), 0, 2);
        ZipFileStream.Write(BitConverter.GetBytes(0u), 0, 4);
        ZipFileStream.Write(BitConverter.GetBytes(0u), 0, 4);
        ZipFileStream.Write(BitConverter.GetBytes(Files.Count + ExistingFiles), 0, 8);
        ZipFileStream.Write(BitConverter.GetBytes(Files.Count + ExistingFiles), 0, 8);
        ZipFileStream.Write(BitConverter.GetBytes(_size), 0, 8);
        ZipFileStream.Write(BitConverter.GetBytes(_offset), 0, 8);
        ZipFileStream.Write(new byte[4] { 80, 75, 6, 7 }, 0, 4);
        ZipFileStream.Write(BitConverter.GetBytes(0u), 0, 4);
        ZipFileStream.Write(BitConverter.GetBytes(dirOffset), 0, 8);
        ZipFileStream.Write(BitConverter.GetBytes(1u), 0, 4);
        Encoding encoder = (EncodeUTF8 ? Encoding.UTF8 : DefaultEncoding);
        byte[] encodedComment = encoder.GetBytes(Comment);
        ZipFileStream.Write(new byte[8] { 80, 75, 5, 6, 0, 0, 0, 0 }, 0, 8);
        ZipFileStream.Write(new byte[12]
        {
            255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
            255, 255
        }, 0, 12);
        ZipFileStream.Write(BitConverter.GetBytes((ushort)encodedComment.Length), 0, 2);
        ZipFileStream.Write(encodedComment, 0, encodedComment.Length);
    }

    private Compression Store(ZipFileEntry _zfe, Stream _source)
    {
        byte[] buffer = new byte[16384];
        uint totalRead = 0u;
        long posStart = ZipFileStream.Position;
        long sourceStart = (_source.CanSeek ? _source.Position : 0);
        Stream outStream = ((_zfe.Method != 0) ? new DeflateStream(ZipFileStream, CompressionMode.Compress, leaveOpen: true) : ZipFileStream);
        _zfe.Crc32 = uint.MaxValue;
        int bytesRead;
        do
        {
            bytesRead = _source.Read(buffer, 0, buffer.Length);
            if (bytesRead > 0)
            {
                outStream.Write(buffer, 0, bytesRead);
            }
            for (uint i = 0u; i < bytesRead; i++)
            {
                _zfe.Crc32 = CrcTable[(_zfe.Crc32 ^ buffer[i]) & 0xFF] ^ (_zfe.Crc32 >> 8);
            }
            totalRead += (uint)bytesRead;
        }
        while (bytesRead > 0);
        outStream.Flush();
        if (_zfe.Method == Compression.Deflate)
        {
            outStream.Dispose();
        }
        _zfe.Crc32 ^= uint.MaxValue;
        _zfe.FileSize = totalRead;
        _zfe.CompressedSize = (uint)(ZipFileStream.Position - posStart);
        if (_zfe.Method == Compression.Deflate && !ForceDeflating && _source.CanSeek && _zfe.CompressedSize > _zfe.FileSize)
        {
            _zfe.Method = Compression.Store;
            ZipFileStream.Position = posStart;
            ZipFileStream.SetLength(posStart);
            _source.Position = sourceStart;
            return Store(_zfe, _source);
        }
        return _zfe.Method;
    }

    private uint DateTimeToDosTime(DateTime _dt)
    {
        return (uint)((_dt.Second / 2) | (_dt.Minute << 5) | (_dt.Hour << 11) | (_dt.Day << 16) | (_dt.Month << 21) | (_dt.Year - 1980 << 25));
    }

    private DateTime? DosTimeToDateTime(uint _dt)
    {
        int year = (int)((_dt >> 25) + 1980);
        int month = (int)((_dt >> 21) & 0xF);
        int day = (int)((_dt >> 16) & 0x1F);
        int hours = (int)((_dt >> 11) & 0x1F);
        int minutes = (int)((_dt >> 5) & 0x3F);
        int seconds = (int)((_dt & 0x1F) * 2);
        if (month == 0 || day == 0 || year >= 2107)
        {
            return DateTime.Now;
        }
        return new DateTime(year, month, day, hours, minutes, seconds);
    }

    private byte[] CreateExtraInfo(ZipFileEntry _zfe)
    {
        byte[] buffer = new byte[72];
        BitConverter.GetBytes((ushort)1).CopyTo(buffer, 0);
        BitConverter.GetBytes((ushort)32).CopyTo(buffer, 2);
        BitConverter.GetBytes((ushort)1).CopyTo(buffer, 8);
        BitConverter.GetBytes((ushort)24).CopyTo(buffer, 10);
        BitConverter.GetBytes(_zfe.FileSize).CopyTo(buffer, 12);
        BitConverter.GetBytes(_zfe.CompressedSize).CopyTo(buffer, 20);
        BitConverter.GetBytes(_zfe.HeaderOffset).CopyTo(buffer, 28);
        BitConverter.GetBytes((ushort)10).CopyTo(buffer, 36);
        BitConverter.GetBytes((ushort)32).CopyTo(buffer, 38);
        BitConverter.GetBytes((ushort)1).CopyTo(buffer, 44);
        BitConverter.GetBytes((ushort)24).CopyTo(buffer, 46);
        BitConverter.GetBytes(_zfe.ModifyTime.ToFileTime()).CopyTo(buffer, 48);
        BitConverter.GetBytes(_zfe.AccessTime.ToFileTime()).CopyTo(buffer, 56);
        BitConverter.GetBytes(_zfe.CreationTime.ToFileTime()).CopyTo(buffer, 64);
        return buffer;
    }

    private void ReadExtraInfo(byte[] buffer, int offset, ZipFileEntry _zfe)
    {
        if (buffer.Length < 4)
        {
            return;
        }
        uint length;
        for (int pos = offset; pos < buffer.Length - 4; pos += (int)(length + 4))
        {
            uint extraId = BitConverter.ToUInt16(buffer, pos);
            length = BitConverter.ToUInt16(buffer, pos + 2);
            if (extraId == 1)
            {
                uint tag = BitConverter.ToUInt16(buffer, pos + 8);
                uint size = BitConverter.ToUInt16(buffer, pos + 10);
                if (tag == 1 && size >= 24)
                {
                    if (_zfe.FileSize == uint.MaxValue)
                    {
                        _zfe.FileSize = BitConverter.ToInt64(buffer, pos + 12);
                    }
                    if (_zfe.CompressedSize == uint.MaxValue)
                    {
                        _zfe.CompressedSize = BitConverter.ToInt64(buffer, pos + 20);
                    }
                    if (_zfe.HeaderOffset == uint.MaxValue)
                    {
                        _zfe.HeaderOffset = BitConverter.ToInt64(buffer, pos + 28);
                    }
                }
            }
            if (extraId == 10)
            {
                uint tag = BitConverter.ToUInt16(buffer, pos + 8);
                uint size = BitConverter.ToUInt16(buffer, pos + 10);
                if (tag == 1 && size == 24)
                {
                    _zfe.ModifyTime = DateTime.FromFileTime(BitConverter.ToInt64(buffer, pos + 12));
                    _zfe.AccessTime = DateTime.FromFileTime(BitConverter.ToInt64(buffer, pos + 20));
                    _zfe.CreationTime = DateTime.FromFileTime(BitConverter.ToInt64(buffer, pos + 28));
                }
            }
        }
    }

    private void UpdateCrcAndSizes(ZipFileEntry _zfe)
    {
        long lastPos = ZipFileStream.Position;
        ZipFileStream.Position = _zfe.HeaderOffset + 8;
        ZipFileStream.Write(BitConverter.GetBytes((ushort)_zfe.Method), 0, 2);
        ZipFileStream.Position = _zfe.HeaderOffset + 14;
        ZipFileStream.Write(BitConverter.GetBytes(_zfe.Crc32), 0, 4);
        ZipFileStream.Write(BitConverter.GetBytes(get32bitSize(_zfe.CompressedSize)), 0, 4);
        ZipFileStream.Write(BitConverter.GetBytes(get32bitSize(_zfe.FileSize)), 0, 4);
        ZipFileStream.Position = lastPos;
    }

    private string NormalizedFilename(string _filename)
    {
        string filename = _filename.Replace('\\', '/');
        int pos = filename.IndexOf(':');
        if (pos >= 0)
        {
            filename = filename.Remove(0, pos + 1);
        }
        return filename.Trim('/');
    }

    private bool ReadFileInfo()
    {
        if (ZipFileStream.Length < 22)
        {
            return false;
        }
        try
        {
            ZipFileStream.Seek(-17L, SeekOrigin.End);
            BinaryReader br = new BinaryReader(ZipFileStream);
            do
            {
                ZipFileStream.Seek(-5L, SeekOrigin.Current);
                uint sig = br.ReadUInt32();
                if (sig != 101010256)
                {
                    continue;
                }
                long dirPosition = ZipFileStream.Position - 4;
                ZipFileStream.Seek(6L, SeekOrigin.Current);
                long entries = br.ReadUInt16();
                long centralSize = br.ReadInt32();
                long centralDirOffset = br.ReadUInt32();
                ushort commentSize = br.ReadUInt16();
                long commentPosition = ZipFileStream.Position;
                if (centralDirOffset == uint.MaxValue)
                {
                    ZipFileStream.Position = dirPosition - 20;
                    sig = br.ReadUInt32();
                    if (sig != 117853008)
                    {
                        return false;
                    }
                    ZipFileStream.Seek(4L, SeekOrigin.Current);
                    long dir64Position = br.ReadInt64();
                    ZipFileStream.Position = dir64Position;
                    sig = br.ReadUInt32();
                    if (sig != 101075792)
                    {
                        return false;
                    }
                    ZipFileStream.Seek(28L, SeekOrigin.Current);
                    entries = br.ReadInt64();
                    centralSize = br.ReadInt64();
                    centralDirOffset = br.ReadInt64();
                }
                if (commentPosition + commentSize != ZipFileStream.Length)
                {
                    return false;
                }
                ExistingFiles = entries;
                CentralDirImage = new byte[centralSize];
                ZipFileStream.Seek(centralDirOffset, SeekOrigin.Begin);
                ZipFileStream.Read(CentralDirImage, 0, (int)centralSize);
                ZipFileStream.Seek(centralDirOffset, SeekOrigin.Begin);
                return true;
            }
            while (ZipFileStream.Position > 0);
        }
        catch
        {
        }
        return false;
    }

    public void Dispose()
    {
        Dispose(disposing: true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!isDisposed)
        {
            if (disposing)
            {
                Close();
            }
            isDisposed = true;
        }
    }
}

Ответы (0 шт):