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:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2022-06-23 13:43:16 +0300
committerKornel <kornel@geekhood.net>2022-06-23 13:43:16 +0300
commitec44a8a0700a8b2444b07f576be332f756754323 (patch)
tree0b19ee3b63dd53aacca6990451022aee54d0aa69 /CPP/7zip/Archive/Zip
parentc3529a41f527101f05e9e834a19205ee33a3b097 (diff)
Diffstat (limited to 'CPP/7zip/Archive/Zip')
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/StdAfx.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipAddCommon.cpp0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipAddCommon.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipCompressionMode.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipHandler.cpp178
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipHandler.h7
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipHandlerOut.cpp81
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipHeader.h9
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipIn.cpp23
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipIn.h0
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipItem.cpp68
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipItem.h5
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipOut.cpp86
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipOut.h9
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipRegister.cpp18
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipUpdate.cpp171
-rwxr-xr-x[-rw-r--r--]CPP/7zip/Archive/Zip/ZipUpdate.h28
17 files changed, 508 insertions, 175 deletions
diff --git a/CPP/7zip/Archive/Zip/StdAfx.h b/CPP/7zip/Archive/Zip/StdAfx.h
index 2854ff3e..2854ff3e 100644..100755
--- a/CPP/7zip/Archive/Zip/StdAfx.h
+++ b/CPP/7zip/Archive/Zip/StdAfx.h
diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
index 2bb57d5c..2bb57d5c 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
+++ b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.h b/CPP/7zip/Archive/Zip/ZipAddCommon.h
index 0aa44adf..0aa44adf 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipAddCommon.h
+++ b/CPP/7zip/Archive/Zip/ZipAddCommon.h
diff --git a/CPP/7zip/Archive/Zip/ZipCompressionMode.h b/CPP/7zip/Archive/Zip/ZipCompressionMode.h
index 842991c4..842991c4 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipCompressionMode.h
+++ b/CPP/7zip/Archive/Zip/ZipCompressionMode.h
diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp
index d8168bbe..1b3985fd 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipHandler.cpp
+++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp
@@ -190,6 +190,8 @@ static const Byte kProps[] =
kpidVolumeIndex,
kpidOffset
// kpidIsAltStream
+ // , kpidChangeTime // for debug
+ // , 255 // for debug
};
static const Byte kArcProps[] =
@@ -347,6 +349,34 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK;
}
+
+static bool NtfsUnixTimeToProp(bool fromCentral,
+ const CExtraBlock &extra,
+ unsigned ntfsIndex, unsigned unixIndex, NWindows::NCOM::CPropVariant &prop)
+{
+ {
+ FILETIME ft;
+ if (extra.GetNtfsTime(ntfsIndex, ft))
+ {
+ PropVariant_SetFrom_NtfsTime(prop, ft);
+ return true;
+ }
+ }
+ {
+ UInt32 unixTime = 0;
+ if (!extra.GetUnixTime(fromCentral, unixIndex, unixTime))
+ return false;
+ /*
+ // we allow unixTime == 0
+ if (unixTime == 0)
+ return false;
+ */
+ PropVariant_SetFrom_UnixTime(prop, unixTime);
+ return true;
+ }
+}
+
+
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
@@ -392,6 +422,30 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidPackSize: prop = item.PackSize; break;
+ case kpidCTime:
+ NtfsUnixTimeToProp(item.FromCentral, extra,
+ NFileHeader::NNtfsExtra::kCTime,
+ NFileHeader::NUnixTime::kCTime, prop);
+ break;
+
+ case kpidATime:
+ NtfsUnixTimeToProp(item.FromCentral, extra,
+ NFileHeader::NNtfsExtra::kATime,
+ NFileHeader::NUnixTime::kATime, prop);
+ break;
+
+ case kpidMTime:
+ {
+ if (!NtfsUnixTimeToProp(item.FromCentral, extra,
+ NFileHeader::NNtfsExtra::kMTime,
+ NFileHeader::NUnixTime::kMTime, prop))
+ {
+ if (item.Time != 0)
+ PropVariant_SetFrom_DosTime(prop, item.Time);
+ }
+ break;
+ }
+
case kpidTimeType:
{
FILETIME ft;
@@ -399,7 +453,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
UInt32 type;
if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, ft))
type = NFileTimeType::kWindows;
- else if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
+ else if (extra.GetUnixTime(item.FromCentral, NFileHeader::NUnixTime::kMTime, unixTime))
type = NFileTimeType::kUnix;
else
type = NFileTimeType::kDOS;
@@ -407,64 +461,28 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
break;
}
- case kpidCTime:
- {
- FILETIME utc;
- bool defined = true;
- if (!extra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, utc))
- {
- UInt32 unixTime = 0;
- if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kCTime, unixTime))
- NTime::UnixTimeToFileTime(unixTime, utc);
- else
- defined = false;
- }
- if (defined)
- prop = utc;
- break;
- }
-
- case kpidATime:
- {
- FILETIME utc;
- bool defined = true;
- if (!extra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, utc))
- {
- UInt32 unixTime = 0;
- if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kATime, unixTime))
- NTime::UnixTimeToFileTime(unixTime, utc);
- else
- defined = false;
- }
- if (defined)
- prop = utc;
-
- break;
- }
-
- case kpidMTime:
+ /*
+ // for debug to get Dos time values:
+ case kpidChangeTime: if (item.Time != 0) PropVariant_SetFrom_DosTime(prop, item.Time); break;
+ // for debug
+ // time difference (dos - utc)
+ case 255:
{
- FILETIME utc;
- bool defined = true;
- if (!extra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utc))
+ if (NtfsUnixTimeToProp(item.FromCentral, extra,
+ NFileHeader::NNtfsExtra::kMTime,
+ NFileHeader::NUnixTime::kMTime, prop))
{
- UInt32 unixTime = 0;
- if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
- NTime::UnixTimeToFileTime(unixTime, utc);
- else
+ FILETIME localFileTime;
+ if (item.Time != 0 && NTime::DosTime_To_FileTime(item.Time, localFileTime))
{
- FILETIME localFileTime;
- if (item.Time == 0)
- defined = false;
- else if (!NTime::DosTimeToFileTime(item.Time, localFileTime) ||
- !LocalFileTimeToFileTime(&localFileTime, &utc))
- utc.dwHighDateTime = utc.dwLowDateTime = 0;
+ UInt64 t1 = FILETIME_To_UInt64(prop.filetime);
+ UInt64 t2 = FILETIME_To_UInt64(localFileTime);
+ prop.Set_Int64(t2 - t1);
}
}
- if (defined)
- prop = utc;
break;
}
+ */
case kpidAttrib: prop = item.GetWinAttrib(); break;
@@ -1122,7 +1140,18 @@ HRESULT CZipDecoder::Decode(
AString_Wipe charPassword;
if (password)
{
- UnicodeStringToMultiByte2(charPassword, (LPCOLESTR)password, CP_ACP);
+ /*
+ // 22.00: do we need UTF-8 passwords here ?
+ if (item.IsUtf8()) // 22.00
+ {
+ // throw 1;
+ ConvertUnicodeToUTF8((LPCOLESTR)password, charPassword);
+ }
+ else
+ */
+ {
+ UnicodeStringToMultiByte2(charPassword, (LPCOLESTR)password, CP_ACP);
+ }
/*
if (wzAesMode || pkAesMode)
{
@@ -1341,6 +1370,8 @@ HRESULT CZipDecoder::Decode(
if (id == NFileHeader::NCompressionMethod::kStore && item.IsEncrypted())
{
+ // for debug : we can disable this code (kStore + 50), if we want to test CopyCoder+Filter
+ // here we use filter without CopyCoder
readFromFilter = false;
COutStreamWithPadPKCS7 *padStreamSpec = NULL;
@@ -1425,33 +1456,44 @@ HRESULT CZipDecoder::Decode(
const UInt32 padSize = _pkAesDecoderSpec->GetPadSize((UInt32)processed);
if (processed + padSize > coderPackSize)
truncatedError = true;
+ else if (processed + padSize < coderPackSize)
+ dataAfterEnd = true;
else
{
- if (processed + padSize < coderPackSize)
- dataAfterEnd = true;
- else
{
- // here we can PKCS7 padding data from reminder (it can be inside stream buffer in coder).
+ // here we check PKCS7 padding data from reminder (it can be inside stream buffer in coder).
CMyComPtr<ICompressReadUnusedFromInBuf> readInStream;
coder->QueryInterface(IID_ICompressReadUnusedFromInBuf, (void **)&readInStream);
- if (readInStream)
+ // CCopyCoder() for kStore doesn't read data outside of (item.Size)
+ if (readInStream || id == NFileHeader::NCompressionMethod::kStore)
{
- // change pad size, it we support another block size in ZipStron
- // here we request more to detect error with data after end.
+ // change pad size, if we support another block size in ZipStrong.
+ // here we request more data to detect error with data after end.
const UInt32 kBufSize = NCrypto::NZipStrong::kAesPadAllign + 16;
Byte buf[kBufSize];
- UInt32 processedSize;
- RINOK(readInStream->ReadUnusedFromInBuf(buf, kBufSize, &processedSize));
+ UInt32 processedSize = 0;
+ if (readInStream)
+ {
+ RINOK(readInStream->ReadUnusedFromInBuf(buf, kBufSize, &processedSize));
+ }
if (processedSize > padSize)
dataAfterEnd = true;
else
{
- if (ReadStream_FALSE(filterStream, buf + processedSize, padSize - processedSize) != S_OK)
- padError = true;
- else
- for (unsigned i = 0; i < padSize; i++)
- if (buf[i] != padSize)
- padError = true;
+ size_t processedSize2 = kBufSize - processedSize;
+ result = ReadStream(filterStream, buf + processedSize, &processedSize2);
+ if (result == S_OK)
+ {
+ processedSize2 += processedSize;
+ if (processedSize2 > padSize)
+ dataAfterEnd = true;
+ else if (processedSize2 < padSize)
+ truncatedError = true;
+ else
+ for (unsigned i = 0; i < padSize; i++)
+ if (buf[i] != padSize)
+ padError = true;
+ }
}
}
}
diff --git a/CPP/7zip/Archive/Zip/ZipHandler.h b/CPP/7zip/Archive/Zip/ZipHandler.h
index 3043e41c..a70a1a76 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipHandler.h
+++ b/CPP/7zip/Archive/Zip/ZipHandler.h
@@ -57,7 +57,9 @@ private:
int m_MainMethod;
bool m_ForceAesMode;
- bool m_WriteNtfsTimeExtra;
+
+ CHandlerTimeOptions TimeOptions;
+
bool _removeSfxBlock;
bool m_ForceLocal;
bool m_ForceUtf8;
@@ -71,7 +73,8 @@ private:
_props.Init();
m_MainMethod = -1;
m_ForceAesMode = false;
- m_WriteNtfsTimeExtra = true;
+ TimeOptions.Init();
+ TimeOptions.Prec = k_PropVar_TimePrec_0;
_removeSfxBlock = false;
m_ForceLocal = false;
m_ForceUtf8 = false;
diff --git a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
index a9b3eae5..77a71df2 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
+++ b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
@@ -30,7 +30,7 @@ namespace NZip {
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
{
- *timeType = NFileTimeType::kDOS;
+ *timeType = TimeOptions.Prec;
return S_OK;
}
@@ -207,27 +207,58 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
}
*/
+ // 22.00 : kpidTimeType is useless here : the code was disabled
+ /*
{
CPropVariant prop;
RINOK(callback->GetProperty(i, kpidTimeType, &prop));
if (prop.vt == VT_UI4)
- ui.NtfsTimeIsDefined = (prop.ulVal == NFileTimeType::kWindows);
+ ui.NtfsTime_IsDefined = (prop.ulVal == NFileTimeType::kWindows);
else
- ui.NtfsTimeIsDefined = m_WriteNtfsTimeExtra;
+ ui.NtfsTime_IsDefined = _Write_NtfsTime;
}
- RINOK(GetTime(callback, i, kpidMTime, ui.Ntfs_MTime));
- RINOK(GetTime(callback, i, kpidATime, ui.Ntfs_ATime));
- RINOK(GetTime(callback, i, kpidCTime, ui.Ntfs_CTime));
+ */
+
+ if (TimeOptions.Write_MTime.Val) RINOK (GetTime (callback, i, kpidMTime, ui.Ntfs_MTime));
+ if (TimeOptions.Write_ATime.Val) RINOK (GetTime (callback, i, kpidATime, ui.Ntfs_ATime));
+ if (TimeOptions.Write_CTime.Val) RINOK (GetTime (callback, i, kpidCTime, ui.Ntfs_CTime));
+ if (TimeOptions.Prec != k_PropVar_TimePrec_DOS)
{
- FILETIME localFileTime = { 0, 0 };
- if (ui.Ntfs_MTime.dwHighDateTime != 0 ||
- ui.Ntfs_MTime.dwLowDateTime != 0)
- if (!FileTimeToLocalFileTime(&ui.Ntfs_MTime, &localFileTime))
- return E_INVALIDARG;
- FileTimeToDosTime(localFileTime, ui.Time);
+ if (TimeOptions.Prec == k_PropVar_TimePrec_Unix ||
+ TimeOptions.Prec == k_PropVar_TimePrec_Base)
+ ui.Write_UnixTime = ! FILETIME_IsZero (ui.Ntfs_MTime);
+ else
+ {
+ /*
+ // if we want to store zero timestamps as zero timestamp, use the following:
+ ui.Write_NtfsTime =
+ _Write_MTime ||
+ _Write_ATime ||
+ _Write_CTime;
+ */
+
+ // We treat zero timestamp as no timestamp
+ ui.Write_NtfsTime =
+ ! FILETIME_IsZero (ui.Ntfs_MTime) ||
+ ! FILETIME_IsZero (ui.Ntfs_ATime) ||
+ ! FILETIME_IsZero (ui.Ntfs_CTime);
+ }
}
+ /*
+ how 0 in dos time works:
+ win10 explorer extract : some random date 1601-04-25.
+ winrar 6.10 : write time.
+ 7zip : MTime of archive is used
+ how 0 in tar works:
+ winrar 6.10 : 1970
+ 0 in dos field can show that there is no timestamp.
+ we write correct 1970-01-01 in dos field, to support correct extraction in Win10.
+ */
+
+ UtcFileTime_To_LocalDosTime(ui.Ntfs_MTime, ui.Time);
+
NItemName::ReplaceSlashes_OsToUnix(name);
bool needSlash = ui.IsDir;
@@ -441,11 +472,21 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (mainMethod != NFileHeader::NCompressionMethod::kStore)
options.MethodSequence.Add(NFileHeader::NCompressionMethod::kStore);
+ CUpdateOptions uo;
+ uo.Write_MTime = TimeOptions.Write_MTime.Val;
+ uo.Write_ATime = TimeOptions.Write_ATime.Val;
+ uo.Write_CTime = TimeOptions.Write_CTime.Val;
+ /*
+ uo.Write_NtfsTime = _Write_NtfsTime &&
+ (_Write_MTime || _Write_ATime || _Write_CTime);
+ uo.Write_UnixTime = _Write_UnixTime;
+ */
+
return Update(
EXTERNAL_CODECS_VARS
m_Items, updateItems, outStream,
m_Archive.IsOpen() ? &m_Archive : NULL, _removeSfxBlock,
- options, callback);
+ uo, options, callback);
COM_TRY_END2
}
@@ -494,10 +535,9 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
return E_INVALIDARG;
}
}
- else if (name.IsEqualTo("tc"))
- {
- RINOK(PROPVARIANT_to_bool(prop, m_WriteNtfsTimeExtra));
- }
+
+
+
else if (name.IsEqualTo("cl"))
{
RINOK(PROPVARIANT_to_bool(prop, m_ForceLocal));
@@ -532,7 +572,12 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
}
else
{
- RINOK(_props.SetProperty(name, prop));
+ bool processed = false;
+ RINOK(TimeOptions.Parse(name, prop, processed));
+ if (!processed)
+ {
+ RINOK(_props.SetProperty(name, prop));
+ }
}
// RINOK(_props.MethodInfo.ParseParamsFromPROPVARIANT(name, prop));
}
diff --git a/CPP/7zip/Archive/Zip/ZipHeader.h b/CPP/7zip/Archive/Zip/ZipHeader.h
index c47659ac..34fa359b 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipHeader.h
+++ b/CPP/7zip/Archive/Zip/ZipHeader.h
@@ -88,14 +88,15 @@ namespace NFileHeader
{
kZip64 = 0x01,
kNTFS = 0x0A,
+ kUnix0 = 0x0D, // Info-ZIP : (UNIX) PK
kStrongEncrypt = 0x17,
kIzNtSecurityDescriptor = 0x4453,
- kUnixTime = 0x5455,
- kUnixExtra = 0x5855,
+ kUnixTime = 0x5455, // "UT" (time) Info-ZIP
+ kUnix1 = 0x5855, // Info-ZIP
kIzUnicodeComment = 0x6375,
kIzUnicodeName = 0x7075,
- kUnix2Extra = 0x7855,
- kUnix3Extra = 0x7875,
+ kUnix2 = 0x7855, // Info-ZIP
+ kUnixN = 0x7875, // Info-ZIP
kWzAES = 0x9901,
kApkAlign = 0xD935
};
diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp
index 076d6bb5..f2b69a9c 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipIn.cpp
+++ b/CPP/7zip/Archive/Zip/ZipIn.cpp
@@ -1045,9 +1045,24 @@ bool CInArchive::ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlo
if (cdItem)
{
- if (isOK && ZIP64_IS_32_MAX(cdItem->LocalHeaderPos))
- { if (size < 8) isOK = false; else { size -= 8; cdItem->LocalHeaderPos = ReadUInt64(); }}
-
+ if (isOK)
+ {
+ if (ZIP64_IS_32_MAX(cdItem->LocalHeaderPos))
+ { if (size < 8) isOK = false; else { size -= 8; cdItem->LocalHeaderPos = ReadUInt64(); }}
+ /*
+ else if (size == 8)
+ {
+ size -= 8;
+ const UInt64 v = ReadUInt64();
+ // soong_zip, an AOSP tool (written in the Go) writes incorrect value.
+ // we can ignore that minor error here
+ if (v != cdItem->LocalHeaderPos)
+ isOK = false; // ignore error
+ // isOK = false; // force error
+ }
+ */
+ }
+
if (isOK && ZIP64_IS_16_MAX(cdItem->Disk))
{ if (size < 4) isOK = false; else { size -= 4; cdItem->Disk = ReadUInt32(); }}
}
@@ -1926,7 +1941,7 @@ static int FindItem(const CObjectVector<CItemEx> &items, const CItemEx &item)
{
if (left >= right)
return -1;
- const unsigned index = (left + right) / 2;
+ const unsigned index = (unsigned)(((size_t)left + (size_t)right) / 2);
const CItemEx &item2 = items[index];
if (item.Disk < item2.Disk)
right = index;
diff --git a/CPP/7zip/Archive/Zip/ZipIn.h b/CPP/7zip/Archive/Zip/ZipIn.h
index 1498afed..1498afed 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipIn.h
+++ b/CPP/7zip/Archive/Zip/ZipIn.h
diff --git a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp
index be336485..cffbb78a 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipItem.cpp
+++ b/CPP/7zip/Archive/Zip/ZipItem.cpp
@@ -30,11 +30,12 @@ static const CUInt32PCharPair g_ExtraTypes[] =
{
{ NExtraID::kZip64, "Zip64" },
{ NExtraID::kNTFS, "NTFS" },
+ { NExtraID::kUnix0, "UNIX" },
{ NExtraID::kStrongEncrypt, "StrongCrypto" },
{ NExtraID::kUnixTime, "UT" },
- { NExtraID::kUnixExtra, "UX" },
- { NExtraID::kUnix2Extra, "Ux" },
- { NExtraID::kUnix3Extra, "ux" },
+ { NExtraID::kUnix1, "UX" },
+ { NExtraID::kUnix2, "Ux" },
+ { NExtraID::kUnixN, "ux" },
{ NExtraID::kIzUnicodeComment, "uc" },
{ NExtraID::kIzUnicodeName, "up" },
{ NExtraID::kIzNtSecurityDescriptor, "SD" },
@@ -50,6 +51,23 @@ void CExtraSubBlock::PrintInfo(AString &s) const
if (pair.Value == ID)
{
s += pair.Name;
+ if (ID == NExtraID::kUnixTime)
+ {
+ if (Data.Size() >= 1)
+ {
+ s += ':';
+ const Byte flags = Data[0];
+ if (flags & 1) s += 'M';
+ if (flags & 2) s += 'A';
+ if (flags & 4) s += 'C';
+ const UInt32 size = (UInt32)(Data.Size()) - 1;
+ if (size % 4 == 0)
+ {
+ s += ':';
+ s.Add_UInt32(size / 4);
+ }
+ }
+ }
/*
if (ID == NExtraID::kApkAlign && Data.Size() >= 2)
{
@@ -133,14 +151,22 @@ bool CExtraSubBlock::ExtractNtfsTime(unsigned index, FILETIME &ft) const
return false;
}
-bool CExtraSubBlock::ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res) const
+bool CExtraSubBlock::Extract_UnixTime(bool isCentral, unsigned index, UInt32 &res) const
{
+ /* Info-Zip :
+ The central-header extra field contains the modification
+ time only, or no timestamp at all.
+ Size of Data is used to flag its presence or absence
+ If "Flags" indicates that Modtime is present in the local header
+ field, it MUST be present in the central header field, too
+ */
+
res = 0;
UInt32 size = (UInt32)Data.Size();
if (ID != NExtraID::kUnixTime || size < 5)
return false;
const Byte *p = (const Byte *)Data;
- Byte flags = *p++;
+ const Byte flags = *p++;
size--;
if (isCentral)
{
@@ -168,18 +194,35 @@ bool CExtraSubBlock::ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res
}
-bool CExtraSubBlock::ExtractUnixExtraTime(unsigned index, UInt32 &res) const
+// Info-ZIP's abandoned "Unix1 timestamps & owner ID info"
+
+bool CExtraSubBlock::Extract_Unix01_Time(unsigned index, UInt32 &res) const
{
res = 0;
- const size_t size = Data.Size();
- unsigned offset = index * 4;
- if (ID != NExtraID::kUnixExtra || size < offset + 4)
+ const unsigned offset = index * 4;
+ if (Data.Size() < offset + 4)
+ return false;
+ if (ID != NExtraID::kUnix0 &&
+ ID != NExtraID::kUnix1)
return false;
const Byte *p = (const Byte *)Data + offset;
res = GetUi32(p);
return true;
}
+/*
+// PKWARE's Unix "extra" is similar to Info-ZIP's abandoned "Unix1 timestamps"
+bool CExtraSubBlock::Extract_Unix_Time(unsigned index, UInt32 &res) const
+{
+ res = 0;
+ const unsigned offset = index * 4;
+ if (ID != NExtraID::kUnix0 || Data.Size() < offset)
+ return false;
+ const Byte *p = (const Byte *)Data + offset;
+ res = GetUi32(p);
+ return true;
+}
+*/
bool CExtraBlock::GetNtfsTime(unsigned index, FILETIME &ft) const
{
@@ -199,7 +242,7 @@ bool CExtraBlock::GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kUnixTime)
- return sb.ExtractUnixTime(isCentral, index, res);
+ return sb.Extract_UnixTime(isCentral, index, res);
}
}
@@ -214,8 +257,9 @@ bool CExtraBlock::GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const
FOR_VECTOR (i, SubBlocks)
{
const CExtraSubBlock &sb = SubBlocks[i];
- if (sb.ID == NFileHeader::NExtraID::kUnixExtra)
- return sb.ExtractUnixExtraTime(index, res);
+ if (sb.ID == NFileHeader::NExtraID::kUnix0 ||
+ sb.ID == NFileHeader::NExtraID::kUnix1)
+ return sb.Extract_Unix01_Time(index, res);
}
}
return false;
diff --git a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h
index 6ee87658..934d7ecf 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipItem.h
+++ b/CPP/7zip/Archive/Zip/ZipItem.h
@@ -31,8 +31,9 @@ struct CExtraSubBlock
CByteBuffer Data;
bool ExtractNtfsTime(unsigned index, FILETIME &ft) const;
- bool ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res) const;
- bool ExtractUnixExtraTime(unsigned index, UInt32 &res) const;
+ bool Extract_UnixTime(bool isCentral, unsigned index, UInt32 &res) const;
+ bool Extract_Unix01_Time(unsigned index, UInt32 &res) const;
+ // bool Extract_Unix_Time(unsigned index, UInt32 &res) const;
bool CheckIzUnicode(const AString &s) const;
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
diff --git a/CPP/7zip/Archive/Zip/ZipOut.h b/CPP/7zip/Archive/Zip/ZipOut.h
index 3546411c..a645d67f 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipOut.h
+++ b/CPP/7zip/Archive/Zip/ZipOut.h
@@ -18,7 +18,8 @@ public:
FILETIME Ntfs_MTime;
FILETIME Ntfs_ATime;
FILETIME Ntfs_CTime;
- bool NtfsTimeIsDefined;
+ bool Write_NtfsTime;
+ bool Write_UnixTime;
// It's possible that NtfsTime is not defined, but there is NtfsTime in Extra.
@@ -32,7 +33,10 @@ public:
return 4 + 5 + size;
}
- CItemOut(): NtfsTimeIsDefined(false) {}
+ CItemOut():
+ Write_NtfsTime(false),
+ Write_UnixTime(false)
+ {}
};
@@ -62,6 +66,7 @@ class COutArchive
Write32(ft.dwHighDateTime);
}
+ void WriteTimeExtra(const CItemOut &item, bool writeNtfs);
void WriteUtfName(const CItemOut &item);
void WriteExtra(const CExtraBlock &extra);
void WriteCommonItemInfo(const CLocalItem &item, bool isZip64);
diff --git a/CPP/7zip/Archive/Zip/ZipRegister.cpp b/CPP/7zip/Archive/Zip/ZipRegister.cpp
index e6929f1b..3ad47153 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipRegister.cpp
+++ b/CPP/7zip/Archive/Zip/ZipRegister.cpp
@@ -20,9 +20,19 @@ REGISTER_ARC_IO(
"zip", "zip z01 zipx jar xpi odt ods docx xlsx epub ipa apk appx", 0, 1,
k_Signature,
0,
- NArcInfoFlags::kFindSignature |
- NArcInfoFlags::kMultiSignature |
- NArcInfoFlags::kUseGlobalOffset,
- IsArc_Zip)
+ NArcInfoFlags::kFindSignature
+ | NArcInfoFlags::kMultiSignature
+ | NArcInfoFlags::kUseGlobalOffset
+ | NArcInfoFlags::kCTime
+ // | NArcInfoFlags::kCTime_Default
+ | NArcInfoFlags::kATime
+ // | NArcInfoFlags::kATime_Default
+ | NArcInfoFlags::kMTime
+ | NArcInfoFlags::kMTime_Default
+ , TIME_PREC_TO_ARC_FLAGS_MASK (NFileTimeType::kWindows)
+ | TIME_PREC_TO_ARC_FLAGS_MASK (NFileTimeType::kUnix)
+ | TIME_PREC_TO_ARC_FLAGS_MASK (NFileTimeType::kDOS)
+ | TIME_PREC_TO_ARC_FLAGS_TIME_DEFAULT (NFileTimeType::kWindows)
+ , IsArc_Zip)
}}
diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
index 26636c78..7f13071a 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipUpdate.cpp
+++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
@@ -74,7 +74,9 @@ static void Copy_From_UpdateItem_To_ItemOut(const CUpdateItem &ui, CItemOut &ite
item.Ntfs_MTime = ui.Ntfs_MTime;
item.Ntfs_ATime = ui.Ntfs_ATime;
item.Ntfs_CTime = ui.Ntfs_CTime;
- item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined;
+
+ item.Write_UnixTime = ui.Write_UnixTime;
+ item.Write_NtfsTime = ui.Write_NtfsTime;
}
static void SetFileHeader(
@@ -476,12 +478,9 @@ static void WriteDirHeader(COutArchive &archive, const CCompressionMethodMode *o
}
-static inline bool IsZero_FILETIME(const FILETIME &ft)
-{
- return (ft.dwHighDateTime == 0 && ft.dwLowDateTime == 0);
-}
-
-static void UpdatePropsFromStream(CUpdateItem &item, ISequentialInStream *fileInStream,
+static void UpdatePropsFromStream(
+ const CUpdateOptions &options,
+ CUpdateItem &item, ISequentialInStream *fileInStream,
IArchiveUpdateCallback *updateCallback, UInt64 &totalComplexity)
{
CMyComPtr<IStreamGetProps> getProps;
@@ -505,36 +504,100 @@ static void UpdatePropsFromStream(CUpdateItem &item, ISequentialInStream *fileIn
}
item.Size = size;
}
-
- if (!IsZero_FILETIME(mTime))
- {
- item.Ntfs_MTime = mTime;
- FILETIME loc = { 0, 0 };
- if (FileTimeToLocalFileTime(&mTime, &loc))
+
+ if (options.Write_MTime)
+ if (!FILETIME_IsZero(mTime))
{
- item.Time = 0;
- NTime::FileTimeToDosTime(loc, item.Time);
+ item.Ntfs_MTime = mTime;
+ NTime::UtcFileTime_To_LocalDosTime(mTime, item.Time);
}
- }
- if (!IsZero_FILETIME(cTime)) item.Ntfs_CTime = cTime;
- if (!IsZero_FILETIME(aTime)) item.Ntfs_ATime = aTime;
+ if (options.Write_CTime) if (!FILETIME_IsZero(cTime)) item.Ntfs_CTime = cTime;
+ if (options.Write_ATime) if (!FILETIME_IsZero(aTime)) item.Ntfs_ATime = aTime;
item.Attrib = attrib;
}
+/*
+static HRESULT ReportProps(
+ IArchiveUpdateCallbackArcProp *reportArcProp,
+ UInt32 index,
+ const CItemOut &item,
+ bool isAesMode)
+{
+ PROPVARIANT prop;
+ prop.vt = VT_EMPTY;
+ prop.wReserved1 = 0;
+
+ NCOM::PropVarEm_Set_UInt64(&prop, item.Size);
+ RINOK(reportArcProp->ReportProp(NEventIndexType::kOutArcIndex, index, kpidSize, &prop));
+
+ NCOM::PropVarEm_Set_UInt64(&prop, item.PackSize);
+ RINOK(reportArcProp->ReportProp(NEventIndexType::kOutArcIndex, index, kpidPackSize, &prop));
+
+ if (!isAesMode)
+ {
+ NCOM::PropVarEm_Set_UInt32(&prop, item.Crc);
+ RINOK(reportArcProp->ReportProp(NEventIndexType::kOutArcIndex, index, kpidCRC, &prop));
+ }
+
+ RINOK(reportArcProp->ReportFinished(NEventIndexType::kOutArcIndex, index, NUpdate::NOperationResult::kOK));
+
+ // if (opCallback) RINOK(opCallback->ReportOperation(NEventIndexType::kOutArcIndex, index, NUpdateNotifyOp::kOpFinished))
+
+ return S_OK;
+}
+*/
+
+/*
+struct CTotalStats
+{
+ UInt64 Size;
+ UInt64 PackSize;
+
+ void UpdateWithItem(const CItemOut &item)
+ {
+ Size += item.Size;
+ PackSize += item.PackSize;
+ }
+};
+
+static HRESULT ReportArcProps(IArchiveUpdateCallbackArcProp *reportArcProp,
+ CTotalStats &st)
+{
+ PROPVARIANT prop;
+ prop.vt = VT_EMPTY;
+ prop.wReserved1 = 0;
+ {
+ NWindows::NCOM::PropVarEm_Set_UInt64(&prop, st.Size);
+ RINOK(reportArcProp->ReportProp(
+ NEventIndexType::kArcProp, 0, kpidSize, &prop));
+ }
+ {
+ NWindows::NCOM::PropVarEm_Set_UInt64(&prop, st.PackSize);
+ RINOK(reportArcProp->ReportProp(
+ NEventIndexType::kArcProp, 0, kpidPackSize, &prop));
+ }
+ return S_OK;
+}
+*/
+
+
static HRESULT Update2St(
DECL_EXTERNAL_CODECS_LOC_VARS
COutArchive &archive,
CInArchive *inArchive,
const CObjectVector<CItemEx> &inputItems,
CObjectVector<CUpdateItem> &updateItems,
+ const CUpdateOptions &updateOptions,
const CCompressionMethodMode *options, bool outSeqMode,
const CByteBuffer *comment,
IArchiveUpdateCallback *updateCallback,
UInt64 &totalComplexity,
- IArchiveUpdateCallbackFile *opCallback)
+ IArchiveUpdateCallbackFile *opCallback
+ // , IArchiveUpdateCallbackArcProp *reportArcProp
+ )
{
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
@@ -575,7 +638,8 @@ static HRESULT Update2St(
}
else
{
- CMyComPtr<ISequentialInStream> fileInStream;
+ CMyComPtr<ISequentialInStream> fileInStream;
+ {
HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream);
if (res == S_FALSE)
{
@@ -596,7 +660,7 @@ static HRESULT Update2St(
}
// seqMode = true; // to test seqMode
- UpdatePropsFromStream(ui, fileInStream, updateCallback, totalComplexity);
+ UpdatePropsFromStream(updateOptions, ui, fileInStream, updateCallback, totalComplexity);
CCompressingResult compressingResult;
@@ -629,10 +693,11 @@ static HRESULT Update2St(
SetItemInfoFromCompressingResult(compressingResult, options->IsRealAesMode(), options->AesKeyMode, item);
archive.WriteLocalHeader_Replace(item);
-
- RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
- unpackSizeTotal += item.Size;
- packSizeTotal += item.PackSize;
+ }
+ // if (reportArcProp) RINOK(ReportProps(reportArcProp, ui.IndexInClient, item, options->IsRealAesMode()))
+ RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
+ unpackSizeTotal += item.Size;
+ packSizeTotal += item.PackSize;
}
}
else
@@ -656,6 +721,14 @@ static HRESULT Update2St(
archive.WriteCentralDir(items, comment);
+ /*
+ CTotalStats stat;
+ stat.Size = unpackSizeTotal;
+ stat.PackSize = packSizeTotal;
+ if (reportArcProp)
+ RINOK(ReportArcProps(reportArcProp, stat))
+ */
+
lps->ProgressOffset += kCentralHeaderSize * updateItems.Size() + 1;
return lps->SetCur();
}
@@ -667,6 +740,7 @@ static HRESULT Update2(
CInArchive *inArchive,
const CObjectVector<CItemEx> &inputItems,
CObjectVector<CUpdateItem> &updateItems,
+ const CUpdateOptions &updateOptions,
const CCompressionMethodMode &options, bool outSeqMode,
const CByteBuffer *comment,
IArchiveUpdateCallback *updateCallback)
@@ -674,6 +748,11 @@ static HRESULT Update2(
CMyComPtr<IArchiveUpdateCallbackFile> opCallback;
updateCallback->QueryInterface(IID_IArchiveUpdateCallbackFile, (void **)&opCallback);
+ /*
+ CMyComPtr<IArchiveUpdateCallbackArcProp> reportArcProp;
+ updateCallback->QueryInterface(IID_IArchiveUpdateCallbackArcProp, (void **)&reportArcProp);
+ */
+
bool unknownComplexity = false;
UInt64 complexity = 0;
UInt64 numFilesToCompress = 0;
@@ -901,11 +980,23 @@ static HRESULT Update2(
return Update2St(
EXTERNAL_CODECS_LOC_VARS
archive, inArchive,
- inputItems, updateItems, &options2, outSeqMode, comment, updateCallback, totalComplexity, opCallback);
+ inputItems, updateItems,
+ updateOptions,
+ &options2, outSeqMode,
+ comment, updateCallback, totalComplexity,
+ opCallback
+ // , reportArcProp
+ );
#ifndef _7ZIP_ST
+ /*
+ CTotalStats stat;
+ stat.Size = 0;
+ stat.PackSize = 0;
+ */
+
CObjectVector<CItemOut> items;
CMtProgressMixer *mtProgressMixerSpec = new CMtProgressMixer;
@@ -1021,7 +1112,7 @@ static HRESULT Update2(
RINOK(res);
if (!fileInStream)
return E_INVALIDARG;
- UpdatePropsFromStream(ui, fileInStream, updateCallback, totalComplexity);
+ UpdatePropsFromStream(updateOptions, ui, fileInStream, updateCallback, totalComplexity);
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
}
@@ -1122,6 +1213,13 @@ static HRESULT Update2(
memRef.WriteToStream(memManager.GetBlockSize(), outStream);
archive.MoveCurPos(item.PackSize);
memRef.FreeOpt(&memManager);
+ /*
+ if (reportArcProp)
+ {
+ stat.UpdateWithItem(item);
+ RINOK(ReportProps(reportArcProp, ui.IndexInClient, item, options.IsRealAesMode()));
+ }
+ */
}
else
{
@@ -1202,6 +1300,14 @@ static HRESULT Update2(
options.IsRealAesMode(), options.AesKeyMode, item);
archive.WriteLocalHeader_Replace(item);
+
+ /*
+ if (reportArcProp)
+ {
+ stat.UpdateWithItem(item);
+ RINOK(ReportProps(reportArcProp, ui.IndexInClient, item, options.IsRealAesMode()));
+ }
+ */
}
else
{
@@ -1230,7 +1336,14 @@ static HRESULT Update2(
RINOK(mtCompressProgressMixer.SetRatioInfo(0, NULL, NULL));
archive.WriteCentralDir(items, comment);
-
+
+ /*
+ if (reportArcProp)
+ {
+ RINOK(ReportArcProps(reportArcProp, stat));
+ }
+ */
+
complexity += kCentralHeaderSize * updateItems.Size() + 1;
mtProgressMixerSpec->Mixer2->SetProgressOffset(complexity);
return mtCompressProgressMixer.SetRatioInfo(0, NULL, NULL);
@@ -1472,6 +1585,7 @@ HRESULT Update(
CObjectVector<CUpdateItem> &updateItems,
ISequentialOutStream *seqOutStream,
CInArchive *inArchive, bool removeSfx,
+ const CUpdateOptions &updateOptions,
const CCompressionMethodMode &compressionMethodMode,
IArchiveUpdateCallback *updateCallback)
{
@@ -1529,6 +1643,7 @@ HRESULT Update(
EXTERNAL_CODECS_LOC_VARS
outArchive, inArchive,
inputItems, updateItems,
+ updateOptions,
compressionMethodMode, outSeqMode,
inArchive ? &inArchive->ArcInfo.Comment : NULL,
updateCallback);
diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.h b/CPP/7zip/Archive/Zip/ZipUpdate.h
index 95e72a47..d1e35347 100644..100755
--- a/CPP/7zip/Archive/Zip/ZipUpdate.h
+++ b/CPP/7zip/Archive/Zip/ZipUpdate.h
@@ -30,7 +30,9 @@ struct CUpdateItem
bool NewData;
bool NewProps;
bool IsDir;
- bool NtfsTimeIsDefined;
+ bool Write_NtfsTime;
+ bool Write_UnixTime;
+ // bool Write_UnixTime_ATime;
bool IsUtf8;
// bool IsAltStream;
int IndexInArc;
@@ -50,30 +52,50 @@ struct CUpdateItem
void Clear()
{
IsDir = false;
- NtfsTimeIsDefined = false;
+
+ Write_NtfsTime = false;
+ Write_UnixTime = false;
+
IsUtf8 = false;
// IsAltStream = false;
+ Time = 0;
Size = 0;
Name.Empty();
Name_Utf.Free();
Comment.Free();
+
+ FILETIME_Clear(Ntfs_MTime);
+ FILETIME_Clear(Ntfs_ATime);
+ FILETIME_Clear(Ntfs_CTime);
}
CUpdateItem():
IsDir(false),
- NtfsTimeIsDefined(false),
+ Write_NtfsTime(false),
+ Write_UnixTime(false),
IsUtf8(false),
// IsAltStream(false),
+ Time(0),
Size(0)
{}
};
+
+struct CUpdateOptions
+{
+ bool Write_MTime;
+ bool Write_ATime;
+ bool Write_CTime;
+};
+
+
HRESULT Update(
DECL_EXTERNAL_CODECS_LOC_VARS
const CObjectVector<CItemEx> &inputItems,
CObjectVector<CUpdateItem> &updateItems,
ISequentialOutStream *seqOutStream,
CInArchive *inArchive, bool removeSfx,
+ const CUpdateOptions &updateOptions,
const CCompressionMethodMode &compressionMethodMode,
IArchiveUpdateCallback *updateCallback);