Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/Archive/Zip/ZipOut.cpp')
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipOut.cpp86
1 files changed, 58 insertions, 28 deletions
diff --git a/CPP/7zip/Archive/Zip/ZipOut.cpp b/CPP/7zip/Archive/Zip/ZipOut.cpp
index efed0a41..8f3f43bf 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipOut.cpp
+++ b/CPP/7zip/Archive/Zip/ZipOut.cpp
@@ -4,6 +4,7 @@
#include "../../../../C/7zCrc.h"
+#include "../../../Windows/TimeUtils.h"
#include "../../Common/OffsetStream.h"
#include "ZipOut.h"
@@ -110,6 +111,40 @@ void COutArchive::WriteUtfName(const CItemOut &item)
WriteBytes(item.Name_Utf, (UInt16)item.Name_Utf.Size());
}
+
+static const unsigned k_Ntfs_ExtraSize = 4 + 2 + 2 + (3 * 8);
+static const unsigned k_UnixTime_ExtraSize = 1 + (1 * 4);
+
+void COutArchive::WriteTimeExtra(const CItemOut &item, bool writeNtfs)
+{
+ if (writeNtfs)
+ {
+ // windows explorer ignores that extra
+ Write16(NFileHeader::NExtraID::kNTFS);
+ Write16(k_Ntfs_ExtraSize);
+ Write32(0); // reserved
+ Write16(NFileHeader::NNtfsExtra::kTagTime);
+ Write16(8 * 3);
+ WriteNtfsTime(item.Ntfs_MTime);
+ WriteNtfsTime(item.Ntfs_ATime);
+ WriteNtfsTime(item.Ntfs_CTime);
+ }
+
+ if (item.Write_UnixTime)
+ {
+ // windows explorer ignores that extra
+ // by specification : should we write to local header also?
+ Write16(NFileHeader::NExtraID::kUnixTime);
+ Write16(k_UnixTime_ExtraSize);
+ const Byte flags = (Byte)((unsigned)1 << NFileHeader::NUnixTime::kMTime);
+ Write8(flags);
+ UInt32 unixTime;
+ NWindows::NTime::FileTime_To_UnixTime(item.Ntfs_MTime, unixTime);
+ Write32(unixTime);
+ }
+}
+
+
void COutArchive::WriteLocalHeader(CItemOut &item, bool needCheck)
{
m_LocalHeaderPos = m_CurPos;
@@ -122,8 +157,14 @@ void COutArchive::WriteLocalHeader(CItemOut &item, bool needCheck)
if (needCheck && m_IsZip64)
isZip64 = true;
+ // Why don't we write NTFS timestamps to local header?
+ // Probably we want to reduce size of archive?
+ const bool writeNtfs = false; // do not write NTFS timestamp to local header
+ // const bool writeNtfs = item.Write_NtfsTime; // write NTFS time to local header
const UInt32 localExtraSize = (UInt32)(
(isZip64 ? (4 + 8 + 8): 0)
+ + (writeNtfs ? 4 + k_Ntfs_ExtraSize : 0)
+ + (item.Write_UnixTime ? 4 + k_UnixTime_ExtraSize : 0)
+ item.Get_UtfName_ExtraSize()
+ item.LocalExtra.GetSize());
if ((UInt16)localExtraSize != localExtraSize)
@@ -168,13 +209,12 @@ void COutArchive::WriteLocalHeader(CItemOut &item, bool needCheck)
Write64(packSize);
}
+ WriteTimeExtra(item, writeNtfs);
+
WriteUtfName(item);
WriteExtra(item.LocalExtra);
- // Why don't we write NTFS timestamps to local header?
- // Probably we want to reduce size of archive?
-
const UInt32 localFileHeaderSize = (UInt32)(m_CurPos - m_LocalHeaderPos);
if (needCheck && m_LocalFileHeaderSize != localFileHeaderSize)
throw CSystemException(E_FAIL);
@@ -231,10 +271,10 @@ void COutArchive::WriteDescriptor(const CItemOut &item)
void COutArchive::WriteCentralHeader(const CItemOut &item)
{
- bool isUnPack64 = DOES_NEED_ZIP64(item.Size);
- bool isPack64 = DOES_NEED_ZIP64(item.PackSize);
- bool isPosition64 = DOES_NEED_ZIP64(item.LocalHeaderPos);
- bool isZip64 = isPack64 || isUnPack64 || isPosition64;
+ const bool isUnPack64 = DOES_NEED_ZIP64(item.Size);
+ const bool isPack64 = DOES_NEED_ZIP64(item.PackSize);
+ const bool isPosition64 = DOES_NEED_ZIP64(item.LocalHeaderPos);
+ const bool isZip64 = isPack64 || isUnPack64 || isPosition64;
Write32(NSignature::kCentralFileHeader);
Write8(item.MadeByVersion.Version);
@@ -249,10 +289,11 @@ void COutArchive::WriteCentralHeader(const CItemOut &item)
Write16((UInt16)item.Name.Len());
const UInt16 zip64ExtraSize = (UInt16)((isUnPack64 ? 8: 0) + (isPack64 ? 8: 0) + (isPosition64 ? 8: 0));
- const UInt16 kNtfsExtraSize = 4 + 2 + 2 + (3 * 8);
+ const bool writeNtfs = item.Write_NtfsTime;
const size_t centralExtraSize =
(isZip64 ? 4 + zip64ExtraSize : 0)
- + (item.NtfsTimeIsDefined ? 4 + kNtfsExtraSize : 0)
+ + (writeNtfs ? 4 + k_Ntfs_ExtraSize : 0)
+ + (item.Write_UnixTime ? 4 + k_UnixTime_ExtraSize : 0)
+ item.Get_UtfName_ExtraSize()
+ item.CentralExtra.GetSize();
@@ -283,18 +324,7 @@ void COutArchive::WriteCentralHeader(const CItemOut &item)
Write64(item.LocalHeaderPos);
}
- if (item.NtfsTimeIsDefined)
- {
- Write16(NFileHeader::NExtraID::kNTFS);
- Write16(kNtfsExtraSize);
- Write32(0); // reserved
- Write16(NFileHeader::NNtfsExtra::kTagTime);
- Write16(8 * 3);
- WriteNtfsTime(item.Ntfs_MTime);
- WriteNtfsTime(item.Ntfs_ATime);
- WriteNtfsTime(item.Ntfs_CTime);
- }
-
+ WriteTimeExtra(item, writeNtfs);
WriteUtfName(item);
WriteExtra(item.CentralExtra);
@@ -304,15 +334,15 @@ void COutArchive::WriteCentralHeader(const CItemOut &item)
void COutArchive::WriteCentralDir(const CObjectVector<CItemOut> &items, const CByteBuffer *comment)
{
- UInt64 cdOffset = GetCurPos();
+ const UInt64 cdOffset = GetCurPos();
FOR_VECTOR (i, items)
WriteCentralHeader(items[i]);
- UInt64 cd64EndOffset = GetCurPos();
- UInt64 cdSize = cd64EndOffset - cdOffset;
- bool cdOffset64 = DOES_NEED_ZIP64(cdOffset);
- bool cdSize64 = DOES_NEED_ZIP64(cdSize);
- bool items64 = items.Size() >= 0xFFFF;
- bool isZip64 = (cdOffset64 || cdSize64 || items64);
+ const UInt64 cd64EndOffset = GetCurPos();
+ const UInt64 cdSize = cd64EndOffset - cdOffset;
+ const bool cdOffset64 = DOES_NEED_ZIP64(cdOffset);
+ const bool cdSize64 = DOES_NEED_ZIP64(cdSize);
+ const bool items64 = items.Size() >= 0xFFFF;
+ const bool isZip64 = (cdOffset64 || cdSize64 || items64);
// isZip64 = true; // to test Zip64