4.58 beta

This commit is contained in:
Igor Pavlov
2008-05-05 00:00:00 +00:00
committed by Kornel Lesiński
parent bd1fa36322
commit 3901bf0ab8
326 changed files with 10643 additions and 14913 deletions

View File

@@ -43,7 +43,7 @@ static HRESULT GetStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC)
resultCRC = CRC_GET_DIGEST(crc);
return S_OK;
}
crc = CrcUpdate(crc, buffer, realProcessedSize);
crc = CrcUpdate(crc, buffer, (size_t)realProcessedSize);
}
}

View File

@@ -81,6 +81,9 @@ STATPROPSTG kProps[] =
{ NULL, kpidSize, VT_UI8},
{ NULL, kpidPackedSize, VT_UI8},
{ NULL, kpidLastWriteTime, VT_FILETIME},
{ NULL, kpidCreationTime, VT_FILETIME},
{ NULL, kpidLastAccessTime, VT_FILETIME},
{ NULL, kpidAttributes, VT_UI4},
{ NULL, kpidEncrypted, VT_BOOL},
@@ -150,17 +153,18 @@ CHandler::CHandler():
InitMethodProperties();
}
static void StringToProp(const CByteBuffer &data, UINT codePage, NWindows::NCOM::CPropVariant &prop)
static AString BytesToString(const CByteBuffer &data)
{
int size = (int)data.GetCapacity();
if (size <= 0)
return;
AString s;
char *p = s.GetBuffer(size + 1);
memcpy(p, (const Byte *)data, size);
p[size] = '\0';
s.ReleaseBuffer();
prop = MultiByteToUnicodeString(s, codePage);
int size = (int)data.GetCapacity();
if (size > 0)
{
char *p = s.GetBuffer(size + 1);
memcpy(p, (const Byte *)data, size);
p[size] = '\0';
s.ReleaseBuffer();
}
return s;
}
IMP_IInArchive_Props
@@ -173,10 +177,8 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
switch(propID)
{
case kpidComment:
{
StringToProp(m_Archive.m_ArchiveInfo.Comment, CP_ACP, prop);
prop = MultiByteToUnicodeString(BytesToString(m_Archive.m_ArchiveInfo.Comment), CP_ACP);
break;
}
}
prop.Detach(value);
COM_TRY_END
@@ -197,8 +199,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
switch(propID)
{
case kpidPath:
prop = NItemName::GetOSName2(
MultiByteToUnicodeString(item.Name, item.GetCodePage()));
prop = NItemName::GetOSName2(item.GetUnicodeString(item.Name));
break;
case kpidIsFolder:
prop = item.IsDirectory();
@@ -209,16 +210,39 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidPackedSize:
prop = item.PackSize;
break;
case kpidTimeType:
FILETIME utcFileTime;
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kTagTime, utcFileTime))
prop = (UInt32)NFileTimeType::kWindows;
break;
case kpidCreationTime:
{
FILETIME ft;
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, ft))
prop = ft;
break;
}
case kpidLastAccessTime:
{
FILETIME ft;
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, ft))
prop = ft;
break;
}
case kpidLastWriteTime:
{
FILETIME localFileTime, utcFileTime;
if (DosTimeToFileTime(item.Time, localFileTime))
FILETIME utcFileTime;
if (!item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utcFileTime))
{
if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
FILETIME localFileTime;
if (DosTimeToFileTime(item.Time, localFileTime))
{
if (!LocalFileTimeToFileTime(&localFileTime, &utcFileTime))
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
}
else
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
}
else
utcFileTime.dwHighDateTime = utcFileTime.dwLowDateTime = 0;
prop = utcFileTime;
break;
}
@@ -230,7 +254,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
break;
case kpidComment:
{
StringToProp(item.Comment, item.GetCodePage(), prop);
prop = item.GetUnicodeString(BytesToString(item.Comment));
break;
}
case kpidCRC:

View File

