diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2015-10-05 03:00:00 +0300 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:16:56 +0300 |
commit | 6543c280208393fa32cb0094f770d14c1cfb13b2 (patch) | |
tree | beb90f5e81e85e7957463ee5ad89cab0b3566560 | |
parent | f6444c32568553e0261ca0105083658f12be6284 (diff) |
15.0815.08
113 files changed, 3100 insertions, 381 deletions
diff --git a/C/7zArcIn.c b/C/7zArcIn.c index 31939daa..5c5524c3 100644 --- a/C/7zArcIn.c +++ b/C/7zArcIn.c @@ -1,5 +1,5 @@ /* 7zArcIn.c -- 7z Input functions -2015-05-16 : Igor Pavlov : Public domain */ +2015-09-28 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -1295,7 +1295,7 @@ static SRes SzReadHeader2( { SKIP_DATA(sd, size); } - else switch((unsigned)type) + else switch ((unsigned)type) { case k7zIdName: { diff --git a/C/7zVersion.h b/C/7zVersion.h index 6ddcfcac..87f6cff8 100644 --- a/C/7zVersion.h +++ b/C/7zVersion.h @@ -1,9 +1,9 @@ #define MY_VER_MAJOR 15 -#define MY_VER_MINOR 07 -#define MY_VER_BUILD 00 -#define MY_VERSION_NUMBERS "15.07" -#define MY_VERSION "15.07 beta" -#define MY_DATE "2015-09-17" +#define MY_VER_MINOR 8 +#define MY_VER_BUILD 0 +#define MY_VERSION_NUMBERS "15.08" +#define MY_VERSION "15.08 beta" +#define MY_DATE "2015-10-01" #undef MY_COPYRIGHT #undef MY_VERSION_COPYRIGHT_DATE #define MY_AUTHOR_NAME "Igor Pavlov" diff --git a/C/MtCoder.c b/C/MtCoder.c index 616f0b41..dc5116c0 100644 --- a/C/MtCoder.c +++ b/C/MtCoder.c @@ -1,5 +1,5 @@ /* MtCoder.c -- Multi-thread Coder -2010-09-24 : Igor Pavlov : Public domain */ +2015-09-28 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -120,7 +120,7 @@ void CMtThread_Construct(CMtThread *p, CMtCoder *mtCoder) LoopThread_Construct(&p->thread); } -#define RINOK_THREAD(x) { if((x) != 0) return SZ_ERROR_THREAD; } +#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; } static void CMtThread_CloseEvents(CMtThread *p) { @@ -1,5 +1,5 @@ /* Ppmd7.c -- PPMdH codec -2010-03-12 : Igor Pavlov : Public domain +2015-09-28 : Igor Pavlov : Public domain This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ #include "Precomp.h" @@ -66,7 +66,7 @@ void Ppmd7_Construct(CPpmd7 *p) for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++) { unsigned step = (i >= 12 ? 4 : (i >> 2) + 1); - do { p->Units2Indx[k++] = (Byte)i; } while(--step); + do { p->Units2Indx[k++] = (Byte)i; } while (--step); p->Indx2Units[i] = (Byte)k; } @@ -257,7 +257,7 @@ static void *AllocUnits(CPpmd7 *p, unsigned indx) #define MyMem12Cpy(dest, src, num) \ { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \ - do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); } + do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while (--n); } static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU) { diff --git a/C/Ppmd7Enc.c b/C/Ppmd7Enc.c index 51c19c9f..e6dd3d2f 100644 --- a/C/Ppmd7Enc.c +++ b/C/Ppmd7Enc.c @@ -1,5 +1,5 @@ /* Ppmd7Enc.c -- PPMdH Encoder -2010-03-12 : Igor Pavlov : Public domain +2015-09-28 : Igor Pavlov : Public domain This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ #include "Precomp.h" @@ -26,7 +26,7 @@ static void RangeEnc_ShiftLow(CPpmd7z_RangeEnc *p) p->Stream->Write(p->Stream, (Byte)(temp + (Byte)(p->Low >> 32))); temp = 0xFF; } - while(--p->CacheSize != 0); + while (--p->CacheSize != 0); p->Cache = (Byte)((UInt32)p->Low >> 24); } p->CacheSize++; @@ -1,5 +1,5 @@ /* Ppmd8.c -- PPMdI codec -2013-11-12 : Igor Pavlov : Public domain +2015-09-28 : Igor Pavlov : Public domain This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */ #include "Precomp.h" @@ -67,7 +67,7 @@ void Ppmd8_Construct(CPpmd8 *p) for (i = 0, k = 0; i < PPMD_NUM_INDEXES; i++) { unsigned step = (i >= 12 ? 4 : (i >> 2) + 1); - do { p->Units2Indx[k++] = (Byte)i; } while(--step); + do { p->Units2Indx[k++] = (Byte)i; } while (--step); p->Indx2Units[i] = (Byte)k; } @@ -241,7 +241,7 @@ static void *AllocUnits(CPpmd8 *p, unsigned indx) #define MyMem12Cpy(dest, src, num) \ { UInt32 *d = (UInt32 *)dest; const UInt32 *s = (const UInt32 *)src; UInt32 n = num; \ - do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while(--n); } + do { d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; s += 3; d += 3; } while (--n); } static void *ShrinkUnits(CPpmd8 *p, void *oldPtr, unsigned oldNU, unsigned newNU) { diff --git a/C/Util/7zipInstall/7zipInstall.c b/C/Util/7zipInstall/7zipInstall.c index 9a360579..33b77ae2 100644 --- a/C/Util/7zipInstall/7zipInstall.c +++ b/C/Util/7zipInstall/7zipInstall.c @@ -1,5 +1,5 @@ /* 7zipInstall.c - 7-Zip Installer -2015-08-04 : Igor Pavlov : Public domain */ +2015-09-28 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -1161,9 +1161,9 @@ if (res == SZ_OK) if (res == SZ_OK) { UInt32 i; - UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call, if(!outBuf) */ + UInt32 blockIndex = 0xFFFFFFFF; /* it can have any value before first call, if (!outBuf) */ Byte *outBuf = NULL; /* it must be NULL before first call for each new archive. */ - size_t outBufSize = 0; /* it can have any value before first call, if(!outBuf) */ + size_t outBufSize = 0; /* it can have any value before first call, if (!outBuf) */ g_TotalSize = 0; diff --git a/CPP/7zip/Archive/7z/7zIn.cpp b/CPP/7zip/Archive/7z/7zIn.cpp index bd6c4d95..fc527be6 100644 --- a/CPP/7zip/Archive/7z/7zIn.cpp +++ b/CPP/7zip/Archive/7z/7zIn.cpp @@ -1180,7 +1180,7 @@ HRESULT CInArchive::ReadHeader( bool isKnownType = true; if (type > ((UInt32)1 << 30)) isKnownType = false; - else switch((UInt32)type) + else switch ((UInt32)type) { case NID::kName: { @@ -1338,7 +1338,7 @@ HRESULT CInArchive::ReadHeader( db.UnsupportedFeatureWarning = true; _inByteBack->SkipRem(); } - // SkipData worked incorrectly in some versions before v4.59 (7zVer <= 00.02) + // SkipData worked incorrectly in some versions before v4.59 (7zVer <= 0.02) if (_inByteBack->GetRem() != 0) ThrowIncorrect(); } diff --git a/CPP/7zip/Archive/7z/7zProperties.cpp b/CPP/7zip/Archive/7z/7zProperties.cpp index a2c9bf31..4cb5a5e6 100644 --- a/CPP/7zip/Archive/7z/7zProperties.cpp +++ b/CPP/7zip/Archive/7z/7zProperties.cpp @@ -14,7 +14,7 @@ namespace N7z { struct CPropMap { UInt32 FilePropID; - STATPROPSTG StatPROPSTG; + CStatProp StatProp; }; static const CPropMap kPropMap[] = @@ -24,11 +24,11 @@ static const CPropMap kPropMap[] = { NID::kPackInfo, { NULL, kpidPackSize, VT_UI8 } }, #ifdef _MULTI_PACK - { 100, { L"Pack0", kpidPackedSize0, VT_UI8 } }, - { 101, { L"Pack1", kpidPackedSize1, VT_UI8 } }, - { 102, { L"Pack2", kpidPackedSize2, VT_UI8 } }, - { 103, { L"Pack3", kpidPackedSize3, VT_UI8 } }, - { 104, { L"Pack4", kpidPackedSize4, VT_UI8 } }, + { 100, { "Pack0", kpidPackedSize0, VT_UI8 } }, + { 101, { "Pack1", kpidPackedSize1, VT_UI8 } }, + { 102, { "Pack2", kpidPackedSize2, VT_UI8 } }, + { 103, { "Pack3", kpidPackedSize3, VT_UI8 } }, + { 104, { "Pack4", kpidPackedSize4, VT_UI8 } }, #endif { NID::kCTime, { NULL, kpidCTime, VT_FILETIME } }, @@ -90,7 +90,7 @@ void CHandler::FillPopIDs() _fileInfoPopIDs.Clear(); #ifdef _7Z_VOL - if(_volumes.Size() < 1) + if (_volumes.Size() < 1) return; const CVolume &volume = _volumes.Front(); const CArchiveDatabaseEx &_db = volume.Database; @@ -156,8 +156,8 @@ STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *propID, const CPropMap &pr = kPropMap[i]; if (pr.FilePropID == id) { - const STATPROPSTG &st = pr.StatPROPSTG; - *propID = st.propid; + const CStatProp &st = pr.StatProp; + *propID = st.PropID; *varType = st.vt; /* if (st.lpwstrName) diff --git a/CPP/7zip/Archive/Chm/ChmHandler.cpp b/CPP/7zip/Archive/Chm/ChmHandler.cpp index b1ab2996..3e29fd00 100644 --- a/CPP/7zip/Archive/Chm/ChmHandler.cpp +++ b/CPP/7zip/Archive/Chm/ChmHandler.cpp @@ -103,7 +103,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val NCOM::CPropVariant prop; if (m_Database.NewFormat) { - switch(propID) + switch (propID) { case kpidSize: prop = (UInt64)m_Database.NewFormatString.Len(); @@ -318,7 +318,7 @@ HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce if (processedSize) *processedSize = 0; - while(size != 0) + while (size != 0) { if (m_FileIsOpen) { diff --git a/CPP/7zip/Archive/ComHandler.cpp b/CPP/7zip/Archive/ComHandler.cpp index 9cfd40cc..e24074a5 100644 --- a/CPP/7zip/Archive/ComHandler.cpp +++ b/CPP/7zip/Archive/ComHandler.cpp @@ -592,13 +592,13 @@ HRESULT CDatabase::Open(IInStream *inStream) MainSubfile = -1; { - FOR_VECTOR(t, Items) + FOR_VECTOR (t, Items) { Update_PhySize_WithItem(t); } } { - FOR_VECTOR(t, Items) + FOR_VECTOR (t, Items) { const CItem &item = Items[t]; @@ -739,7 +739,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, return S_OK; UInt32 i; UInt64 totalSize = 0; - for(i = 0; i < numItems; i++) + for (i = 0; i < numItems; i++) { const CItem &item = _db.Items[_db.Refs[allFilesMode ? i : indices[i]].Did]; if (!item.IsDir()) diff --git a/CPP/7zip/Archive/Common/MultiStream.cpp b/CPP/7zip/Archive/Common/MultiStream.cpp index 5bf0bef9..1de74afe 100644 --- a/CPP/7zip/Archive/Common/MultiStream.cpp +++ b/CPP/7zip/Archive/Common/MultiStream.cpp @@ -119,9 +119,9 @@ HRESULT COutVolumeStream::Flush() /* STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *processedSize) { - if(processedSize != NULL) + if (processedSize) *processedSize = 0; - while(size > 0) + while (size > 0) { if (_streamIndex >= Streams.Size()) { @@ -157,7 +157,7 @@ STDMETHODIMP COutMultiStream::Write(const void *data, UInt32 size, UInt32 *proce _absPos += realProcessed; if (_absPos > _length) _length = _absPos; - if(processedSize != NULL) + if (processedSize) *processedSize += realProcessed; if (subStream.Pos == subStream.Size) { diff --git a/CPP/7zip/Archive/CpioHandler.cpp b/CPP/7zip/Archive/CpioHandler.cpp index 2436fb5e..e8898cac 100644 --- a/CPP/7zip/Archive/CpioHandler.cpp +++ b/CPP/7zip/Archive/CpioHandler.cpp @@ -5,6 +5,7 @@ #include "../../../C/CpuArch.h" #include "../../Common/ComTry.h" +#include "../../Common/MyLinux.h" #include "../../Common/StringConvert.h" #include "../../Common/StringToInt.h" #include "../../Common/UTFConvert.h" @@ -121,7 +122,7 @@ struct CItem bool IsBin() const { return Type == k_Type_BinLe || Type == k_Type_BinBe; } bool IsCrcFormat() const { return Type == k_Type_HexCrc; } - bool IsDir() const { return (Mode & 0170000) == 0040000; } + bool IsDir() const { return MY_LIN_S_ISDIR(Mode); } bool IsTrailer() const { return strcmp(Name, kName_TRAILER) == 0; } UInt64 GetDataPosition() const { return HeaderPos + HeaderSize; } }; diff --git a/CPP/7zip/Archive/CramfsHandler.cpp b/CPP/7zip/Archive/CramfsHandler.cpp index e776b3c7..020f84b7 100644 --- a/CPP/7zip/Archive/CramfsHandler.cpp +++ b/CPP/7zip/Archive/CramfsHandler.cpp @@ -8,6 +8,7 @@ #include "../../../C/LzmaDec.h" #include "../../Common/ComTry.h" +#include "../../Common/MyLinux.h" #include "../../Common/StringConvert.h" #include "../../Windows/PropVariantUtils.h" @@ -98,7 +99,7 @@ struct CNode #define Get32(p) (be ? GetBe32(p) : GetUi32(p)) static UInt32 GetMode(const Byte *p, bool be) { return be ? GetBe16(p) : GetUi16(p); } -static bool IsDir(const Byte *p, bool be) { return (GetMode(p, be) & 0xF000) == 0x4000; } +static bool IsDir(const Byte *p, bool be) { return MY_LIN_S_ISDIR(GetMode(p, be)); } static UInt32 GetSize(const Byte *p, bool be) { @@ -146,7 +147,7 @@ struct CHeader { if (memcmp(p + 16, kSignature, ARRAY_SIZE(kSignature)) != 0) return false; - switch(GetUi32(p)) + switch (GetUi32(p)) { case 0x28CD3D45: be = false; break; case 0x453DCD28: be = true; break; @@ -354,7 +355,7 @@ HRESULT CHandler::Open2(IInStream *inStream) if (!_h.IsVer2()) { - FOR_VECTOR(i, _items) + FOR_VECTOR (i, _items) { const CItem &item = _items[i]; const Byte *p = _data + item.Offset; @@ -530,7 +531,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val const Byte *p = _data + item.Offset; bool be = _h.be; bool isDir = IsDir(p, be); - switch(propID) + switch (propID) { case kpidPath: prop = MultiByteToUnicodeString(GetPath(index), CP_OEMCP); break; case kpidIsDir: prop = isDir; break; @@ -660,10 +661,6 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, CMyComPtr<ICompressProgressInfo> progress = lps; lps->Init(extractCallback, false); - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr<ISequentialInStream> inStream(streamSpec); - streamSpec->SetStream(_stream); - for (i = 0; i < numItems; i++) { lps->InSize = totalPackSize; @@ -701,20 +698,16 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, int res = NExtract::NOperationResult::kDataError; { CMyComPtr<ISequentialInStream> inSeqStream; - CMyComPtr<IInStream> inStream; HRESULT hres = GetStream(index, &inSeqStream); - if (inSeqStream) - inSeqStream.QueryInterface(IID_IInStream, &inStream); if (hres == E_OUTOFMEMORY) return E_OUTOFMEMORY; - if (hres == S_FALSE || !inStream) + if (hres == S_FALSE || !inSeqStream) res = NExtract::NOperationResult::kUnsupportedMethod; else { RINOK(hres); - if (inStream) { - HRESULT hres = copyCoder->Code(inStream, outStream, NULL, NULL, progress); + HRESULT hres = copyCoder->Code(inSeqStream, outStream, NULL, NULL, progress); if (hres == S_OK) { if (copyCoderSpec->TotalSize == curSize) @@ -729,6 +722,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, } RINOK(extractCallback->SetOperationResult(res)); } + return S_OK; COM_TRY_END } diff --git a/CPP/7zip/Archive/ElfHandler.cpp b/CPP/7zip/Archive/ElfHandler.cpp index beca8036..1c3c7c45 100644 --- a/CPP/7zip/Archive/ElfHandler.cpp +++ b/CPP/7zip/Archive/ElfHandler.cpp @@ -632,7 +632,7 @@ enum kpidInfoSection }; -static const STATPROPSTG kProps[] = +static const CStatProp kProps[] = { { NULL, kpidPath, VT_BSTR }, { NULL, kpidSize, VT_UI8 }, @@ -641,8 +641,8 @@ static const STATPROPSTG kProps[] = { NULL, kpidVa, VT_UI8 }, { NULL, kpidType, VT_BSTR }, { NULL, kpidCharacts, VT_BSTR } - , { (LPOLESTR)L"Link Section", kpidLinkSection, VT_BSTR} - , { (LPOLESTR)L"Info Section", kpidInfoSection, VT_BSTR} + , { "Link Section", kpidLinkSection, VT_BSTR} + , { "Info Section", kpidInfoSection, VT_BSTR} }; IMP_IInArchive_Props_WITH_NAME diff --git a/CPP/7zip/Archive/ExtHandler.cpp b/CPP/7zip/Archive/ExtHandler.cpp new file mode 100644 index 00000000..6d8101f5 --- /dev/null +++ b/CPP/7zip/Archive/ExtHandler.cpp @@ -0,0 +1,2610 @@ +// ExtHandler.cpp + +#include "StdAfx.h" + +// #define SHOW_DEBUG_INFO + +#ifdef SHOW_DEBUG_INFO +#include <stdio.h> +#define PRF(x) x +#else +#define PRF(x) +#endif + +#include "../../../C/Alloc.h" +#include "../../../C/CpuArch.h" + +#include "../../Common/ComTry.h" +#include "../../Common/IntToString.h" +#include "../../Common/MyLinux.h" +#include "../../Common/StringConvert.h" +#include "../../Common/UTFConvert.h" + +#include "../../Windows/PropVariantUtils.h" +#include "../../Windows/TimeUtils.h" + +#include "../Common/LimitedStreams.h" +#include "../Common/ProgressUtils.h" +#include "../Common/RegisterArc.h" +#include "../Common/StreamObjects.h" +#include "../Common/StreamUtils.h" + +#include "../Compress/CopyCoder.h" + +using namespace NWindows; + +namespace NArchive { +namespace NExt { + +#define Get16(p) GetUi16(p) +#define Get32(p) GetUi32(p) +#define Get64(p) GetUi64(p) + +#define LE_16(offs, dest) dest = Get16(p + (offs)); +#define LE_32(offs, dest) dest = Get32(p + (offs)); +#define LE_64(offs, dest) dest = Get64(p + (offs)); + +#define HI_16(offs, dest) dest |= (((UInt32)Get16(p + (offs))) << 16); +#define HI_32(offs, dest) dest |= (((UInt64)Get32(p + (offs))) << 32); + +/* +static UInt32 g_Crc32CTable[256]; + +static struct CInitCrc32C +{ + CInitCrc32C() + { + for (unsigned i = 0; i < 256; i++) + { + UInt32 r = i; + unsigned j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (0x82F63B78 & ~((r & 1) - 1)); + g_Crc32CTable[i] = r; + } + } +} g_InitCrc32C; + +#define CRC32C_INIT_VAL 0xFFFFFFFF +#define CRC32C_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL) +#define CRC32C_UPDATE_BYTE(crc, b) (g_Crc32CTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +static UInt32 Crc32C_Update(UInt32 crc, Byte const *data, size_t size) +{ + for (size_t i = 0; i < size; i++) + crc = CRC32C_UPDATE_BYTE(crc, data[i]); + return crc; +} + +static UInt32 Crc32C_Calc(Byte const *data, size_t size) +{ + return Crc32C_Update(CRC32C_INIT_VAL, data, size); +} +*/ + + +// CRC-16-ANSI. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) +static UInt16 g_Crc16Table[256]; + +static struct CInitCrc16 +{ + CInitCrc16() + { + for (unsigned i = 0; i < 256; i++) + { + UInt32 r = i; + unsigned j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (0xA001 & ~((r & 1) - 1)); + g_Crc16Table[i] = (UInt16)r; + } + } +} g_InitCrc16; + +#define CRC16_UPDATE_BYTE(crc, b) (g_Crc16Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) +#define CRC16_INIT_VAL 0xFFFF + +static UInt32 Crc16Update(UInt32 crc, Byte const *data, size_t size) +{ + for (size_t i = 0; i < size; i++) + crc = CRC16_UPDATE_BYTE(crc, data[i]); + return crc; +} + +static UInt32 Crc16Calc(Byte const *data, size_t size) +{ + return Crc16Update(CRC16_INIT_VAL, data, size); +} + + +#define EXT4_GOOD_OLD_INODE_SIZE 128 + +// inodes numbers + +// #define k_INODE_BAD 1 // Bad blocks +#define k_INODE_ROOT 2 // Root dir +// #define k_INODE_USR_QUOTA 3 // User quota +// #define k_INODE_GRP_QUOTA 4 // Group quota +// #define k_INODE_BOOT_LOADER 5 // Boot loader +// #define k_INODE_UNDEL_DIR 6 // Undelete dir +#define k_INODE_RESIZE 7 // Reserved group descriptors +// #define k_INODE_JOURNAL 8 // Journal + +// First non-reserved inode for old ext4 filesystems +#define k_INODE_GOOD_OLD_FIRST 11 + +static const char * const k_SysInode_Names[] = +{ + "0" + , "Bad" + , "Root" + , "UserQuota" + , "GroupQuota" + , "BootLoader" + , "Undelete" + , "Resize" + , "Journal" + , "Exclude" + , "Replica" +}; + +static const char * const kHostOS[] = +{ + "Linux" + , "Hurd" + , "Masix" + , "FreeBSD" + , "Lites" +}; + +static const CUInt32PCharPair g_FeatureCompat_Flags[] = +{ + { 0, "DIR_PREALLOC" }, + { 1, "IMAGIC_INODES" }, + { 2, "HAS_JOURNAL" }, + { 3, "EXT_ATTR" }, + { 4, "RESIZE_INODE" }, + { 5, "DIR_INDEX" }, + { 6, "LAZY_BG" }, // not in Linux + // { 7, "EXCLUDE_INODE" }, // not used + // { 8, "EXCLUDE_BITMAP" }, // not in kernel + { 9, "SPARSE_SUPER2" } +}; + + +#define EXT4_FEATURE_INCOMPAT_FILETYPE (1 << 1) +#define EXT4_FEATURE_INCOMPAT_64BIT (1 << 7) + +static const CUInt32PCharPair g_FeatureIncompat_Flags[] = +{ + { 0, "COMPRESSION" }, + { 1, "FILETYPE" }, + { 2, "RECOVER" }, /* Needs recovery */ + { 3, "JOURNAL_DEV" }, /* Journal device */ + { 4, "META_BG" }, + + { 6, "EXTENTS" }, /* extents support */ + { 7, "64BIT" }, + { 8, "MMP" }, + { 9, "FLEX_BG" }, + { 10, "EA_INODE" }, /* EA in inode */ + + { 12, "DIRDATA" }, /* data in dirent */ + { 13, "BG_USE_META_CSUM" }, /* use crc32c for bg */ + { 14, "LARGEDIR" }, /* >2GB or 3-lvl htree */ + { 15, "INLINE_DATA" }, /* data in inode */ + { 16, "ENCRYPT" } +}; + + +static const UInt32 RO_COMPAT_GDT_CSUM = 1 << 4; +static const UInt32 RO_COMPAT_METADATA_CSUM = 1 << 10; + +static const CUInt32PCharPair g_FeatureRoCompat_Flags[] = +{ + { 0, "SPARSE_SUPER" }, + { 1, "LARGE_FILE" }, + { 2, "BTREE_DIR" }, + { 3, "HUGE_FILE" }, + { 4, "GDT_CSUM" }, + { 5, "DIR_NLINK" }, + { 6, "EXTRA_ISIZE" }, + { 7, "HAS_SNAPSHOT" }, + { 8, "QUOTA" }, + { 9, "BIGALLOC" }, + { 10, "METADATA_CSUM" }, + { 11, "REPLICA" }, + { 12, "READONLY" } +}; + + + +static const UInt32 k_NodeFlags_HUGE = (UInt32)1 << 18; +static const UInt32 k_NodeFlags_EXTENTS = (UInt32)1 << 19; + + +static const CUInt32PCharPair g_NodeFlags[] = +{ + { 0, "SECRM" }, + { 1, "UNRM" }, + { 2, "COMPR" }, + { 3, "SYNC" }, + { 4, "IMMUTABLE" }, + { 5, "APPEND" }, + { 6, "NODUMP" }, + { 7, "NOATIME" }, + { 8, "DIRTY" }, + { 9, "COMPRBLK" }, + { 10, "NOCOMPR" }, + { 11, "ENCRYPT" }, + { 12, "INDEX" }, + { 13, "IMAGIC" }, + { 14, "JOURNAL_DATA" }, + { 15, "NOTAIL" }, + { 16, "DIRSYNC" }, + { 17, "TOPDIR" }, + { 18, "HUGE_FILE" }, + { 19, "EXTENTS" }, + + { 21, "EA_INODE" }, + { 22, "EOFBLOCKS" }, + + { 28, "INLINE_DATA" } +}; + + +static inline char GetHex(unsigned t) { return (char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))); } + +static inline void PrintHex(unsigned v, char *s) +{ + s[0] = GetHex((v >> 4) & 0xF); + s[1] = GetHex(v & 0xF); +} + + +enum +{ + k_Type_UNKNOWN, + k_Type_REG_FILE, + k_Type_DIR, + k_Type_CHRDEV, + k_Type_BLKDEV, + k_Type_FIFO, + k_Type_SOCK, + k_Type_SYMLINK +}; + +static const UInt16 k_TypeToMode[] = +{ + 0, + MY_LIN_S_IFREG, + MY_LIN_S_IFDIR, + MY_LIN_S_IFCHR, + MY_LIN_S_IFBLK, + MY_LIN_S_IFIFO, + MY_LIN_S_IFSOCK, + MY_LIN_S_IFLNK +}; + + +#define EXT4_GOOD_OLD_REV 0 // old (original) format +// #define EXT4_DYNAMIC_REV 1 // V2 format with dynamic inode sizes + +struct CHeader +{ + unsigned BlockBits; + unsigned ClusterBits; + + UInt32 NumInodes; + UInt64 NumBlocks; + // UInt64 NumBlocksSuper; + UInt64 NumFreeBlocks; + UInt32 NumFreeInodes; + UInt32 FirstDataBlock; + + UInt32 BlocksPerGroup; + UInt32 ClustersPerGroup; + UInt32 InodesPerGroup; + + UInt32 MountTime; + UInt32 WriteTime; + + // UInt16 NumMounts; + // UInt16 NumMountsMax; + + // UInt16 State; + // UInt16 Errors; + // UInt16 MinorRevLevel; + + UInt32 LastCheckTime; + // UInt32 CheckInterval; + UInt32 CreatorOs; + UInt32 RevLevel; + + // UInt16 DefResUid; + // UInt16 DefResGid; + + UInt32 FirstInode; + UInt16 InodeSize; + UInt16 BlockGroupNr; + UInt32 FeatureCompat; + UInt32 FeatureIncompat; + UInt32 FeatureRoCompat; + Byte Uuid[16]; + char VolName[16]; + char LastMount[64]; + // UInt32 BitmapAlgo; + + UInt32 JournalInode; + UInt16 GdSize; // = 64 if 64-bit(); + UInt32 CTime; + UInt16 MinExtraISize; + // UInt16 WantExtraISize; + // UInt32 Flags; + // Byte LogGroupsPerFlex; + // Byte ChecksumType; + + UInt64 WrittenKB; + + bool IsOldRev() const { return RevLevel == EXT4_GOOD_OLD_REV; } + + UInt64 GetNumGroups() const { return (NumBlocks + BlocksPerGroup - 1) / BlocksPerGroup; } + + bool IsThereFileType() const { return (FeatureIncompat & EXT4_FEATURE_INCOMPAT_FILETYPE) != 0; } + bool Is64Bit() const { return (FeatureIncompat & EXT4_FEATURE_INCOMPAT_64BIT) != 0; } + bool UseGdtChecksum() const { return (FeatureRoCompat & RO_COMPAT_GDT_CSUM) != 0; } + bool UseMetadataChecksum() const { return (FeatureRoCompat & RO_COMPAT_METADATA_CSUM) != 0; } + + bool Parse(const Byte *p); +}; + + +static int inline GetLog(UInt32 num) +{ + for (unsigned i = 0; i < 32; i++) + if (((UInt32)1 << i) == num) + return i; + return -1; +} + +bool CHeader::Parse(const Byte *p) +{ + if (GetUi16(p + 0x38) != 0xEF53) + return false; + + LE_32 (0x18, BlockBits); + LE_32 (0x1C, ClusterBits); + + if (ClusterBits != 0 && BlockBits != ClusterBits) + return false; + + if (BlockBits > 16 - 10) return false; + BlockBits += 10; + if (ClusterBits > 16) return false; + + LE_32 (0x00, NumInodes); + LE_32 (0x04, NumBlocks); + // LE_32 (0x08, NumBlocksSuper); + LE_32 (0x0C, NumFreeBlocks); + LE_32 (0x10, NumFreeInodes); + LE_32 (0x14, FirstDataBlock); + + if (FirstDataBlock != 0) + return false; + + LE_32 (0x20, BlocksPerGroup); + LE_32 (0x24, ClustersPerGroup); + + if (BlocksPerGroup != ClustersPerGroup) + return false; + if (BlocksPerGroup != ((UInt32)1 << (BlockBits + 3))) + return false; + + LE_32 (0x28, InodesPerGroup); + + LE_32 (0x2C, MountTime); + LE_32 (0x30, WriteTime); + + // LE_16 (0x34, NumMounts); + // LE_16 (0x36, NumMountsMax); + + // LE_16 (0x3A, State); + // LE_16 (0x3C, Errors); + // LE_16 (0x3E, MinorRevLevel); + + LE_32 (0x40, LastCheckTime); + // LE_32 (0x44, CheckInterval); + LE_32 (0x48, CreatorOs); + LE_32 (0x4C, RevLevel); + + // LE_16 (0x50, DefResUid); + // LE_16 (0x52, DefResGid); + + FirstInode = k_INODE_GOOD_OLD_FIRST; + InodeSize = EXT4_GOOD_OLD_INODE_SIZE; + + if (!IsOldRev()) + { + LE_32 (0x54, FirstInode); + LE_16 (0x58, InodeSize); + if (FirstInode < k_INODE_GOOD_OLD_FIRST) + return false; + if (InodeSize > (UInt32)1 << BlockBits) + return false; + if (GetLog(InodeSize) < 0) + return false; + } + + LE_16 (0x5A, BlockGroupNr); + LE_32 (0x5C, FeatureCompat); + LE_32 (0x60, FeatureIncompat); + LE_32 (0x64, FeatureRoCompat); + + memcpy(Uuid, p + 0x68, sizeof(Uuid)); + memcpy(VolName, p + 0x78, sizeof(VolName)); + memcpy(LastMount, p + 0x88, sizeof(LastMount)); + + // LE_32 (0xC8, BitmapAlgo); + + LE_32 (0xE0, JournalInode); + + LE_16 (0xFE, GdSize); + + LE_32 (0x108, CTime); + + if (Is64Bit()) + { + HI_32(150, NumBlocks); + // HI_32(154, NumBlocksSuper); + HI_32(0x158, NumFreeBlocks); + } + + if (NumBlocks >= (UInt64)1 << (63 - BlockBits)) + return false; + + + LE_16(0x15C, MinExtraISize); + // LE_16(0x15E, WantExtraISize); + // LE_32(0x160, Flags); + // LE_16(0x164, RaidStride); + // LE_16(0x166, MmpInterval); + // LE_64(0x168, MmpBlock); + + // LogGroupsPerFlex = p[0x174]; + // ChecksumType = p[0x175]; + + LE_64 (0x178, WrittenKB); + + // LE_32(0x194, ErrorCount); + // LE_32(0x198, ErrorTime); + // LE_32(0x19C, ErrorINode); + // LE_32(0x1A0, ErrorBlock); + + if (NumBlocks < 1) + return false; + if (NumFreeBlocks > NumBlocks) + return false; + + return true; +} + + +struct CGroupDescriptor +{ + UInt64 BlockBitmap; + UInt64 InodeBitmap; + UInt64 InodeTable; + UInt32 NumFreeBlocks; + UInt32 NumFreeInodes; + UInt32 DirCount; + + UInt16 Flags; + + UInt64 ExcludeBitmap; + UInt32 BlockBitmap_Checksum; + UInt32 InodeBitmap_Checksum; + UInt32 UnusedCount; + UInt16 Checksum; + + void Parse(const Byte *p, unsigned size); +}; + +void CGroupDescriptor::Parse(const Byte *p, unsigned size) +{ + LE_32 (0x00, BlockBitmap); + LE_32 (0x04, InodeBitmap); + LE_32 (0x08, InodeTable); + LE_16 (0x0C, NumFreeBlocks); + LE_16 (0x0E, NumFreeInodes); + LE_16 (0x10, DirCount); + LE_16 (0x12, Flags); + LE_32 (0x14, ExcludeBitmap); + LE_16 (0x18, BlockBitmap_Checksum); + LE_16 (0x1A, InodeBitmap_Checksum); + LE_16 (0x1C, UnusedCount); + LE_16 (0x1E, Checksum); + + if (size >= 64) + { + p += 0x20; + HI_32 (0x00, BlockBitmap); + HI_32 (0x04, InodeBitmap); + HI_32 (0x08, InodeTable); + HI_16 (0x0C, NumFreeBlocks); + HI_16 (0x0E, NumFreeInodes); + HI_16 (0x10, DirCount); + HI_16 (0x12, UnusedCount); // instead of Flags + HI_32 (0x14, ExcludeBitmap); + HI_16 (0x18, BlockBitmap_Checksum); + HI_16 (0x1A, InodeBitmap_Checksum); + // HI_16 (0x1C, Reserved); + } +} + + +static const unsigned kNodeBlockFieldSize = 60; + +struct CExtentTreeHeader +{ + UInt16 NumEntries; + UInt16 MaxEntries; + UInt16 Depth; + // UInt32 Generation; + + bool Parse(const Byte *p) + { + LE_16 (0x02, NumEntries); + LE_16 (0x04, MaxEntries); + LE_16 (0x06, Depth); + // LE_32 (0x08, Generation); + return Get16(p) == 0xF30A; // magic + } +}; + +struct CExtentIndexNode +{ + UInt32 VirtBlock; + UInt64 PhyLeaf; + + void Parse(const Byte *p) + { + LE_32 (0x00, VirtBlock); + LE_32 (0x04, PhyLeaf); + PhyLeaf |= (((UInt64)Get16(p + 8)) << 32); + // unused 16-bit field (at offset 0x0A) can be not zero in some cases. Why? + } +}; + +struct CExtent +{ + UInt32 VirtBlock; + UInt16 Len; + bool IsInited; + UInt64 PhyStart; + + UInt32 GetVirtEnd() const { return VirtBlock + Len; } + bool IsLenOK() const { return VirtBlock + Len >= VirtBlock; } + + void Parse(const Byte *p) + { + LE_32 (0x00, VirtBlock); + LE_16 (0x04, Len); + IsInited = true; + if (Len > (UInt32)0x8000) + { + IsInited = false; + Len -= (UInt32)0x8000; + } + LE_32 (0x08, PhyStart); + UInt16 hi; + LE_16 (0x06, hi); + PhyStart |= ((UInt64)hi << 32); + } +}; + + + +struct CExtTime +{ + UInt32 Val; + UInt32 Extra; +}; + +struct CNode +{ + Int32 ParentNode; // in _nodes[], -1 if not dir + int ItemIndex; // in _items[] + int SymLinkIndex; // in _symLinks[] + int DirIndex; // in _dirs[] + + UInt16 Mode; + UInt16 Uid; + UInt16 Gid; + // UInt16 Checksum; + bool IsEmpty; + + UInt64 FileSize; + CExtTime MTime; + CExtTime ATime; + CExtTime CTime; + // CExtTime InodeChangeTime; + // CExtTime DTime; + + UInt64 NumBlocks; + UInt32 NumLinks; + UInt32 Flags; + + UInt32 NumLinksCalced; + + Byte Block[kNodeBlockFieldSize]; + + CNode(): + ParentNode(-1), + ItemIndex(-1), + SymLinkIndex(-1), + DirIndex(0), + NumLinksCalced(0) + {} + + bool IsFlags_HUGE() const { return (Flags & k_NodeFlags_HUGE) != 0; } + bool IsFlags_EXTENTS() const { return (Flags & k_NodeFlags_EXTENTS) != 0; } + + bool IsDir() const { return MY_LIN_S_ISDIR(Mode); } + bool IsRegular() const { return MY_LIN_S_ISREG(Mode); } + bool IsLink() const { return MY_LIN_S_ISLNK(Mode); } + + bool Parse(const Byte *p, const CHeader &_h); +}; + + +bool CNode::Parse(const Byte *p, const CHeader &_h) +{ + MTime.Extra = 0; + ATime.Extra = 0; + CTime.Extra = 0; + // InodeChangeTime.Extra = 0; + // DTime.Extra = 0; + + LE_16 (0x00, Mode); + LE_16 (0x02, Uid); + LE_32 (0x04, FileSize); + LE_32 (0x08, ATime.Val); + // LE_32 (0x0C, InodeChangeTime.Val); + LE_32 (0x10, MTime.Val); + // LE_32 (0x14, DTime.Val); + LE_16 (0x18, Gid); + LE_16 (0x1A, NumLinks); + + LE_32 (0x1C, NumBlocks); + LE_32 (0x20, Flags); + // LE_32 (0x24, Union osd1); + + memcpy(Block, p + 0x28, kNodeBlockFieldSize); + + // LE_32 (0x64, Generation); // File version (for NFS) + // LE_32 (0x68, ACL); + + { + UInt32 highSize; + LE_32 (0x6C, highSize); // In ext2/3 this field was named i_dir_acl + + if (IsRegular()) // do we need that check ? + FileSize |= ((UInt64)highSize << 32); + } + + // LE_32 (0x70, fragmentAddress); + + // osd2 + { + // Linux; + UInt32 numBlocksHigh; + LE_16 (0x74, numBlocksHigh); + NumBlocks |= (UInt64)numBlocksHigh << 32; + HI_16 (0x74 + 4, Uid); + HI_16 (0x74 + 6, Gid); + /* + UInt32 checksum; + LE_16 (0x74 + 8, checksum); + checksum = checksum; + */ + } + + // 0x74: Byte Union osd2[12]; + + if (_h.InodeSize > 128) + { + UInt16 extra_isize; + LE_16 (0x80, extra_isize); + if (128 + extra_isize > _h.InodeSize) + return false; + if (extra_isize >= 0x1C) + { + // UInt16 checksumUpper; + // LE_16 (0x82, checksumUpper); + // LE_32 (0x84, InodeChangeTime.Extra); + LE_32 (0x88, MTime.Extra); + LE_32 (0x8C, ATime.Extra); + LE_32 (0x90, CTime.Val); + LE_32 (0x94, CTime.Extra); + // LE_32 (0x98, VersionHi); + } + } + + PRF(printf("size = %5d", (unsigned)FileSize)); + + return true; +} + + +struct CItem +{ + unsigned Node; // in _nodes[] + int ParentNode; // in _nodes[] + int SymLinkItemIndex; // in _items[], if the Node contains SymLink to existing dir + Byte Type; + + AString Name; + + CItem(): + Node(0), + ParentNode(-1), + SymLinkItemIndex(-1), + Type(k_Type_UNKNOWN) + {} + + void Clear() + { + Node = 0; + ParentNode = -1; + SymLinkItemIndex = -1; + Type = k_Type_UNKNOWN; + Name.Empty(); + } + + bool IsDir() const { return Type == k_Type_DIR; } + // bool IsNotDir() const { return Type != k_Type_DIR && Type != k_Type_UNKNOWN; } + +}; + + + +static const unsigned kNumTreeLevelsMax = 6; // must be >= 3 + + +class CHandler: + public IInArchive, + public IArchiveGetRawProps, + public IInArchiveGetStream, + public CMyUnknownImp +{ + CObjectVector<CItem> _items; + CRecordVector<CNode> _nodes; + CObjectVector<CUIntVector> _dirs; // each CUIntVector contains indexes in _items[] only for dir items; + AStringVector _symLinks; + AStringVector _auxItems; + int _auxSysIndex; + int _auxUnknownIndex; + + CMyComPtr<IInStream> _stream; + UInt64 _phySize; + bool _isArc; + bool _headersError; + bool _linksError; + + bool _isUTF; + + CHeader _h; + + IArchiveOpenCallback *_openCallback; + UInt64 _totalRead; + UInt64 _totalReadPrev; + + CByteBuffer _tempBufs[kNumTreeLevelsMax]; + + + HRESULT CheckProgress2() + { + const UInt64 numFiles = _items.Size(); + return _openCallback->SetCompleted(&numFiles, &_totalRead); + } + + HRESULT CheckProgress() + { + HRESULT res = S_OK; + if (_openCallback) + { + if (_totalRead - _totalReadPrev >= ((UInt32)1 << 20)) + { + _totalReadPrev = _totalRead; + res = CheckProgress2(); + } + } + return res; + } + + + const int GetParentAux(const CItem &item) const + { + if (item.Node < _h.FirstInode && _auxSysIndex >= 0) + return _auxSysIndex; + return _auxUnknownIndex; + } + + HRESULT SeekAndRead(IInStream *inStream, UInt64 block, Byte *data, size_t size); + HRESULT ParseDir(const Byte *data, size_t size, unsigned nodeIndex); + int FindTargetItem_for_SymLink(unsigned dirNode, const AString &path) const; + + HRESULT FillFileBlocks2(UInt32 block, unsigned level, unsigned numBlocks, CRecordVector<UInt32> &blocks); + HRESULT FillFileBlocks(const Byte *p, unsigned numBlocks, CRecordVector<UInt32> &blocks); + HRESULT FillExtents(const Byte *p, size_t size, CRecordVector<CExtent> &extents, int parentDepth); + + HRESULT GetStream_Node(UInt32 nodeIndex, ISequentialInStream **stream); + HRESULT ExtractNode(unsigned nodeIndex, CByteBuffer &data); + + void ClearRefs(); + HRESULT Open2(IInStream *inStream); + + void GetPath(unsigned index, AString &s) const; + bool GetPackSize(unsigned index, UInt64 &res) const; + +public: + CHandler() {} + ~CHandler() {} + + MY_UNKNOWN_IMP3(IInArchive, IArchiveGetRawProps, IInArchiveGetStream) + + INTERFACE_IInArchive(;) + INTERFACE_IArchiveGetRawProps(;) + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream); +}; + + + +HRESULT CHandler::ParseDir(const Byte *p, size_t size, unsigned nodeIndex) +{ + bool isThereSelfLink = false; + + PRF(printf("\n\n========= node = %5d size = %5d", nodeIndex, size)); + + CNode &nodeDir = _nodes[nodeIndex]; + nodeDir.DirIndex = _dirs.Size(); + CUIntVector &dir = _dirs.AddNew(); + int parentNode = -1; + + CItem item; + + for (;;) + { + if (size == 0) + break; + if (size < 8) + return S_FALSE; + UInt32 iNode; + LE_32 (0x00, iNode); + unsigned recLen; + LE_16 (0x04, recLen); + unsigned nameLen = p[6]; + Byte type = p[7]; + + if (recLen > size) + return S_FALSE; + if (nameLen + 8 > recLen) + return S_FALSE; + + if (iNode >= _nodes.Size()) + return S_FALSE; + + item.Clear(); + + if (_h.IsThereFileType()) + item.Type = type; + else if (type != 0) + return S_FALSE; + + item.ParentNode = nodeIndex; + item.Node = iNode; + item.Name.SetFrom_CalcLen((const char *)(p + 8), nameLen); + + p += recLen; + size -= recLen; + + if (item.Name.Len() != nameLen) + return S_FALSE; + + if (_isUTF) + _isUTF = CheckUTF8(item.Name); + + if (iNode == 0) + { + /* + ext3 deleted?? + if (item.Name.Len() != 0) + return S_FALSE; + */ + + PRF(printf("\n EMPTY %6d %d %s", recLen, type, (const char *)item.Name)); + if (type == 0xDE) + { + // checksum + } + continue; + } + + CNode &node = _nodes[iNode]; + if (node.IsEmpty) + return S_FALSE; + + if (_h.IsThereFileType() && type != 0) + { + if (type >= ARRAY_SIZE(k_TypeToMode)) + return S_FALSE; + if (k_TypeToMode[type] != (node.Mode & MY_LIN_S_IFMT)) + return S_FALSE; + } + + node.NumLinksCalced++; + + PRF(printf("\n%s %6d %s", item.IsDir() ? "DIR " : " ", item.Node, (const char *)item.Name)); + + if (item.Name[0] == '.') + { + if (item.Name[1] == 0) + { + if (isThereSelfLink) + return S_FALSE; + isThereSelfLink = true; + if (nodeIndex != nodeIndex) + return S_FALSE; + continue; + } + + if (item.Name[1] == '.' && item.Name[2] == 0) + { + if (parentNode >= 0) + return S_FALSE; + if (!node.IsDir()) + return S_FALSE; + if (iNode == nodeIndex && iNode != k_INODE_ROOT) + return S_FALSE; + + parentNode = iNode; + + if (nodeDir.ParentNode < 0) + nodeDir.ParentNode = iNode; + else if ((unsigned)nodeDir.ParentNode != iNode) + return S_FALSE; + + continue; + } + } + + if (iNode == nodeIndex) + return S_FALSE; + + if (parentNode < 0) + return S_FALSE; + + if (node.IsDir()) + { + if (node.ParentNode < 0) + node.ParentNode = nodeIndex; + else if ((unsigned)node.ParentNode != nodeIndex) + return S_FALSE; + const unsigned itemIndex = _items.Size(); + dir.Add(itemIndex); + node.ItemIndex = itemIndex; + } + + _items.Add(item); + } + + if (parentNode < 0 || !isThereSelfLink) + return S_FALSE; + + return S_OK; +} + + +int CHandler::FindTargetItem_for_SymLink(unsigned nodeIndex, const AString &path) const +{ + unsigned pos = 0; + + if (path.IsEmpty()) + return -1; + + if (path[0] == '/') + { + nodeIndex = k_INODE_ROOT; + if (nodeIndex >= _nodes.Size()) + return -1; + pos = 1; + } + + AString s; + + while (pos != path.Len()) + { + const CNode &node = _nodes[nodeIndex]; + int slash = path.Find('/', pos); + + if (slash < 0) + { + s = path.Ptr(pos); + pos = path.Len(); + } + else + { + s.SetFrom(path.Ptr(pos), slash - pos); + pos = slash + 1; + } + + if (s[0] == '.') + { + if (s[1] == 0) + continue; + else if (s[1] == '.' && s[2] == 0) + { + if (node.ParentNode < 0) + return -1; + if (nodeIndex == k_INODE_ROOT) + return -1; + nodeIndex = node.ParentNode; + continue; + } + } + + if (node.DirIndex < 0) + return -1; + + const CUIntVector &dir = _dirs[node.DirIndex]; + + for (unsigned i = 0;; i++) + { + if (i >= dir.Size()) + return -1; + const CItem &item = _items[dir[i]]; + if (item.Name == s) + { + nodeIndex = item.Node; + break; + } + } + } + + return _nodes[nodeIndex].ItemIndex; +} + + +HRESULT CHandler::SeekAndRead(IInStream *inStream, UInt64 block, Byte *data, size_t size) +{ + if (block == 0 || block >= _h.NumBlocks) + return S_FALSE; + if (((size + (1 << _h.BlockBits) + 1) >> _h.BlockBits) > _h.NumBlocks - block) + return S_FALSE; + RINOK(inStream->Seek((UInt64)block << _h.BlockBits, STREAM_SEEK_SET, NULL)); + _totalRead += size; + return ReadStream_FALSE(inStream, data, size); +} + + +static const unsigned kHeaderSize = 2 * 1024; +static const unsigned kHeaderDataOffset = 1024; + +HRESULT CHandler::Open2(IInStream *inStream) +{ + { + Byte buf[kHeaderSize]; + RINOK(ReadStream_FALSE(inStream, buf, kHeaderSize)); + if (!_h.Parse(buf + kHeaderDataOffset)) + return S_FALSE; + if (_h.BlockGroupNr != 0) + return S_FALSE; // it's just copy of super block + } + + { + // ---------- Read groups and nodes ---------- + + unsigned numGroups; + { + UInt64 numGroups64 = _h.GetNumGroups(); + if (numGroups64 > (UInt32)1 << 31) + return S_FALSE; + numGroups = (unsigned)numGroups64; + } + + unsigned gdBits = 5; + if (_h.Is64Bit()) + { + if (_h.GdSize != 64) + return S_FALSE; + gdBits = 6; + } + + _isArc = true; + _phySize = _h.NumBlocks << _h.BlockBits; + + if (_openCallback) + { + RINOK(_openCallback->SetTotal(NULL, &_phySize)); + } + + CRecordVector<CGroupDescriptor> groups; + + { + // ---------- Read groups ---------- + + CByteBuffer gdBuf; + size_t gdBufSize = (size_t)numGroups << gdBits; + if ((gdBufSize >> gdBits) != numGroups) + return S_FALSE; + gdBuf.Alloc(gdBufSize); + RINOK(SeekAndRead(inStream, (_h.BlockBits <= 10 ? 2 : 1), gdBuf, gdBufSize)); + + for (unsigned i = 0; i < numGroups; i++) + { + CGroupDescriptor gd; + + const Byte *p = gdBuf + ((size_t)i << gdBits); + unsigned gd_Size = (unsigned)1 << gdBits; + gd.Parse(p, gd_Size); + + if (_h.UseMetadataChecksum()) + { + // use CRC32c + } + else if (_h.UseGdtChecksum()) + { + UInt32 crc = Crc16Calc(_h.Uuid, sizeof(_h.Uuid)); + Byte i_le[4]; + SetUi32(i_le, i); + crc = Crc16Update(crc, i_le, 4); + crc = Crc16Update(crc, p, 32 - 2); + if (gd_Size != 32) + crc = Crc16Update(crc, p + 32, gd_Size - 32); + if (crc != gd.Checksum) + return S_FALSE; + } + + groups.Add(gd); + } + } + + { + // ---------- Read nodes ---------- + + if (_h.NumInodes < _h.NumFreeInodes) + return S_FALSE; + + UInt32 numReserveInodes = _h.NumInodes - _h.NumFreeInodes + 1; + // numReserveInodes = _h.NumInodes + 1; + if (numReserveInodes != 0) + _nodes.Reserve(numReserveInodes); + + UInt32 numNodes = _h.InodesPerGroup; + if (numNodes > _h.NumInodes) + numNodes = _h.NumInodes; + size_t nodesDataSize = numNodes * _h.InodeSize; + if (nodesDataSize / _h.InodeSize != numNodes) + return S_FALSE; + + CByteBuffer nodesData; + nodesData.Alloc(nodesDataSize); + + CByteBuffer nodesMap; + const size_t blockSize = (size_t)1 << _h.BlockBits; + nodesMap.Alloc(blockSize); + + unsigned globalNodeIndex = 0; + + FOR_VECTOR (gi, groups) + { + if (globalNodeIndex >= _h.NumInodes) + break; + + const CGroupDescriptor &gd = groups[gi]; + + PRF(printf("\n\ng%6d block = %6x\n", gi, gd.InodeTable)); + + RINOK(SeekAndRead(inStream, gd.InodeBitmap, nodesMap, blockSize)); + RINOK(SeekAndRead(inStream, gd.InodeTable, nodesData, nodesDataSize)); + + for (size_t n = 0; n < numNodes && globalNodeIndex < _h.NumInodes; n++, globalNodeIndex++) + { + if ((nodesMap[n >> 3] & ((unsigned)1 << (n & 7))) == 0) + continue; + + const Byte *p = nodesData + (size_t)n * _h.InodeSize; + unsigned j = 0; + for (j = 0; j < _h.InodeSize; j++) + if (p[j] != 0) + break; + + if (j == _h.InodeSize) + { + if (_nodes.Size() >= _h.FirstInode) + { + // return S_FALSE; + } + continue; + } + + CNode node; + node.IsEmpty = false; + + PRF(printf("\nnode = %5d ", (unsigned)n)); + + if (!node.Parse(p, _h)) + return S_FALSE; + + // PRF(printf("\n %6d", n)); + /* + SetUi32(p + 0x7C, 0) + SetUi32(p + 0x82, 0) + + UInt32 crc = Crc32C_Calc(_h.Uuid, sizeof(_h.Uuid)); + Byte i_le[4]; + SetUi32(i_le, n); + crc = Crc32C_Update(crc, i_le, 4); + crc = Crc32C_Update(crc, p, _h.InodeSize); + if (crc != node.Checksum) return S_FALSE; + */ + + while (_nodes.Size() < globalNodeIndex + 1) + { + CNode node2; + node2.IsEmpty = true; + _nodes.Add(node2); + } + + _nodes.Add(node); + } + } + + if (_nodes.Size() <= k_INODE_ROOT) + return S_FALSE; + } + } + + _stream = inStream; // we need stream for dir nodes + + { + // ---------- Read Dirs ---------- + + CByteBuffer dataBuf; + + FOR_VECTOR (i, _nodes) + { + { + const CNode &node = _nodes[i]; + if (node.IsEmpty || !node.IsDir()) + continue; + } + RINOK(ExtractNode(i, dataBuf)); + if (dataBuf.Size() == 0) + { + // _headersError = true; + return S_FALSE; + } + else + { + RINOK(ParseDir(dataBuf, dataBuf.Size(), i)); + } + RINOK(CheckProgress()); + } + + if (_nodes[k_INODE_ROOT].ParentNode != k_INODE_ROOT) + return S_FALSE; + } + + { + // ---------- Check NumLinks and unreferenced dir nodes ---------- + + FOR_VECTOR (i, _nodes) + { + const CNode &node = _nodes[i]; + if (node.IsEmpty) + continue; + + if (node.NumLinks != node.NumLinksCalced) + { + if (node.NumLinks != 1 || node.NumLinksCalced != 0 + // ) && i >= _h.FirstInode + ) + { + _linksError = true; + // return S_FALSE; + } + } + + if (!node.IsDir()) + continue; + + if (node.ParentNode < 0) + { + if (i >= _h.FirstInode) + return S_FALSE; + continue; + } + } + } + + { + // ---------- Check that there is no loops in parents list ---------- + + unsigned numNodes = _nodes.Size(); + CIntArr UsedByNode(numNodes); + { + for (unsigned i = 0; i < numNodes; i++) + UsedByNode[i] = -1; + } + + FOR_VECTOR (i, _nodes) + { + { + CNode &node = _nodes[i]; + if (node.IsEmpty + || node.ParentNode < 0 // not dir + || i == k_INODE_ROOT) + continue; + } + + unsigned c = i; + + for (;;) + { + CNode &node = _nodes[c]; + if (node.IsEmpty) + return S_FALSE; + + if (UsedByNode[c] != -1) + { + if ((unsigned)UsedByNode[c] == i) + return S_FALSE; + break; + } + + UsedByNode[c] = i; + if (node.ParentNode < 0 || node.ParentNode == k_INODE_ROOT) + break; + if ((unsigned)node.ParentNode == i) + return S_FALSE; + c = node.ParentNode; + } + } + } + + { + // ---------- Fill SymLinks data ---------- + + AString s; + CByteBuffer data; + + unsigned i; + for (i = 0; i < _nodes.Size(); i++) + { + CNode &node = _nodes[i]; + if (node.IsEmpty || !node.IsLink()) + continue; + if (node.FileSize > ((UInt32)1 << 14)) + continue; + if (ExtractNode(i, data) == S_OK && data.Size() != 0) + { + s.SetFrom_CalcLen((const char *)(const Byte *)data, (unsigned)data.Size()); + if (s.Len() == data.Size()) + node.SymLinkIndex = _symLinks.Add(s); + RINOK(CheckProgress()); + } + } + + unsigned prev = 0; + unsigned complex = 0; + + for (i = 0; i < _items.Size(); i++) + { + CItem &item = _items[i]; + int sym = _nodes[item.Node].SymLinkIndex; + if (sym >= 0 && item.ParentNode >= 0) + { + item.SymLinkItemIndex = FindTargetItem_for_SymLink(item.ParentNode, _symLinks[sym]); + if (_openCallback) + { + complex++; + if (complex - prev >= (1 << 10)) + { + RINOK(CheckProgress2()); + prev = complex; + } + } + } + } + } + + { + // ---------- Add items and aux folders for unreferenced files ---------- + + bool useSys = false; + bool useUnknown = false; + + for (unsigned i = 0; i < _nodes.Size(); i++) + { + const CNode &node = _nodes[i]; + if (node.IsEmpty) + continue; + + if (node.NumLinksCalced == 0 /* || i > 100 && i < 150 */) // for debug + { + CItem item; + item.Node = i; + + // we don't know how to work with k_INODE_RESIZE node (strange FileSize and Block values). + // so we ignore it; + + if (i == k_INODE_RESIZE) + continue; + + if (node.FileSize == 0) + continue; + + if (i < _h.FirstInode) + { + if (item.Node < ARRAY_SIZE(k_SysInode_Names)) + item.Name = k_SysInode_Names[item.Node]; + useSys = true; + } + else + useUnknown = true; + + if (item.Name.IsEmpty()) + { + char temp[16]; + ConvertUInt32ToString(item.Node, temp); + item.Name = temp; + } + + _items.Add(item); + } + } + + if (useSys) + _auxSysIndex = _auxItems.Add("[SYS]"); + if (useUnknown) + _auxUnknownIndex = _auxItems.Add("[UNKNOWN]"); + } + + return S_OK; +} + + +STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *callback) +{ + COM_TRY_BEGIN + { + Close(); + HRESULT res; + try + { + _openCallback = callback; + res = Open2(stream); + } + catch(...) + { + ClearRefs(); + throw; + } + + if (res != S_OK) + { + ClearRefs(); + return res; + } + _stream = stream; + } + return S_OK; + COM_TRY_END +} + + +void CHandler::ClearRefs() +{ + _stream.Release(); + _items.Clear(); + _nodes.Clear(); + _auxItems.Clear(); + _symLinks.Clear(); + _dirs.Clear(); + _auxSysIndex = -1; + _auxUnknownIndex = -1; +} + + +STDMETHODIMP CHandler::Close() +{ + _totalRead = 0; + _totalReadPrev = 0; + _phySize = 0; + _isArc = false; + _headersError = false; + _linksError = false; + _isUTF = true; + + ClearRefs(); + return S_OK; +} + + +void CHandler::GetPath(unsigned index, AString &s) const +{ + s.Empty(); + + if (index >= _items.Size()) + { + s = _auxItems[index - _items.Size()]; + return; + } + + for (;;) + { + const CItem &item = _items[index]; + if (!s.IsEmpty()) + s.InsertAtFront(CHAR_PATH_SEPARATOR); + s.Insert(0, item.Name); + + if (item.ParentNode == k_INODE_ROOT) + return; + + if (item.ParentNode < 0) + { + int aux = GetParentAux(item); + if (aux < 0) + break; + s.InsertAtFront(CHAR_PATH_SEPARATOR); + s.Insert(0, _auxItems[aux]); + return; + } + + const CNode &node = _nodes[item.ParentNode]; + if (node.ItemIndex < 0) + return; + index = node.ItemIndex; + + if (s.Len() > ((UInt32)1 << 16)) + { + s.Insert(0, "[LONG]" STRING_PATH_SEPARATOR); + return; + } + } +} + + +bool CHandler::GetPackSize(unsigned index, UInt64 &totalPack) const +{ + if (index >= _items.Size()) + { + totalPack = 0; + return false; + } + + const CItem &item = _items[index]; + const CNode &node = _nodes[item.Node]; + + // if (!node.IsFlags_EXTENTS()) + { + totalPack = (UInt64)node.NumBlocks << (node.IsFlags_HUGE() ? _h.BlockBits : 9); + return true; + } + + /* + CExtentTreeHeader eth; + if (!eth.Parse(node.Block)) + return false; + if (eth.NumEntries > 3) + return false; + if (!eth.Depth == 0) + return false; + + UInt64 numBlocks = 0; + { + for (unsigned i = 0; i < eth.NumEntries; i++) + { + CExtent e; + e.Parse(node.Block + 12 + i * 12); + // const CExtent &e = node.leafs[i]; + if (e.IsInited) + numBlocks += e.Len; + } + } + + totalPack = numBlocks << _h.BlockBits; + return true; + */ +} + + +STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) +{ + *numItems = _items.Size() + _auxItems.Size(); + return S_OK; +} + +enum +{ + kpidMountTime = kpidUserDefined, + kpidLastCheckTime, + kpidRevision, + kpidINodeSize, + kpidLastMount, + kpidFeatureIncompat, + kpidFeatureRoCompat, + kpidWrittenKB + + // kpidGroupSize, + + // kpidChangeTime = kpidUserDefined + 256, + // kpidDTime +}; + +static const UInt32 kProps[] = +{ + kpidPath, + kpidIsDir, + kpidSize, + kpidPackSize, + kpidPosixAttrib, + kpidMTime, + kpidCTime, + kpidATime, + // kpidChangeTime, + // kpidDTime, + kpidINode, + kpidLinks, + kpidSymLink, + kpidCharacts, + kpidUser, + kpidGroup +}; + + +static const CStatProp kArcProps[] = +{ + { NULL, kpidHeadersSize, VT_BSTR }, + // { NULL, kpidFileSystem, VT_BSTR }, + // kpidMethod, + { NULL, kpidClusterSize, VT_UI4 }, + // { "Group Size", kpidGroupSize, VT_UI8 }, + { NULL, kpidFreeSpace, VT_UI8 }, + + { NULL, kpidMTime, VT_FILETIME }, + { NULL, kpidCTime, VT_FILETIME }, + { "Mount Time", kpidMountTime, VT_FILETIME }, + { "Last Check Time", kpidLastCheckTime, VT_FILETIME }, + + { NULL, kpidHostOS, VT_BSTR}, + { "Revision", kpidRevision, VT_UI4}, + { "inode Size", kpidINodeSize, VT_UI4}, + { NULL, kpidCodePage, VT_BSTR}, + { NULL, kpidVolumeName, VT_BSTR}, + { "Last Mounted", kpidLastMount, VT_BSTR}, + { NULL, kpidId, VT_BSTR}, + { NULL, kpidCharacts, VT_BSTR }, + { "Incompatible Features", kpidFeatureIncompat, VT_BSTR }, + { "Readonly-compatible Features", kpidFeatureRoCompat, VT_BSTR }, + { "Written KiB", kpidWrittenKB, VT_UI8 } +}; + +IMP_IInArchive_Props +IMP_IInArchive_ArcProps_WITH_NAME + +static void StringToProp(bool isUTF, const char *s, unsigned size, NCOM::CPropVariant &prop) +{ + UString u; + AString a; + a.SetFrom_CalcLen(s, size); + if (!isUTF || !ConvertUTF8ToUnicode(a, u)) + MultiByteToUnicodeString2(u, a); + prop = u; +} + +static void UnixTimeToProp(UInt32 val, NCOM::CPropVariant &prop) +{ + if (val != 0) + { + FILETIME ft; + NTime::UnixTimeToFileTime(val, ft); + prop = ft; + } +} + +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + + NCOM::CPropVariant prop; + + switch (propID) + { + /* + case kpidFileSystem: + { + AString res = "Ext4"; + prop = res; + break; + } + */ + + case kpidIsTree: prop = true; break; + case kpidIsAux: prop = true; break; + case kpidINode: prop = true; break; + + case kpidClusterSize: prop = (UInt32)1 << _h.BlockBits; break; + // case kpidGroupSize: prop = (UInt64)_h.BlocksPerGroup << _h.BlockBits; break; + + case kpidFreeSpace: prop = (UInt64)_h.NumFreeBlocks << _h.BlockBits; break; + + case kpidCTime: UnixTimeToProp(_h.CTime, prop); break; + case kpidMTime: UnixTimeToProp(_h.WriteTime, prop); break; + case kpidMountTime: UnixTimeToProp(_h.MountTime, prop); break; + case kpidLastCheckTime: UnixTimeToProp(_h.LastCheckTime, prop); break; + + case kpidHostOS: + { + char temp[16]; + const char *s = NULL; + if (_h.CreatorOs < ARRAY_SIZE(kHostOS)) + s = kHostOS[_h.CreatorOs]; + else + { + ConvertUInt32ToString(_h.CreatorOs, temp); + s = temp; + } + prop = s; + break; + } + + case kpidRevision: prop = _h.RevLevel; break; + + case kpidINodeSize: prop = _h.InodeSize; break; + + case kpidId: + { + char s[16 * 2 + 2]; + for (unsigned i = 0; i < 16; i++) + PrintHex(_h.Uuid[i], s + i * 2); + s[16 * 2] = 0; + prop = s; + break; + } + + case kpidCodePage: if (_isUTF) prop = "UTF-8"; break; + case kpidVolumeName: StringToProp(_isUTF, _h.VolName, sizeof(_h.VolName), prop); break; + case kpidLastMount: StringToProp(_isUTF, _h.LastMount, sizeof(_h.LastMount), prop); break; + + case kpidCharacts: FLAGS_TO_PROP(g_FeatureCompat_Flags, _h.FeatureCompat, prop); break; + case kpidFeatureIncompat: FLAGS_TO_PROP(g_FeatureIncompat_Flags, _h.FeatureIncompat, prop); break; + case kpidFeatureRoCompat: FLAGS_TO_PROP(g_FeatureRoCompat_Flags, _h.FeatureRoCompat, prop); break; + case kpidWrittenKB: prop = _h.WrittenKB; break; + + case kpidPhySize: prop = _phySize; break; + + case kpidErrorFlags: + { + UInt32 v = 0; + if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;; + if (_linksError) v |= kpv_ErrorFlags_HeadersError; + if (_headersError) v |= kpv_ErrorFlags_HeadersError; + if (!_stream && v == 0 && _isArc) + v = kpv_ErrorFlags_HeadersError; + if (v != 0) + prop = v; + break; + } + } + + prop.Detach(value); + return S_OK; + + COM_TRY_END +} + + +/* +static const Byte kRawProps[] = +{ + // kpidSha1, +}; +*/ + +STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps) +{ + // *numProps = ARRAY_SIZE(kRawProps); + *numProps = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID) +{ + // *propID = kRawProps[index]; + *propID = 0; + *name = 0; + return S_OK; +} + +STDMETHODIMP CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType) +{ + *parentType = NParentType::kDir; + *parent = (UInt32)(Int32)-1; + + if (index >= _items.Size()) + return S_OK; + + const CItem &item = _items[index]; + + if (item.ParentNode < 0) + { + int aux = GetParentAux(item); + if (aux >= 0) + *parent = _items.Size() + aux; + } + else + { + int itemIndex = _nodes[item.ParentNode].ItemIndex; + if (itemIndex >= 0) + *parent = itemIndex; + } + + return S_OK; +} + + +STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType) +{ + *data = NULL; + *dataSize = 0; + *propType = 0; + + if (propID == kpidName && _isUTF) + { + if (index < _items.Size()) + { + const AString &s = _items[index].Name; + if (!s.IsEmpty()) + { + *data = (void *)(const char *)s; + *dataSize = (UInt32)s.Len() + 1; + *propType = NPropDataType::kUtf8z; + } + return S_OK; + } + else + { + const AString &s = _auxItems[index - _items.Size()]; + { + *data = (void *)(const char *)s; + *dataSize = (UInt32)s.Len() + 1; + *propType = NPropDataType::kUtf8z; + } + return S_OK; + } + } + + return S_OK; +} + + +static void ExtTimeToProp(const CExtTime &t, NCOM::CPropVariant &prop) +{ + /* + UInt32 nano = 0; + if (t.Extra != 0) + { + UInt32 mask = t.Extra & 3; + if (mask != 0) + return; + nano = t.Extra >> 2; + } + UInt64 v; + if (t.Val == 0 && nano == 0) + return; + if (!NTime::UnixTime_to_FileTime64(t.Val, v)) + return; + if (nano != 0) + v += nano / 100; + + FILETIME ft; + ft.dwLowDateTime = (DWORD)v; + ft.dwHighDateTime = (DWORD)(v >> 32); + prop = ft; + */ + if (t.Val == 0) + return; + if (t.Extra != 0) + { + UInt32 mask = t.Extra & 3; + if (mask != 0) + return; + } + FILETIME ft; + if (NTime::UnixTime64ToFileTime(t.Val, ft)) + prop = ft; +} + + +STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NCOM::CPropVariant prop; + + if (index >= _items.Size()) + { + switch (propID) + { + case kpidPath: + case kpidName: + { + AString s = _auxItems[index - _items.Size()]; + prop = s; + break; + } + case kpidIsDir: prop = true; break; + case kpidIsAux: prop = true; break; + } + } + else + { + + const CItem &item = _items[index]; + const CNode &node = _nodes[item.Node]; + bool isDir = node.IsDir(); + + switch (propID) + { + case kpidPath: + { + UString u; + { + AString s; + GetPath(index, s); + if (!_isUTF || !ConvertUTF8ToUnicode(s, u)) + MultiByteToUnicodeString2(u, s); + } + prop = u; + break; + } + + case kpidName: + { + { + UString u; + { + if (!_isUTF || !ConvertUTF8ToUnicode(item.Name, u)) + MultiByteToUnicodeString2(u, item.Name); + } + prop = u; + } + break; + } + + case kpidIsDir: + { + bool isDir2 = isDir; + if (item.SymLinkItemIndex >= 0) + isDir2 = _nodes[_items[item.SymLinkItemIndex].Node].IsDir(); + prop = isDir2; + break; + } + + case kpidSize: if (!isDir) prop = node.FileSize; break; + + case kpidPackSize: + if (!isDir) + { + UInt64 size; + if (GetPackSize(index, size)) + prop = size; + } + break; + + case kpidPosixAttrib: + { + /* + if (node.Type != 0 && node.Type < ARRAY_SIZE(k_TypeToMode)) + prop = (UInt32)(node.Mode & 0xFFF) | k_TypeToMode[node.Type]; + */ + prop = (UInt32)(node.Mode); + break; + } + + case kpidMTime: ExtTimeToProp(node.MTime, prop); break; + case kpidCTime: ExtTimeToProp(node.CTime, prop); break; + case kpidATime: ExtTimeToProp(node.ATime, prop); break; + // case kpidDTime: ExtTimeToProp(node.DTime, prop); break; + // case kpidChangeTime: ExtTimeToProp(node.InodeChangeTime, prop); break; + + case kpidUser: prop = (UInt32)node.Uid; break; + case kpidGroup: prop = (UInt32)node.Gid; break; + case kpidLinks: prop = node.NumLinks; break; + case kpidINode: prop = (UInt32)item.Node; break; + case kpidStreamId: if (!isDir) prop = (UInt32)item.Node; break; + case kpidCharacts: FLAGS_TO_PROP(g_NodeFlags, (UInt32)node.Flags, prop); break; + + case kpidSymLink: + { + if (node.SymLinkIndex >= 0) + { + UString u; + { + const AString &s = _symLinks[node.SymLinkIndex]; + if (!_isUTF || !ConvertUTF8ToUnicode(s, u)) + MultiByteToUnicodeString2(u, s); + } + prop = u; + } + break; + } + } + + } + + prop.Detach(value); + return S_OK; + COM_TRY_END +} + + +class CExtInStream: + public IInStream, + public CMyUnknownImp +{ + UInt64 _virtPos; + UInt64 _phyPos; +public: + UInt64 _size; + unsigned BlockBits; + CMyComPtr<IInStream> Stream; + CRecordVector<CExtent> Extents; + + CExtInStream() {} + + HRESULT StartSeek() + { + _virtPos = 0; + _phyPos = 0; + return Stream->Seek(_phyPos, STREAM_SEEK_SET, NULL); + } + + MY_UNKNOWN_IMP2(ISequentialInStream, IInStream) + STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); +}; + +STDMETHODIMP CExtInStream::Read(void *data, UInt32 size, UInt32 *processedSize) +{ + if (processedSize) + *processedSize = 0; + if (_virtPos >= _size) + return S_OK; + UInt64 rem = _size - _virtPos; + if (size > rem) + size = (UInt32)rem; + if (size == 0) + return S_OK; + + UInt32 blockIndex = (UInt32)(_virtPos >> BlockBits); + + unsigned left = 0, right = Extents.Size(); + for (;;) + { + unsigned mid = (left + right) / 2; + if (mid == left) + break; + if (blockIndex < Extents[mid].VirtBlock) + right = mid; + else + left = mid; + } + + { + const CExtent &extent = Extents[left]; + if (blockIndex < extent.VirtBlock) + return E_FAIL; + UInt32 bo = blockIndex - extent.VirtBlock; + if (bo >= extent.Len) + return E_FAIL; + + UInt32 offset = ((UInt32)_virtPos & (((UInt32)1 << BlockBits) - 1)); + UInt32 remBlocks = extent.Len - bo; + UInt64 remBytes = ((UInt64)remBlocks << BlockBits); + remBytes -= offset; + + if (size > remBytes) + size = (UInt32)remBytes; + + if (!extent.IsInited) + { + memset(data, 0, size); + _virtPos += size; + if (processedSize) + *processedSize = size; + return S_OK; + } + + UInt64 phyBlock = extent.PhyStart + bo; + UInt64 phy = (phyBlock << BlockBits) + offset; + + if (phy != _phyPos) + { + RINOK(Stream->Seek(phy, STREAM_SEEK_SET, NULL)); + _phyPos = phy; + } + + UInt32 realProcessSize = 0; + + HRESULT res = Stream->Read(data, size, &realProcessSize); + + _phyPos += realProcessSize; + _virtPos += realProcessSize; + if (processedSize) + *processedSize = realProcessSize; + return res; + } +} + + +STDMETHODIMP CExtInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +{ + switch (seekOrigin) + { + case STREAM_SEEK_SET: break; + case STREAM_SEEK_CUR: offset += _virtPos; break; + case STREAM_SEEK_END: offset += _size; break; + default: return STG_E_INVALIDFUNCTION; + } + if (offset < 0) + return HRESULT_WIN32_ERROR_NEGATIVE_SEEK; + _virtPos = offset; + if (newPosition) + *newPosition = offset; + return S_OK; +} + + + +HRESULT CHandler::FillFileBlocks2(UInt32 block, unsigned level, unsigned numBlocks, CRecordVector<UInt32> &blocks) +{ + const size_t blockSize = (size_t)1 << _h.BlockBits; + CByteBuffer &tempBuf = _tempBufs[level]; + tempBuf.Alloc(blockSize); + + RINOK(SeekAndRead(_stream, block, tempBuf, blockSize)); + + const Byte *p = tempBuf; + size_t num = (size_t)1 << (_h.BlockBits - 2); + + for (size_t i = 0; i < num; i++) + { + if (blocks.Size() == numBlocks) + break; + UInt32 val = GetUi32(p + 4 * i); + if (val == 0 || val >= _h.NumBlocks) + return S_FALSE; + + if (level != 0) + { + RINOK(FillFileBlocks2(val, level - 1, numBlocks, blocks)); + continue; + } + + PRF(printf("\n i = %3d, start = %5d ", (unsigned)val)); + + blocks.Add(val); + } + + return S_OK; +} + + +static const unsigned kNumDirectNodeBlocks = 12; + +HRESULT CHandler::FillFileBlocks(const Byte *p, unsigned numBlocks, CRecordVector<UInt32> &blocks) +{ + blocks.ClearAndReserve(numBlocks); + + unsigned i; + + for (i = 0; i < kNumDirectNodeBlocks; i++) + { + if (i == numBlocks) + return S_OK; + UInt32 val = GetUi32(p + 4 * i); + if (val == 0 || val >= _h.NumBlocks) + return S_FALSE; + blocks.Add(val); + } + + for (i = 0; i < 3; i++) + { + if (blocks.Size() == numBlocks) + break; + UInt32 val = GetUi32(p + 4 * (kNumDirectNodeBlocks + i)); + if (val == 0 || val >= _h.NumBlocks) + return S_FALSE; + RINOK(FillFileBlocks2(val, i, numBlocks, blocks)); + } + + return S_OK; +} + + +static void AddSkipExtents(CRecordVector<CExtent> &extents, UInt32 virtBlock, UInt32 numBlocks) +{ + while (numBlocks != 0) + { + UInt32 len = numBlocks; + const UInt32 kLenMax = (UInt32)1 << 15; + if (len > kLenMax) + len = kLenMax; + CExtent e; + e.VirtBlock = virtBlock; + e.Len = (UInt16)len; + e.IsInited = false; + e.PhyStart = 0; + extents.Add(e); + virtBlock += len; + numBlocks -= len; + } +} + +static bool UpdateExtents(CRecordVector<CExtent> &extents, UInt32 block) +{ + if (extents.IsEmpty()) + { + if (block == 0) + return true; + AddSkipExtents(extents, 0, block); + return true; + } + + const CExtent &prev = extents.Back(); + if (block < prev.VirtBlock) + return false; + UInt32 prevEnd = prev.GetVirtEnd(); + if (block == prevEnd) + return true; + AddSkipExtents(extents, prevEnd, block - prevEnd); + return true; +} + + +HRESULT CHandler::FillExtents(const Byte *p, size_t size, CRecordVector<CExtent> &extents, int parentDepth) +{ + CExtentTreeHeader eth; + if (!eth.Parse(p)) + return S_FALSE; + + if (parentDepth >= 0 && eth.Depth != parentDepth - 1) // (eth.Depth >= parentDepth) + return S_FALSE; + + if (12 + 12 * (size_t)eth.NumEntries > size) + return S_FALSE; + + if (eth.Depth >= kNumTreeLevelsMax) + return S_FALSE; + + if (eth.Depth == 0) + { + for (unsigned i = 0; i < eth.NumEntries; i++) + { + CExtent e; + e.Parse(p + 12 + i * 12); + if (e.PhyStart == 0 + || e.PhyStart > _h.NumBlocks + || e.PhyStart + e.Len > _h.NumBlocks + || !e.IsLenOK()) + return S_FALSE; + if (!UpdateExtents(extents, e.VirtBlock)) + return S_FALSE; + extents.Add(e); + } + + return S_OK; + } + + const size_t blockSize = (size_t)1 << _h.BlockBits; + CByteBuffer &tempBuf = _tempBufs[eth.Depth]; + tempBuf.Alloc(blockSize); + + for (unsigned i = 0; i < eth.NumEntries; i++) + { + CExtentIndexNode e; + e.Parse(p + 12 + i * 12); + + if (e.PhyLeaf == 0 || e.PhyLeaf >= _h.NumBlocks) + return S_FALSE; + + if (!UpdateExtents(extents, e.VirtBlock)) + return S_FALSE; + + RINOK(SeekAndRead(_stream, e.PhyLeaf, tempBuf, blockSize)); + RINOK(FillExtents(tempBuf, blockSize, extents, eth.Depth)); + } + + return S_OK; +} + + +HRESULT CHandler::GetStream_Node(UInt32 nodeIndex, ISequentialInStream **stream) +{ + COM_TRY_BEGIN + + *stream = NULL; + + const CNode &node = _nodes[nodeIndex]; + + if (!node.IsFlags_EXTENTS()) + { + // maybe sparse file can have NumBlocks == 0 ? + if (node.NumBlocks == 0 && node.FileSize < kNodeBlockFieldSize) + { + Create_BufInStream_WithNewBuffer(node.Block, (size_t)node.FileSize, stream); + return S_OK; + } + } + + if (node.FileSize >= ((UInt64)1 << 63)) + return S_FALSE; + + CMyComPtr<IInStream> streamTemp; + + UInt64 numBlocks64 = (node.FileSize + (UInt64)(((UInt32)1 << _h.BlockBits) - 1)) >> _h.BlockBits; + + if (node.IsFlags_EXTENTS()) + { + if ((UInt32)numBlocks64 != numBlocks64) + return S_FALSE; + + CExtInStream *streamSpec = new CExtInStream; + streamTemp = streamSpec; + + streamSpec->BlockBits = _h.BlockBits; + streamSpec->_size = node.FileSize; + streamSpec->Stream = _stream; + + RINOK(FillExtents(node.Block, kNodeBlockFieldSize, streamSpec->Extents, -1)); + + UInt32 end = 0; + if (!streamSpec->Extents.IsEmpty()) + end = streamSpec->Extents.Back().GetVirtEnd(); + if (end < numBlocks64) + { + AddSkipExtents(streamSpec->Extents, end, (UInt32)(numBlocks64 - end)); + // return S_FALSE; + } + + RINOK(streamSpec->StartSeek()); + } + else + { + { + UInt64 numBlocks2 = numBlocks64; + + if (numBlocks64 > kNumDirectNodeBlocks) + { + UInt64 rem = numBlocks64 - kNumDirectNodeBlocks; + const unsigned refBits = (_h.BlockBits - 2); + const size_t numRefsInBlocks = (size_t)1 << refBits; + numBlocks2++; + if (rem > numRefsInBlocks) + { + numBlocks2++; + const UInt64 numL2 = (rem - 1) >> refBits; + numBlocks2 += numL2; + if (numL2 > numRefsInBlocks) + { + numBlocks2++; + numBlocks2 += (numL2 - 1) >> refBits; + } + } + } + + const unsigned specBits = (node.IsFlags_HUGE() ? 0 : _h.BlockBits - 9); + const UInt32 specMask = ((UInt32)1 << specBits) - 1;; + if ((node.NumBlocks & specMask) != 0) + return S_FALSE; + const UInt64 numBlocks64_from_header = node.NumBlocks >> specBits; + if (numBlocks64_from_header < numBlocks2) + { + // why (numBlocks64_from_header > numBlocks2) in some cases? + // return S_FALSE; + } + } + + unsigned numBlocks = (unsigned)numBlocks64; + if (numBlocks != numBlocks64) + return S_FALSE; + + CClusterInStream *streamSpec = new CClusterInStream; + streamTemp = streamSpec; + + streamSpec->BlockSizeLog = _h.BlockBits; + streamSpec->StartOffset = 0; + streamSpec->Size = node.FileSize; + streamSpec->Stream = _stream; + + RINOK(FillFileBlocks(node.Block, numBlocks, streamSpec->Vector)); + streamSpec->InitAndSeek(); + } + + *stream = streamTemp.Detach(); + + return S_OK; + + COM_TRY_END +} + + +HRESULT CHandler::ExtractNode(unsigned nodeIndex, CByteBuffer &data) +{ + data.Free(); + const CNode &node = _nodes[nodeIndex]; + size_t size = (size_t)node.FileSize; + if (size != node.FileSize) + return S_FALSE; + CMyComPtr<ISequentialInStream> inSeqStream; + RINOK(GetStream_Node(nodeIndex, &inSeqStream)); + if (!inSeqStream) + return S_FALSE; + data.Alloc(size); + _totalRead += size; + return ReadStream_FALSE(inSeqStream, data, size); +} + + +STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, + Int32 testMode, IArchiveExtractCallback *extractCallback) +{ + COM_TRY_BEGIN + bool allFilesMode = (numItems == (UInt32)(Int32)-1); + if (allFilesMode) + numItems = _items.Size() + _auxItems.Size(); + if (numItems == 0) + return S_OK; + + UInt64 totalSize = 0; + UInt32 i; + + for (i = 0; i < numItems; i++) + { + UInt32 index = allFilesMode ? i : indices[i]; + if (index >= _items.Size()) + continue; + const CItem &item = _items[index]; + const CNode &node = _nodes[item.Node]; + if (!node.IsDir()) + totalSize += node.FileSize; + } + + extractCallback->SetTotal(totalSize); + + UInt64 totalPackSize; + totalSize = totalPackSize = 0; + + NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); + CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; + + CLocalProgress *lps = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> progress = lps; + lps->Init(extractCallback, false); + + for (i = 0;; i++) + { + lps->InSize = totalPackSize; + lps->OutSize = totalSize; + RINOK(lps->SetCur()); + + if (i == numItems) + break; + + CMyComPtr<ISequentialOutStream> outStream; + Int32 askMode = testMode ? + NExtract::NAskMode::kTest : + NExtract::NAskMode::kExtract; + + UInt32 index = allFilesMode ? i : indices[i]; + + RINOK(extractCallback->GetStream(index, &outStream, askMode)); + + if (index >= _items.Size()) + { + RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + continue; + } + + const CItem &item = _items[index]; + const CNode &node = _nodes[item.Node]; + + if (node.IsDir()) + { + RINOK(extractCallback->PrepareOperation(askMode)); + RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + continue; + } + + UInt64 unpackSize = node.FileSize; + totalSize += unpackSize; + UInt64 packSize; + if (GetPackSize(index, packSize)) + totalPackSize += packSize; + + if (!testMode && !outStream) + continue; + RINOK(extractCallback->PrepareOperation(askMode)); + + int res = NExtract::NOperationResult::kDataError; + { + CMyComPtr<ISequentialInStream> inSeqStream; + HRESULT hres = GetStream(index, &inSeqStream); + if (hres == S_FALSE || !inSeqStream) + { + if (hres == E_OUTOFMEMORY) + return hres; + res = NExtract::NOperationResult::kUnsupportedMethod; + } + else + { + RINOK(hres); + { + HRESULT hres = copyCoder->Code(inSeqStream, outStream, NULL, NULL, progress); + if (hres == S_OK) + { + if (copyCoderSpec->TotalSize == unpackSize) + res = NExtract::NOperationResult::kOK; + } + else if (hres == E_NOTIMPL) + { + res = NExtract::NOperationResult::kUnsupportedMethod; + } + else if (hres != S_FALSE) + { + RINOK(hres); + } + } + } + } + RINOK(extractCallback->SetOperationResult(res)); + } + + return S_OK; + COM_TRY_END +} + + +STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream) +{ + *stream = NULL; + if (index >= _items.Size()) + return S_FALSE; + return GetStream_Node(_items[index].Node, stream); +} + + +API_FUNC_static_IsArc IsArc_Ext(const Byte *p, size_t size) +{ + if (size < kHeaderSize) + return k_IsArc_Res_NEED_MORE; + CHeader h; + if (!h.Parse(p + kHeaderDataOffset)) + return k_IsArc_Res_NO; + return k_IsArc_Res_YES; +} +} + +static const Byte k_Signature[] = { 0x53, 0xEF }; + +REGISTER_ARC_I( + "Ext", "ext ext3 ext4", 0, 0xC7, + k_Signature, + 0x438, + 0, + IsArc_Ext) + +}} diff --git a/CPP/7zip/Archive/FatHandler.cpp b/CPP/7zip/Archive/FatHandler.cpp index 649d54bd..e16a8860 100644 --- a/CPP/7zip/Archive/FatHandler.cpp +++ b/CPP/7zip/Archive/FatHandler.cpp @@ -805,7 +805,7 @@ enum // kpidFileSysType }; -static const STATPROPSTG kArcProps[] = +static const CStatProp kArcProps[] = { { NULL, kpidFileSystem, VT_BSTR}, { NULL, kpidClusterSize, VT_UI4}, @@ -814,12 +814,12 @@ static const STATPROPSTG kArcProps[] = { NULL, kpidMTime, VT_FILETIME}, { NULL, kpidVolumeName, VT_BSTR}, - { (LPOLESTR)L"FATs", kpidNumFats, VT_UI4}, + { "FATs", kpidNumFats, VT_UI4}, { NULL, kpidSectorSize, VT_UI4}, { NULL, kpidId, VT_UI4}, - // { (LPOLESTR)L"OEM Name", kpidOemName, VT_BSTR}, - // { (LPOLESTR)L"Volume Name", kpidVolName, VT_BSTR}, - // { (LPOLESTR)L"File System Type", kpidFileSysType, VT_BSTR} + // { "OEM Name", kpidOemName, VT_BSTR}, + // { "Volume Name", kpidVolName, VT_BSTR}, + // { "File System Type", kpidFileSysType, VT_BSTR} // { NULL, kpidSectorsPerTrack, VT_UI4}, // { NULL, kpidNumHeads, VT_UI4}, // { NULL, kpidHiddenSectors, VT_UI4} @@ -858,7 +858,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; - switch(propID) + switch (propID) { case kpidFileSystem: { @@ -897,7 +897,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; const CItem &item = Items[index]; - switch(propID) + switch (propID) { case kpidPath: prop = GetItemPath(index); break; case kpidShortName: prop = item.GetShortName(); break; diff --git a/CPP/7zip/Archive/FlvHandler.cpp b/CPP/7zip/Archive/FlvHandler.cpp index dafb250b..72ccd993 100644 --- a/CPP/7zip/Archive/FlvHandler.cpp +++ b/CPP/7zip/Archive/FlvHandler.cpp @@ -145,7 +145,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val { NWindows::NCOM::CPropVariant prop; const CItem2 &item = _items2[index]; - switch(propID) + switch (propID) { case kpidExtension: prop = _isRaw ? @@ -209,7 +209,7 @@ AString CHandler::GetComment() Byte type = *p++; size--; bool ok = false; - switch(type) + switch (type) { case 0: { @@ -256,7 +256,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { // COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; - switch(propID) + switch (propID) { // case kpidComment: prop = GetComment(); break; case kpidPhySize: prop = (UInt64)_phySize; break; diff --git a/CPP/7zip/Archive/HandlerCont.cpp b/CPP/7zip/Archive/HandlerCont.cpp index 23a184f2..ca9153b8 100644 --- a/CPP/7zip/Archive/HandlerCont.cpp +++ b/CPP/7zip/Archive/HandlerCont.cpp @@ -227,4 +227,30 @@ STDMETHODIMP CHandlerImg::Extract(const UInt32 *indices, UInt32 numItems, COM_TRY_END } + +HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize) +{ + areThereNonZeros = false; + numZeros = 0; + const size_t kBufSize = 1 << 11; + Byte buf[kBufSize]; + for (;;) + { + UInt32 size = 0; + HRESULT(stream->Read(buf, kBufSize, &size)); + if (size == 0) + return S_OK; + for (UInt32 i = 0; i < size; i++) + if (buf[i] != 0) + { + areThereNonZeros = true; + numZeros += i; + return S_OK; + } + numZeros += size; + if (numZeros > maxSize) + return S_OK; + } +} + } diff --git a/CPP/7zip/Archive/HandlerCont.h b/CPP/7zip/Archive/HandlerCont.h index 603a6511..58b45d54 100644 --- a/CPP/7zip/Archive/HandlerCont.h +++ b/CPP/7zip/Archive/HandlerCont.h @@ -85,6 +85,9 @@ public: STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); }; + +HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize); + } #endif diff --git a/CPP/7zip/Archive/IArchive.h b/CPP/7zip/Archive/IArchive.h index 84a4cc4b..0028d762 100644 --- a/CPP/7zip/Archive/IArchive.h +++ b/CPP/7zip/Archive/IArchive.h @@ -293,12 +293,14 @@ namespace NPropDataType const UInt32 kMask_ZeroEnd = 1 << 4; // const UInt32 kMask_BigEndian = 1 << 5; const UInt32 kMask_Utf = 1 << 6; - // const UInt32 kMask_Utf8 = kMask_Utf | 0; + const UInt32 kMask_Utf8 = kMask_Utf | 0; const UInt32 kMask_Utf16 = kMask_Utf | 1; // const UInt32 kMask_Utf32 = kMask_Utf | 2; const UInt32 kNotDefined = 0; const UInt32 kRaw = 1; + + const UInt32 kUtf8z = kMask_Utf8 | kMask_ZeroEnd; const UInt32 kUtf16z = kMask_Utf16 | kMask_ZeroEnd; }; @@ -512,12 +514,26 @@ ARCHIVE_INTERFACE(IArchiveAllowTail, 0x05) { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \ *propID = k[index]; *varType = k7z_PROPID_To_VARTYPE[(unsigned)*propID]; *name = 0; return S_OK; } \ + +struct CStatProp +{ + const char *Name; + UInt32 PropID; + VARTYPE vt; +}; + +namespace NWindows { +namespace NCOM { +// PropVariant.cpp +BSTR AllocBstrFromAscii(const char *s) throw(); +}} + #define IMP_IInArchive_GetProp_WITH_NAME(k) \ (UInt32 index, BSTR *name, PROPID *propID, VARTYPE *varType) \ { if (index >= ARRAY_SIZE(k)) return E_INVALIDARG; \ - const STATPROPSTG &srcItem = k[index]; \ - *propID = srcItem.propid; *varType = srcItem.vt; \ - if (srcItem.lpwstrName == 0) *name = 0; else *name = ::SysAllocString(srcItem.lpwstrName); return S_OK; } \ + const CStatProp &prop = k[index]; \ + *propID = (PROPID)prop.PropID; *varType = prop.vt; \ + *name = NWindows::NCOM::AllocBstrFromAscii(prop.Name); return S_OK; } \ #define IMP_IInArchive_Props \ STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProps) \ diff --git a/CPP/7zip/Archive/Iso/IsoIn.cpp b/CPP/7zip/Archive/Iso/IsoIn.cpp index b72e8687..39034b63 100644 --- a/CPP/7zip/Archive/Iso/IsoIn.cpp +++ b/CPP/7zip/Archive/Iso/IsoIn.cpp @@ -8,6 +8,8 @@ #include "../../Common/StreamUtils.h" +#include "../HandlerCont.h" + #include "IsoIn.h" namespace NArchive { @@ -596,7 +598,7 @@ HRESULT CInArchive::Open2() ReadBootInfo(); { - FOR_VECTOR(i, Refs) + FOR_VECTOR (i, Refs) { const CRef &ref = Refs[i]; for (UInt32 j = 0; j < ref.NumExtents; j++) @@ -608,12 +610,28 @@ HRESULT CInArchive::Open2() } } { - FOR_VECTOR(i, BootEntries) + FOR_VECTOR (i, BootEntries) { const CBootInitialEntry &be = BootEntries[i]; UpdatePhySize(be.LoadRBA, GetBootItemSize(i)); } } + + if (PhySize < _fileSize) + { + UInt64 rem = _fileSize - PhySize; + const UInt64 kRemMax = 1 << 21; + if (rem <= kRemMax) + { + RINOK(_stream->Seek(PhySize, STREAM_SEEK_SET, NULL)); + bool areThereNonZeros = false; + UInt64 numZeros = 0; + RINOK(ReadZeroTail(_stream, areThereNonZeros, numZeros, kRemMax)); + if (!areThereNonZeros) + PhySize += numZeros; + } + } + return S_OK; } diff --git a/CPP/7zip/Archive/MbrHandler.cpp b/CPP/7zip/Archive/MbrHandler.cpp index 5135e5f8..93b615d2 100644 --- a/CPP/7zip/Archive/MbrHandler.cpp +++ b/CPP/7zip/Archive/MbrHandler.cpp @@ -332,15 +332,15 @@ enum kpidEndChs }; -static const STATPROPSTG kProps[] = +static const CStatProp kProps[] = { { NULL, kpidPath, VT_BSTR}, { NULL, kpidSize, VT_UI8}, { NULL, kpidFileSystem, VT_BSTR}, { NULL, kpidOffset, VT_UI8}, - { (LPOLESTR)L"Primary", kpidPrimary, VT_BOOL}, - { (LPOLESTR)L"Begin CHS", kpidBegChs, VT_BSTR}, - { (LPOLESTR)L"End CHS", kpidEndChs, VT_BSTR} + { "Primary", kpidPrimary, VT_BOOL}, + { "Begin CHS", kpidBegChs, VT_BSTR}, + { "End CHS", kpidEndChs, VT_BSTR} }; IMP_IInArchive_Props_WITH_NAME diff --git a/CPP/7zip/Archive/NtfsHandler.cpp b/CPP/7zip/Archive/NtfsHandler.cpp index 67cd385f..70023fe4 100644 --- a/CPP/7zip/Archive/NtfsHandler.cpp +++ b/CPP/7zip/Archive/NtfsHandler.cpp @@ -519,7 +519,7 @@ bool CAttr::ParseExtents(CRecordVector<CExtent> &extents, UInt64 numClustersMax, UInt64 vSize = 0; { unsigned i = num; - do vSize = (vSize << 8) | p[--i]; while(i); + do vSize = (vSize << 8) | p[--i]; while (i); } if (vSize == 0) return false; @@ -1835,7 +1835,7 @@ HRESULT CDatabase::Open() int indexOfUnnamedStream = -1; if (!rec.IsDir()) { - FOR_VECTOR(di, rec.DataRefs) + FOR_VECTOR (di, rec.DataRefs) if (rec.DataAttrs[rec.DataRefs[di].Start].Name.IsEmpty()) { indexOfUnnamedStream = di; @@ -1849,7 +1849,7 @@ HRESULT CDatabase::Open() if (i < kNumSysRecs) { needShow = false; - FOR_VECTOR(di, rec.DataRefs) + FOR_VECTOR (di, rec.DataRefs) if (rec.GetSize(di) != 0) { needShow = true; @@ -1905,7 +1905,7 @@ HRESULT CDatabase::Open() unsigned numAltStreams = 0; - FOR_VECTOR(di, rec.DataRefs) + FOR_VECTOR (di, rec.DataRefs) { if (!rec.IsDir() && (int)di == indexOfUnnamedStream) continue; @@ -2173,7 +2173,7 @@ enum kpidATime2 }; -static const STATPROPSTG kProps[] = +static const CStatProp kProps[] = { { NULL, kpidPath, VT_BSTR}, { NULL, kpidSize, VT_UI8}, @@ -2181,20 +2181,20 @@ static const STATPROPSTG kProps[] = // { NULL, kpidLink, VT_BSTR}, - // { (LPOLESTR)L"Link 2", kpidLink2, VT_BSTR}, - // { (LPOLESTR)L"Link Type", kpidLinkType, VT_UI2}, + // { "Link 2", kpidLink2, VT_BSTR}, + // { "Link Type", kpidLinkType, VT_UI2}, { NULL, kpidINode, VT_UI8}, { NULL, kpidMTime, VT_FILETIME}, { NULL, kpidCTime, VT_FILETIME}, { NULL, kpidATime, VT_FILETIME}, - // { (LPOLESTR)L"Record Modified", kpidRecMTime, VT_FILETIME}, + // { "Record Modified", kpidRecMTime, VT_FILETIME}, - // { (LPOLESTR)L"Modified 2", kpidMTime2, VT_FILETIME}, - // { (LPOLESTR)L"Created 2", kpidCTime2, VT_FILETIME}, - // { (LPOLESTR)L"Accessed 2", kpidATime2, VT_FILETIME}, - // { (LPOLESTR)L"Record Modified 2", kpidRecMTime2, VT_FILETIME}, + // { "Modified 2", kpidMTime2, VT_FILETIME}, + // { "Created 2", kpidCTime2, VT_FILETIME}, + // { "Accessed 2", kpidATime2, VT_FILETIME}, + // { "Record Modified 2", kpidRecMTime2, VT_FILETIME}, { NULL, kpidAttrib, VT_UI4}, { NULL, kpidNumBlocks, VT_UI4}, @@ -2226,13 +2226,13 @@ enum kpidRecordSize = kpidUserDefined }; -static const STATPROPSTG kArcProps[] = +static const CStatProp kArcProps[] = { { NULL, kpidVolumeName, VT_BSTR}, { NULL, kpidFileSystem, VT_BSTR}, { NULL, kpidClusterSize, VT_UI4}, { NULL, kpidSectorSize, VT_UI4}, - { (LPOLESTR)L"Record Size", kpidRecordSize, VT_UI4}, + { "Record Size", kpidRecordSize, VT_UI4}, { NULL, kpidHeadersSize, VT_UI8}, { NULL, kpidCTime, VT_FILETIME}, { NULL, kpidId, VT_UI8}, diff --git a/CPP/7zip/Archive/PeHandler.cpp b/CPP/7zip/Archive/PeHandler.cpp index 43450e80..9cbc7c3c 100644 --- a/CPP/7zip/Archive/PeHandler.cpp +++ b/CPP/7zip/Archive/PeHandler.cpp @@ -765,7 +765,7 @@ enum // kpidBaseOfData32, }; -static const STATPROPSTG kArcProps[] = +static const CStatProp kArcProps[] = { // { NULL, kpidWarning, VT_BSTR}, { NULL, kpidCpu, VT_BSTR}, @@ -776,28 +776,28 @@ static const STATPROPSTG kArcProps[] = { NULL, kpidChecksum, VT_UI4}, { NULL, kpidName, VT_BSTR}, - { (LPOLESTR)L"Image Size", kpidImageSize, VT_UI4}, - { (LPOLESTR)L"Section Alignment", kpidSectAlign, VT_UI4}, - { (LPOLESTR)L"File Alignment", kpidFileAlign, VT_UI4}, - { (LPOLESTR)L"Code Size", kpidCodeSize, VT_UI4}, - { (LPOLESTR)L"Initialized Data Size", kpidInitDataSize, VT_UI4}, - { (LPOLESTR)L"Uninitialized Data Size", kpidUnInitDataSize, VT_UI4}, - { (LPOLESTR)L"Linker Version", kpidLinkerVer, VT_BSTR}, - { (LPOLESTR)L"OS Version", kpidOsVer, VT_BSTR}, - { (LPOLESTR)L"Image Version", kpidImageVer, VT_BSTR}, - { (LPOLESTR)L"Subsystem Version", kpidSubsysVer, VT_BSTR}, - { (LPOLESTR)L"Subsystem", kpidSubSystem, VT_BSTR}, - { (LPOLESTR)L"DLL Characteristics", kpidDllCharacts, VT_BSTR}, - { (LPOLESTR)L"Stack Reserve", kpidStackReserve, VT_UI8}, - { (LPOLESTR)L"Stack Commit", kpidStackCommit, VT_UI8}, - { (LPOLESTR)L"Heap Reserve", kpidHeapReserve, VT_UI8}, - { (LPOLESTR)L"Heap Commit", kpidHeapCommit, VT_UI8}, - { (LPOLESTR)L"Image Base", kpidImageBase, VT_UI8}, + { "Image Size", kpidImageSize, VT_UI4}, + { "Section Alignment", kpidSectAlign, VT_UI4}, + { "File Alignment", kpidFileAlign, VT_UI4}, + { "Code Size", kpidCodeSize, VT_UI4}, + { "Initialized Data Size", kpidInitDataSize, VT_UI4}, + { "Uninitialized Data Size", kpidUnInitDataSize, VT_UI4}, + { "Linker Version", kpidLinkerVer, VT_BSTR}, + { "OS Version", kpidOsVer, VT_BSTR}, + { "Image Version", kpidImageVer, VT_BSTR}, + { "Subsystem Version", kpidSubsysVer, VT_BSTR}, + { "Subsystem", kpidSubSystem, VT_BSTR}, + { "DLL Characteristics", kpidDllCharacts, VT_BSTR}, + { "Stack Reserve", kpidStackReserve, VT_UI8}, + { "Stack Commit", kpidStackCommit, VT_UI8}, + { "Heap Reserve", kpidHeapReserve, VT_UI8}, + { "Heap Commit", kpidHeapCommit, VT_UI8}, + { "Image Base", kpidImageBase, VT_UI8}, { NULL, kpidComment, VT_BSTR}, - // { (LPOLESTR)L"Address Of Entry Point", kpidAddressOfEntryPoint, VT_UI8}, - // { (LPOLESTR)L"Base Of Code", kpidBaseOfCode, VT_UI8}, - // { (LPOLESTR)L"Base Of Data", kpidBaseOfData32, VT_UI8}, + // { "Address Of Entry Point", kpidAddressOfEntryPoint, VT_UI8}, + // { "Base Of Code", kpidBaseOfCode, VT_UI8}, + // { "Base Of Data", kpidBaseOfData32, VT_UI8}, }; static const Byte kProps[] = @@ -2233,7 +2233,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback) sections.Sort(); UInt32 limit = (1 << 12); unsigned num = 0; - FOR_VECTOR(i, sections) + FOR_VECTOR (i, sections) { const CSection &s = sections[i]; if (s.Pa > limit) @@ -2798,12 +2798,12 @@ enum // , kpidImageBase }; -static const STATPROPSTG kArcProps[] = +static const CStatProp kArcProps[] = { // { NULL, kpidHeadersSize, VT_UI4 }, { NULL, kpidCpu, VT_BSTR}, - { (LPOLESTR)L"Subsystem", kpidSubSystem, VT_BSTR }, - // { (LPOLESTR)L"Image Base", kpidImageBase, VT_UI8 } + { "Subsystem", kpidSubSystem, VT_BSTR }, + // { "Image Base", kpidImageBase, VT_UI8 } }; IMP_IInArchive_Props diff --git a/CPP/7zip/Archive/Rar/Rar5Handler.cpp b/CPP/7zip/Archive/Rar/Rar5Handler.cpp index 72fe4f68..2cfe805e 100644 --- a/CPP/7zip/Archive/Rar/Rar5Handler.cpp +++ b/CPP/7zip/Archive/Rar/Rar5Handler.cpp @@ -30,6 +30,8 @@ #include "../Common/FindSignature.h" #include "../Common/ItemNameUtils.h" +#include "../HandlerCont.h" + #include "RarVol.h" #include "Rar5Handler.h" @@ -38,13 +40,6 @@ using namespace NWindows; #define Get32(p) GetUi32(p) namespace NArchive { - -namespace NRar { - -HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize); - -} - namespace NRar5 { static const unsigned kMarkerSize = 8; @@ -1938,7 +1933,7 @@ HRESULT CHandler::Open2(IInStream *stream, bool areThereNonZeros; UInt64 numZeros; const UInt64 maxSize = 1 << 12; - RINOK(NRar::ReadZeroTail(inStream, areThereNonZeros, numZeros, maxSize)); + RINOK(ReadZeroTail(inStream, areThereNonZeros, numZeros, maxSize)); if (!areThereNonZeros && numZeros != 0 && numZeros <= maxSize) arcInfo.EndPos += numZeros; } diff --git a/CPP/7zip/Archive/Rar/RarHandler.cpp b/CPP/7zip/Archive/Rar/RarHandler.cpp index d6d894f4..dde15958 100644 --- a/CPP/7zip/Archive/Rar/RarHandler.cpp +++ b/CPP/7zip/Archive/Rar/RarHandler.cpp @@ -30,6 +30,8 @@ #include "../Common/ItemNameUtils.h" #include "../Common/OutStreamWithCRC.h" +#include "../HandlerCont.h" + #include "RarVol.h" #include "RarHandler.h" @@ -938,7 +940,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val if (item.BaseFileIndex >= 0) mainItem = &_items[_refItems[item.BaseFileIndex].ItemIndex]; */ - switch(propID) + switch (propID) { case kpidPath: { @@ -998,31 +1000,6 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val } -HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64 &numZeros, UInt64 maxSize) -{ - areThereNonZeros = false; - numZeros = 0; - const size_t kBufSize = 1 << 9; - Byte buf[kBufSize]; - for (;;) - { - UInt32 size = 0; - HRESULT(stream->Read(buf, kBufSize, &size)); - if (size == 0) - return S_OK; - for (UInt32 i = 0; i < size; i++) - if (buf[i] != 0) - { - areThereNonZeros = true; - numZeros += i; - return S_OK; - } - numZeros += size; - if (numZeros > maxSize) - return S_OK; - } -} - HRESULT CHandler::Open2(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *openCallback) @@ -1593,7 +1570,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, CMyComPtr<ICompressCoder> commonCoder; - switch(item.Method) + switch (item.Method) { case '0': { diff --git a/CPP/7zip/Archive/SquashfsHandler.cpp b/CPP/7zip/Archive/SquashfsHandler.cpp index c65067af..fc195717 100644 --- a/CPP/7zip/Archive/SquashfsHandler.cpp +++ b/CPP/7zip/Archive/SquashfsHandler.cpp @@ -8,6 +8,7 @@ #include "../../../C/Xz.h" #include "../../Common/ComTry.h" +#include "../../Common/MyLinux.h" #include "../../Common/IntToString.h" #include "../../Common/StringConvert.h" @@ -76,14 +77,6 @@ static const char * const k_Methods[] = static const UInt32 kMetadataBlockSizeLog = 13; static const UInt32 kMetadataBlockSize = (1 << kMetadataBlockSizeLog); -#define MY_S_IFIFO 0x1000 -#define MY_S_IFCHR 0x2000 -#define MY_S_IFDIR 0x4000 -#define MY_S_IFBLK 0x6000 -#define MY_S_IFREG 0x8000 -#define MY_S_IFLNK 0xA000 -#define MY_S_IFSOCK 0xC000 - enum { kType_IPC, @@ -99,8 +92,8 @@ enum static const UInt32 k_TypeToMode[] = { 0, - MY_S_IFDIR, MY_S_IFREG, MY_S_IFLNK, MY_S_IFBLK, MY_S_IFCHR, MY_S_IFIFO, MY_S_IFSOCK, - MY_S_IFDIR, MY_S_IFREG, MY_S_IFLNK, MY_S_IFBLK, MY_S_IFCHR, MY_S_IFIFO, MY_S_IFSOCK + MY_LIN_S_IFDIR, MY_LIN_S_IFREG, MY_LIN_S_IFLNK, MY_LIN_S_IFBLK, MY_LIN_S_IFCHR, MY_LIN_S_IFIFO, MY_LIN_S_IFSOCK, + MY_LIN_S_IFDIR, MY_LIN_S_IFREG, MY_LIN_S_IFLNK, MY_LIN_S_IFBLK, MY_LIN_S_IFCHR, MY_LIN_S_IFIFO, MY_LIN_S_IFSOCK }; @@ -754,7 +747,7 @@ UInt32 CNode::Parse4(const Byte *p, UInt32 size, const CHeader &_h) } unsigned offset = 20; - switch(Type) + switch (Type) { case kType_FIFO: case kType_FIFO + 7: case kType_SOCK: case kType_SOCK + 7: @@ -939,7 +932,7 @@ static const Byte kArcProps[] = kpidHeadersSize, kpidFileSystem, kpidMethod, - kpidBlock, + kpidClusterSize, kpidBigEndian, kpidCTime, kpidCharacts @@ -1552,7 +1545,7 @@ HRESULT CHandler::Open2(IInStream *inStream) const Byte *p = _inodesData.Data + pos; UInt32 size = totalSize - pos; - switch(_h.Major) + switch (_h.Major) { case 1: size = n.Parse1(p, size, _h); break; case 2: size = n.Parse2(p, size, _h); break; @@ -1817,7 +1810,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; - switch(propID) + switch (propID) { case kpidMethod: { @@ -1850,7 +1843,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) prop = res; break; } - case kpidBlock: prop = _h.BlockSize; break; + case kpidClusterSize: prop = _h.BlockSize; break; case kpidBigEndian: prop = _h.be; break; case kpidCTime: if (_h.CTime != 0) @@ -1882,7 +1875,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val bool isDir = node.IsDir(); bool be = _h.be; - switch(propID) + switch (propID) { case kpidPath: prop = MultiByteToUnicodeString(GetPath(index), CP_OEMCP); break; case kpidIsDir: prop = isDir; break; @@ -1899,7 +1892,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val case kpidMTime: { UInt32 offset = 0; - switch(_h.Major) + switch (_h.Major) { case 1: if (node.Type == kType_FILE) @@ -2111,11 +2104,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, int res = NExtract::NOperationResult::kDataError; { CMyComPtr<ISequentialInStream> inSeqStream; - CMyComPtr<IInStream> inStream; HRESULT hres = GetStream(index, &inSeqStream); - if (inSeqStream) - inSeqStream.QueryInterface(IID_IInStream, &inStream); - if (hres == S_FALSE || !inStream) + if (hres == S_FALSE || !inSeqStream) { if (hres == E_OUTOFMEMORY) return hres; @@ -2124,9 +2114,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, else { RINOK(hres); - if (inStream) { - HRESULT hres = copyCoder->Code(inStream, outStream, NULL, NULL, progress); + HRESULT hres = copyCoder->Code(inSeqStream, outStream, NULL, NULL, progress); if (hres == S_OK) { if (copyCoderSpec->TotalSize == unpackSize) @@ -2136,15 +2125,17 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, { res = NExtract::NOperationResult::kUnsupportedMethod; } - else if(hres != S_FALSE) + else if (hres != S_FALSE) { RINOK(hres); } } } } + RINOK(extractCallback->SetOperationResult(res)); } + return S_OK; COM_TRY_END } diff --git a/CPP/7zip/Archive/Tar/TarHandler.cpp b/CPP/7zip/Archive/Tar/TarHandler.cpp index d1eec144..14cf3e59 100644 --- a/CPP/7zip/Archive/Tar/TarHandler.cpp +++ b/CPP/7zip/Archive/Tar/TarHandler.cpp @@ -639,6 +639,7 @@ void CHandler::Init() _forceCodePage = false; // _codePage = CP_OEMCP; _curCodePage = _specifiedCodePage = CP_UTF8; // CP_OEMCP; + _thereIsPaxExtendedHeader = false; } STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps) diff --git a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp index 8dd99869..429a8afe 100644 --- a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp +++ b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp @@ -4,6 +4,7 @@ #include "../../../Common/ComTry.h" #include "../../../Common/Defs.h" +#include "../../../Common/MyLinux.h" #include "../../../Common/StringConvert.h" #include "../../../Common/UTFConvert.h" @@ -113,7 +114,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt NCOM::CPropVariant prop; RINOK(callback->GetProperty(i, kpidPosixAttrib, &prop)); if (prop.vt == VT_EMPTY) - ui.Mode = 0777 | (ui.IsDir ? 0040000 : 0100000); + ui.Mode = + MY_LIN_S_IRWXO + | MY_LIN_S_IRWXG + | MY_LIN_S_IRWXU + | (ui.IsDir ? MY_LIN_S_IFDIR : MY_LIN_S_IFREG); else if (prop.vt != VT_UI4) return E_INVALIDARG; else diff --git a/CPP/7zip/Archive/Udf/UdfHandler.cpp b/CPP/7zip/Archive/Udf/UdfHandler.cpp index d35db9fb..876482d1 100644 --- a/CPP/7zip/Archive/Udf/UdfHandler.cpp +++ b/CPP/7zip/Archive/Udf/UdfHandler.cpp @@ -58,7 +58,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; - switch(propID) + switch (propID) { case kpidPhySize: prop = _archive.PhySize; break; diff --git a/CPP/7zip/Archive/UefiHandler.cpp b/CPP/7zip/Archive/UefiHandler.cpp index 3de6351a..015a9caa 100644 --- a/CPP/7zip/Archive/UefiHandler.cpp +++ b/CPP/7zip/Archive/UefiHandler.cpp @@ -694,7 +694,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val NWindows::NCOM::CPropVariant prop; const CItem2 &item2 = _items2[index]; const CItem &item = _items[item2.MainIndex]; - switch(propID) + switch (propID) { case kpidPath: { @@ -754,7 +754,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { COM_TRY_BEGIN NWindows::NCOM::CPropVariant prop; - switch(propID) + switch (propID) { case kpidMethod: { @@ -1039,7 +1039,7 @@ HRESULT CHandler::ParseSections(int bufIndex, UInt32 posBase, UInt32 size, int p else { bool needAdd = true; - switch(type) + switch (type) { case SECTION_RAW: { diff --git a/CPP/7zip/Archive/VhdHandler.cpp b/CPP/7zip/Archive/VhdHandler.cpp index d7c3ca95..0459571b 100644 --- a/CPP/7zip/Archive/VhdHandler.cpp +++ b/CPP/7zip/Archive/VhdHandler.cpp @@ -599,17 +599,17 @@ enum kpidSavedState }; -static const STATPROPSTG kArcProps[] = +static const CStatProp kArcProps[] = { { NULL, kpidSize, VT_UI8}, { NULL, kpidOffset, VT_UI8}, { NULL, kpidCTime, VT_FILETIME}, { NULL, kpidClusterSize, VT_UI8}, { NULL, kpidMethod, VT_BSTR}, - { (LPOLESTR)L"Parent", kpidParent, VT_BSTR}, + { "Parent", kpidParent, VT_BSTR}, { NULL, kpidCreatorApp, VT_BSTR}, { NULL, kpidHostOS, VT_BSTR}, - { (LPOLESTR)L"Saved State", kpidSavedState, VT_BOOL}, + { "Saved State", kpidSavedState, VT_BOOL}, { NULL, kpidId, VT_BSTR} }; diff --git a/CPP/7zip/Archive/Wim/WimHandler.cpp b/CPP/7zip/Archive/Wim/WimHandler.cpp index 0c635eae..6c07f37c 100644 --- a/CPP/7zip/Archive/Wim/WimHandler.cpp +++ b/CPP/7zip/Archive/Wim/WimHandler.cpp @@ -56,7 +56,7 @@ enum kpidBootImage }; -static const STATPROPSTG kArcProps[] = +static const CStatProp kArcProps[] = { { NULL, kpidSize, VT_UI8}, { NULL, kpidPackSize, VT_UI8}, @@ -69,8 +69,8 @@ static const STATPROPSTG kArcProps[] = { NULL, kpidIsVolume, VT_BOOL}, { NULL, kpidVolume, VT_UI4}, { NULL, kpidNumVolumes, VT_UI4}, - { (LPOLESTR)L"Images", kpidNumImages, VT_UI4}, - { (LPOLESTR)L"Boot Image", kpidBootImage, VT_UI4} + { "Images", kpidNumImages, VT_UI4}, + { "Boot Image", kpidBootImage, VT_UI4} }; diff --git a/CPP/7zip/Archive/Wim/WimIn.cpp b/CPP/7zip/Archive/Wim/WimIn.cpp index 2c1ec5de..1da6ca98 100644 --- a/CPP/7zip/Archive/Wim/WimIn.cpp +++ b/CPP/7zip/Archive/Wim/WimIn.cpp @@ -21,7 +21,7 @@ #include "../../Common/StreamObjects.h" #include "../../Common/StreamUtils.h" -#include "../../Compress/XPressDecoder.h" +#include "../../Compress/XpressDecoder.h" #include "../Common/OutStreamWithSha1.h" diff --git a/CPP/7zip/Archive/Wim/WimIn.h b/CPP/7zip/Archive/Wim/WimIn.h index ac4a2bd8..6a387212 100644 --- a/CPP/7zip/Archive/Wim/WimIn.h +++ b/CPP/7zip/Archive/Wim/WimIn.h @@ -221,6 +221,7 @@ namespace NHeaderFlags const UInt32 kXPRESS = (UInt32)1 << 17; const UInt32 kLZX = (UInt32)1 << 18; const UInt32 kLZMS = (UInt32)1 << 19; + const UInt32 kXPRESS2 = (UInt32)1 << 21; // XPRESS with nonstandard chunk size ? const UInt32 kMethodMask = 0xFFFE0000; } @@ -277,7 +278,8 @@ struct CHeader return (!IsCompressed() || (Flags & NHeaderFlags::kLZX) != 0 || (Flags & NHeaderFlags::kXPRESS) != 0 - || (Flags & NHeaderFlags::kLZMS) != 0); + || (Flags & NHeaderFlags::kLZMS) != 0 + || (Flags & NHeaderFlags::kXPRESS2) != 0); } unsigned GetMethod() const @@ -289,6 +291,7 @@ struct CHeader if (mask == NHeaderFlags::kXPRESS) return NMethod::kXPRESS; if (mask == NHeaderFlags::kLZX) return NMethod::kLZX; if (mask == NHeaderFlags::kLZMS) return NMethod::kLZMS; + if (mask == NHeaderFlags::kXPRESS2) return NMethod::kXPRESS; return mask; } diff --git a/CPP/7zip/Archive/XarHandler.cpp b/CPP/7zip/Archive/XarHandler.cpp index 5ef3bdf9..80111b6b 100644 --- a/CPP/7zip/Archive/XarHandler.cpp +++ b/CPP/7zip/Archive/XarHandler.cpp @@ -5,6 +5,7 @@ #include "../../../C/CpuArch.h" #include "../../Common/ComTry.h" +#include "../../Common/MyLinux.h" #include "../../Common/MyXml.h" #include "../../Common/StringToInt.h" #include "../../Common/UTFConvert.h" @@ -360,7 +361,7 @@ HRESULT CHandler::Open2(IInStream *stream) UInt64 totalPackSize = 0; unsigned numMainFiles = 0; - FOR_VECTOR(i, _files) + FOR_VECTOR (i, _files) { const CFile &file = _files[i]; file.UpdateTotalPackSize(totalPackSize); @@ -511,10 +512,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val if (item.ModeDefined) { UInt32 mode = item.Mode; - const UInt32 k_PosixAttrib_Dir = (1 << 14); - const UInt32 k_PosixAttrib_RegFile = (1 << 15); - if ((mode & 0xF000) == 0) - mode |= (item.IsDir ? k_PosixAttrib_Dir : k_PosixAttrib_RegFile); + if ((mode & MY_LIN_S_IFMT) == 0) + mode |= (item.IsDir ? MY_LIN_S_IFDIR : MY_LIN_S_IFREG); prop = mode; } break; diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp index c9c290aa..06fbe22f 100644 --- a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp +++ b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp @@ -271,7 +271,7 @@ HRESULT CAddCommon::Compress( else { CMethodId methodId; - switch(method) + switch (method) { case NFileHeader::NCompressionMethod::kBZip2: methodId = kMethodId_BZip2; diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp index 3e29a880..510ecb41 100644 --- a/CPP/7zip/Archive/Zip/ZipHandler.cpp +++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp @@ -929,7 +929,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, bool allFilesMode = (numItems == (UInt32)(Int32)-1); if (allFilesMode) numItems = m_Items.Size(); - if(numItems == 0) + if (numItems == 0) return S_OK; UInt32 i; for (i = 0; i < numItems; i++) diff --git a/CPP/7zip/Archive/Zip/ZipHeader.h b/CPP/7zip/Archive/Zip/ZipHeader.h index c109992c..18ba064a 100644 --- a/CPP/7zip/Archive/Zip/ZipHeader.h +++ b/CPP/7zip/Archive/Zip/ZipHeader.h @@ -153,36 +153,7 @@ namespace NFileHeader }; } - namespace NUnixAttrib - { - const UInt32 kIFMT = 0170000; // file type mask - - const UInt32 kIFDIR = 0040000; // directory - const UInt32 kIFREG = 0100000; // regular file - const UInt32 kIFSOCK = 0140000; // socket (BSD, not SysV or Amiga) - const UInt32 kIFLNK = 0120000; // symbolic link (not SysV, Amiga) - const UInt32 kIFBLK = 0060000; // block special (not Amiga) - const UInt32 kIFCHR = 0020000; // character special (not Amiga) - const UInt32 kIFIFO = 0010000; // fifo (BCC, not MSC or Amiga) - - const UInt32 kISUID = 04000; // set user id on execution - const UInt32 kISGID = 02000; // set group id on execution - const UInt32 kISVTX = 01000; // directory permissions control - const UInt32 kENFMT = kISGID; // record locking enforcement flag - const UInt32 kIRWXU = 00700; // read, write, execute: owner - const UInt32 kIRUSR = 00400; // read permission: owner - const UInt32 kIWUSR = 00200; // write permission: owner - const UInt32 kIXUSR = 00100; // execute permission: owner - const UInt32 kIRWXG = 00070; // read, write, execute: group - const UInt32 kIRGRP = 00040; // read permission: group - const UInt32 kIWGRP = 00020; // write permission: group - const UInt32 kIXGRP = 00010; // execute permission: group - const UInt32 kIRWXO = 00007; // read, write, execute: other - const UInt32 kIROTH = 00004; // read permission: other - const UInt32 kIWOTH = 00002; // write permission: other - const UInt32 kIXOTH = 00001; // execute permission: other - } - + namespace NAmigaAttrib { const UInt32 kIFMT = 06000; // Amiga file type mask diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp index 3c466424..f72e7f8c 100644 --- a/CPP/7zip/Archive/Zip/ZipIn.cpp +++ b/CPP/7zip/Archive/Zip/ZipIn.cpp @@ -579,7 +579,7 @@ static bool FlagsAreSame(const CItem &i1, const CItem &i2) if (i1.Flags == i2.Flags) return true; UInt32 mask = 0xFFFF; - switch(i1.Method) + switch (i1.Method) { case NFileHeader::NCompressionMethod::kDeflated: mask = 0x7FF9; diff --git a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp index f2ccc814..9e1f5e00 100644 --- a/CPP/7zip/Archive/Zip/ZipItem.cpp +++ b/CPP/7zip/Archive/Zip/ZipItem.cpp @@ -2,11 +2,14 @@ #include "StdAfx.h" -#include "ZipHeader.h" -#include "ZipItem.h" -#include "../Common/ItemNameUtils.h" #include "../../../../C/CpuArch.h" +#include "../../../Common/MyLinux.h" + +#include "../Common/ItemNameUtils.h" + +#include "ZipItem.h" + namespace NArchive { namespace NZip { @@ -114,7 +117,7 @@ bool CItem::IsDir() const case NHostOS::kMVS: return false; // change it throw kUnknownAttributes; case NHostOS::kUnix: - return ((highAttrib & NUnixAttrib::kIFMT) == NUnixAttrib::kIFDIR); + return MY_LIN_S_ISDIR(highAttrib); default: return false; } @@ -151,7 +154,7 @@ bool CItem::GetPosixAttrib(UInt32 &attrib) const } attrib = 0; if (IsDir()) - attrib = NUnixAttrib::kIFDIR; + attrib = MY_LIN_S_IFDIR; return false; } diff --git a/CPP/7zip/Bundles/Format7zF/Arc.mak b/CPP/7zip/Bundles/Format7zF/Arc.mak index 3ea45b5d..d4002e9b 100644 --- a/CPP/7zip/Bundles/Format7zF/Arc.mak +++ b/CPP/7zip/Bundles/Format7zF/Arc.mak @@ -61,6 +61,7 @@ AR_OBJS = \ $O\DeflateProps.obj \ $O\DmgHandler.obj \ $O\ElfHandler.obj \ + $O\ExtHandler.obj \ $O\FatHandler.obj \ $O\FlvHandler.obj \ $O\GzHandler.obj \ diff --git a/CPP/7zip/Bundles/Format7zF/Format7z.dsp b/CPP/7zip/Bundles/Format7zF/Format7z.dsp index f22d746e..69d4f3a0 100644 --- a/CPP/7zip/Bundles/Format7zF/Format7z.dsp +++ b/CPP/7zip/Bundles/Format7zF/Format7z.dsp @@ -283,6 +283,10 @@ SOURCE=..\..\..\Common\MyInitGuid.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\MyLinux.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyMap.cpp # End Source File # Begin Source File @@ -2431,6 +2435,10 @@ SOURCE=..\..\Archive\ElfHandler.cpp # End Source File # Begin Source File +SOURCE=..\..\Archive\ExtHandler.cpp +# End Source File +# Begin Source File + SOURCE=..\..\Archive\FatHandler.cpp # End Source File # Begin Source File diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp b/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp index ac7df6b2..79330630 100644 --- a/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp +++ b/CPP/7zip/Bundles/SFXSetup/ExtractCallbackSfx.cpp @@ -141,7 +141,7 @@ STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index, } RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop)); - switch(prop.vt) + switch (prop.vt) { case VT_EMPTY: _processedFileInfo.MTime = _defaultMTime; break; case VT_FILETIME: _processedFileInfo.MTime = prop.filetime; break; @@ -215,7 +215,7 @@ STDMETHODIMP CExtractCallbackImp::PrepareOperation(Int32 askExtractMode) STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResult) { - switch(resultEOperationResult) + switch (resultEOperationResult) { case NArchive::NExtract::NOperationResult::kOK: break; @@ -223,7 +223,7 @@ STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 resultEOperationResul default: { _outFileStream.Release(); - switch(resultEOperationResult) + switch (resultEOperationResult) { case NArchive::NExtract::NOperationResult::kUnsupportedMethod: _message = kUnsupportedMethod; diff --git a/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp b/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp index cd2584fd..d3890235 100644 --- a/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp +++ b/CPP/7zip/Bundles/SFXSetup/SfxSetup.cpp @@ -281,7 +281,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, execInfo.hProcess = 0; /* BOOL success = */ ::ShellExecuteEx(&execInfo); UINT32 result = (UINT32)(UINT_PTR)execInfo.hInstApp; - if(result <= 32) + if (result <= 32) { if (!assumeYes) ShowErrorMessage(L"Can not open file"); diff --git a/CPP/7zip/Common/CWrappers.cpp b/CPP/7zip/Common/CWrappers.cpp index a15794e2..a77b67e8 100644 --- a/CPP/7zip/Common/CWrappers.cpp +++ b/CPP/7zip/Common/CWrappers.cpp @@ -86,7 +86,7 @@ CSeqOutStreamWrap::CSeqOutStreamWrap(ISequentialOutStream *stream) throw() HRESULT SResToHRESULT(SRes res) throw() { - switch(res) + switch (res) { case SZ_OK: return S_OK; case SZ_ERROR_MEM: return E_OUTOFMEMORY; @@ -111,7 +111,7 @@ static SRes InStreamWrap_Seek(void *pp, Int64 *offset, ESzSeek origin) throw() { CSeekInStreamWrap *p = (CSeekInStreamWrap *)pp; UInt32 moveMethod; - switch(origin) + switch (origin) { case SZ_SEEK_SET: moveMethod = STREAM_SEEK_SET; break; case SZ_SEEK_CUR: moveMethod = STREAM_SEEK_CUR; break; diff --git a/CPP/7zip/Common/MemBlocks.cpp b/CPP/7zip/Common/MemBlocks.cpp index eb0cc39a..5aba046b 100644 --- a/CPP/7zip/Common/MemBlocks.cpp +++ b/CPP/7zip/Common/MemBlocks.cpp @@ -103,7 +103,7 @@ void CMemBlockManagerMt::FreeBlock(void *p, bool lockMode) void CMemBlocks::Free(CMemBlockManagerMt *manager) { - while(Blocks.Size() > 0) + while (Blocks.Size() > 0) { manager->FreeBlock(Blocks.Back()); Blocks.DeleteBack(); diff --git a/CPP/7zip/Compress/CodecExports.cpp b/CPP/7zip/Compress/CodecExports.cpp index 019cb3c1..99085040 100644 --- a/CPP/7zip/Compress/CodecExports.cpp +++ b/CPP/7zip/Compress/CodecExports.cpp @@ -8,7 +8,6 @@ #include "../../Common/MyCom.h" #include "../../Windows/Defs.h" -#include "../../Windows/PropVariant.h" #include "../ICoder.h" @@ -23,7 +22,7 @@ extern const CHasherInfo *g_Hashers[]; static void SetPropFromAscii(const char *s, PROPVARIANT *prop) throw() { UINT len = (UINT)strlen(s); - OLECHAR *dest = ::SysAllocStringLen(NULL, len); + BSTR dest = ::SysAllocStringLen(NULL, len); if (dest) { for (UINT i = 0; i <= len; i++) diff --git a/CPP/7zip/Compress/Lzma2Decoder.cpp b/CPP/7zip/Compress/Lzma2Decoder.cpp index 05b136a7..1a378bbe 100644 --- a/CPP/7zip/Compress/Lzma2Decoder.cpp +++ b/CPP/7zip/Compress/Lzma2Decoder.cpp @@ -10,7 +10,7 @@ static HRESULT SResToHRESULT(SRes res) { - switch(res) + switch (res) { case SZ_OK: return S_OK; case SZ_ERROR_MEM: return E_OUTOFMEMORY; diff --git a/CPP/7zip/Compress/LzmaDecoder.cpp b/CPP/7zip/Compress/LzmaDecoder.cpp index d96be8ce..9002678a 100644 --- a/CPP/7zip/Compress/LzmaDecoder.cpp +++ b/CPP/7zip/Compress/LzmaDecoder.cpp @@ -10,7 +10,7 @@ static HRESULT SResToHRESULT(SRes res) { - switch(res) + switch (res) { case SZ_OK: return S_OK; case SZ_ERROR_MEM: return E_OUTOFMEMORY; diff --git a/CPP/7zip/Compress/LzxDecoder.cpp b/CPP/7zip/Compress/LzxDecoder.cpp index 8bdcc307..55231ce5 100644 --- a/CPP/7zip/Compress/LzxDecoder.cpp +++ b/CPP/7zip/Compress/LzxDecoder.cpp @@ -457,16 +457,15 @@ HRESULT CDecoder::CodeSpec(UInt32 curSize) HRESULT CDecoder::Code(const Byte *inData, size_t inSize, UInt32 outSize) { - if (_pos == _winSize) + if (!_keepHistory) { _pos = 0; - _overDict = true; + _overDict = false; } - - if (!_keepHistory) + else if (_pos == _winSize) { _pos = 0; - _overDict = false; + _overDict = true; } _writePos = _pos; diff --git a/CPP/7zip/Compress/PpmdDecoder.cpp b/CPP/7zip/Compress/PpmdDecoder.cpp index ce00343b..c868730e 100644 --- a/CPP/7zip/Compress/PpmdDecoder.cpp +++ b/CPP/7zip/Compress/PpmdDecoder.cpp @@ -49,7 +49,7 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size) HRESULT CDecoder::CodeSpec(Byte *memStream, UInt32 size) { - switch(_status) + switch (_status) { case kStatus_Finished: return S_OK; case kStatus_Error: return S_FALSE; diff --git a/CPP/7zip/Compress/Rar2Decoder.cpp b/CPP/7zip/Compress/Rar2Decoder.cpp index 4d1bd6b2..b3f2b4b3 100644 --- a/CPP/7zip/Compress/Rar2Decoder.cpp +++ b/CPP/7zip/Compress/Rar2Decoder.cpp @@ -56,7 +56,7 @@ Byte CFilter::Decode(int &channelDelta, Byte deltaByte) Dif[i] = 0; } - switch(numMinDif) + switch (numMinDif) { case 1: if (K1 >= -16) K1--; break; case 2: if (K1 < 16) K1++; break; diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h index d8dfd11a..c130cec6 100644 --- a/CPP/7zip/Compress/Rar3Decoder.h +++ b/CPP/7zip/Compress/Rar3Decoder.h @@ -254,7 +254,7 @@ public: _winPos += len; do *dest++ = *src++; - while(--len != 0); + while (--len != 0); return; } do @@ -263,7 +263,7 @@ public: winPos = (winPos + 1) & kWindowMask; pos = (pos + 1) & kWindowMask; } - while(--len != 0); + while (--len != 0); _winPos = winPos; } diff --git a/CPP/7zip/Compress/Rar5Decoder.cpp b/CPP/7zip/Compress/Rar5Decoder.cpp index 19b40f39..627f7ee6 100644 --- a/CPP/7zip/Compress/Rar5Decoder.cpp +++ b/CPP/7zip/Compress/Rar5Decoder.cpp @@ -23,7 +23,7 @@ void CBitDecoder::Prepare2() throw() size_t rem = _bufLim - _buf; if (rem != 0) - memcpy(_bufBase, _buf, rem); + memmove(_bufBase, _buf, rem); _bufLim = _bufBase + rem; _processedSize += (_buf - _bufBase); diff --git a/CPP/7zip/Crypto/7zAes.cpp b/CPP/7zip/Crypto/7zAes.cpp index a3c725eb..d33b562a 100644 --- a/CPP/7zip/Crypto/7zAes.cpp +++ b/CPP/7zip/Crypto/7zAes.cpp @@ -70,7 +70,7 @@ void CKeyInfo::CalcKey() if (++(ctr[i]) != 0) break; } - while(--numRounds != 0); + while (--numRounds != 0); Sha256_Final(&sha, Key); } diff --git a/CPP/7zip/Guid.txt b/CPP/7zip/Guid.txt index 02bcdea3..7edab6ea 100644 --- a/CPP/7zip/Guid.txt +++ b/CPP/7zip/Guid.txt @@ -163,6 +163,7 @@ Handler GUIDs: 0C xz 0D ppmd + C7 Ext C8 VMDK C9 VDI CA Qcow diff --git a/CPP/7zip/UI/Agent/AgentOut.cpp b/CPP/7zip/UI/Agent/AgentOut.cpp index 0468fdd1..1302d8c7 100644 --- a/CPP/7zip/UI/Agent/AgentOut.cpp +++ b/CPP/7zip/UI/Agent/AgentOut.cpp @@ -265,7 +265,7 @@ STDMETHODIMP CAgent::DoOperation( UInt32 value; RINOK(outArchive->GetFileTimeType(&value)); - switch(value) + switch (value) { case NFileTimeType::kWindows: case NFileTimeType::kDOS: diff --git a/CPP/7zip/UI/Agent/AgentProxy.cpp b/CPP/7zip/UI/Agent/AgentProxy.cpp index 543cfbaa..9a977c70 100644 --- a/CPP/7zip/UI/Agent/AgentProxy.cpp +++ b/CPP/7zip/UI/Agent/AgentProxy.cpp @@ -3,10 +3,16 @@ #include "StdAfx.h" // #include <stdio.h> +#ifdef _WIN32 +#include <wchar.h> +#else +#include <ctype.h> +#endif #include "../../../../C/Sort.h" #include "../../../../C/CpuArch.h" +#include "../../../Common/UTFConvert.h" #include "../../../Common/Wildcard.h" #include "../../../Windows/PropVariant.h" @@ -555,7 +561,10 @@ HRESULT CProxyArc2::Load(const CArc &arc, IProgress *progress) } Files.Alloc(numItems); - + + UString tempUString; + AString tempAString; + UInt32 i; for (i = 0; i < numItems; i++) { @@ -567,12 +576,12 @@ HRESULT CProxyArc2::Load(const CArc &arc, IProgress *progress) CProxyFile2 &file = Files[i]; - #ifdef MY_CPU_LE const void *p; UInt32 size; UInt32 propType; RINOK(arc.GetRawProps->GetRawProp(i, kpidName, &p, &size, &propType)); + #ifdef MY_CPU_LE if (p && propType == PROP_DATA_TYPE_wchar_t_PTR_Z_LE) { file.Name = (const wchar_t *)p; @@ -582,6 +591,16 @@ HRESULT CProxyArc2::Load(const CArc &arc, IProgress *progress) } else #endif + if (p && propType == NPropDataType::kUtf8z) + { + tempAString = (const char *)p; + ConvertUTF8ToUnicode(tempAString, tempUString); + file.NameLen = tempUString.Len(); + file.Name = new wchar_t[file.NameLen + 1]; + file.NeedDeleteName = true; + wmemcpy((wchar_t *)file.Name, tempUString.Ptr(), file.NameLen + 1); + } + else { NCOM::CPropVariant prop; RINOK(arc.Archive->GetProperty(i, kpidName, &prop)); @@ -595,7 +614,7 @@ HRESULT CProxyArc2::Load(const CArc &arc, IProgress *progress) file.NameLen = MyStringLen(s); file.Name = new wchar_t[file.NameLen + 1]; file.NeedDeleteName = true; - MyStringCopy((wchar_t *)file.Name, s); + wmemcpy((wchar_t *)file.Name, s, file.NameLen + 1); } UInt32 parent = (UInt32)(Int32)-1; diff --git a/CPP/7zip/UI/Client7z/Client7z.cpp b/CPP/7zip/UI/Client7z/Client7z.cpp index 4d85754d..e13061ae 100644 --- a/CPP/7zip/UI/Client7z/Client7z.cpp +++ b/CPP/7zip/UI/Client7z/Client7z.cpp @@ -309,7 +309,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, NCOM::CPropVariant prop; RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop)); _processedFileInfo.MTimeDefined = false; - switch(prop.vt) + switch (prop.vt) { case VT_EMPTY: // _processedFileInfo.MTime = _utcMTimeDefault; @@ -582,7 +582,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR { const CDirItem &dirItem = (*DirItems)[index]; - switch(propID) + switch (propID) { case kpidPath: prop = dirItem.Name; break; case kpidIsDir: prop = dirItem.isDir(); break; diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp index 99013946..067b32f3 100644 --- a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp +++ b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp @@ -1329,5 +1329,5 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options) { } else - throw 9815676711; + throw 20150919; } diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp index 040f9b41..877326b8 100644 --- a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp +++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp @@ -608,6 +608,10 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre _curSizeDefined = false; _index = index; + _diskFilePath.Empty(); + + // _fi.Clear(); + #ifdef SUPPORT_LINKS // _CopyFile_Path.Empty(); linkPath.Empty(); @@ -1454,7 +1458,7 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes) } #ifdef _USE_SECURITY_CODE - if (_ntOptions.NtSecurity.Val && _arc->GetRawProps) + if (!_stdOutMode && _extractMode && _ntOptions.NtSecurity.Val && _arc->GetRawProps) { const void *data; UInt32 dataSize; @@ -1497,7 +1501,7 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes) else NumFiles++; - if (_extractMode && _fi.AttribDefined) + if (!_stdOutMode && _extractMode && _fi.AttribDefined) SetFileAttrib(_diskFilePath, _fi.Attrib); RINOK(_extractCallback2->SetOperationResult(opRes, BoolToInt(_encrypted))); diff --git a/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp b/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp index 2ed68e80..47af7251 100644 --- a/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp +++ b/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp @@ -40,12 +40,12 @@ STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value) COM_TRY_BEGIN NCOM::CPropVariant prop; if (_subArchiveMode) - switch(propID) + switch (propID) { case kpidName: prop = _subArchiveName; break; } else - switch(propID) + switch (propID) { case kpidName: prop = _fileInfo.Name; break; case kpidIsDir: prop = _fileInfo.IsDir(); break; diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.cpp b/CPP/7zip/UI/Common/ExtractingFilePath.cpp index 7e088cfe..39e67b7f 100644 --- a/CPP/7zip/UI/Common/ExtractingFilePath.cpp +++ b/CPP/7zip/UI/Common/ExtractingFilePath.cpp @@ -18,7 +18,7 @@ static void ReplaceIncorrectChars(UString &s) #ifdef _WIN32 c == ':' || c == '*' || c == '?' || c < 0x20 || c == '<' || c == '>' || c == '|' || c == '"' || c == '/' - || c == 0x202E // RLO + // || c == 0x202E // RLO || #endif c == WCHAR_PATH_SEPARATOR) @@ -190,9 +190,7 @@ void Correct_FsPath(bool absIsAllowed, UStringVector &parts, bool isDir) { UString &s = parts[i]; - #ifdef _WIN32 Correct_PathPart(s); - #endif if (s.IsEmpty()) { diff --git a/CPP/7zip/UI/Common/OpenArchive.cpp b/CPP/7zip/UI/Common/OpenArchive.cpp index a7488044..a6afaf1c 100644 --- a/CPP/7zip/UI/Common/OpenArchive.cpp +++ b/CPP/7zip/UI/Common/OpenArchive.cpp @@ -268,7 +268,7 @@ void CHandler::AddItem(const CParseItem &item) } /* -static const STATPROPSTG kProps[] = +static const CStatProp kProps[] = { { NULL, kpidPath, VT_BSTR}, { NULL, kpidSize, VT_UI8}, diff --git a/CPP/7zip/UI/Common/Update.cpp b/CPP/7zip/UI/Common/Update.cpp index 78eec82f..2dfb2104 100644 --- a/CPP/7zip/UI/Common/Update.cpp +++ b/CPP/7zip/UI/Common/Update.cpp @@ -571,6 +571,7 @@ static HRESULT Compress( const CArcItem &ai = arcItems[i]; bool needRename = false; UString dest; + if (ai.Censored) { FOR_VECTOR (j, options.RenamePairs) @@ -581,6 +582,8 @@ static HRESULT Compress( needRename = true; break; } + + #ifdef SUPPORT_ALT_STREAMS if (ai.IsAltStream) { int colonPos = FindAltStreamColon_in_Path(ai.Name); @@ -600,8 +603,10 @@ static HRESULT Compress( } } } + #endif } } + CUpdatePair2 up2; up2.SetAs_NoChangeArcItem(ai.IndexInServer); if (needRename) diff --git a/CPP/7zip/UI/Common/UpdateCallback.cpp b/CPP/7zip/UI/Common/UpdateCallback.cpp index 058e9153..ac57e1a9 100644 --- a/CPP/7zip/UI/Common/UpdateCallback.cpp +++ b/CPP/7zip/UI/Common/UpdateCallback.cpp @@ -92,7 +92,7 @@ STDMETHODIMP CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UI /* -static const STATPROPSTG kProps[] = +static const CStatProp kProps[] = { { NULL, kpidPath, VT_BSTR}, { NULL, kpidIsDir, VT_BOOL}, diff --git a/CPP/7zip/UI/Console/ConsoleClose.cpp b/CPP/7zip/UI/Console/ConsoleClose.cpp index 6bf2531d..73498188 100644 --- a/CPP/7zip/UI/Console/ConsoleClose.cpp +++ b/CPP/7zip/UI/Console/ConsoleClose.cpp @@ -27,7 +27,7 @@ static BOOL WINAPI HandlerRoutine(DWORD ctrlType) return TRUE; return FALSE; /* - switch(ctrlType) + switch (ctrlType) { case CTRL_C_EVENT: case CTRL_BREAK_EVENT: @@ -50,7 +50,7 @@ void CheckCtrlBreak() CCtrlHandlerSetter::CCtrlHandlerSetter() { #if !defined(UNDER_CE) && defined(_WIN32) - if(!SetConsoleCtrlHandler(HandlerRoutine, TRUE)) + if (!SetConsoleCtrlHandler(HandlerRoutine, TRUE)) throw "SetConsoleCtrlHandler fails"; #endif } @@ -58,7 +58,7 @@ CCtrlHandlerSetter::CCtrlHandlerSetter() CCtrlHandlerSetter::~CCtrlHandlerSetter() { #if !defined(UNDER_CE) && defined(_WIN32) - if(!SetConsoleCtrlHandler(HandlerRoutine, FALSE)) + if (!SetConsoleCtrlHandler(HandlerRoutine, FALSE)) throw "SetConsoleCtrlHandler fails"; #endif } diff --git a/CPP/7zip/UI/Console/UserInputUtils.cpp b/CPP/7zip/UI/Console/UserInputUtils.cpp index 2974a5b9..c7f830ff 100644 --- a/CPP/7zip/UI/Console/UserInputUtils.cpp +++ b/CPP/7zip/UI/Console/UserInputUtils.cpp @@ -34,7 +34,7 @@ NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream) AString scannedString = g_StdIn.ScanStringUntilNewLine(); scannedString.Trim(); if (!scannedString.IsEmpty()) - switch(::MyCharLower_Ascii(scannedString[0])) + switch (::MyCharLower_Ascii(scannedString[0])) { case kYes: return NUserAnswerMode::kYes; case kNo: return NUserAnswerMode::kNo; diff --git a/CPP/7zip/UI/Explorer/ContextMenu.cpp b/CPP/7zip/UI/Explorer/ContextMenu.cpp index 64a916b2..68af4a1e 100644 --- a/CPP/7zip/UI/Explorer/ContextMenu.cpp +++ b/CPP/7zip/UI/Explorer/ContextMenu.cpp @@ -940,7 +940,7 @@ STDMETHODIMP CZipContextMenu::GetCommandString(UINT_PTR commandOffset, UINT uTyp UINT * /* pwReserved */ , LPSTR pszName, UINT /* cchMax */) { int cmdOffset = (int)commandOffset; - switch(uType) + switch (uType) { #ifdef UNDER_CE case GCS_VALIDATE: diff --git a/CPP/7zip/UI/Far/ExtractEngine.cpp b/CPP/7zip/UI/Far/ExtractEngine.cpp index e1db1c9f..c21655fd 100644 --- a/CPP/7zip/UI/Far/ExtractEngine.cpp +++ b/CPP/7zip/UI/Far/ExtractEngine.cpp @@ -100,7 +100,7 @@ STDMETHODIMP CExtractCallbackImp::AskOverwrite( NOverwriteDialog::NResult::EEnum result = NOverwriteDialog::Execute(oldFileInfo, newFileInfo); - switch(result) + switch (result) { case NOverwriteDialog::NResult::kCancel: // *answer = NOverwriteAnswer::kCancel; diff --git a/CPP/7zip/UI/Far/Far.cpp b/CPP/7zip/UI/Far/Far.cpp index 0cd53cc5..6505c6c4 100644 --- a/CPP/7zip/UI/Far/Far.cpp +++ b/CPP/7zip/UI/Far/Far.cpp @@ -259,13 +259,13 @@ STDMETHODIMP COpenArchiveCallback::GetProperty(PROPID propID, PROPVARIANT *value NCOM::CPropVariant prop; if (_subArchiveMode) { - switch(propID) + switch (propID) { case kpidName: prop = _subArchiveName; break; } } else - switch(propID) + switch (propID) { case kpidName: prop = GetUnicodeString(_fileInfo.Name, CP_OEMCP); break; case kpidIsDir: prop = _fileInfo.IsDir(); break; @@ -447,30 +447,34 @@ EXTERN_C HANDLE WINAPI OpenFilePluginW(const wchar_t *name,const unsigned char * EXTERN_C HANDLE WINAPI OpenPlugin(int openFrom, INT_PTR item) { MY_TRY_BEGIN; - if(openFrom == OPEN_COMMANDLINE) + + if (openFrom == OPEN_COMMANDLINE) { AString fileName = (const char *)item; - if(fileName.IsEmpty()) + if (fileName.IsEmpty()) return INVALID_HANDLE_VALUE; - if (fileName.Len() >= 2 && - fileName[0] == '\"' && fileName.Back() == '\"') + if (fileName.Len() >= 2 + && fileName[0] == '\"' + && fileName.Back() == '\"') { fileName.DeleteBack(); fileName.DeleteFrontal(1); } return MyOpenFilePlugin(fileName); } - if(openFrom == OPEN_PLUGINSMENU) + + if (openFrom == OPEN_PLUGINSMENU) { - switch(item) + switch (item) { case 0: { PluginPanelItem pluginPanelItem; - if(!g_StartupInfo.ControlGetActivePanelCurrentItemInfo(pluginPanelItem)) + if (!g_StartupInfo.ControlGetActivePanelCurrentItemInfo(pluginPanelItem)) throw 142134; return MyOpenFilePlugin(pluginPanelItem.FindData.cFileName); } + case 1: { CObjectVector<PluginPanelItem> pluginPanelItem; @@ -491,10 +495,12 @@ EXTERN_C HANDLE WINAPI OpenPlugin(int openFrom, INT_PTR item) } return INVALID_HANDLE_VALUE; } + default: throw 4282215; } } + return INVALID_HANDLE_VALUE; MY_TRY_END2("OpenPlugin", INVALID_HANDLE_VALUE); } diff --git a/CPP/7zip/UI/Far/Far.dsp b/CPP/7zip/UI/Far/Far.dsp index 26365152..2433b252 100644 --- a/CPP/7zip/UI/Far/Far.dsp +++ b/CPP/7zip/UI/Far/Far.dsp @@ -166,6 +166,14 @@ SOURCE=..\..\..\Common\StringToInt.h # End Source File # Begin Source File +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\Wildcard.cpp # End Source File # Begin Source File diff --git a/CPP/7zip/UI/Far/Plugin.cpp b/CPP/7zip/UI/Far/Plugin.cpp index 8df7b512..485358d3 100644 --- a/CPP/7zip/UI/Far/Plugin.cpp +++ b/CPP/7zip/UI/Far/Plugin.cpp @@ -40,11 +40,11 @@ CPlugin::CPlugin(const FString &fileName, CAgent *agent, UString archiveTypeName CPlugin::~CPlugin() {} -static void MyGetFileTime(IFolderFolder *anArchiveFolder, UInt32 itemIndex, +static void MyGetFileTime(IFolderFolder *folder, UInt32 itemIndex, PROPID propID, FILETIME &fileTime) { NCOM::CPropVariant prop; - if (anArchiveFolder->GetProperty(itemIndex, propID, &prop) != S_OK) + if (folder->GetProperty(itemIndex, propID, &prop) != S_OK) throw 271932; if (prop.vt == VT_EMPTY) { diff --git a/CPP/7zip/UI/Far/PluginCommon.cpp b/CPP/7zip/UI/Far/PluginCommon.cpp index ce1a18bb..e1d44582 100644 --- a/CPP/7zip/UI/Far/PluginCommon.cpp +++ b/CPP/7zip/UI/Far/PluginCommon.cpp @@ -10,7 +10,7 @@ void CPlugin::AddRealIndexOfFile(const CArchiveFolderItem &aFolder, { const CArchiveFolderFileItem &anItem = aFolder.m_FileSubItems[anIndexInVector]; int aHandlerItemIndex = m_ProxyHandler->GetHandlerItemIndex(anItem.m_Properties); - if(aHandlerItemIndex < 0) + if (aHandlerItemIndex < 0) throw "error"; aRealIndexes.push_back(aHandlerItemIndex); } @@ -19,11 +19,11 @@ void CPlugin::AddRealIndexes(const CArchiveFolderItem &anItem, vector<int> &aRealIndexes) { int aHandlerItemIndex = m_ProxyHandler->GetHandlerItemIndex(anItem.m_Properties); - if(aHandlerItemIndex >= 0) // test -1 value + if (aHandlerItemIndex >= 0) // test -1 value aRealIndexes.push_back(aHandlerItemIndex); - for(int i = 0; i < anItem.m_DirSubItems.Size(); i++) + for (int i = 0; i < anItem.m_DirSubItems.Size(); i++) AddRealIndexes(anItem.m_DirSubItems[i], aRealIndexes); - for(i = 0; i < anItem.m_FileSubItems.Size(); i++) + for (i = 0; i < anItem.m_FileSubItems.Size(); i++) AddRealIndexOfFile(anItem, i , aRealIndexes); } @@ -32,7 +32,7 @@ void CPlugin::GetRealIndexes(PluginPanelItem *aPanelItems, int anItemsNumber, vector<int> &aRealIndexes) { aRealIndexes.clear(); - for(int i = 0; i < anItemsNumber; i++) + for (int i = 0; i < anItemsNumber; i++) { int anIndex = aPanelItems[i].UserData; if (anIndex < m_FolderItem->m_DirSubItems.Size()) diff --git a/CPP/7zip/UI/Far/makefile b/CPP/7zip/UI/Far/makefile index 0fff95a2..621c8d9e 100644 --- a/CPP/7zip/UI/Far/makefile +++ b/CPP/7zip/UI/Far/makefile @@ -20,6 +20,7 @@ CURRENT_OBJS = \ $O\PluginWrite.obj \ $O\ProgressBox.obj \ $O\UpdateCallbackFar.obj \ + $O\UTFConvert.obj \ COMMON_OBJS = \ $O\IntToString.obj \ diff --git a/CPP/7zip/UI/FileManager/BrowseDialog.cpp b/CPP/7zip/UI/FileManager/BrowseDialog.cpp index 8b605d0f..1c2f6374 100644 --- a/CPP/7zip/UI/FileManager/BrowseDialog.cpp +++ b/CPP/7zip/UI/FileManager/BrowseDialog.cpp @@ -277,7 +277,7 @@ bool CBrowseDialog::OnInit() if (!GetParentPath(FilePath, DirPrefix, name)) DirPrefix = _topDirPrefix; - for(;;) + for (;;) { UString baseFolder = DirPrefix; if (Reload(baseFolder, name) == S_OK) diff --git a/CPP/7zip/UI/FileManager/CopyDialog.cpp b/CPP/7zip/UI/FileManager/CopyDialog.cpp index 76441215..4b17110d 100644 --- a/CPP/7zip/UI/FileManager/CopyDialog.cpp +++ b/CPP/7zip/UI/FileManager/CopyDialog.cpp @@ -75,7 +75,7 @@ bool CCopyDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) bool CCopyDialog::OnButtonClicked(int buttonID, HWND buttonHWND) { - switch(buttonID) + switch (buttonID) { case IDB_COPY_SET_PATH: OnButtonSetPath(); diff --git a/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp b/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp index 291ea1f1..d34d67bb 100644 --- a/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp +++ b/CPP/7zip/UI/FileManager/EnumFormatEtc.cpp @@ -30,7 +30,7 @@ private: static void DeepCopyFormatEtc(FORMATETC *dest, const FORMATETC *src) { *dest = *src; - if(src->ptd) + if (src->ptd) { dest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE)); *(dest->ptd) = *(src->ptd); @@ -43,20 +43,20 @@ CEnumFormatEtc::CEnumFormatEtc(const FORMATETC *pFormatEtc, ULONG numFormats) m_Index = 0; m_NumFormats = 0; m_Formats = new FORMATETC[numFormats]; - if(m_Formats) + if (m_Formats) { m_NumFormats = numFormats; - for(ULONG i = 0; i < numFormats; i++) + for (ULONG i = 0; i < numFormats; i++) DeepCopyFormatEtc(&m_Formats[i], &pFormatEtc[i]); } } CEnumFormatEtc::~CEnumFormatEtc() { - if(m_Formats) + if (m_Formats) { - for(ULONG i = 0; i < m_NumFormats; i++) - if(m_Formats[i].ptd) + for (ULONG i = 0; i < m_NumFormats; i++) + if (m_Formats[i].ptd) CoTaskMemFree(m_Formats[i].ptd); delete[]m_Formats; } @@ -65,15 +65,15 @@ CEnumFormatEtc::~CEnumFormatEtc() STDMETHODIMP CEnumFormatEtc::Next(ULONG celt, FORMATETC *pFormatEtc, ULONG *pceltFetched) { ULONG copied = 0; - if(celt == 0 || pFormatEtc == 0) + if (celt == 0 || pFormatEtc == 0) return E_INVALIDARG; - while(m_Index < m_NumFormats && copied < celt) + while (m_Index < m_NumFormats && copied < celt) { DeepCopyFormatEtc(&pFormatEtc[copied], &m_Formats[m_Index]); copied++; m_Index++; } - if(pceltFetched != 0) + if (pceltFetched != 0) *pceltFetched = copied; return (copied == celt) ? S_OK : S_FALSE; } @@ -93,7 +93,7 @@ STDMETHODIMP CEnumFormatEtc::Reset(void) STDMETHODIMP CEnumFormatEtc::Clone(IEnumFORMATETC ** ppEnumFormatEtc) { HRESULT hResult = CreateEnumFormatEtc(m_NumFormats, m_Formats, ppEnumFormatEtc); - if(hResult == S_OK) + if (hResult == S_OK) ((CEnumFormatEtc *)*ppEnumFormatEtc)->m_Index = m_Index; return hResult; } @@ -101,7 +101,7 @@ STDMETHODIMP CEnumFormatEtc::Clone(IEnumFORMATETC ** ppEnumFormatEtc) // replacement for SHCreateStdEnumFmtEtc HRESULT CreateEnumFormatEtc(UINT numFormats, const FORMATETC *formats, IEnumFORMATETC **enumFormat) { - if(numFormats == 0 || formats == 0 || enumFormat == 0) + if (numFormats == 0 || formats == 0 || enumFormat == 0) return E_INVALIDARG; *enumFormat = new CEnumFormatEtc(formats, numFormats); return (*enumFormat) ? S_OK : E_OUTOFMEMORY; diff --git a/CPP/7zip/UI/FileManager/FSDrives.cpp b/CPP/7zip/UI/FileManager/FSDrives.cpp index 69f89325..dd4ba724 100644 --- a/CPP/7zip/UI/FileManager/FSDrives.cpp +++ b/CPP/7zip/UI/FileManager/FSDrives.cpp @@ -100,7 +100,7 @@ static HRESULT CopyFileSpec(CFSTR fromPath, CFSTR toPath, bool writeToDisk, UInt return S_OK; } -static const PROPID kProps[] = +static const Byte kProps[] = { kpidName, // kpidOutName, diff --git a/CPP/7zip/UI/FileManager/FoldersPage.cpp b/CPP/7zip/UI/FileManager/FoldersPage.cpp index 8c0b5a0c..8719dd2c 100644 --- a/CPP/7zip/UI/FileManager/FoldersPage.cpp +++ b/CPP/7zip/UI/FileManager/FoldersPage.cpp @@ -52,7 +52,7 @@ bool CFoldersPage::OnInit() int CFoldersPage::GetWorkMode() const { for (int i = 0; i < kNumWorkModeButtons; i++) - if(IsButtonCheckedBool(kWorkModeButtons[i])) + if (IsButtonCheckedBool(kWorkModeButtons[i])) return i; throw 0; } @@ -104,7 +104,7 @@ bool CFoldersPage::OnButtonClicked(int buttonID, HWND buttonHWND) ModifiedEvent(); return true; } - switch(buttonID) + switch (buttonID) { case IDB_FOLDERS_WORK_PATH: OnFoldersWorkButtonPath(); diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.cpp b/CPP/7zip/UI/FileManager/ListViewDialog.cpp index 78c9562a..58468816 100644 --- a/CPP/7zip/UI/FileManager/ListViewDialog.cpp +++ b/CPP/7zip/UI/FileManager/ListViewDialog.cpp @@ -78,7 +78,7 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header) { if (header->hwndFrom != _listView) return false; - switch(header->code) + switch (header->code) { case LVN_ITEMACTIVATE: if (g_LVN_ITEMACTIVATE_Support) @@ -99,7 +99,7 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header) case LVN_KEYDOWN: { LPNMLVKEYDOWN keyDownInfo = LPNMLVKEYDOWN(header); - switch(keyDownInfo->wVKey) + switch (keyDownInfo->wVKey) { case VK_DELETE: { diff --git a/CPP/7zip/UI/FileManager/MyLoadMenu.cpp b/CPP/7zip/UI/FileManager/MyLoadMenu.cpp index 4b299b5c..b9dbf232 100644 --- a/CPP/7zip/UI/FileManager/MyLoadMenu.cpp +++ b/CPP/7zip/UI/FileManager/MyLoadMenu.cpp @@ -95,7 +95,7 @@ public: // it's hack for supporting Windows NT // constants are from WinUser.h -#if(WINVER < 0x0500) +#if (WINVER < 0x0500) #define MIIM_STRING 0x00000040 #define MIIM_BITMAP 0x00000080 #define MIIM_FTYPE 0x00000100 @@ -162,6 +162,8 @@ static void MyChangeMenu(HMENU menuLoc, int level, int menuIndex) if (langID == IDM_OPEN_INSIDE_ONE || langID == IDM_OPEN_INSIDE_PARSER) { LangString_OnlyFromLangFile(IDM_OPEN_INSIDE, newString); + if (newString.IsEmpty()) + continue; newString.Replace(L"&", L""); int tabPos = newString.Find(L"\t"); if (tabPos >= 0) diff --git a/CPP/7zip/UI/FileManager/NetFolder.cpp b/CPP/7zip/UI/FileManager/NetFolder.cpp index bfccc353..112f8c06 100644 --- a/CPP/7zip/UI/FileManager/NetFolder.cpp +++ b/CPP/7zip/UI/FileManager/NetFolder.cpp @@ -13,7 +13,7 @@ using namespace NWindows; using namespace NNet; -static const PROPID kProps[] = +static const Byte kProps[] = { kpidName, kpidLocalName, @@ -170,7 +170,7 @@ STDMETHODIMP CNetFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIAN { NCOM::CPropVariant prop; const CResourceEx &item = _items[itemIndex]; - switch(propID) + switch (propID) { case kpidIsDir: prop = true; break; case kpidName: @@ -243,7 +243,7 @@ IMP_IFolderFolder_Props(CNetFolder) STDMETHODIMP CNetFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value) { NWindows::NCOM::CPropVariant prop; - switch(propID) + switch (propID) { case kpidType: prop = "NetFolder"; break; case kpidPath: prop = _path; break; diff --git a/CPP/7zip/UI/FileManager/OpenCallback.cpp b/CPP/7zip/UI/FileManager/OpenCallback.cpp index d5afb2da..331b171b 100644 --- a/CPP/7zip/UI/FileManager/OpenCallback.cpp +++ b/CPP/7zip/UI/FileManager/OpenCallback.cpp @@ -60,14 +60,14 @@ STDMETHODIMP COpenArchiveCallback::GetProperty(PROPID propID, PROPVARIANT *value NCOM::CPropVariant prop; if (_subArchiveMode) { - switch(propID) + switch (propID) { case kpidName: prop = _subArchiveName; break; } } else { - switch(propID) + switch (propID) { case kpidName: prop = _fileInfo.Name; break; case kpidIsDir: prop = _fileInfo.IsDir(); break; diff --git a/CPP/7zip/UI/FileManager/PanelFolderChange.cpp b/CPP/7zip/UI/FileManager/PanelFolderChange.cpp index 4d9ce51f..dd8d3029 100644 --- a/CPP/7zip/UI/FileManager/PanelFolderChange.cpp +++ b/CPP/7zip/UI/FileManager/PanelFolderChange.cpp @@ -460,7 +460,7 @@ extern UString RootFolder_GetName_Documents(int &iconIndex); bool CPanel::OnComboBoxCommand(UINT code, LPARAM /* param */, LRESULT &result) { result = FALSE; - switch(code) + switch (code) { case CBN_DROPDOWN: { diff --git a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp index 5ff605f4..8bf40f5e 100644 --- a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp +++ b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp @@ -544,7 +544,7 @@ static HRESULT StartApplication(const UString &dir, const UString &path, HWND wi } if (result <= 32) { - switch(result) + switch (result) { case SE_ERR_NOASSOC: ::MessageBoxW(window, @@ -1241,7 +1241,7 @@ static bool CheckDeleteItem(UINT64 currentFileTime, UINT64 folderFileTime) void DeleteOldTempFiles() { UString tempPath; - if(!MyGetTempPath(tempPath)) + if (!MyGetTempPath(tempPath)) throw 1; UINT64 currentFileTime; @@ -1250,12 +1250,12 @@ void DeleteOldTempFiles() searchWildCard += WCHAR(NName::kAnyStringWildcard); NFind::CEnumeratorW enumerator(searchWildCard); NFind::CFileInfo fileInfo; - while(enumerator.Next(fileInfo)) + while (enumerator.Next(fileInfo)) { if (!fileInfo.IsDir()) continue; const UINT64 &cTime = *(const UINT64 *)(&fileInfo.CTime); - if(CheckDeleteItem(cTime, currentFileTime)) + if (CheckDeleteItem(cTime, currentFileTime)) RemoveDirectoryWithSubItems(tempPath + fileInfo.Name); } } diff --git a/CPP/7zip/UI/FileManager/PanelKey.cpp b/CPP/7zip/UI/FileManager/PanelKey.cpp index db8e3311..c87d04e1 100644 --- a/CPP/7zip/UI/FileManager/PanelKey.cpp +++ b/CPP/7zip/UI/FileManager/PanelKey.cpp @@ -78,14 +78,14 @@ bool CPanel::OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result) g_App.SwitchOnOffOnePanel(); } - if(keyDownInfo->wVKey >= VK_F3 && keyDownInfo->wVKey <= VK_F12 && ctrl) + if (keyDownInfo->wVKey >= VK_F3 && keyDownInfo->wVKey <= VK_F12 && ctrl) { int index = FindVKeyPropIDPair(keyDownInfo->wVKey); if (index >= 0) SortItemsWithPropID(g_VKeyPropIDPairs[index].PropID); } - switch(keyDownInfo->wVKey) + switch (keyDownInfo->wVKey) { case VK_SHIFT: { @@ -191,7 +191,7 @@ bool CPanel::OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result) } case VK_DOWN: { - if(shift) + if (shift) OnArrowWithShift(); return false; } @@ -199,7 +199,7 @@ bool CPanel::OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result) { if (alt) _panelCallback->OnSetSameFolder(); - else if(shift) + else if (shift) OnArrowWithShift(); return false; } @@ -207,7 +207,7 @@ bool CPanel::OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result) { if (alt) _panelCallback->OnSetSubFolder(); - else if(shift) + else if (shift) OnArrowWithShift(); return false; } @@ -215,7 +215,7 @@ bool CPanel::OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result) { if (alt) _panelCallback->OnSetSubFolder(); - else if(shift) + else if (shift) OnArrowWithShift(); return false; } @@ -234,7 +234,7 @@ bool CPanel::OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result) SelectByType(true); else if (shift) SelectAll(true); - else if(!ctrl) + else if (!ctrl) SelectSpec(true); return true; } @@ -272,7 +272,7 @@ bool CPanel::OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result) } */ case 'A': - if(ctrl) + if (ctrl) { SelectAll(true); return true; @@ -307,14 +307,14 @@ bool CPanel::OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result) } return false; case 'R': - if(ctrl) + if (ctrl) { OnReload(); return true; } return false; case 'Z': - if(ctrl) + if (ctrl) { ChangeComment(); return true; @@ -324,7 +324,7 @@ bool CPanel::OnKeyDown(LPNMLVKEYDOWN keyDownInfo, LRESULT &result) case '2': case '3': case '4': - if(ctrl) + if (ctrl) { int styleIndex = keyDownInfo->wVKey - '1'; SetListViewMode(styleIndex); diff --git a/CPP/7zip/UI/FileManager/PanelListNotify.cpp b/CPP/7zip/UI/FileManager/PanelListNotify.cpp index 74a75d02..408ffae1 100644 --- a/CPP/7zip/UI/FileManager/PanelListNotify.cpp +++ b/CPP/7zip/UI/FileManager/PanelListNotify.cpp @@ -465,7 +465,7 @@ void CPanel::OnNotifyActivateItems() bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result) { - switch(header->code) + switch (header->code) { case LVN_ITEMCHANGED: { @@ -507,7 +507,7 @@ bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result) { LPNMLVKEYDOWN keyDownInfo = LPNMLVKEYDOWN(header); bool boolResult = OnKeyDown(keyDownInfo, result); - switch(keyDownInfo->wVKey) + switch (keyDownInfo->wVKey) { case VK_CONTROL: case VK_SHIFT: @@ -602,7 +602,7 @@ bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result) bool CPanel::OnCustomDraw(LPNMLVCUSTOMDRAW lplvcd, LRESULT &result) { - switch(lplvcd->nmcd.dwDrawStage) + switch (lplvcd->nmcd.dwDrawStage) { case CDDS_PREPAINT : result = CDRF_NOTIFYITEMDRAW; diff --git a/CPP/7zip/UI/FileManager/PanelMenu.cpp b/CPP/7zip/UI/FileManager/PanelMenu.cpp index 5a527cb4..8a9f6276 100644 --- a/CPP/7zip/UI/FileManager/PanelMenu.cpp +++ b/CPP/7zip/UI/FileManager/PanelMenu.cpp @@ -480,7 +480,7 @@ void CPanel::CreateSystemMenu(HMENU menuSpec, // HMENU hMenu = CreatePopupMenu(); CMenu popupMenu; // CMenuDestroyer menuDestroyer(popupMenu); - if(!popupMenu.CreatePopup()) + if (!popupMenu.CreatePopup()) throw 210503; HMENU hMenu = popupMenu; diff --git a/CPP/7zip/UI/FileManager/PanelOperations.cpp b/CPP/7zip/UI/FileManager/PanelOperations.cpp index 0afbc07b..bd128695 100644 --- a/CPP/7zip/UI/FileManager/PanelOperations.cpp +++ b/CPP/7zip/UI/FileManager/PanelOperations.cpp @@ -57,7 +57,7 @@ public: HRESULT CThreadFolderOperations::ProcessVirt() { NCOM::CComInitializer comInitializer; - switch(OpType) + switch (OpType) { case FOLDER_TYPE_CREATE_FOLDER: Result = FolderOperations->CreateFolder(Name, UpdateCallback); diff --git a/CPP/7zip/UI/FileManager/ProgressDialog.cpp b/CPP/7zip/UI/FileManager/ProgressDialog.cpp index 4b20f1a9..65201a9e 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog.cpp +++ b/CPP/7zip/UI/FileManager/ProgressDialog.cpp @@ -132,7 +132,7 @@ bool CProgressDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */) bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) { - switch(message) + switch (message) { case kCloseMessage: { @@ -158,7 +158,7 @@ bool CProgressDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) bool CProgressDialog::OnButtonClicked(int buttonID, HWND buttonHWND) { - switch(buttonID) + switch (buttonID) { case IDCANCEL: { diff --git a/CPP/7zip/UI/FileManager/RootFolder.cpp b/CPP/7zip/UI/FileManager/RootFolder.cpp index 2a5d513a..b9629263 100644 --- a/CPP/7zip/UI/FileManager/RootFolder.cpp +++ b/CPP/7zip/UI/FileManager/RootFolder.cpp @@ -41,7 +41,7 @@ static const unsigned kNumRootFolderItems = using namespace NWindows; -static const PROPID kProps[] = +static const Byte kProps[] = { kpidName }; @@ -108,7 +108,7 @@ STDMETHODIMP CRootFolder::GetNumberOfItems(UInt32 *numItems) STDMETHODIMP CRootFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value) { NCOM::CPropVariant prop; - switch(propID) + switch (propID) { case kpidIsDir: prop = true; break; case kpidName: prop = _names[itemIndex]; break; diff --git a/CPP/7zip/UI/FileManager/SettingsPage.cpp b/CPP/7zip/UI/FileManager/SettingsPage.cpp index 7a51e1b7..cecaf808 100644 --- a/CPP/7zip/UI/FileManager/SettingsPage.cpp +++ b/CPP/7zip/UI/FileManager/SettingsPage.cpp @@ -93,7 +93,7 @@ void CSettingsPage::OnNotifyHelp() bool CSettingsPage::OnButtonClicked(int buttonID, HWND buttonHWND) { - switch(buttonID) + switch (buttonID) { case IDX_SETTINGS_SINGLE_CLICK: /* diff --git a/CPP/7zip/UI/FileManager/SplitDialog.cpp b/CPP/7zip/UI/FileManager/SplitDialog.cpp index d7d14d7c..455874ef 100644 --- a/CPP/7zip/UI/FileManager/SplitDialog.cpp +++ b/CPP/7zip/UI/FileManager/SplitDialog.cpp @@ -77,7 +77,7 @@ bool CSplitDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize) bool CSplitDialog::OnButtonClicked(int buttonID, HWND buttonHWND) { - switch(buttonID) + switch (buttonID) { case IDB_SPLIT_PATH: OnButtonSetPath(); diff --git a/CPP/7zip/UI/GUI/BenchmarkDialog.cpp b/CPP/7zip/UI/GUI/BenchmarkDialog.cpp index db4b1378..41173e1f 100644 --- a/CPP/7zip/UI/GUI/BenchmarkDialog.cpp +++ b/CPP/7zip/UI/GUI/BenchmarkDialog.cpp @@ -505,7 +505,7 @@ bool CBenchmarkDialog::OnCommand(int code, int itemID, LPARAM lParam) bool CBenchmarkDialog::OnButtonClicked(int buttonID, HWND buttonHWND) { - switch(buttonID) + switch (buttonID) { case IDB_RESTART: OnRestartButton(); diff --git a/CPP/7zip/UI/GUI/ExtractDialog.cpp b/CPP/7zip/UI/GUI/ExtractDialog.cpp index 9a14c6c4..af47fc2d 100644 --- a/CPP/7zip/UI/GUI/ExtractDialog.cpp +++ b/CPP/7zip/UI/GUI/ExtractDialog.cpp @@ -253,7 +253,7 @@ void CExtractDialog::UpdatePasswordControl() bool CExtractDialog::OnButtonClicked(int buttonID, HWND buttonHWND) { - switch(buttonID) + switch (buttonID) { case IDB_EXTRACT_SET_PATH: OnButtonSetPath(); diff --git a/CPP/7zip/UI/GUI/ExtractGUI.cpp b/CPP/7zip/UI/GUI/ExtractGUI.cpp index e58f6b2b..7fb843a1 100644 --- a/CPP/7zip/UI/GUI/ExtractGUI.cpp +++ b/CPP/7zip/UI/GUI/ExtractGUI.cpp @@ -229,7 +229,7 @@ HRESULT ExtractGUI( NName::NormalizeDirPathPrefix(options.OutputDir); /* - if(!CreateComplexDirectory(options.OutputDir)) + if (!CreateComplexDirectory(options.OutputDir)) { UString s = GetUnicodeString(NError::MyFormatMessage(GetLastError())); UString s2 = MyFormatNew(IDS_CANNOT_CREATE_FOLDER, diff --git a/CPP/7zip/UI/GUI/HashGUI.cpp b/CPP/7zip/UI/GUI/HashGUI.cpp index 3eb7d7d4..68c2b768 100644 --- a/CPP/7zip/UI/GUI/HashGUI.cpp +++ b/CPP/7zip/UI/GUI/HashGUI.cpp @@ -13,7 +13,7 @@ #include "../FileManager/ProgressDialog2.h" #include "../FileManager/ProgressDialog2Res.h" #include "../FileManager/PropertyNameRes.h" -#include "../FileManager/resourceGUI.h" +#include "../FileManager/resourceGui.h" #include "HashGUI.h" diff --git a/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp b/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp index 240f4880..0723b223 100644 --- a/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp +++ b/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp @@ -10,7 +10,7 @@ #include "../FileManager/FormatUtils.h" #include "../FileManager/LangUtils.h" -#include "../FileManager/resourceGUI.h" +#include "../FileManager/resourceGui.h" #include "resource2.h" diff --git a/CPP/Common/MyLinux.h b/CPP/Common/MyLinux.h new file mode 100644 index 00000000..1a918993 --- /dev/null +++ b/CPP/Common/MyLinux.h @@ -0,0 +1,42 @@ +// MyLinux.h + +#ifndef __MY_LIN_LINUX_H +#define __MY_LIN_LINUX_H + +#define MY_LIN_S_IFMT 00170000 +#define MY_LIN_S_IFSOCK 0140000 +#define MY_LIN_S_IFLNK 0120000 +#define MY_LIN_S_IFREG 0100000 +#define MY_LIN_S_IFBLK 0060000 +#define MY_LIN_S_IFDIR 0040000 +#define MY_LIN_S_IFCHR 0020000 +#define MY_LIN_S_IFIFO 0010000 + +#define MY_LIN_S_ISLNK(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFLNK) +#define MY_LIN_S_ISREG(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFREG) +#define MY_LIN_S_ISDIR(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFDIR) +#define MY_LIN_S_ISCHR(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFCHR) +#define MY_LIN_S_ISBLK(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFBLK) +#define MY_LIN_S_ISFIFO(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFIFO) +#define MY_LIN_S_ISSOCK(m) (((m) & MY_LIN_S_IFMT) == MY_LIN_S_IFSOCK) + +#define MY_LIN_S_ISUID 0004000 +#define MY_LIN_S_ISGID 0002000 +#define MY_LIN_S_ISVTX 0001000 + +#define MY_LIN_S_IRWXU 00700 +#define MY_LIN_S_IRUSR 00400 +#define MY_LIN_S_IWUSR 00200 +#define MY_LIN_S_IXUSR 00100 + +#define MY_LIN_S_IRWXG 00070 +#define MY_LIN_S_IRGRP 00040 +#define MY_LIN_S_IWGRP 00020 +#define MY_LIN_S_IXGRP 00010 + +#define MY_LIN_S_IRWXO 00007 +#define MY_LIN_S_IROTH 00004 +#define MY_LIN_S_IWOTH 00002 +#define MY_LIN_S_IXOTH 00001 + +#endif diff --git a/CPP/Common/TextConfig.cpp b/CPP/Common/TextConfig.cpp index 9c7ccaf4..7606ee7b 100644 --- a/CPP/Common/TextConfig.cpp +++ b/CPP/Common/TextConfig.cpp @@ -88,7 +88,7 @@ bool GetTextConfig(const AString &s, CObjectVector<CTextConfigPair> &pairs) if (c == '\\') { char c = s[pos++]; - switch(c) + switch (c) { case 'n': message += '\n'; break; case 't': message += '\t'; break; diff --git a/CPP/Windows/Control/Window2.cpp b/CPP/Windows/Control/Window2.cpp index 019046cd..994d96e0 100644 --- a/CPP/Windows/Control/Window2.cpp +++ b/CPP/Windows/Control/Window2.cpp @@ -178,7 +178,7 @@ bool CWindow2::OnCommand(int /* code */, int /* itemID */, LPARAM /* lParam */, /* bool CDialog::OnButtonClicked(int buttonID, HWND buttonHWND) { - switch(aButtonID) + switch (buttonID) { case IDOK: OnOK(); diff --git a/CPP/Windows/ProcessUtils.h b/CPP/Windows/ProcessUtils.h index c7226813..a50bb5fc 100644 --- a/CPP/Windows/ProcessUtils.h +++ b/CPP/Windows/ProcessUtils.h @@ -25,7 +25,7 @@ public: bool GetExitCodeProcess(LPDWORD lpExitCode) { return BOOLToBool(::GetExitCodeProcess(_handle, lpExitCode)); } bool Terminate(UINT exitCode) { return BOOLToBool(::TerminateProcess(_handle, exitCode)); } - #if(WINVER >= 0x0500) + #if (WINVER >= 0x0500) DWORD GetGuiResources (DWORD uiFlags) { return ::GetGuiResources(_handle, uiFlags); } #endif bool SetPriorityClass(DWORD dwPriorityClass) { return BOOLToBool(::SetPriorityClass(_handle, dwPriorityClass)); } diff --git a/CPP/Windows/PropVariant.cpp b/CPP/Windows/PropVariant.cpp index 8c7d5e19..9e36c634 100644 --- a/CPP/Windows/PropVariant.cpp +++ b/CPP/Windows/PropVariant.cpp @@ -9,23 +9,23 @@ namespace NWindows { namespace NCOM { -HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw() +BSTR AllocBstrFromAscii(const char *s) throw() { - p->bstrVal = ::SysAllocStringLen(0, numChars); - if (!p->bstrVal) + if (!s) + return NULL; + UINT len = (UINT)strlen(s); + BSTR p = ::SysAllocStringLen(NULL, len); + if (p) { - p->vt = VT_ERROR; - p->scode = E_OUTOFMEMORY; - return E_OUTOFMEMORY; + for (UINT i = 0; i <= len; i++) + p[i] = (Byte)s[i]; } - p->vt = VT_BSTR; - return S_OK; + return p; } -HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw() +HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw() { - UINT len = (UINT)strlen(s); - p->bstrVal = ::SysAllocStringLen(0, len); + p->bstrVal = ::SysAllocStringLen(NULL, numChars); if (!p->bstrVal) { p->vt = VT_ERROR; @@ -33,12 +33,19 @@ HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw() return E_OUTOFMEMORY; } p->vt = VT_BSTR; - BSTR dest = p->bstrVal; - for (UINT i = 0; i <= len; i++) - dest[i] = (Byte)s[i]; return S_OK; } +HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw() +{ + p->bstrVal = AllocBstrFromAscii(s); + if (p->bstrVal) + return S_OK; + p->vt = VT_ERROR; + p->scode = E_OUTOFMEMORY; + return E_OUTOFMEMORY; +} + CPropVariant::CPropVariant(const PROPVARIANT &varSrc) { vt = VT_EMPTY; @@ -68,6 +75,7 @@ CPropVariant& CPropVariant::operator=(const CPropVariant &varSrc) InternalCopy(&varSrc); return *this; } + CPropVariant& CPropVariant::operator=(const PROPVARIANT &varSrc) { InternalCopy(&varSrc); @@ -144,20 +152,13 @@ CPropVariant& CPropVariant::operator=(const char *s) InternalClear(); vt = VT_BSTR; wReserved1 = 0; - UINT len = (UINT)strlen(s); - bstrVal = ::SysAllocStringLen(0, len); + bstrVal = AllocBstrFromAscii(s); if (!bstrVal) { throw kMemException; // vt = VT_ERROR; // scode = E_OUTOFMEMORY; } - else - { - BSTR dest = bstrVal; - for (UINT i = 0; i <= len; i++) - dest[i] = (Byte)s[i]; - } return *this; } @@ -178,7 +179,7 @@ BSTR CPropVariant::AllocBstr(unsigned numChars) InternalClear(); vt = VT_BSTR; wReserved1 = 0; - bstrVal = ::SysAllocStringLen(0, numChars); + bstrVal = ::SysAllocStringLen(NULL, numChars); if (!bstrVal) { throw kMemException; @@ -244,7 +245,7 @@ HRESULT CPropVariant::Clear() throw() HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) throw() { ::VariantClear((tagVARIANT *)this); - switch(pSrc->vt) + switch (pSrc->vt) { case VT_UI1: case VT_I1: diff --git a/CPP/Windows/PropVariant.h b/CPP/Windows/PropVariant.h index adece3e3..3610d6a8 100644 --- a/CPP/Windows/PropVariant.h +++ b/CPP/Windows/PropVariant.h @@ -10,6 +10,8 @@ namespace NWindows { namespace NCOM { +BSTR AllocBstrFromAscii(const char *s) throw(); + HRESULT PropVariant_Clear(PROPVARIANT *p) throw(); HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw(); diff --git a/CPP/Windows/PropVariantConv.cpp b/CPP/Windows/PropVariantConv.cpp index 78f98720..fe86f936 100644 --- a/CPP/Windows/PropVariantConv.cpp +++ b/CPP/Windows/PropVariantConv.cpp @@ -37,7 +37,17 @@ bool ConvertFileTimeToString(const FILETIME &ft, char *s, bool includeTime, bool UINT_TO_STR_2(' ', st.wHour); UINT_TO_STR_2(':', st.wMinute); if (includeSeconds) + { UINT_TO_STR_2(':', st.wSecond); + /* + *s++ = '.'; + unsigned val = st.wMilliseconds; + s[2] = (char)('0' + val % 10); val /= 10; + s[1] = (char)('0' + val % 10); + s[0] = (char)('0' + val / 10); + s += 3; + */ + } } *s = 0; return true; diff --git a/CPP/Windows/Shell.cpp b/CPP/Windows/Shell.cpp index 0d2ac618..8e82c14a 100644 --- a/CPP/Windows/Shell.cpp +++ b/CPP/Windows/Shell.cpp @@ -177,7 +177,7 @@ bool BrowseForFolder(LPBROWSEINFO browseInfo, CSysString &resultPath) int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM /* lp */, LPARAM data) { #ifndef UNDER_CE - switch(uMsg) + switch (uMsg) { case BFFM_INITIALIZED: { @@ -275,7 +275,7 @@ bool BrowseForFolder(LPBROWSEINFOW browseInfo, UString &resultPath) int CALLBACK BrowseCallbackProc2(HWND hwnd, UINT uMsg, LPARAM /* lp */, LPARAM data) { - switch(uMsg) + switch (uMsg) { case BFFM_INITIALIZED: { diff --git a/DOC/7zip.inf b/DOC/7zip.inf index f63f48c3..ab3dcf0b 100644 --- a/DOC/7zip.inf +++ b/DOC/7zip.inf @@ -10,8 +10,8 @@ AppName = "7-Zip" InstallDir = %CE1%\%AppName% [Strings] -AppVer = "15.07" -AppDate = "2015-09-17" +AppVer = "15.08" +AppDate = "2015-10-01" [CEDevice] ; ProcessorType = 2577 ; ARM diff --git a/DOC/7zip.nsi b/DOC/7zip.nsi index ed5d1f33..b8bbe319 100644 --- a/DOC/7zip.nsi +++ b/DOC/7zip.nsi @@ -2,7 +2,7 @@ ;Defines !define VERSION_MAJOR 15 -!define VERSION_MINOR 07 +!define VERSION_MINOR 08 !define VERSION_POSTFIX_FULL " beta" !ifdef WIN64 !ifdef IA64 diff --git a/DOC/7zip.wxs b/DOC/7zip.wxs index d82b11b9..fe7e115a 100644 --- a/DOC/7zip.wxs +++ b/DOC/7zip.wxs @@ -1,7 +1,7 @@ <?xml version="1.0"?> <?define VerMajor = "15" ?> -<?define VerMinor = "07" ?> +<?define VerMinor = "08" ?> <?define VerBuild = "00" ?> <?define MmVer = "$(var.VerMajor).$(var.VerMinor)" ?> <?define MmHex = "$(var.VerMajor)$(var.VerMinor)" ?> diff --git a/DOC/readme.txt b/DOC/readme.txt index 38d9087d..4f5f9124 100644 --- a/DOC/readme.txt +++ b/DOC/readme.txt @@ -1,4 +1,4 @@ -7-Zip 15.07 Sources +7-Zip 15.08 Sources ------------------- 7-Zip is a file archiver for Windows. |