Пример #1
0
        private void WriteHeader(System.IO.Stream s, byte[] bytes)
        {
            // write the header info

            int i = 0;

            // signature
            bytes[i++] = (byte)(ZipEntrySignature & 0x000000FF);
            bytes[i++] = (byte)((ZipEntrySignature & 0x0000FF00) >> 8);
            bytes[i++] = (byte)((ZipEntrySignature & 0x00FF0000) >> 16);
            bytes[i++] = (byte)((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);

            // compression method
            Int16 CompressionMethod = 0x08;             // 0x08 = Deflate

            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);

            // CRC32 (Int32)
            CRC32  crc32 = new CRC32();
            UInt32 crc   = 0;

            using (System.IO.Stream input = System.IO.File.OpenRead(FileName)) {
                crc = crc32.GetCrc32AndCopy(input, CompressedStream);
            }
            CompressedStream.Close();              // to get the footer bytes written to the underlying stream

            bytes[i++] = (byte)(crc & 0x000000FF);
            bytes[i++] = (byte)((crc & 0x0000FF00) >> 8);
            bytes[i++] = (byte)((crc & 0x00FF0000) >> 16);
            bytes[i++] = (byte)((crc & 0xFF000000) >> 24);

            // CompressedSize (Int32)
            Int32  isz = (Int32)_UnderlyingMemoryStream.Length;
            UInt32 sz  = (UInt32)isz;

            bytes[i++] = (byte)(sz & 0x000000FF);
            bytes[i++] = (byte)((sz & 0x0000FF00) >> 8);
            bytes[i++] = (byte)((sz & 0x00FF0000) >> 16);
            bytes[i++] = (byte)((sz & 0xFF000000) >> 24);

            // UncompressedSize (Int32)
            if (_Debug)
            {
                System.Console.WriteLine("Uncompressed Size: {0}", crc32.TotalBytesRead);
            }
            bytes[i++] = (byte)(crc32.TotalBytesRead & 0x000000FF);
            bytes[i++] = (byte)((crc32.TotalBytesRead & 0x0000FF00) >> 8);
            bytes[i++] = (byte)((crc32.TotalBytesRead & 0x00FF0000) >> 16);
            bytes[i++] = (byte)((crc32.TotalBytesRead & 0xFF000000) >> 24);

            // filename length (Int16)
            Int16 length = (Int16)FileName.Length;

            // see note below about TrimVolumeFromFullyQualifiedPaths.
            if ((TrimVolumeFromFullyQualifiedPaths) && (FileName[1] == ':') && (FileName[2] == '\\'))
            {
                length -= 3;
            }
            bytes[i++] = (byte)(length & 0x00FF);
            bytes[i++] = (byte)((length & 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];
            }
        }
Пример #2
0
		private void WriteHeader(System.IO.Stream s, byte[] bytes) {
			// write the header info

			int i = 0;
			// signature
			bytes[i++] = (byte)(ZipEntrySignature & 0x000000FF);
			bytes[i++] = (byte)((ZipEntrySignature & 0x0000FF00) >> 8);
			bytes[i++] = (byte)((ZipEntrySignature & 0x00FF0000) >> 16);
			bytes[i++] = (byte)((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);

			// compression method
			Int16 CompressionMethod = 0x08; // 0x08 = Deflate
			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);

			// CRC32 (Int32)
			CRC32 crc32 = new CRC32();
			UInt32 crc = 0;
			using (System.IO.Stream input = System.IO.File.OpenRead(FileName)) {
				crc = crc32.GetCrc32AndCopy(input, CompressedStream);
			}
			CompressedStream.Close();  // to get the footer bytes written to the underlying stream

			bytes[i++] = (byte)(crc & 0x000000FF);
			bytes[i++] = (byte)((crc & 0x0000FF00) >> 8);
			bytes[i++] = (byte)((crc & 0x00FF0000) >> 16);
			bytes[i++] = (byte)((crc & 0xFF000000) >> 24);

			// CompressedSize (Int32)
			Int32 isz = (Int32)_UnderlyingMemoryStream.Length;
			UInt32 sz = (UInt32)isz;
			bytes[i++] = (byte)(sz & 0x000000FF);
			bytes[i++] = (byte)((sz & 0x0000FF00) >> 8);
			bytes[i++] = (byte)((sz & 0x00FF0000) >> 16);
			bytes[i++] = (byte)((sz & 0xFF000000) >> 24);

			// UncompressedSize (Int32)
			if (_Debug)
				System.Console.WriteLine("Uncompressed Size: {0}", crc32.TotalBytesRead);
			bytes[i++] = (byte)(crc32.TotalBytesRead & 0x000000FF);
			bytes[i++] = (byte)((crc32.TotalBytesRead & 0x0000FF00) >> 8);
			bytes[i++] = (byte)((crc32.TotalBytesRead & 0x00FF0000) >> 16);
			bytes[i++] = (byte)((crc32.TotalBytesRead & 0xFF000000) >> 24);

			// filename length (Int16)
			Int16 length = (Int16)FileName.Length;
			// see note below about TrimVolumeFromFullyQualifiedPaths.
			if ((TrimVolumeFromFullyQualifiedPaths) && (FileName[1] == ':') && (FileName[2] == '\\'))
				length -= 3;
			bytes[i++] = (byte)(length & 0x00FF);
			bytes[i++] = (byte)((length & 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];

		}