Beispiel #1
0
        private void WriteLocalEntryHeader(ZipUpdate update)
        {
            ZipEntry outEntry = update.OutEntry;
            outEntry.Offset = baseStream_.Position;
            if (update.Command != UpdateCommand.Copy)
            {
                if (outEntry.CompressionMethod == CompressionMethod.Deflated)
                {
                    if (outEntry.Size == 0L)
                    {
                        outEntry.CompressedSize = outEntry.Size;
                        outEntry.Crc = 0L;
                        outEntry.CompressionMethod = CompressionMethod.Stored;
                    }
                }
                else if (outEntry.CompressionMethod == CompressionMethod.Stored)
                {
                    outEntry.Flags &= -9;
                }
                if (HaveKeys)
                {
                    outEntry.IsCrypted = true;
                    if (outEntry.Crc < 0L)
                    {
                        outEntry.Flags |= 8;
                    }
                }
                else
                {
                    outEntry.IsCrypted = false;
                }
                switch (useZip64_)
                {
                    case UseZip64.On:
                        outEntry.ForceZip64();
                        break;

                    case UseZip64.Dynamic:
                        if (outEntry.Size < 0L)
                        {
                            outEntry.ForceZip64();
                        }
                        break;
                }
            }
            WriteLEInt(0x4034b50);
            WriteLEShort(outEntry.Version);
            WriteLEShort(outEntry.Flags);
            WriteLEShort((byte)outEntry.CompressionMethod);
            WriteLEInt((int)outEntry.DosTime);
            if (!outEntry.HasCrc)
            {
                update.CrcPatchOffset = baseStream_.Position;
                WriteLEInt(0);
            }
            else
            {
                WriteLEInt((int)outEntry.Crc);
            }
            if (outEntry.LocalHeaderRequiresZip64)
            {
                WriteLEInt(-1);
                WriteLEInt(-1);
            }
            else
            {
                if ((outEntry.CompressedSize < 0L) || (outEntry.Size < 0L))
                {
                    update.SizePatchOffset = baseStream_.Position;
                }
                WriteLEInt((int)outEntry.CompressedSize);
                WriteLEInt((int)outEntry.Size);
            }
            byte[] buffer = ZipConstants.ConvertToArray(outEntry.Flags, outEntry.Name);
            if (buffer.Length > 0xffff)
            {
                throw new ZipException("Entry name too long.");
            }
            ZipExtraData data = new ZipExtraData(outEntry.ExtraData);
            if (outEntry.LocalHeaderRequiresZip64)
            {
                data.StartNewEntry();
                data.AddLeLong(outEntry.Size);
                data.AddLeLong(outEntry.CompressedSize);
                data.AddNewEntry(1);
            }
            else
            {
                data.Delete(1);
            }
            outEntry.ExtraData = data.GetEntryData();
            WriteLEShort(buffer.Length);
            WriteLEShort(outEntry.ExtraData.Length);
            if (buffer.Length > 0)
            {
                baseStream_.Write(buffer, 0, buffer.Length);
            }
            if (outEntry.LocalHeaderRequiresZip64)
            {
                if (!data.Find(1))
                {
                    throw new ZipException("Internal error cannot find extra data");
                }
                update.SizePatchOffset = baseStream_.Position + data.CurrentReadIndex;
            }
            if (outEntry.ExtraData.Length > 0)
            {
                baseStream_.Write(outEntry.ExtraData, 0, outEntry.ExtraData.Length);
            }
        }
