FIX: Zip - update time extra fields (fixes #492)

(cherry picked from commit 29cea47087)
This commit is contained in:
Alexander Koblov 2022-08-09 18:50:38 +03:00
commit 2c15917a14
2 changed files with 51 additions and 3 deletions

View file

@ -1262,9 +1262,7 @@ begin
{$IFDEF MSWINDOWS}
Result := GetFileAttributesExW(PWideChar(CeUtf8ToUtf16(aFileName)), GetFileExInfoStandard, @FindData);
if Result then begin
if Windows.FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime) and
FileTimeToDosDateTime(LocalFileTime, FileDate.Hi, FileDate.Lo) then
aAttr.Time := FileDateToDateTime(Integer(FileDate));
aAttr.Time := WinFileTimeToDateTime(FindData.ftLastWriteTime);
LARGE_INTEGER(aAttr.Size).LowPart := FindData.nFileSizeLow;
LARGE_INTEGER(aAttr.Size).HighPart := FindData.nFileSizeHigh;
aAttr.Attr := FindData.dwFileAttributes;

View file

@ -73,6 +73,23 @@ const
Ab_XceedUnicodePathSubfieldID : Word = $554E;
Ab_XceedUnicodePathSignature : LongWord= $5843554E;
type
TNtfsTimeField = packed record
Reserved : UInt32;
Tag : UInt16;
Size : UInt16;
Mtime : UInt64;
Atime : UInt64;
Ctime : UInt64;
end;
PNtfsTimeField = ^TNtfsTimeField;
TInfoZipTimeField = packed record
Tag : Byte;
Mtime : UInt32;
end;
PInfoZipTimeField = ^TInfoZipTimeField;
type
PAbByteArray4K = ^TAbByteArray4K;
TAbByteArray4K = array[1..4096] of Byte;
@ -421,6 +438,7 @@ type
procedure SetLastModFileDate(const Value : Word ); override;
procedure SetLastModFileTime(const Value : Word ); override;
procedure SetUncompressedSize( const Value : Int64 ); override;
procedure SetLastModTimeAsDateTime(const Value: TDateTime); override;
public {methods}
constructor Create;
@ -1782,6 +1800,38 @@ begin
FItemInfo.UncompressedSize:= Min(Value, $FFFFFFFF);
UpdateZip64ExtraHeader;
end;
procedure TAbZipItem.SetLastModTimeAsDateTime(const Value: TDateTime);
var
DataSize: Word;
ANtfsTime: PNtfsTimeField;
AInfoZipTime: PInfoZipTimeField;
begin
inherited SetLastModTimeAsDateTime(Value);
// Update time extra fields
if FItemInfo.ExtraField.Get(Ab_NTFSSubfieldID, ANtfsTime, DataSize) then
begin
if (DataSize = SizeOf(TNtfsTimeField)) then
begin
if ANtfsTime^.Tag = $0001 then
begin
ANtfsTime^.Mtime := DateTimeToWinFileTime(Value);
end;
end;
end
else if FItemInfo.ExtraField.Get(Ab_InfoZipTimestampSubfieldID, AInfoZipTime, DataSize) then
begin
if (DataSize = SizeOf(TInfoZipTimeField)) then
begin
if (AInfoZipTime^.Tag and $01 <> 0) then
begin
AInfoZipTime^.Mtime := UInt32(DateTimeToUnixFileTime(Value));
end;
end;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbZipItem.SetVersionMadeBy( Value : Word );
begin