void COutArchive::WriteLocalHeader(const CLocalItem &item) { SeekTo(m_BasePosition); bool isZip64 = m_IsZip64 || item.PackSize >= 0xFFFFFFFF || item.UnPackSize >= 0xFFFFFFFF; WriteUInt32(NSignature::kLocalFileHeader); { Byte ver = item.ExtractVersion.Version; if (isZip64 && ver < NFileHeader::NCompressionMethod::kExtractVersion_Zip64) ver = NFileHeader::NCompressionMethod::kExtractVersion_Zip64; WriteByte(ver); } WriteByte(item.ExtractVersion.HostOS); WriteUInt16(item.Flags); WriteUInt16(item.CompressionMethod); WriteUInt32(item.Time); WriteUInt32(item.FileCRC); WriteUInt32(isZip64 ? 0xFFFFFFFF: (UInt32)item.PackSize); WriteUInt32(isZip64 ? 0xFFFFFFFF: (UInt32)item.UnPackSize); WriteUInt16((UInt16)item.Name.Length()); { UInt16 localExtraSize = (UInt16)((isZip64 ? (4 + 16): 0) + item.LocalExtra.GetSize()); if (localExtraSize > m_ExtraSize) throw CSystemException(E_FAIL); } WriteUInt16((UInt16)m_ExtraSize); // test it; WriteBytes((const char *)item.Name, item.Name.Length()); UInt32 extraPos = 0; if (isZip64) { extraPos += 4 + 16; WriteUInt16(NFileHeader::NExtraID::kZip64); WriteUInt16(16); WriteUInt64(item.UnPackSize); WriteUInt64(item.PackSize); } WriteExtra(item.LocalExtra); extraPos += (UInt32)item.LocalExtra.GetSize(); for (; extraPos < m_ExtraSize; extraPos++) WriteByte(0); m_OutBuffer.FlushWithCheck(); MoveBasePosition(item.PackSize); SeekTo(m_BasePosition); }
void COutArchive::WriteCentralHeader(const CItem &item) { bool isUnPack64 = item.UnPackSize >= 0xFFFFFFFF; bool isPack64 = item.PackSize >= 0xFFFFFFFF; bool isPosition64 = item.LocalHeaderPosition >= 0xFFFFFFFF; bool isZip64 = isPack64 || isUnPack64 || isPosition64; WriteUInt32(NSignature::kCentralFileHeader); WriteByte(item.MadeByVersion.Version); WriteByte(item.MadeByVersion.HostOS); WriteByte(item.ExtractVersion.Version); WriteByte(item.ExtractVersion.HostOS); WriteUInt16(item.Flags); WriteUInt16(item.CompressionMethod); WriteUInt32(item.Time); WriteUInt32(item.FileCRC); WriteUInt32(isPack64 ? 0xFFFFFFFF: (UInt32)item.PackSize); WriteUInt32(isUnPack64 ? 0xFFFFFFFF: (UInt32)item.UnPackSize); WriteUInt16((UInt16)item.Name.Length()); UInt16 zip64ExtraSize = (UInt16)((isUnPack64 ? 8: 0) + (isPack64 ? 8: 0) + (isPosition64 ? 8: 0)); UInt16 centralExtraSize = (UInt16)(isZip64 ? (4 + zip64ExtraSize) : 0); centralExtraSize = (UInt16)(centralExtraSize + item.CentralExtra.GetSize()); WriteUInt16(centralExtraSize); // test it; WriteUInt16((UInt16)item.Comment.GetCapacity()); WriteUInt16(0); // DiskNumberStart; WriteUInt16(item.InternalAttributes); WriteUInt32(item.ExternalAttributes); WriteUInt32(isPosition64 ? 0xFFFFFFFF: (UInt32)item.LocalHeaderPosition); WriteBytes((const char *)item.Name, item.Name.Length()); if (isZip64) { WriteUInt16(NFileHeader::NExtraID::kZip64); WriteUInt16(zip64ExtraSize); if(isUnPack64) WriteUInt64(item.UnPackSize); if(isPack64) WriteUInt64(item.PackSize); if(isPosition64) WriteUInt64(item.LocalHeaderPosition); } WriteExtra(item.CentralExtra); if (item.Comment.GetCapacity() > 0) WriteBytes(item.Comment, (UInt32)item.Comment.GetCapacity()); }
void COutArchive::WriteCentralHeader(const CItem &item) { bool isUnPack64 = item.UnPackSize >= 0xFFFFFFFF; bool isPack64 = item.PackSize >= 0xFFFFFFFF; bool isPosition64 = item.LocalHeaderPosition >= 0xFFFFFFFF; bool isZip64 = isPack64 || isUnPack64 || isPosition64; WriteUInt32(NSignature::kCentralFileHeader); WriteByte(item.MadeByVersion.Version); WriteByte(item.MadeByVersion.HostOS); { Byte ver = item.ExtractVersion.Version; if (isZip64 && ver < NFileHeader::NCompressionMethod::kExtractVersion_Zip64) ver = NFileHeader::NCompressionMethod::kExtractVersion_Zip64; WriteByte(ver); } WriteByte(item.ExtractVersion.HostOS); WriteUInt16(item.Flags); WriteUInt16(item.CompressionMethod); WriteUInt32(item.Time); WriteUInt32(item.FileCRC); WriteUInt32(isPack64 ? 0xFFFFFFFF: (UInt32)item.PackSize); WriteUInt32(isUnPack64 ? 0xFFFFFFFF: (UInt32)item.UnPackSize); WriteUInt16((UInt16)item.Name.Length()); UInt16 zip64ExtraSize = (UInt16)((isUnPack64 ? 8: 0) + (isPack64 ? 8: 0) + (isPosition64 ? 8: 0)); const UInt16 kNtfsExtraSize = 4 + 2 + 2 + (3 * 8); UInt16 centralExtraSize = (UInt16)(isZip64 ? (4 + zip64ExtraSize) : 0) + (item.NtfsTimeIsDefined ? (4 + kNtfsExtraSize) : 0); centralExtraSize = (UInt16)(centralExtraSize + item.CentralExtra.GetSize()); WriteUInt16(centralExtraSize); // test it; WriteUInt16((UInt16)item.Comment.GetCapacity()); WriteUInt16(0); // DiskNumberStart; WriteUInt16(item.InternalAttributes); WriteUInt32(item.ExternalAttributes); WriteUInt32(isPosition64 ? 0xFFFFFFFF: (UInt32)item.LocalHeaderPosition); WriteBytes((const char *)item.Name, item.Name.Length()); if (isZip64) { WriteUInt16(NFileHeader::NExtraID::kZip64); WriteUInt16(zip64ExtraSize); if(isUnPack64) WriteUInt64(item.UnPackSize); if(isPack64) WriteUInt64(item.PackSize); if(isPosition64) WriteUInt64(item.LocalHeaderPosition); } if (item.NtfsTimeIsDefined) { WriteUInt16(NFileHeader::NExtraID::kNTFS); WriteUInt16(kNtfsExtraSize); WriteUInt32(0); // reserved WriteUInt16(NFileHeader::NNtfsExtra::kTagTime); WriteUInt16(8 * 3); WriteUInt32(item.NtfsMTime.dwLowDateTime); WriteUInt32(item.NtfsMTime.dwHighDateTime); WriteUInt32(item.NtfsATime.dwLowDateTime); WriteUInt32(item.NtfsATime.dwHighDateTime); WriteUInt32(item.NtfsCTime.dwLowDateTime); WriteUInt32(item.NtfsCTime.dwHighDateTime); } WriteExtra(item.CentralExtra); if (item.Comment.GetCapacity() > 0) WriteBytes(item.Comment, (UInt32)item.Comment.GetCapacity()); }