Beispiel #2
0
 private int WriteCentralDirectoryHeader(ZipEntry entry)
 {
     if (entry.CompressedSize < 0L)
     {
         throw new ZipException("Attempt to write central directory entry with unknown csize");
     }
     if (entry.Size < 0L)
     {
         throw new ZipException("Attempt to write central directory entry with unknown size");
     }
     if (entry.Crc < 0L)
     {
         throw new ZipException("Attempt to write central directory entry with unknown crc");
     }
     WriteLEInt(0x2014b50);
     WriteLEShort(0x33);
     WriteLEShort(entry.Version);
     WriteLEShort(entry.Flags);
     WriteLEShort((byte)entry.CompressionMethod);
     WriteLEInt((int)entry.DosTime);
     WriteLEInt((int)entry.Crc);
     if (entry.IsZip64Forced() || (entry.CompressedSize >= 0xffffffffL))
     {
         WriteLEInt(-1);
     }
     else
     {
         WriteLEInt((int)(((ulong)entry.CompressedSize) & 0xffffffffL));
     }
     if (entry.IsZip64Forced() || (entry.Size >= 0xffffffffL))
     {
         WriteLEInt(-1);
     }
     else
     {
         WriteLEInt((int)entry.Size);
     }
     byte[] buffer = ZipConstants.ConvertToArray(entry.Flags, entry.Name);
     if (buffer.Length > 0xffff)
     {
         throw new ZipException("Entry name is too long.");
     }
     WriteLEShort(buffer.Length);
     ZipExtraData data = new ZipExtraData(entry.ExtraData);
     if (entry.CentralHeaderRequiresZip64)
     {
         data.StartNewEntry();
         if ((entry.Size >= 0xffffffffL) || (useZip64_ == UseZip64.On))
         {
             data.AddLeLong(entry.Size);
         }
         if ((entry.CompressedSize >= 0xffffffffL) || (useZip64_ == UseZip64.On))
         {
             data.AddLeLong(entry.CompressedSize);
         }
         if (entry.Offset >= 0xffffffffL)
         {
             data.AddLeLong(entry.Offset);
         }
         data.AddNewEntry(1);
     }
     else
     {
         data.Delete(1);
     }
     byte[] entryData = data.GetEntryData();
     WriteLEShort(entryData.Length);
     WriteLEShort((entry.Comment != null) ? entry.Comment.Length : 0);
     WriteLEShort(0);
     WriteLEShort(0);
     if (entry.ExternalFileAttributes != -1)
     {
         WriteLEInt(entry.ExternalFileAttributes);
     }
     else if (entry.IsDirectory)
     {
         WriteLEUint(0x10);
     }
     else
     {
         WriteLEUint(0);
     }
     if (entry.Offset >= 0xffffffffL)
     {
         WriteLEUint(uint.MaxValue);
     }
     else
     {
         WriteLEUint((uint)((int)entry.Offset));
     }
     if (buffer.Length > 0)
     {
         baseStream_.Write(buffer, 0, buffer.Length);
     }
     if (entryData.Length > 0)
     {
         baseStream_.Write(entryData, 0, entryData.Length);
     }
     byte[] buffer3 = (entry.Comment != null) ? Encoding.ASCII.GetBytes(entry.Comment) : new byte[0];
     if (buffer3.Length > 0)
     {
         baseStream_.Write(buffer3, 0, buffer3.Length);
     }
     return (((0x2e + buffer.Length) + entryData.Length) + buffer3.Length);
 }
