private void WriteHeader(System.IO.Stream s, byte[] bytes) { // write the header info int i = 0; // signature bytes[i++] = (byte)(ZipConstants.ZipEntrySignature & 0x000000FF); bytes[i++] = (byte)((ZipConstants.ZipEntrySignature & 0x0000FF00) >> 8); bytes[i++] = (byte)((ZipConstants.ZipEntrySignature & 0x00FF0000) >> 16); bytes[i++] = (byte)((ZipConstants.ZipEntrySignature & 0xFF000000) >> 24); // version needed Int16 FixedVersionNeeded = 0x14; // from examining existing zip files bytes[i++] = (byte)(FixedVersionNeeded & 0x00FF); bytes[i++] = (byte)((FixedVersionNeeded & 0xFF00) >> 8); // bitfield Int16 BitField = 0x00; // from examining existing zip files bytes[i++] = (byte)(BitField & 0x00FF); bytes[i++] = (byte)((BitField & 0xFF00) >> 8); Int16 CompressionMethod = 0x00; // 0x08 = Deflate, 0x00 == No Compression // compression for directories = 0x00 (No Compression) if (!IsDirectory) { CompressionMethod = 0x08; // CRC32 (Int32) if (_FileData != null) { // If we have FileData, that means we've read this entry from an // existing zip archive. We must just copy the existing file data, // CRC, compressed size, and uncompressed size // over to the new (updated) archive. } else { // special case zero-length files System.IO.FileInfo fi = new System.IO.FileInfo(LocalFileName); if (fi.Length == 0) { CompressionMethod = 0x00; _UncompressedSize = 0; _CompressedSize = 0; _Crc32 = 0; } else { // Read in the data from the file in the filesystem, comress it, and // calculate a CRC on it as we read. CRC32 crc32 = new CRC32(); using (System.IO.Stream input = System.IO.File.OpenRead(LocalFileName)) { UInt32 crc = crc32.GetCrc32AndCopy(input, CompressedStream); _Crc32 = (Int32)crc; } CompressedStream.Close(); // to get the footer bytes written to the underlying stream _UncompressedSize = crc32.TotalBytesRead; _CompressedSize = (Int32)_UnderlyingMemoryStream.Length; // It is possible that applying this stream compression on a previously compressed // file will actually increase the size of the data. In that case, we back-off // and just store the uncompressed (really, already compressed) data. // We need to recompute the CRC, and point to the right data. if (_CompressedSize > _UncompressedSize) { using (System.IO.Stream input = System.IO.File.OpenRead(LocalFileName)) { _UnderlyingMemoryStream = new System.IO.MemoryStream(); UInt32 crc = crc32.GetCrc32AndCopy(input, _UnderlyingMemoryStream); _Crc32 = (Int32)crc; } _UncompressedSize = crc32.TotalBytesRead; _CompressedSize = (Int32)_UnderlyingMemoryStream.Length; if (_CompressedSize != _UncompressedSize) { throw new Exception("No compression but unequal stream lengths!"); } CompressionMethod = 0x00; } } } } // compression method bytes[i++] = (byte)(CompressionMethod & 0x00FF); bytes[i++] = (byte)((CompressionMethod & 0xFF00) >> 8); // LastMod bytes[i++] = (byte)(_LastModDateTime & 0x000000FF); bytes[i++] = (byte)((_LastModDateTime & 0x0000FF00) >> 8); bytes[i++] = (byte)((_LastModDateTime & 0x00FF0000) >> 16); bytes[i++] = (byte)((_LastModDateTime & 0xFF000000) >> 24); // calculated above bytes[i++] = (byte)(_Crc32 & 0x000000FF); bytes[i++] = (byte)((_Crc32 & 0x0000FF00) >> 8); bytes[i++] = (byte)((_Crc32 & 0x00FF0000) >> 16); bytes[i++] = (byte)((_Crc32 & 0xFF000000) >> 24); // CompressedSize (Int32) bytes[i++] = (byte)(_CompressedSize & 0x000000FF); bytes[i++] = (byte)((_CompressedSize & 0x0000FF00) >> 8); bytes[i++] = (byte)((_CompressedSize & 0x00FF0000) >> 16); bytes[i++] = (byte)((_CompressedSize & 0xFF000000) >> 24); // UncompressedSize (Int32) if (_Debug) { System.Console.WriteLine("Uncompressed Size: {0}", _UncompressedSize); } bytes[i++] = (byte)(_UncompressedSize & 0x000000FF); bytes[i++] = (byte)((_UncompressedSize & 0x0000FF00) >> 8); bytes[i++] = (byte)((_UncompressedSize & 0x00FF0000) >> 16); bytes[i++] = (byte)((_UncompressedSize & 0xFF000000) >> 24); // filename length (Int16) Int16 filenameLength = (Int16)FileName.Length; // see note below about TrimVolumeFromFullyQualifiedPaths. if ((TrimVolumeFromFullyQualifiedPaths) && (FileName[1] == ':') && (FileName[2] == '\\')) { filenameLength -= 3; } // apply upper bound to the length if (filenameLength + i > bytes.Length) { filenameLength = (Int16)(bytes.Length - (Int16)i); } bytes[i++] = (byte)(filenameLength & 0x00FF); bytes[i++] = (byte)((filenameLength & 0xFF00) >> 8); // extra field length (short) Int16 ExtraFieldLength = 0x00; bytes[i++] = (byte)(ExtraFieldLength & 0x00FF); bytes[i++] = (byte)((ExtraFieldLength & 0xFF00) >> 8); // Tue, 27 Mar 2007 16:35 // Creating a zip that contains entries with "fully qualified" pathnames // can result in a zip archive that is unreadable by Windows Explorer. // Such archives are valid according to other tools but not to explorer. // To avoid this, we can trim off the leading volume name and slash (eg // c:\) when creating (writing) a zip file. We do this by default and we // leave the old behavior available with the // TrimVolumeFromFullyQualifiedPaths flag - set it to false to get the old // behavior. It only affects zip creation. // actual filename char[] c = ((TrimVolumeFromFullyQualifiedPaths) && (FileName[1] == ':') && (FileName[2] == '\\')) ? FileName.Substring(3).ToCharArray() : // trim off volume letter, colon, and slash FileName.ToCharArray(); int j = 0; if (_Debug) { System.Console.WriteLine("local header: writing filename, {0} chars", c.Length); System.Console.WriteLine("starting offset={0}", i); } for (j = 0; (j < c.Length) && (i + j < bytes.Length); j++) { bytes[i + j] = System.BitConverter.GetBytes(c[j])[0]; if (_Debug) { System.Console.Write(" {0:X2}", bytes[i + j]); } } if (_Debug) { System.Console.WriteLine(); } i += j; // extra field (we always write nothing in this implementation) // ;; // remember the file offset of this header _RelativeOffsetOfHeader = (int)s.Length; if (_Debug) { System.Console.WriteLine("\nAll header data:"); for (j = 0; j < i; j++) { System.Console.Write(" {0:X2}", bytes[j]); } System.Console.WriteLine(); } // finally, write the header to the stream s.Write(bytes, 0, i); // preserve this header data for use with the central directory structure. _header = new byte[i]; if (_Debug) { System.Console.WriteLine("preserving header of {0} bytes", _header.Length); } for (j = 0; j < i; j++) { _header[j] = bytes[j]; } }
private void WriteHeader(Stream s, byte[] bytes) { int num = 0; bytes[num++] = 80; bytes[num++] = 0x4b; bytes[num++] = 3; bytes[num++] = 4; short num2 = 20; bytes[num++] = (byte) (num2 & 0xff); bytes[num++] = (byte) ((num2 & 0xff00) >> 8); short num3 = 0; bytes[num++] = (byte) (num3 & 0xff); bytes[num++] = (byte) ((num3 & 0xff00) >> 8); short num4 = 0; if (!this.IsDirectory) { num4 = 8; if (this._FileData == null) { FileInfo info = new FileInfo(this.LocalFileName); if (info.Length == 0L) { num4 = 0; this._UncompressedSize = 0; this._CompressedSize = 0; this._Crc32 = 0; } else { Stream stream; uint num5; CRC32 crc = new CRC32(); using (stream = File.OpenRead(this.LocalFileName)) { num5 = crc.GetCrc32AndCopy(stream, this.CompressedStream); this._Crc32 = (int) num5; } this.CompressedStream.Close(); this._CompressedStream = null; this._UncompressedSize = crc.TotalBytesRead; this._CompressedSize = (int) this._UnderlyingMemoryStream.Length; if (this._CompressedSize > this._UncompressedSize) { using (stream = File.OpenRead(this.LocalFileName)) { this._UnderlyingMemoryStream = new MemoryStream(); num5 = crc.GetCrc32AndCopy(stream, this._UnderlyingMemoryStream); this._Crc32 = (int) num5; } this._UncompressedSize = crc.TotalBytesRead; this._CompressedSize = (int) this._UnderlyingMemoryStream.Length; if (this._CompressedSize != this._UncompressedSize) { throw new Exception("No compression but unequal stream lengths!"); } num4 = 0; } } } } bytes[num++] = (byte) (num4 & 0xff); bytes[num++] = (byte) ((num4 & 0xff00) >> 8); bytes[num++] = (byte) (this._LastModDateTime & 0xff); bytes[num++] = (byte) ((this._LastModDateTime & 0xff00) >> 8); bytes[num++] = (byte) ((this._LastModDateTime & 0xff0000) >> 0x10); bytes[num++] = (byte) ((this._LastModDateTime & 0xff000000L) >> 0x18); bytes[num++] = (byte) (this._Crc32 & 0xff); bytes[num++] = (byte) ((this._Crc32 & 0xff00) >> 8); bytes[num++] = (byte) ((this._Crc32 & 0xff0000) >> 0x10); bytes[num++] = (byte) ((this._Crc32 & 0xff000000L) >> 0x18); bytes[num++] = (byte) (this._CompressedSize & 0xff); bytes[num++] = (byte) ((this._CompressedSize & 0xff00) >> 8); bytes[num++] = (byte) ((this._CompressedSize & 0xff0000) >> 0x10); bytes[num++] = (byte) ((this._CompressedSize & 0xff000000L) >> 0x18); if (this._Debug) { Console.WriteLine("Uncompressed Size: {0}", this._UncompressedSize); } bytes[num++] = (byte) (this._UncompressedSize & 0xff); bytes[num++] = (byte) ((this._UncompressedSize & 0xff00) >> 8); bytes[num++] = (byte) ((this._UncompressedSize & 0xff0000) >> 0x10); bytes[num++] = (byte) ((this._UncompressedSize & 0xff000000L) >> 0x18); short length = (short) this.FileName.Length; if ((this.TrimVolumeFromFullyQualifiedPaths && (this.FileName[1] == ':')) && (this.FileName[2] == '\\')) { length = (short) (length - 3); } if ((length + num) > bytes.Length) { length = (short) (bytes.Length - ((short) num)); } bytes[num++] = (byte) (length & 0xff); bytes[num++] = (byte) ((length & 0xff00) >> 8); short num7 = 0; bytes[num++] = (byte) (num7 & 0xff); bytes[num++] = (byte) ((num7 & 0xff00) >> 8); char[] chArray = ((this.TrimVolumeFromFullyQualifiedPaths && (this.FileName[1] == ':')) && (this.FileName[2] == '\\')) ? this.FileName.Substring(3).Replace(@"\", "/").ToCharArray() : this.FileName.Replace(@"\", "/").ToCharArray(); int index = 0; if (this._Debug) { Console.WriteLine("local header: writing filename, {0} chars", chArray.Length); Console.WriteLine("starting offset={0}", num); } index = 0; while ((index < chArray.Length) && ((num + index) < bytes.Length)) { bytes[num + index] = BitConverter.GetBytes(chArray[index])[0]; if (this._Debug) { Console.Write(" {0:X2}", bytes[num + index]); } index++; } if (this._Debug) { Console.WriteLine(); } num += index; this._RelativeOffsetOfHeader = (int) s.Length; if (this._Debug) { Console.WriteLine("\nAll header data:"); for (index = 0; index < num; index++) { Console.Write(" {0:X2}", bytes[index]); } Console.WriteLine(); } s.Write(bytes, 0, num); this._header = new byte[num]; if (this._Debug) { Console.WriteLine("preserving header of {0} bytes", this._header.Length); } for (index = 0; index < num; index++) { this._header[index] = bytes[index]; } }
private void WriteHeader(Stream s, byte[] bytes) { int num = 0; bytes[num++] = 80; bytes[num++] = 0x4b; bytes[num++] = 3; bytes[num++] = 4; short num2 = 20; bytes[num++] = (byte)(num2 & 0xff); bytes[num++] = (byte)((num2 & 0xff00) >> 8); short num3 = 0; bytes[num++] = (byte)(num3 & 0xff); bytes[num++] = (byte)((num3 & 0xff00) >> 8); short num4 = 0; if (!this.IsDirectory) { num4 = 8; if (this._FileData == null) { FileInfo info = new FileInfo(this.LocalFileName); if (info.Length == 0L) { num4 = 0; this._UncompressedSize = 0; this._CompressedSize = 0; this._Crc32 = 0; } else { Stream stream; uint num5; CRC32 crc = new CRC32(); using (stream = File.OpenRead(this.LocalFileName)) { num5 = crc.GetCrc32AndCopy(stream, this.CompressedStream); this._Crc32 = (int)num5; } this.CompressedStream.Close(); this._CompressedStream = null; this._UncompressedSize = crc.TotalBytesRead; this._CompressedSize = (int)this._UnderlyingMemoryStream.Length; if (this._CompressedSize > this._UncompressedSize) { using (stream = File.OpenRead(this.LocalFileName)) { this._UnderlyingMemoryStream = new MemoryStream(); num5 = crc.GetCrc32AndCopy(stream, this._UnderlyingMemoryStream); this._Crc32 = (int)num5; } this._UncompressedSize = crc.TotalBytesRead; this._CompressedSize = (int)this._UnderlyingMemoryStream.Length; if (this._CompressedSize != this._UncompressedSize) { throw new Exception("No compression but unequal stream lengths!"); } num4 = 0; } } } } bytes[num++] = (byte)(num4 & 0xff); bytes[num++] = (byte)((num4 & 0xff00) >> 8); bytes[num++] = (byte)(this._LastModDateTime & 0xff); bytes[num++] = (byte)((this._LastModDateTime & 0xff00) >> 8); bytes[num++] = (byte)((this._LastModDateTime & 0xff0000) >> 0x10); bytes[num++] = (byte)((this._LastModDateTime & 0xff000000L) >> 0x18); bytes[num++] = (byte)(this._Crc32 & 0xff); bytes[num++] = (byte)((this._Crc32 & 0xff00) >> 8); bytes[num++] = (byte)((this._Crc32 & 0xff0000) >> 0x10); bytes[num++] = (byte)((this._Crc32 & 0xff000000L) >> 0x18); bytes[num++] = (byte)(this._CompressedSize & 0xff); bytes[num++] = (byte)((this._CompressedSize & 0xff00) >> 8); bytes[num++] = (byte)((this._CompressedSize & 0xff0000) >> 0x10); bytes[num++] = (byte)((this._CompressedSize & 0xff000000L) >> 0x18); if (this._Debug) { Console.WriteLine("Uncompressed Size: {0}", this._UncompressedSize); } bytes[num++] = (byte)(this._UncompressedSize & 0xff); bytes[num++] = (byte)((this._UncompressedSize & 0xff00) >> 8); bytes[num++] = (byte)((this._UncompressedSize & 0xff0000) >> 0x10); bytes[num++] = (byte)((this._UncompressedSize & 0xff000000L) >> 0x18); short length = (short)this.FileName.Length; if ((this.TrimVolumeFromFullyQualifiedPaths && (this.FileName[1] == ':')) && (this.FileName[2] == '\\')) { length = (short)(length - 3); } if ((length + num) > bytes.Length) { length = (short)(bytes.Length - ((short)num)); } bytes[num++] = (byte)(length & 0xff); bytes[num++] = (byte)((length & 0xff00) >> 8); short num7 = 0; bytes[num++] = (byte)(num7 & 0xff); bytes[num++] = (byte)((num7 & 0xff00) >> 8); char[] chArray = ((this.TrimVolumeFromFullyQualifiedPaths && (this.FileName[1] == ':')) && (this.FileName[2] == '\\')) ? this.FileName.Substring(3).Replace(@"\", "/").ToCharArray() : this.FileName.Replace(@"\", "/").ToCharArray(); int index = 0; if (this._Debug) { Console.WriteLine("local header: writing filename, {0} chars", chArray.Length); Console.WriteLine("starting offset={0}", num); } index = 0; while ((index < chArray.Length) && ((num + index) < bytes.Length)) { bytes[num + index] = BitConverter.GetBytes(chArray[index])[0]; if (this._Debug) { Console.Write(" {0:X2}", bytes[num + index]); } index++; } if (this._Debug) { Console.WriteLine(); } num += index; this._RelativeOffsetOfHeader = (int)s.Length; if (this._Debug) { Console.WriteLine("\nAll header data:"); for (index = 0; index < num; index++) { Console.Write(" {0:X2}", bytes[index]); } Console.WriteLine(); } s.Write(bytes, 0, num); this._header = new byte[num]; if (this._Debug) { Console.WriteLine("preserving header of {0} bytes", this._header.Length); } for (index = 0; index < num; index++) { this._header[index] = bytes[index]; } }
private void WriteHeader(System.IO.Stream s, byte[] bytes) { // write the header info int i = 0; // signature bytes[i++] = (byte)(ZipConstants.ZipEntrySignature & 0x000000FF); bytes[i++] = (byte)((ZipConstants.ZipEntrySignature & 0x0000FF00) >> 8); bytes[i++] = (byte)((ZipConstants.ZipEntrySignature & 0x00FF0000) >> 16); bytes[i++] = (byte)((ZipConstants.ZipEntrySignature & 0xFF000000) >> 24); // version needed Int16 FixedVersionNeeded = 0x14; // from examining existing zip files bytes[i++] = (byte)(FixedVersionNeeded & 0x00FF); bytes[i++] = (byte)((FixedVersionNeeded & 0xFF00) >> 8); // bitfield Int16 BitField = 0x00; // from examining existing zip files bytes[i++] = (byte)(BitField & 0x00FF); bytes[i++] = (byte)((BitField & 0xFF00) >> 8); Int16 CompressionMethod = 0x00; // 0x08 = Deflate, 0x00 == No Compression // compression for directories = 0x00 (No Compression) if (!IsDirectory) { CompressionMethod = 0x08; // CRC32 (Int32) if (_FileData != null) { // If we have FileData, that means we've read this entry from an // existing zip archive. We must just copy the existing file data, // CRC, compressed size, and uncompressed size // over to the new (updated) archive. } else { // special case zero-length files System.IO.FileInfo fi = new System.IO.FileInfo(LocalFileName); if (fi.Length == 0) { CompressionMethod = 0x00; _UncompressedSize = 0; _CompressedSize = 0; _Crc32 = 0; } else { // Read in the data from the file in the filesystem, comress it, and // calculate a CRC on it as we read. CRC32 crc32 = new CRC32(); using (System.IO.Stream input = System.IO.File.OpenRead(LocalFileName)) { UInt32 crc = crc32.GetCrc32AndCopy(input, CompressedStream); _Crc32 = (Int32)crc; } CompressedStream.Close(); // to get the footer bytes written to the underlying stream _UncompressedSize = crc32.TotalBytesRead; _CompressedSize = (Int32)_UnderlyingMemoryStream.Length; // It is possible that applying this stream compression on a previously compressed // file will actually increase the size of the data. In that case, we back-off // and just store the uncompressed (really, already compressed) data. // We need to recompute the CRC, and point to the right data. if (_CompressedSize > _UncompressedSize) { using (System.IO.Stream input = System.IO.File.OpenRead(LocalFileName)) { _UnderlyingMemoryStream = new System.IO.MemoryStream(); UInt32 crc = crc32.GetCrc32AndCopy(input, _UnderlyingMemoryStream); _Crc32 = (Int32)crc; } _UncompressedSize = crc32.TotalBytesRead; _CompressedSize = (Int32)_UnderlyingMemoryStream.Length; if (_CompressedSize != _UncompressedSize) throw new Exception("No compression but unequal stream lengths!"); CompressionMethod = 0x00; } } } } // compression method bytes[i++] = (byte)(CompressionMethod & 0x00FF); bytes[i++] = (byte)((CompressionMethod & 0xFF00) >> 8); // LastMod bytes[i++] = (byte)(_LastModDateTime & 0x000000FF); bytes[i++] = (byte)((_LastModDateTime & 0x0000FF00) >> 8); bytes[i++] = (byte)((_LastModDateTime & 0x00FF0000) >> 16); bytes[i++] = (byte)((_LastModDateTime & 0xFF000000) >> 24); // calculated above bytes[i++] = (byte)(_Crc32 & 0x000000FF); bytes[i++] = (byte)((_Crc32 & 0x0000FF00) >> 8); bytes[i++] = (byte)((_Crc32 & 0x00FF0000) >> 16); bytes[i++] = (byte)((_Crc32 & 0xFF000000) >> 24); // CompressedSize (Int32) bytes[i++] = (byte)(_CompressedSize & 0x000000FF); bytes[i++] = (byte)((_CompressedSize & 0x0000FF00) >> 8); bytes[i++] = (byte)((_CompressedSize & 0x00FF0000) >> 16); bytes[i++] = (byte)((_CompressedSize & 0xFF000000) >> 24); // UncompressedSize (Int32) if (_Debug) System.Console.WriteLine("Uncompressed Size: {0}", _UncompressedSize); bytes[i++] = (byte)(_UncompressedSize & 0x000000FF); bytes[i++] = (byte)((_UncompressedSize & 0x0000FF00) >> 8); bytes[i++] = (byte)((_UncompressedSize & 0x00FF0000) >> 16); bytes[i++] = (byte)((_UncompressedSize & 0xFF000000) >> 24); // filename length (Int16) Int16 filenameLength = (Int16)FileName.Length; // see note below about TrimVolumeFromFullyQualifiedPaths. if ((TrimVolumeFromFullyQualifiedPaths) && (FileName[1] == ':') && (FileName[2] == '\\')) filenameLength -= 3; // apply upper bound to the length if (filenameLength + i > bytes.Length) filenameLength = (Int16)(bytes.Length - (Int16)i); bytes[i++] = (byte)(filenameLength & 0x00FF); bytes[i++] = (byte)((filenameLength & 0xFF00) >> 8); // extra field length (short) Int16 ExtraFieldLength = 0x00; bytes[i++] = (byte)(ExtraFieldLength & 0x00FF); bytes[i++] = (byte)((ExtraFieldLength & 0xFF00) >> 8); // Tue, 27 Mar 2007 16:35 // Creating a zip that contains entries with "fully qualified" pathnames // can result in a zip archive that is unreadable by Windows Explorer. // Such archives are valid according to other tools but not to explorer. // To avoid this, we can trim off the leading volume name and slash (eg // c:\) when creating (writing) a zip file. We do this by default and we // leave the old behavior available with the // TrimVolumeFromFullyQualifiedPaths flag - set it to false to get the old // behavior. It only affects zip creation. // actual filename char[] c = ((TrimVolumeFromFullyQualifiedPaths) && (FileName[1] == ':') && (FileName[2] == '\\')) ? FileName.Substring(3).ToCharArray() : // trim off volume letter, colon, and slash FileName.ToCharArray(); int j = 0; if (_Debug) { System.Console.WriteLine("local header: writing filename, {0} chars", c.Length); System.Console.WriteLine("starting offset={0}", i); } for (j = 0; (j < c.Length) && (i + j < bytes.Length); j++) { bytes[i + j] = System.BitConverter.GetBytes(c[j])[0]; if (_Debug) System.Console.Write(" {0:X2}", bytes[i + j]); } if (_Debug) System.Console.WriteLine(); i += j; // extra field (we always write nothing in this implementation) // ;; // remember the file offset of this header _RelativeOffsetOfHeader = (int)s.Length; if (_Debug) { System.Console.WriteLine("\nAll header data:"); for (j = 0; j < i; j++) System.Console.Write(" {0:X2}", bytes[j]); System.Console.WriteLine(); } // finally, write the header to the stream s.Write(bytes, 0, i); // preserve this header data for use with the central directory structure. _header = new byte[i]; if (_Debug) System.Console.WriteLine("preserving header of {0} bytes", _header.Length); for (j = 0; j < i; j++) _header[j] = bytes[j]; }