@@ -59,6 +59,10 @@ private:
bool m_IsAesMode;
Byte m_AesKeyMode;
bool m_WriteNtfsTimeExtra;
bool m_ForseLocal;
bool m_ForseUtf8;
#ifdef COMPRESS_MT
UInt32 _numThreads;
#endif
@@ -77,6 +81,9 @@ private:
m_NumMatchFinderCyclesDefined = false;
m_IsAesMode = false;
m_AesKeyMode = 3; // aes-256
m_WriteNtfsTimeExtra = false;
m_ForseLocal = false;
m_ForseUtf8 = false;
#ifdef COMPRESS_MT
_numThreads = NWindows::NSystem::GetNumberOfProcessors();;
#endif

View File

@@ -66,138 +66,179 @@ static bool IsAsciiString(const UString &s)
catch(const CSystemException &e) { return e.ErrorCode; } \
catch(...) { return E_OUTOFMEMORY; }
static HRESULT GetTime(IArchiveUpdateCallback *callback, int index, PROPID propID, FILETIME &filetime)
{
filetime.dwHighDateTime = filetime.dwLowDateTime = 0;
NCOM::CPropVariant prop;
RINOK(callback->GetProperty(index, propID, &prop));
if (prop.vt == VT_FILETIME)
filetime = prop.filetime;
else if (prop.vt != VT_EMPTY)
return E_INVALIDARG;
return S_OK;
}
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *updateCallback)
IArchiveUpdateCallback *callback)
{
COM_TRY_BEGIN2
CObjectVector<CUpdateItem> updateItems;
for(UInt32 i = 0; i < numItems; i++)
{
CUpdateItem updateItem;
CUpdateItem ui;
Int32 newData;
Int32 newProperties;
UInt32 indexInArchive;
if (!updateCallback)
if (!callback)
return E_FAIL;
RINOK(updateCallback->GetUpdateItemInfo(i,
RINOK(callback->GetUpdateItemInfo(i,
&newData, // 1 - compress 0 - copy
&newProperties,
&indexInArchive));
updateItem.NewProperties = IntToBool(newProperties);
updateItem.NewData = IntToBool(newData);
updateItem.IndexInArchive = indexInArchive;
updateItem.IndexInClient = i;
ui.NewProperties = IntToBool(newProperties);
ui.NewData = IntToBool(newData);
ui.IndexInArchive = indexInArchive;
ui.IndexInClient = i;
// bool existInArchive = (indexInArchive != UInt32(-1));
if (IntToBool(newProperties))
{
FILETIME utcFileTime;
UString name;
bool isDirectoryStatusDefined;
{
NCOM::CPropVariant propVariant;
RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant));
if (propVariant.vt == VT_EMPTY)
updateItem.Attributes = 0;
else if (propVariant.vt != VT_UI4)
NCOM::CPropVariant prop;
RINOK(callback->GetProperty(i, kpidAttributes, &prop));
if (prop.vt == VT_EMPTY)
ui.Attributes = 0;
else if (prop.vt != VT_UI4)
return E_INVALIDARG;
else
updateItem.Attributes = propVariant.ulVal;
ui.Attributes = prop.ulVal;
}
{
NCOM::CPropVariant propVariant;
RINOK(updateCallback->GetProperty(i, kpidLastWriteTime, &propVariant));
if (propVariant.vt != VT_FILETIME)
return E_INVALIDARG;
utcFileTime = propVariant.filetime;
}
{
NCOM::CPropVariant propVariant;
RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant));
if (propVariant.vt == VT_EMPTY)
NCOM::CPropVariant prop;
RINOK(callback->GetProperty(i, kpidPath, &prop));
if (prop.vt == VT_EMPTY)
name.Empty();
else if (propVariant.vt != VT_BSTR)
else if (prop.vt != VT_BSTR)
return E_INVALIDARG;
else
name = propVariant.bstrVal;
name = prop.bstrVal;
}
{
NCOM::CPropVariant propVariant;
RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant));
if (propVariant.vt == VT_EMPTY)
NCOM::CPropVariant prop;
RINOK(callback->GetProperty(i, kpidIsFolder, &prop));
if (prop.vt == VT_EMPTY)
isDirectoryStatusDefined = false;
else if (propVariant.vt != VT_BOOL)
else if (prop.vt != VT_BOOL)
return E_INVALIDARG;
else
{
updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE);
ui.IsDirectory = (prop.boolVal != VARIANT_FALSE);
isDirectoryStatusDefined = true;
}
}
FILETIME localFileTime;
if(!FileTimeToLocalFileTime(&utcFileTime, &localFileTime))
return E_INVALIDARG;
if(!FileTimeToDosTime(localFileTime, updateItem.Time))
{
// return E_INVALIDARG;
CPropVariant prop;
RINOK(callback->GetProperty(i, kpidTimeType, &prop));
if (prop.vt == VT_UI4)
ui.NtfsTimeIsDefined = (prop.ulVal == NFileTimeType::kWindows);
else
ui.NtfsTimeIsDefined = m_WriteNtfsTimeExtra;
}
RINOK(GetTime(callback, i, kpidLastWriteTime, ui.NtfsMTime));
RINOK(GetTime(callback, i, kpidLastAccessTime, ui.NtfsATime));
RINOK(GetTime(callback, i, kpidCreationTime, ui.NtfsCTime));
{
FILETIME localFileTime = { 0, 0 };
if (ui.NtfsMTime.dwHighDateTime != 0 ||
ui.NtfsMTime.dwLowDateTime != 0)
if (!FileTimeToLocalFileTime(&ui.NtfsMTime, &localFileTime))
return E_INVALIDARG;
FileTimeToDosTime(localFileTime, ui.Time);
}
if (!isDirectoryStatusDefined)
updateItem.IsDirectory = ((updateItem.Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
ui.IsDirectory = ((ui.Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
name = NItemName::MakeLegalName(name);
bool needSlash = updateItem.IsDirectory;
bool needSlash = ui.IsDirectory;
const wchar_t kSlash = L'/';
if (!name.IsEmpty())
{
if (name[name.Length() - 1] == kSlash)
{
if (!updateItem.IsDirectory)
if (!ui.IsDirectory)
return E_INVALIDARG;
needSlash = false;
}
}
if (needSlash)
name += kSlash;
updateItem.Name = UnicodeStringToMultiByte(name, CP_OEMCP);
if (updateItem.Name.Length() > 0xFFFF)
bool tryUtf8 = true;
if (m_ForseLocal || !m_ForseUtf8)
{
bool defaultCharWasUsed;
ui.Name = UnicodeStringToMultiByte(name, CP_OEMCP, '_', defaultCharWasUsed);
tryUtf8 = (!m_ForseLocal && defaultCharWasUsed);
}
if (tryUtf8)
{
bool needUtf = false;
for (int i = 0; i < name.Length(); i++)
if ((unsigned)name[i] >= 0x80)
{
needUtf = true;
break;
}
ui.IsUtf8 = needUtf;
if (!ConvertUnicodeToUTF8(name, ui.Name))
return E_INVALIDARG;
}
if (ui.Name.Length() > 0xFFFF)
return E_INVALIDARG;
updateItem.IndexInClient = i;
ui.IndexInClient = i;
/*
if(existInArchive)
{
const CItemEx &itemInfo = m_Items[indexInArchive];
// updateItem.Commented = itemInfo.IsCommented();
updateItem.Commented = false;
if(updateItem.Commented)
// ui.Commented = itemInfo.IsCommented();
ui.Commented = false;
if(ui.Commented)
{
updateItem.CommentRange.Position = itemInfo.GetCommentPosition();
updateItem.CommentRange.Size = itemInfo.CommentSize;
ui.CommentRange.Position = itemInfo.GetCommentPosition();
ui.CommentRange.Size = itemInfo.CommentSize;
}
}
else
updateItem.Commented = false;
ui.Commented = false;
*/
}
if (IntToBool(newData))
{
UInt64 size;
{
NCOM::CPropVariant propVariant;
RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant));
if (propVariant.vt != VT_UI8)
NCOM::CPropVariant prop;
RINOK(callback->GetProperty(i, kpidSize, &prop));
if (prop.vt != VT_UI8)
return E_INVALIDARG;
size = propVariant.uhVal.QuadPart;
size = prop.uhVal.QuadPart;
}
updateItem.Size = size;
ui.Size = size;
}
updateItems.Add(updateItem);
updateItems.Add(ui);
}
CMyComPtr<ICryptoGetTextPassword2> getTextPassword;
if (!getTextPassword)
{
CMyComPtr<IArchiveUpdateCallback> udateCallBack2(updateCallback);
CMyComPtr<IArchiveUpdateCallback> udateCallBack2(callback);
udateCallBack2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword);
}
CCompressionMethodMode options;
@@ -281,7 +322,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return Update(
EXTERNAL_CODECS_VARS
m_Items, updateItems, outStream,
m_ArchiveIsOpen ? &m_Archive : NULL, &options, updateCallback);
m_ArchiveIsOpen ? &m_Archive : NULL, &options, callback);
COM_TRY_END2
}
@@ -406,6 +447,22 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
RINOK(ParsePropValue(name.Mid(1), prop, num));
m_Algo = num;
}
else if (name.CompareNoCase(L"TC") == 0)
return SetBoolProperty(m_WriteNtfsTimeExtra, prop);
else if (name.CompareNoCase(L"CL") == 0)
{
RINOK(SetBoolProperty(m_ForseLocal, prop));
if (m_ForseLocal)
m_ForseUtf8 = false;
return S_OK;
}
else if (name.CompareNoCase(L"CU") == 0)
{
RINOK(SetBoolProperty(m_ForseUtf8, prop));
if (m_ForseUtf8)
m_ForseLocal = false;
return S_OK;
}
else
return E_INVALIDARG;
}