Beispiel #3
0
 public void PutNextEntry(ZipEntry entry)
 {
     bool hasCrc;
     if (entry == null)
     {
         throw new ArgumentNullException("entry");
     }
     if (entries == null)
     {
         throw new InvalidOperationException("ZipOutputStream was finished");
     }
     if (curEntry != null)
     {
         CloseEntry();
     }
     if (entries.Count == 0x7fffffff)
     {
         throw new ZipException("Too many entries for Zip file");
     }
     CompressionMethod compressionMethod = entry.CompressionMethod;
     int compressionLevel = defaultCompressionLevel;
     entry.Flags &= 0x800;
     patchEntryHeader = false;
     if (entry.Size == 0L)
     {
         entry.CompressedSize = entry.Size;
         entry.Crc = 0L;
         compressionMethod = CompressionMethod.Stored;
         hasCrc = true;
     }
     else
     {
         hasCrc = (entry.Size >= 0L) && entry.HasCrc;
         if (compressionMethod == CompressionMethod.Stored)
         {
             if (!hasCrc)
             {
                 if (!CanPatchEntries)
                 {
                     compressionMethod = CompressionMethod.Deflated;
                     compressionLevel = 0;
                 }
             }
             else
             {
                 entry.CompressedSize = entry.Size;
                 hasCrc = entry.HasCrc;
             }
         }
     }
     if (!hasCrc)
     {
         if (!CanPatchEntries)
         {
             entry.Flags |= 8;
         }
         else
         {
             patchEntryHeader = true;
         }
     }
     if (Password != null)
     {
         entry.IsCrypted = true;
         if (entry.Crc < 0L)
         {
             entry.Flags |= 8;
         }
     }
     entry.Offset = offset;
     entry.CompressionMethod = compressionMethod;
     curMethod = compressionMethod;
     sizePatchPos = -1L;
     if ((useZip64_ == UseZip64.On) || ((entry.Size < 0L) && (useZip64_ == UseZip64.Dynamic)))
     {
         entry.ForceZip64();
     }
     WriteLeInt(0x4034b50);
     WriteLeShort(entry.Version);
     WriteLeShort(entry.Flags);
     WriteLeShort((byte)entry.CompressionMethodForHeader);
     WriteLeInt((int)entry.DosTime);
     if (hasCrc)
     {
         WriteLeInt((int)entry.Crc);
         if (entry.LocalHeaderRequiresZip64)
         {
             WriteLeInt(-1);
             WriteLeInt(-1);
         }
         else
         {
             WriteLeInt(entry.IsCrypted ? (((int)entry.CompressedSize) + 12) : ((int)entry.CompressedSize));
             WriteLeInt((int)entry.Size);
         }
     }
     else
     {
         if (patchEntryHeader)
         {
             crcPatchPos = baseOutputStream_.Position;
         }
         WriteLeInt(0);
         if (patchEntryHeader)
         {
             sizePatchPos = baseOutputStream_.Position;
         }
         if (entry.LocalHeaderRequiresZip64 || patchEntryHeader)
         {
             WriteLeInt(-1);
             WriteLeInt(-1);
         }
         else
         {
             WriteLeInt(0);
             WriteLeInt(0);
         }
     }
     byte[] buffer = ZipConstants.ConvertToArray(entry.Flags, entry.Name);
     if (buffer.Length > 0xffff)
     {
         throw new ZipException("Entry name too long.");
     }
     ZipExtraData extraData = new ZipExtraData(entry.ExtraData);
     if (entry.LocalHeaderRequiresZip64)
     {
         extraData.StartNewEntry();
         if (hasCrc)
         {
             extraData.AddLeLong(entry.Size);
             extraData.AddLeLong(entry.CompressedSize);
         }
         else
         {
             extraData.AddLeLong(-1L);
             extraData.AddLeLong(-1L);
         }
         extraData.AddNewEntry(1);
         if (!extraData.Find(1))
         {
             throw new ZipException("Internal error cant find extra data");
         }
         if (patchEntryHeader)
         {
             sizePatchPos = extraData.CurrentReadIndex;
         }
     }
     else
     {
         extraData.Delete(1);
     }
     if (entry.AESKeySize > 0)
     {
         AddExtraDataAES(entry, extraData);
     }
     byte[] entryData = extraData.GetEntryData();
     WriteLeShort(buffer.Length);
     WriteLeShort(entryData.Length);
     if (buffer.Length > 0)
     {
         baseOutputStream_.Write(buffer, 0, buffer.Length);
     }
     if (entry.LocalHeaderRequiresZip64 && patchEntryHeader)
     {
         sizePatchPos += baseOutputStream_.Position;
     }
     if (entryData.Length > 0)
     {
         baseOutputStream_.Write(entryData, 0, entryData.Length);
     }
     offset += (30 + buffer.Length) + entryData.Length;
     if (entry.AESKeySize > 0)
     {
         offset += entry.AESOverheadSize;
     }
     curEntry = entry;
     crc.Reset();
     if (compressionMethod == CompressionMethod.Deflated)
     {
         deflater_.Reset();
         deflater_.SetLevel(compressionLevel);
     }
     size = 0L;
     if (entry.IsCrypted)
     {
         if (entry.AESKeySize > 0)
         {
             WriteAESHeader(entry);
         }
         else if (entry.Crc < 0L)
         {
             WriteEncryptionHeader(entry.DosTime << 0x10);
         }
         else
         {
             WriteEncryptionHeader(entry.Crc);
         }
     }
 }
