blob: 4dd58f7d60c7bfc3c6009d7e92af15199156f458 [file] [log] [blame]
// 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); }
}}