private static bool ReadHeader(Stream s, ZipEntry ze) { var signature = Shared.ReadSignature(s); // return null if this is not a local file header signature if (SignatureIsNotValid(signature)) { s.Seek(-4, SeekOrigin.Current); if (ze._Debug) { Console.WriteLine(" ZipEntry::Read(): Bad signature ({0:X8}) at position {1}", signature, s.Position); } return(false); } var block = new byte[26]; var n = s.Read(block, 0, block.Length); if (n != block.Length) { return(false); } var i = 0; ze.VersionNeeded = (short)(block[i++] + block[i++] * 256); ze.BitField = (short)(block[i++] + block[i++] * 256); ze.CompressionMethod = (short)(block[i++] + block[i++] * 256); ze._LastModDateTime = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256; // the PKZIP spec says that if bit 3 is set (0x0008), then the CRC, Compressed size, and uncompressed size // come directly after the file data. The only way to find it is to scan the zip archive for the signature of // the Data Descriptor, and presume that that signature does not appear in the (compressed) data of the compressed file. if ((ze.BitField & 0x0008) != 0x0008) { ze._Crc32 = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256; ze.CompressedSize = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256; ze.UncompressedSize = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256; } else { // the CRC, compressed size, and uncompressed size are stored later in the stream. // here, we advance the pointer. i += 12; } var filenameLength = (short)(block[i++] + block[i++] * 256); var extraFieldLength = (short)(block[i++] + block[i++] * 256); block = new byte[filenameLength]; n = s.Read(block, 0, block.Length); ze.FileName = Shared.StringFromBuffer(block, 0, block.Length); ze._Extra = new byte[extraFieldLength]; n = s.Read(ze._Extra, 0, ze._Extra.Length); // transform the time data into something usable ze.LastModified = Shared.PackedToDateTime(ze._LastModDateTime); // actually get the compressed size and CRC if necessary if ((ze.BitField & 0x0008) == 0x0008) { var posn = s.Position; var SizeOfDataRead = Shared.FindSignature(s, ZipEntryDataDescriptorSignature); if (SizeOfDataRead == -1) { return(false); } // read 3x 4-byte fields (CRC, Compressed Size, Uncompressed Size) block = new byte[12]; n = s.Read(block, 0, block.Length); if (n != 12) { return(false); } i = 0; ze._Crc32 = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256; ze.CompressedSize = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256; ze.UncompressedSize = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256; if (SizeOfDataRead != ze.CompressedSize) { throw new Exception("Data format error (bit 3 is set)"); } // seek back to previous position, to read file data s.Seek(posn, SeekOrigin.Begin); } return(true); }