Beispiel #4
0
 private static void AddExtraDataAES(ZipEntry entry, ZipExtraData extraData)
 {
     extraData.StartNewEntry();
     extraData.AddLeShort(2);
     extraData.AddLeShort(0x4541);
     extraData.AddData(entry.AESEncryptionStrength);
     extraData.AddLeShort((int)entry.CompressionMethod);
     extraData.AddNewEntry(0x9901);
 }
Beispiel #5
0
 public override void Finish()
 {
     if (entries != null)
     {
         if (curEntry != null)
         {
             CloseEntry();
         }
         long count = entries.Count;
         long sizeEntries = 0L;
         foreach (ZipEntry entry in entries)
         {
             WriteLeInt(0x2014b50);
             WriteLeShort(0x33);
             WriteLeShort(entry.Version);
             WriteLeShort(entry.Flags);
             WriteLeShort((short)entry.CompressionMethodForHeader);
             WriteLeInt((int)entry.DosTime);
             WriteLeInt((int)entry.Crc);
             if (entry.IsZip64Forced() || (entry.CompressedSize >= 0xffffffffL))
             {
                 WriteLeInt(-1);
             }
             else
             {
                 WriteLeInt((int)entry.CompressedSize);
             }
             if (entry.IsZip64Forced() || (entry.Size >= 0xffffffffL))
             {
                 WriteLeInt(-1);
             }
             else
             {
                 WriteLeInt((int)entry.Size);
             }
             byte[] buffer = ZipConstants.ConvertToArray(entry.Flags, entry.Name);
             if (buffer.Length > 0xffff)
             {
                 throw new ZipException("Name too long.");
             }
             ZipExtraData extraData = new ZipExtraData(entry.ExtraData);
             if (entry.CentralHeaderRequiresZip64)
             {
                 extraData.StartNewEntry();
                 if (entry.IsZip64Forced() || (entry.Size >= 0xffffffffL))
                 {
                     extraData.AddLeLong(entry.Size);
                 }
                 if (entry.IsZip64Forced() || (entry.CompressedSize >= 0xffffffffL))
                 {
                     extraData.AddLeLong(entry.CompressedSize);
                 }
                 if (entry.Offset >= 0xffffffffL)
                 {
                     extraData.AddLeLong(entry.Offset);
                 }
                 extraData.AddNewEntry(1);
             }
             else
             {
                 extraData.Delete(1);
             }
             if (entry.AESKeySize > 0)
             {
                 AddExtraDataAES(entry, extraData);
             }
             byte[] entryData = extraData.GetEntryData();
             byte[] buffer3 = (entry.Comment != null) ? ZipConstants.ConvertToArray(entry.Flags, entry.Comment) : new byte[0];
             if (buffer3.Length > 0xffff)
             {
                 throw new ZipException("Comment too long.");
             }
             WriteLeShort(buffer.Length);
             WriteLeShort(entryData.Length);
             WriteLeShort(buffer3.Length);
             WriteLeShort(0);
             WriteLeShort(0);
             if (entry.ExternalFileAttributes != -1)
             {
                 WriteLeInt(entry.ExternalFileAttributes);
             }
             else if (entry.IsDirectory)
             {
                 WriteLeInt(0x10);
             }
             else
             {
                 WriteLeInt(0);
             }
             if (entry.Offset >= 0xffffffffL)
             {
                 WriteLeInt(-1);
             }
             else
             {
                 WriteLeInt((int)entry.Offset);
             }
             if (buffer.Length > 0)
             {
                 baseOutputStream_.Write(buffer, 0, buffer.Length);
             }
             if (entryData.Length > 0)
             {
                 baseOutputStream_.Write(entryData, 0, entryData.Length);
             }
             if (buffer3.Length > 0)
             {
                 baseOutputStream_.Write(buffer3, 0, buffer3.Length);
             }
             sizeEntries += ((0x2e + buffer.Length) + entryData.Length) + buffer3.Length;
         }
         using (ZipHelperStream stream = new ZipHelperStream(baseOutputStream_))
         {
             stream.WriteEndOfCentralDirectory(count, sizeEntries, offset, zipComment);
         }
         entries = null;
     }
 }