| // Archive/ZipItem.cpp |
| |
| #include "StdAfx.h" |
| |
| #include "ZipHeader.h" |
| #include "ZipItem.h" |
| #include "../Common/ItemNameUtils.h" |
| #include "../../../../C/CpuArch.h" |
| |
| namespace NArchive { |
| namespace NZip { |
| |
| bool operator==(const CVersion &v1, const CVersion &v2) |
| { |
| return (v1.Version == v2.Version) && (v1.HostOS == v2.HostOS); |
| } |
| |
| 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 CExtraSubBlock::ExtractUnixTime(int index, UInt32 &res) const |
| { |
| res = 0; |
| UInt32 size = (UInt32)Data.GetCapacity(); |
| if (ID != NFileHeader::NExtraID::kUnixTime || size < 5) |
| return false; |
| const Byte *p = (const Byte *)Data; |
| Byte flags = *p++; |
| size--; |
| for (int i = 0; i < 3; i++) |
| if ((flags & (1 << i)) != 0) |
| { |
| if (size < 4) |
| return false; |
| if (index == i) |
| { |
| res = GetUi32(p); |
| return true; |
| } |
| p += 4; |
| size -= 4; |
| } |
| return false; |
| } |
| |
| bool CLocalItem::IsDir() const |
| { |
| return NItemName::HasTailSlash(Name, GetCodePage()); |
| } |
| |
| bool CItem::IsDir() const |
| { |
| if (NItemName::HasTailSlash(Name, GetCodePage())) |
| return true; |
| if (!FromCentral) |
| return false; |
| WORD highAttributes = WORD((ExternalAttributes >> 16 ) & 0xFFFF); |
| switch(MadeByVersion.HostOS) |
| { |
| case NFileHeader::NHostOS::kAMIGA: |
| switch (highAttributes & NFileHeader::NAmigaAttribute::kIFMT) |
| { |
| case NFileHeader::NAmigaAttribute::kIFDIR: return true; |
| case NFileHeader::NAmigaAttribute::kIFREG: return false; |
| default: return false; // change it throw kUnknownAttributes; |
| } |
| case NFileHeader::NHostOS::kFAT: |
| case NFileHeader::NHostOS::kNTFS: |
| case NFileHeader::NHostOS::kHPFS: |
| case NFileHeader::NHostOS::kVFAT: |
| return ((ExternalAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0); |
| case NFileHeader::NHostOS::kAtari: |
| case NFileHeader::NHostOS::kMac: |
| case NFileHeader::NHostOS::kVMS: |
| case NFileHeader::NHostOS::kVM_CMS: |
| case NFileHeader::NHostOS::kAcorn: |
| case NFileHeader::NHostOS::kMVS: |
| return false; // change it throw kUnknownAttributes; |
| default: |
| /* |
| switch (highAttributes & NFileHeader::NUnixAttribute::kIFMT) |
| { |
| case NFileHeader::NUnixAttribute::kIFDIR: |
| return true; |
| default: |
| return false; |
| } |
| */ |
| return false; |
| } |
| } |
| |
| #ifndef FILE_ATTRIBUTE_UNIX_EXTENSION |
| UInt32 CLocalItem::GetWinAttributes() const |
| { |
| DWORD winAttributes = 0; |
| if (IsDir()) |
| winAttributes |= FILE_ATTRIBUTE_DIRECTORY; |
| return winAttributes; |
| } |
| #endif |
| |
| UInt32 CItem::GetWinAttributes() const |
| { |
| DWORD winAttributes = 0; |
| switch(MadeByVersion.HostOS) |
| { |
| case NFileHeader::NHostOS::kFAT: |
| case NFileHeader::NHostOS::kNTFS: |
| if (FromCentral) |
| winAttributes = ExternalAttributes; |
| break; |
| #ifdef FILE_ATTRIBUTE_UNIX_EXTENSION |
| case NFileHeader::NHostOS::kUnix: |
| winAttributes = (ExternalAttributes & 0xFFFF0000) | FILE_ATTRIBUTE_UNIX_EXTENSION; |
| if (winAttributes & (NFileHeader::NUnixAttribute::kIFDIR << 16)) |
| winAttributes |= FILE_ATTRIBUTE_DIRECTORY; |
| return winAttributes; |
| #endif |
| default: |
| winAttributes = 0; // must be converted from unix value; |
| } |
| if (IsDir()) // test it; |
| winAttributes |= FILE_ATTRIBUTE_DIRECTORY; |
| return winAttributes; |
| } |
| |
| void CLocalItem::SetFlagBits(int startBitNumber, int numBits, int value) |
| { |
| UInt16 mask = (UInt16)(((1 << numBits) - 1) << startBitNumber); |
| Flags &= ~mask; |
| Flags |= value << startBitNumber; |
| } |
| |
| void CLocalItem::SetBitMask(int bitMask, bool enable) |
| { |
| if(enable) |
| Flags |= bitMask; |
| else |
| Flags &= ~bitMask; |
| } |
| |
| void CLocalItem::SetEncrypted(bool encrypted) |
| { SetBitMask(NFileHeader::NFlags::kEncrypted, encrypted); } |
| void CLocalItem::SetUtf8(bool isUtf8) |
| { SetBitMask(NFileHeader::NFlags::kUtf8, isUtf8); } |
| |
| }} |