View File

@@ -86,11 +86,23 @@ namespace NFileHeader
enum
{
kZip64 = 0x01,
kNTFS = 0x0A,
kStrongEncrypt = 0x17,
kWzAES = 0x9901
};
}
namespace NNtfsExtra
{
const UInt16 kTagTime = 1;
enum
{
kMTime = 0,
kATime = 1,
kCTime = 2
};
}
const UInt32 kLocalBlockSize = 26;
/*
struct CLocalBlock
@@ -156,13 +168,11 @@ namespace NFileHeader
namespace NFlags
{
const int kNumUsedBits = 4;
const int kUsedBitsMask = (1 << kNumUsedBits) - 1;
const int kEncrypted = 1 << 0;
const int kDescriptorUsedMask = 1 << 3;
const int kStrongEncrypted = 1 << 6;
const int kUtf8 = 1 << 11;
const int kImplodeDictionarySizeMask = 1 << 1;
const int kImplodeLiteralsOnMask = 1 << 2;

View File

@@ -114,10 +114,10 @@ bool CInArchive::FindAndReadMarker(const UInt64 *searchHeaderSizeLimit)
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 *processedSize)
{
UInt32 realProcessedSize;
HRESULT result = ReadStream(m_Stream, data, size, &realProcessedSize);
size_t realProcessedSize = size;
HRESULT result = ReadStream(m_Stream, data, &realProcessedSize);
if(processedSize != NULL)
*processedSize = realProcessedSize;
*processedSize = (UInt32)realProcessedSize;
m_Position += realProcessedSize;
return result;
}
@@ -304,7 +304,7 @@ HRESULT CInArchive::ReadLocalItem(CItemEx &item)
{
item.ExtractVersion.Version = ReadByte();
item.ExtractVersion.HostOS = ReadByte();
item.Flags = ReadUInt16(); // & NFileHeader::NFlags::kUsedBitsMask;
item.Flags = ReadUInt16();
item.CompressionMethod = ReadUInt16();
item.Time = ReadUInt32();
item.FileCRC = ReadUInt32();
@@ -467,7 +467,7 @@ HRESULT CInArchive::ReadCdItem(CItemEx &item)
item.MadeByVersion.HostOS = ReadByte();
item.ExtractVersion.Version = ReadByte();
item.ExtractVersion.HostOS = ReadByte();
item.Flags = ReadUInt16(); // & NFileHeader::NFlags::kUsedBitsMask;
item.Flags = ReadUInt16();
item.CompressionMethod = ReadUInt16();
item.Time = ReadUInt32();
item.FileCRC = ReadUInt32();
@@ -772,7 +772,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr
return S_FALSE;
UInt16 thisDiskNumber16 = ReadUInt16();
if (!isZip64 || thisDiskNumber16)
if (!isZip64 || thisDiskNumber16 != 0xFFFF)
thisDiskNumber = thisDiskNumber16;
UInt16 startCDDiskNumber16 = ReadUInt16();

View File

@@ -5,6 +5,7 @@
#include "ZipHeader.h"
#include "ZipItem.h"
#include "../Common/ItemNameUtils.h"
#include "../../../../C/CpuArch.h"
namespace NArchive {
namespace NZip {
@@ -19,6 +20,37 @@ bool operator!=(const CVersion &v1, const CVersion &v2)
return !(v1 == v2);
}
bool CExtraSubBlock::ExtractNtfsTime(int index, FILETIME &ft) const
{
ft.dwHighDateTime = ft.dwLowDateTime = 0;
UInt32 size = (UInt32)Data.GetCapacity();
if (ID != NFileHeader::NExtraID::kNTFS || size < 32)
return false;
const Byte *p = (const Byte *)Data;
p += 4; // for reserved
size -= 4;
while (size > 4)
{
UInt16 tag = GetUi16(p);
UInt32 attrSize = GetUi16(p + 2);
p += 4;
size -= 4;
if (attrSize > size)
attrSize = size;
if (tag == NFileHeader::NNtfsExtra::kTagTime && attrSize >= 24)
{
p += 8 * index;
ft.dwLowDateTime = GetUi32(p);
ft.dwHighDateTime = GetUi32(p + 4);
return true;
}
p += attrSize;
size -= attrSize;
}
return false;
}
bool CLocalItem::IsImplodeBigDictionary() const
{
if (CompressionMethod != NFileHeader::NCompressionMethod::kImploded)
@@ -126,5 +158,7 @@ void CLocalItem::SetBitMask(int bitMask, bool enable)
void CLocalItem::SetEncrypted(bool encrypted)
{ SetBitMask(NFileHeader::NFlags::kEncrypted, encrypted); }
void CLocalItem::SetUtf8(bool isUtf8)
{ SetBitMask(NFileHeader::NFlags::kUtf8, isUtf8); }
}}

View File

@@ -6,6 +6,8 @@
#include "Common/Types.h"
#include "Common/MyString.h"
#include "Common/Buffer.h"
#include "Common/UTFConvert.h"
#include "Common/StringConvert.h"
#include "ZipHeader.h"
@@ -25,6 +27,7 @@ struct CExtraSubBlock
{
UInt16 ID;
CByteBuffer Data;
bool ExtractNtfsTime(int index, FILETIME &ft) const;
};
struct CWzAesExtraField
@@ -137,6 +140,17 @@ struct CExtraBlock
return GetWzAesField(aesField);
}
bool GetNtfsTime(int index, FILETIME &ft) const
{
for (int i = 0; i < SubBlocks.Size(); i++)
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kNTFS)
return sb.ExtractNtfsTime(index, ft);
}
return false;
}
/*
bool HasStrongCryptoField() const
{
@@ -147,14 +161,9 @@ struct CExtraBlock
void RemoveUnknownSubBlocks()
{
for (int i = SubBlocks.Size() - 1; i >= 0;)
{
const CExtraSubBlock &subBlock = SubBlocks[i];
if (subBlock.ID != NFileHeader::NExtraID::kWzAES)
for (int i = SubBlocks.Size() - 1; i >= 0; i--)
if (SubBlocks[i].ID != NFileHeader::NExtraID::kWzAES)
SubBlocks.Delete(i);
else
i--;
}
}
};
@@ -173,6 +182,8 @@ public:
AString Name;
CExtraBlock LocalExtra;
bool IsUtf8() const { return (Flags & NFileHeader::NFlags::kUtf8) != 0; }
bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kEncrypted) != 0; }
bool IsStrongEncrypted() const { return IsEncrypted() && (Flags & NFileHeader::NFlags::kStrongEncrypted) != 0; };
@@ -186,6 +197,16 @@ public:
bool HasDescriptor() const { return (Flags & NFileHeader::NFlags::kDescriptorUsedMask) != 0; }
UString GetUnicodeString(const AString &s) const
{
UString res;
if (IsUtf8())
if (!ConvertUTF8ToUnicode(s, res))
res.Empty();
if (res.IsEmpty())
res = MultiByteToUnicodeString(s, GetCodePage());
return res;
}
private:
void SetFlagBits(int startBitNumber, int numBits, int value);
@@ -193,11 +214,9 @@ private:
public:
void ClearFlags() { Flags = 0; }
void SetEncrypted(bool encrypted);
void SetUtf8(bool isUtf8);
WORD GetCodePage() const
{
return CP_OEMCP;
}
WORD GetCodePage() const { return CP_OEMCP; }
};
class CItem: public CLocalItem
@@ -209,11 +228,16 @@ public:
UInt64 LocalHeaderPosition;
FILETIME NtfsMTime;
FILETIME NtfsATime;
FILETIME NtfsCTime;
CExtraBlock CentralExtra;
CByteBuffer Comment;
bool FromLocal;
bool FromCentral;
bool NtfsTimeIsDefined;
bool IsDirectory() const;
UInt32 GetWinAttributes() const;
@@ -235,7 +259,7 @@ public:
|| MadeByVersion.HostOS == NFileHeader::NHostOS::kNTFS
) ? CP_OEMCP : CP_ACP);
}
CItem() : FromLocal(false), FromCentral(false) {}
CItem() : FromLocal(false), FromCentral(false), NtfsTimeIsDefined(false) {}
};
}}

View File

@@ -172,7 +172,8 @@ void COutArchive::WriteCentralHeader(const CItem &item)
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);
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());
@@ -192,6 +193,20 @@ void COutArchive::WriteCentralHeader(const CItem &item)
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());

View File

@@ -69,12 +69,19 @@ static void SetFileHeader(
item.UnPackSize = updateItem.Size;
bool isDirectory;
item.ClearFlags();
if (updateItem.NewProperties)
{
isDirectory = updateItem.IsDirectory;
item.Name = updateItem.Name;
item.SetUtf8(updateItem.IsUtf8);
item.ExternalAttributes = updateItem.Attributes;
item.Time = updateItem.Time;
item.NtfsMTime = updateItem.NtfsMTime;
item.NtfsATime = updateItem.NtfsATime;
item.NtfsCTime = updateItem.NtfsCTime;
item.NtfsTimeIsDefined = updateItem.NtfsTimeIsDefined;
}
else
isDirectory = item.IsDirectory();
@@ -86,7 +93,6 @@ static void SetFileHeader(
item.ExtractVersion.HostOS = kExtractHostOS;
item.InternalAttributes = 0; // test it
item.ClearFlags();
item.SetEncrypted(!isDirectory && options.PasswordIsDefined);
if (isDirectory)
{
@@ -341,7 +347,13 @@ static HRESULT UpdateItemOldData(COutArchive &archive,
// item.ExternalAttributes = updateItem.Attributes;
// Test it
item.Name = updateItem.Name;
item.SetUtf8(updateItem.IsUtf8);
item.Time = updateItem.Time;
item.NtfsMTime = updateItem.NtfsMTime;
item.NtfsATime = updateItem.NtfsATime;
item.NtfsCTime = updateItem.NtfsCTime;
item.NtfsTimeIsDefined = updateItem.NtfsTimeIsDefined;
item.CentralExtra.RemoveUnknownSubBlocks();
item.LocalExtra.RemoveUnknownSubBlocks();

View File

@@ -27,6 +27,8 @@ struct CUpdateItem
bool NewData;
bool NewProperties;
bool IsDirectory;
bool NtfsTimeIsDefined;
bool IsUtf8;
int IndexInArchive;
int IndexInClient;
UInt32 Attributes;
@@ -35,7 +37,11 @@ struct CUpdateItem
AString Name;
// bool Commented;
// CUpdateRange CommentRange;
CUpdateItem(): Size(0) {}
FILETIME NtfsMTime;
FILETIME NtfsATime;
FILETIME NtfsCTime;
CUpdateItem(): NtfsTimeIsDefined(false), IsUtf8(false), Size(0) {}
};
HRESULT Update(