From e5431fa6f5505e385c6f9367260717e9c47dc2ee Mon Sep 17 00:00:00 2001 From: Igor Pavlov <87184205+ip7z@users.noreply.github.com> Date: Fri, 29 Nov 2024 00:00:00 +0000 Subject: 24.09 --- CPP/7zip/7zip_gcc.mak | 16 ++ CPP/7zip/Archive/ApmHandler.cpp | 182 ++++++++++----- CPP/7zip/Archive/Common/HandlerOut.h | 4 +- CPP/7zip/Archive/HfsHandler.cpp | 256 +++++++++++---------- CPP/7zip/Archive/LpHandler.cpp | 4 + CPP/7zip/Archive/Rar/Rar5Handler.cpp | 14 +- CPP/7zip/Archive/XarHandler.cpp | 90 ++++++-- CPP/7zip/Archive/XzHandler.cpp | 4 +- CPP/7zip/Bundles/Format7zF/Arc.mak | 8 + CPP/7zip/Bundles/Format7zF/Arc_gcc.mak | 8 + CPP/7zip/Bundles/Format7zF/Format7z.dsp | 92 ++++++++ CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp | 21 +- CPP/7zip/Common/CreateCoder.cpp | 2 +- CPP/7zip/Common/MethodProps.h | 12 +- CPP/7zip/Crypto/Rar5Aes.cpp | 117 +++++----- CPP/7zip/Crypto/Rar5Aes.h | 57 +++-- CPP/7zip/Crypto/RarAes.cpp | 12 +- CPP/7zip/Crypto/ZipStrong.cpp | 43 ++-- CPP/7zip/GuiCommon.rc | 2 +- CPP/7zip/Guid.txt | 2 + CPP/7zip/UI/Agent/Agent.cpp | 2 + CPP/7zip/UI/Agent/Agent.h | 33 +-- CPP/7zip/UI/Agent/ArchiveFolder.cpp | 6 + CPP/7zip/UI/Agent/ArchiveFolderOut.cpp | 76 ++++++- CPP/7zip/UI/Agent/IFolderArchive.h | 16 ++ CPP/7zip/UI/Client7z/makefile.gcc | 3 + CPP/7zip/UI/Common/ArchiveExtractCallback.cpp | 138 +++++++----- CPP/7zip/UI/Common/ArchiveExtractCallback.h | 95 ++++---- CPP/7zip/UI/Common/Bench.cpp | 48 +++- CPP/7zip/UI/Common/EnumDirItems.cpp | 4 +- CPP/7zip/UI/Common/HashCalc.cpp | 34 ++- CPP/7zip/UI/Common/TempFiles.cpp | 3 +- CPP/7zip/UI/Common/TempFiles.h | 3 + CPP/7zip/UI/Common/Update.cpp | 68 +++++- CPP/7zip/UI/Common/Update.h | 5 +- CPP/7zip/UI/Common/WorkDir.cpp | 16 +- CPP/7zip/UI/Common/WorkDir.h | 8 +- CPP/7zip/UI/Common/ZipRegistry.cpp | 37 ++-- CPP/7zip/UI/Console/ConsoleClose.cpp | 10 +- CPP/7zip/UI/Console/ConsoleClose.h | 2 +- CPP/7zip/UI/Console/ExtractCallbackConsole.cpp | 2 +- CPP/7zip/UI/Console/MainAr.cpp | 2 + CPP/7zip/UI/Console/PercentPrinter.h | 18 +- CPP/7zip/UI/Console/UpdateCallbackConsole.cpp | 113 ++++++++++ CPP/7zip/UI/Console/UpdateCallbackConsole.h | 36 +-- CPP/7zip/UI/Explorer/ContextMenu.cpp | 10 +- CPP/7zip/UI/Explorer/ContextMenu.h | 4 + CPP/7zip/UI/Far/Far.cpp | 7 +- CPP/7zip/UI/Far/FarUtils.cpp | 4 +- CPP/7zip/UI/Far/ProgressBox.h | 10 +- CPP/7zip/UI/Far/UpdateCallbackFar.cpp | 90 ++++++++ CPP/7zip/UI/Far/UpdateCallbackFar.h | 16 +- CPP/7zip/UI/FileManager/App.cpp | 14 +- CPP/7zip/UI/FileManager/App.h | 2 +- CPP/7zip/UI/FileManager/ExtractCallback.cpp | 272 +++++++++++++++-------- CPP/7zip/UI/FileManager/ExtractCallback.h | 190 ++++++++-------- CPP/7zip/UI/FileManager/FM.cpp | 17 +- CPP/7zip/UI/FileManager/MemDialog.cpp | 10 +- CPP/7zip/UI/FileManager/MemDialog.h | 2 +- CPP/7zip/UI/FileManager/MyLoadMenu.cpp | 8 +- CPP/7zip/UI/FileManager/OpenCallback.cpp | 2 +- CPP/7zip/UI/FileManager/Panel.cpp | 11 +- CPP/7zip/UI/FileManager/Panel.h | 289 ++++++++++++------------ CPP/7zip/UI/FileManager/PanelCopy.cpp | 52 ++++- CPP/7zip/UI/FileManager/PanelDrag.cpp | 8 +- CPP/7zip/UI/FileManager/PanelItemOpen.cpp | 105 +++++---- CPP/7zip/UI/FileManager/PanelItems.cpp | 17 +- CPP/7zip/UI/FileManager/PanelListNotify.cpp | 2 +- CPP/7zip/UI/FileManager/PanelOperations.cpp | 2 +- CPP/7zip/UI/FileManager/ProgressDialog2.cpp | 105 +++++---- CPP/7zip/UI/FileManager/ProgressDialog2.h | 57 +++-- CPP/7zip/UI/FileManager/RegistryUtils.cpp | 8 +- CPP/7zip/UI/FileManager/SettingsPage.cpp | 6 +- CPP/7zip/UI/FileManager/SysIconUtils.cpp | 2 +- CPP/7zip/UI/FileManager/UpdateCallback100.cpp | 23 ++ CPP/7zip/UI/FileManager/UpdateCallback100.h | 5 +- CPP/7zip/UI/FileManager/ViewSettings.cpp | 17 +- CPP/7zip/UI/FileManager/resource.h | 11 +- CPP/7zip/UI/FileManager/resource.rc | 6 +- CPP/7zip/UI/FileManager/resourceGui.h | 2 + CPP/7zip/UI/FileManager/resourceGui.rc | 2 + CPP/7zip/UI/GUI/BenchmarkDialog.cpp | 77 ++++--- CPP/7zip/UI/GUI/CompressDialog.cpp | 67 +++--- CPP/7zip/UI/GUI/CompressDialog.h | 20 +- CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp | 15 ++ CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp | 73 +++++- CPP/7zip/UI/GUI/UpdateCallbackGUI2.h | 31 ++- CPP/7zip/warn_gcc.mak | 17 +- CPP/Common/Md5Reg.cpp | 44 ++++ CPP/Common/MyCom.h | 37 ++++ CPP/Common/Sha3Reg.cpp | 76 +++++++ CPP/Common/Sha512Prepare.cpp | 7 + CPP/Common/Sha512Reg.cpp | 83 +++++++ CPP/Windows/FileDir.cpp | 138 +++++++++--- CPP/Windows/FileDir.h | 23 +- CPP/Windows/FileName.cpp | 8 +- CPP/Windows/Registry.cpp | 295 +++++++++++++++---------- CPP/Windows/Registry.h | 48 ++-- CPP/Windows/System.cpp | 41 ++-- CPP/Windows/System.h | 2 +- CPP/Windows/SystemInfo.cpp | 125 +++++++++-- CPP/Windows/SystemInfo.h | 2 +- 102 files changed, 2996 insertions(+), 1345 deletions(-) create mode 100644 CPP/Common/Md5Reg.cpp create mode 100644 CPP/Common/Sha3Reg.cpp create mode 100644 CPP/Common/Sha512Prepare.cpp create mode 100644 CPP/Common/Sha512Reg.cpp (limited to 'CPP') diff --git a/CPP/7zip/7zip_gcc.mak b/CPP/7zip/7zip_gcc.mak index 45c9ab3..bcb06a0 100644 --- a/CPP/7zip/7zip_gcc.mak +++ b/CPP/7zip/7zip_gcc.mak @@ -302,6 +302,8 @@ $O/ListFileUtils.o: ../../../Common/ListFileUtils.cpp $(CXX) $(CXXFLAGS) $< $O/LzFindPrepare.o: ../../../Common/LzFindPrepare.cpp $(CXX) $(CXXFLAGS) $< +$O/Md5Reg.o: ../../../Common/Md5Reg.cpp + $(CXX) $(CXXFLAGS) $< $O/MyMap.o: ../../../Common/MyMap.cpp $(CXX) $(CXXFLAGS) $< $O/MyString.o: ../../../Common/MyString.cpp @@ -326,6 +328,12 @@ $O/Sha256Prepare.o: ../../../Common/Sha256Prepare.cpp $(CXX) $(CXXFLAGS) $< $O/Sha256Reg.o: ../../../Common/Sha256Reg.cpp $(CXX) $(CXXFLAGS) $< +$O/Sha3Reg.o: ../../../Common/Sha3Reg.cpp + $(CXX) $(CXXFLAGS) $< +$O/Sha512Prepare.o: ../../../Common/Sha512Prepare.cpp + $(CXX) $(CXXFLAGS) $< +$O/Sha512Reg.o: ../../../Common/Sha512Reg.cpp + $(CXX) $(CXXFLAGS) $< $O/StdInStream.o: ../../../Common/StdInStream.cpp $(CXX) $(CXXFLAGS) $< $O/StdOutStream.o: ../../../Common/StdOutStream.cpp @@ -1207,6 +1215,8 @@ $O/Lzma2Enc.o: ../../../../C/Lzma2Enc.c $(CC) $(CFLAGS) $< $O/LzmaLib.o: ../../../../C/LzmaLib.c $(CC) $(CFLAGS) $< +$O/Md5.o: ../../../../C/Md5.c + $(CC) $(CFLAGS) $< $O/MtCoder.o: ../../../../C/MtCoder.c $(CC) $(CFLAGS) $< $O/MtDec.o: ../../../../C/MtDec.c @@ -1229,6 +1239,12 @@ $O/Sha1.o: ../../../../C/Sha1.c $(CC) $(CFLAGS) $< $O/Sha256.o: ../../../../C/Sha256.c $(CC) $(CFLAGS) $< +$O/Sha3.o: ../../../../C/Sha3.c + $(CC) $(CFLAGS) $< +$O/Sha512.o: ../../../../C/Sha512.c + $(CC) $(CFLAGS) $< +$O/Sha512Opt.o: ../../../../C/Sha512Opt.c + $(CC) $(CFLAGS) $< $O/Sort.o: ../../../../C/Sort.c $(CC) $(CFLAGS) $< $O/SwapBytes.o: ../../../../C/SwapBytes.c diff --git a/CPP/7zip/Archive/ApmHandler.cpp b/CPP/7zip/Archive/ApmHandler.cpp index 56d9b6e..e88d2fe 100644 --- a/CPP/7zip/Archive/ApmHandler.cpp +++ b/CPP/7zip/Archive/ApmHandler.cpp @@ -6,7 +6,6 @@ #include "../../Common/ComTry.h" -#include "../../Windows/PropVariant.h" #include "../../Windows/PropVariantUtils.h" #include "../Common/RegisterArc.h" @@ -14,8 +13,7 @@ #include "HandlerCont.h" -// #define Get16(p) GetBe16(p) -#define Get32(p) GetBe32(p) +#define Get32(p) GetBe32a(p) using namespace NWindows; @@ -41,8 +39,8 @@ static const CUInt32PCharPair k_Flags[] = { 5, "WRITABLE" }, { 6, "OS_PIC_CODE" }, // { 7, "OS_SPECIFIC_2" }, // "Unused" - // { 8, "ChainCompatible" }, // "OS_SPECIFIC_1" - // { 9, "RealDeviceDriver" }, + { 8, "ChainCompatible" }, // "OS_SPECIFIC_1" + { 9, "RealDeviceDriver" }, // { 10, "CanChainToNext" }, { 30, "MOUNTED_AT_STARTUP" }, { 31, "STARTUP" } @@ -74,16 +72,16 @@ struct CItem bool Is_Valid_and_Allocated() const { return (Flags & (DPME_FLAGS_VALID | DPME_FLAGS_ALLOCATED)) != 0; } - bool Parse(const Byte *p, UInt32 &numBlocksInMap) + bool Parse(const UInt32 *p32, UInt32 &numBlocksInMap) { - numBlocksInMap = Get32(p + 4); - StartBlock = Get32(p + 8); - NumBlocks = Get32(p + 0xc); - Flags = Get32(p + 0x58); - memcpy(Name, p + 0x10, k_Str_Size); - memcpy(Type, p + 0x30, k_Str_Size); - if (GetUi32(p) != 0x4d50) // "PM" + if (GetUi32a(p32) != 0x4d50) // "PM" return false; + numBlocksInMap = Get32(p32 + 4 / 4); + StartBlock = Get32(p32 + 8 / 4); + NumBlocks = Get32(p32 + 0xc / 4); + Flags = Get32(p32 + 0x58 / 4); + memcpy(Name, p32 + 0x10 / 4, k_Str_Size); + memcpy(Type, p32 + 0x30 / 4, k_Str_Size); /* DataStartBlock = Get32(p + 0x50); NumDataBlocks = Get32(p + 0x54); @@ -96,7 +94,7 @@ struct CItem if (Get32(p + 0x70) != 0) return false; BootChecksum = Get32(p + 0x74); - memcpy(Processor, p + 0x78, 16); + memcpy(Processor, p32 + 0x78 / 4, 16); */ return true; } @@ -109,9 +107,9 @@ Z7_class_CHandler_final: public CHandlerCont CRecordVector _items; unsigned _blockSizeLog; - UInt32 _numBlocks; - UInt64 _phySize; bool _isArc; + // UInt32 _numBlocks; + UInt64 _phySize; UInt64 BlocksToBytes(UInt32 i) const { return (UInt64)i << _blockSizeLog; } @@ -132,11 +130,11 @@ API_FUNC_static_IsArc IsArc_Apm(const Byte *p, size_t size) { if (size < kSectorSize) return k_IsArc_Res_NEED_MORE; - if (GetUi64(p + 8) != 0) + if (GetUi32(p + 12) != 0) return k_IsArc_Res_NO; UInt32 v = GetUi32(p); // we read as little-endian - v ^= (kSig0 | (unsigned)kSig1 << 8); - if ((v & ~((UInt32)0xf << 17))) + v ^= kSig0 | (unsigned)kSig1 << 8; + if (v & ~((UInt32)0xf << 17)) return k_IsArc_Res_NO; if ((0x116u >> (v >> 17)) & 1) return k_IsArc_Res_YES; @@ -149,55 +147,103 @@ Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallb COM_TRY_BEGIN Close(); - Byte buf[kSectorSize]; - unsigned numSectors_in_Cluster; + UInt32 buf32[kSectorSize / 4]; + unsigned numPadSectors, blockSizeLog_from_Header; { - RINOK(ReadStream_FALSE(stream, buf, kSectorSize)) - if (GetUi64(buf + 8) != 0) + // Driver Descriptor Map (DDM) + RINOK(ReadStream_FALSE(stream, buf32, kSectorSize)) + // 8: UInt16 sbDevType : =0 (usually), =1 in Apple Mac OS X 10.3.0 iso + // 10: UInt16 sbDevId : =0 (usually), =1 in Apple Mac OS X 10.3.0 iso + // 12: UInt32 sbData : =0 + if (buf32[3] != 0) return S_FALSE; - UInt32 v = GetUi32(buf); // we read as little-endian - v ^= (kSig0 | (unsigned)kSig1 << 8); - if ((v & ~((UInt32)0xf << 17))) + UInt32 v = GetUi32a(buf32); // we read as little-endian + v ^= kSig0 | (unsigned)kSig1 << 8; + if (v & ~((UInt32)0xf << 17)) return S_FALSE; v >>= 16; if (v == 0) return S_FALSE; if (v & (v - 1)) return S_FALSE; - const unsigned a = (0x30210u >> v) & 3; - // a = 0; // for debug - numSectors_in_Cluster = 1u << a; - _blockSizeLog = 9 + a; + // v == { 16,8,4,2 } : block size (x256 bytes) + const unsigned a = +#if 1 + (0x30210u >> v) & 3; +#else + 0; // for debug : hardcoded switch to 512-bytes mode +#endif + numPadSectors = (1u << a) - 1; + _blockSizeLog = blockSizeLog_from_Header = 9 + a; } - UInt32 numBlocks = Get32(buf + 4); - _numBlocks = numBlocks; - +/* + some APMs (that are ".iso" macOS installation files) contain + (blockSizeLog == 11) in DDM header, + and contain 2 overlapping maps: + 1) map for 512-bytes-step + 2) map for 2048-bytes-step + 512-bytes-step map is correct. + 2048-bytes-step map can be incorrect in some cases. + + macos 8 / OSX DP2 iso: + There is shared "hfs" item in both maps. + And correct (offset/size) values for "hfs" partition + can be calculated only in 512-bytes mode (ignoring blockSizeLog == 11). + But some records (Macintosh.Apple_Driver*_) + can be correct on both modes: 512-bytes mode / 2048-bytes-step. + + macos 921 ppc / Apple Mac OS X 10.3.0 iso: + Both maps are correct. + If we use 512-bytes-step, each 4th item is (Apple_Void) with zero size. + And these zero size (Apple_Void) items will be first items in 2048-bytes-step map. +*/ + +// we define Z7_APM_SWITCH_TO_512_BYTES, because +// we want to support old MACOS APMs that contain correct value only +// for 512-bytes-step mode +#define Z7_APM_SWITCH_TO_512_BYTES + + const UInt32 numBlocks_from_Header = Get32(buf32 + 1); + UInt32 numBlocks = 0; { - for (unsigned k = numSectors_in_Cluster; --k != 0;) + for (unsigned k = 0; k < numPadSectors; k++) { - RINOK(ReadStream_FALSE(stream, buf, kSectorSize)) + RINOK(ReadStream_FALSE(stream, buf32, kSectorSize)) +#ifdef Z7_APM_SWITCH_TO_512_BYTES + if (k == 0) + { + if (GetUi32a(buf32) == 0x4d50 // "PM" + // && (Get32(buf32 + 0x58 / 4) & 1) // Flags::VALID + // some old APMs don't use VALID flag for Apple_partition_map item + && Get32(buf32 + 8 / 4) == 1) // StartBlock + { + // we switch the mode to 512-bytes-step map reading: + numPadSectors = 0; + _blockSizeLog = 9; + break; + } + } +#endif } } - UInt32 numBlocksInMap = 0; - for (unsigned i = 0;;) { - RINOK(ReadStream_FALSE(stream, buf, kSectorSize)) +#ifdef Z7_APM_SWITCH_TO_512_BYTES + if (i != 0 || _blockSizeLog == blockSizeLog_from_Header) +#endif + { + RINOK(ReadStream_FALSE(stream, buf32, kSectorSize)) + } CItem item; - - UInt32 numBlocksInMap2 = 0; - if (!item.Parse(buf, numBlocksInMap2)) + UInt32 numBlocksInMap = 0; + if (!item.Parse(buf32, numBlocksInMap)) return S_FALSE; - if (i == 0) - { - numBlocksInMap = numBlocksInMap2; - if (numBlocksInMap > (1 << 8) || numBlocksInMap == 0) - return S_FALSE; - } - else if (numBlocksInMap2 != numBlocksInMap) + // v24.09: we don't check that all entries have same (numBlocksInMap) values, + // because some APMs have different (numBlocksInMap) values, if (Apple_Void) is used. + if (numBlocksInMap > (1 << 8) || numBlocksInMap <= i) return S_FALSE; const UInt32 finish = item.StartBlock + item.NumBlocks; @@ -207,15 +253,19 @@ Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallb numBlocks = finish; _items.Add(item); - for (unsigned k = numSectors_in_Cluster; --k != 0;) + if (numPadSectors != 0) { - RINOK(ReadStream_FALSE(stream, buf, kSectorSize)) + RINOK(stream->Seek(numPadSectors << 9, STREAM_SEEK_CUR, NULL)) } if (++i == numBlocksInMap) break; } _phySize = BlocksToBytes(numBlocks); + // _numBlocks = numBlocks; + const UInt64 physSize = (UInt64)numBlocks_from_Header << blockSizeLog_from_Header; + if (_phySize < physSize) + _phySize = physSize; _isArc = true; _stream = stream; @@ -240,22 +290,21 @@ static const Byte kProps[] = kpidSize, kpidOffset, kpidCharacts + // , kpidCpu }; static const Byte kArcProps[] = { - kpidClusterSize, - kpidNumBlocks + kpidClusterSize + // , kpidNumBlocks }; IMP_IInArchive_Props IMP_IInArchive_ArcProps -static AString GetString(const char *s) +static void GetString(AString &dest, const char *src) { - AString res; - res.SetFrom_CalcLen(s, k_Str_Size); - return res; + dest.SetFrom_CalcLen(src, k_Str_Size); } Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) @@ -272,7 +321,8 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) const CItem &item = _items[i]; if (!item.Is_Valid_and_Allocated()) continue; - AString s (GetString(item.Type)); + AString s; + GetString(s, item.Type); if (NDmg::Is_Apple_FS_Or_Unknown(s)) { if (mainIndex != -1) @@ -289,7 +339,7 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) } case kpidClusterSize: prop = (UInt32)1 << _blockSizeLog; break; case kpidPhySize: prop = _phySize; break; - case kpidNumBlocks: prop = _numBlocks; break; + // case kpidNumBlocks: prop = _numBlocks; break; case kpidErrorFlags: { @@ -319,10 +369,12 @@ Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val { case kpidPath: { - AString s (GetString(item.Name)); + AString s; + GetString(s, item.Name); if (s.IsEmpty()) s.Add_UInt32(index); - AString type (GetString(item.Type)); + AString type; + GetString(type, item.Type); { const char *ext = NDmg::Find_Apple_FS_Ext(type); if (ext) @@ -336,6 +388,16 @@ Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val prop = s; break; } +/* + case kpidCpu: + { + AString s; + s.SetFrom_CalcLen(item.Processor, sizeof(item.Processor)); + if (!s.IsEmpty()) + prop = s; + break; + } +*/ case kpidSize: case kpidPackSize: prop = BlocksToBytes(item.NumBlocks); diff --git a/CPP/7zip/Archive/Common/HandlerOut.h b/CPP/7zip/Archive/Common/HandlerOut.h index cfba46e..9340e1b 100644 --- a/CPP/7zip/Archive/Common/HandlerOut.h +++ b/CPP/7zip/Archive/Common/HandlerOut.h @@ -22,7 +22,7 @@ protected: _numThreads_WasForced = false; #endif - UInt64 memAvail = (UInt64)(sizeof(size_t)) << 28; + size_t memAvail = (size_t)sizeof(size_t) << 28; _memAvail = memAvail; _memUsage_Compress = memAvail; _memUsage_Decompress = memAvail; @@ -55,7 +55,7 @@ public: bool _memUsage_WasSet; UInt64 _memUsage_Compress; UInt64 _memUsage_Decompress; - UInt64 _memAvail; + size_t _memAvail; bool SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres); diff --git a/CPP/7zip/Archive/HfsHandler.cpp b/CPP/7zip/Archive/HfsHandler.cpp index 4049fbc..46e0239 100644 --- a/CPP/7zip/Archive/HfsHandler.cpp +++ b/CPP/7zip/Archive/HfsHandler.cpp @@ -25,6 +25,9 @@ #define Get32(p) GetBe32(p) #define Get64(p) GetBe64(p) +#define Get16a(p) GetBe16a(p) +#define Get32a(p) GetBe32a(p) + namespace NArchive { namespace NHfs { @@ -104,23 +107,21 @@ UInt32 CFork::Calc_NumBlocks_from_Extents() const { UInt32 num = 0; FOR_VECTOR (i, Extents) - { num += Extents[i].NumBlocks; - } return num; } bool CFork::Check_NumBlocks() const { - UInt32 num = 0; + UInt32 num = NumBlocks; FOR_VECTOR (i, Extents) { - UInt32 next = num + Extents[i].NumBlocks; - if (next < num) + const UInt32 cur = Extents[i].NumBlocks; + if (num < cur) return false; - num = next; + num -= cur; } - return num == NumBlocks; + return num == 0; } struct CIdIndexPair @@ -175,7 +176,7 @@ static int Find_in_IdExtents(const CObjectVector &items, UInt32 id) bool CFork::Upgrade(const CObjectVector &items, UInt32 id) { - int index = Find_in_IdExtents(items, id); + const int index = Find_in_IdExtents(items, id); if (index < 0) return true; const CIdExtents &item = items[index]; @@ -188,8 +189,13 @@ bool CFork::Upgrade(const CObjectVector &items, UInt32 id) struct CVolHeader { - Byte Header[2]; - UInt16 Version; + unsigned BlockSizeLog; + UInt32 NumFiles; + UInt32 NumFolders; + UInt32 NumBlocks; + UInt32 NumFreeBlocks; + + bool Is_Hsfx_ver5; // UInt32 Attr; // UInt32 LastMountedVersion; // UInt32 JournalInfoBlock; @@ -199,19 +205,13 @@ struct CVolHeader // UInt32 BackupTime; // UInt32 CheckedTime; - UInt32 NumFiles; - UInt32 NumFolders; - unsigned BlockSizeLog; - UInt32 NumBlocks; - UInt32 NumFreeBlocks; - // UInt32 WriteCount; // UInt32 FinderInfo[8]; // UInt64 VolID; UInt64 GetPhySize() const { return (UInt64)NumBlocks << BlockSizeLog; } UInt64 GetFreeSize() const { return (UInt64)NumFreeBlocks << BlockSizeLog; } - bool IsHfsX() const { return Version > 4; } + bool IsHfsX() const { return Is_Hsfx_ver5; } }; inline void HfsTimeToFileTime(UInt32 hfsTime, FILETIME &ft) @@ -463,18 +463,18 @@ public: bool UnsupportedFeature; bool ThereAreAltStreams; // bool CaseSensetive; + UInt32 MethodsMask; UString ResFileName; UInt64 SpecOffset; - UInt64 PhySize; + // UInt64 PhySize; UInt64 PhySize2; UInt64 ArcFileSize; - UInt32 MethodsMask; void Clear() { SpecOffset = 0; - PhySize = 0; + // PhySize = 0; PhySize2 = 0; ArcFileSize = 0; MethodsMask = 0; @@ -596,7 +596,7 @@ HRESULT CDatabase::ReadFile(const CFork &fork, CByteBuffer &buf, IInStream *inSt { if (fork.NumBlocks >= Header.NumBlocks) return S_FALSE; - if ((ArcFileSize >> Header.BlockSizeLog) + 1 < fork.NumBlocks) + if (((ArcFileSize - SpecOffset) >> Header.BlockSizeLog) + 1 < fork.NumBlocks) return S_FALSE; const size_t totalSize = (size_t)fork.NumBlocks << Header.BlockSizeLog; @@ -1328,28 +1328,26 @@ HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector 5) - return k_IsArc_Res_NO; - } + const UInt32 sig = GetUi32(p); + if (sig != k_Signature_LE32_HFSP_VER4) + if (sig != k_Signature_LE32_HFSX_VER5) + if ((UInt16)sig != k_Signature_LE16_HFS_BD + || GetUi16(p + 0x7c) != k_Signature_LE16_HPLUS) + return k_IsArc_Res_NO; return k_IsArc_Res_YES; } } @@ -1357,30 +1355,42 @@ API_FUNC_static_IsArc IsArc_HFS(const Byte *p, size_t size) HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress) { Clear(); - Byte buf[kHfsHeaderSize]; - RINOK(ReadStream_FALSE(inStream, buf, kHfsHeaderSize)) - { - for (unsigned i = 0; i < kHeaderPadSize; i++) - if (buf[i] != 0) - return S_FALSE; - } - const Byte *p = buf + kHeaderPadSize; + UInt32 buf32[kHfsHeaderSize / 4]; + RINOK(ReadStream_FALSE(inStream, buf32, kHfsHeaderSize)) + const Byte *p = (const Byte *)buf32 + kHeaderPadSize; CVolHeader &h = Header; - h.Header[0] = p[0]; - h.Header[1] = p[1]; - - if (p[0] == 'B' && p[1] == 'D') + if (GetUi16a(p) == k_Signature_LE16_HFS_BD) { /* It's header for old HFS format. We don't support old HFS format, but we support - special HFS volume that contains embedded HFS+ volume + special HFS volume that contains embedded HFS+ volume. + HFS MDB : Master directory block + HFS VIB : Volume information block + some old images contain boot data with "LK" signature at start of buf32. */ - - if (p[0x7C] != 'H' || p[0x7C + 1] != '+') +#if 1 + // here we check first bytes of archive, + // because start data can contain signature of some another + // archive type that could have priority over HFS. + const void *buf_ptr = (const void *)buf32; + const unsigned sig = GetUi16a(buf_ptr); + if (sig != 'L' + ((unsigned)'K' << 8)) + { + // some old HFS (non HFS+) files have no "LK" signature, + // but have non-zero data after 2 first bytes in start 1 KiB. + if (sig != 0) + return S_FALSE; +/* + for (unsigned i = 0; i < kHeaderPadSize / 4; i++) + if (buf32[i] != 0) + return S_FALSE; +*/ + } +#endif + if (GetUi16a(p + 0x7c) != k_Signature_LE16_HPLUS) // signature of embedded HFS+ volume return S_FALSE; - /* h.CTime = Get32(p + 0x2); h.MTime = Get32(p + 0x6); @@ -1399,80 +1409,104 @@ HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress) h.NumFreeBlocks = Get16(p + 0x22); */ - UInt32 blockSize = Get32(p + 0x14); - - { - unsigned i; - for (i = 9; ((UInt32)1 << i) != blockSize; i++) - if (i == 31) - return S_FALSE; - h.BlockSizeLog = i; - } - - h.NumBlocks = Get16(p + 0x12); + // v24.09: blockSize in old HFS image can be non-power of 2. + const UInt32 blockSize = Get32a(p + 0x14); // drAlBlkSiz + if (blockSize == 0 || (blockSize & 0x1ff)) + return S_FALSE; + const unsigned numBlocks = Get16a(p + 0x12); // drNmAlBlks + // UInt16 drFreeBks = Get16a(p + 0x22); // number of unused allocation blocks /* - we suppose that it has the follwing layout + we suppose that it has the following layout: { - start block with header - [h.NumBlocks] - end block with header + start data with header + blocks[h.NumBlocks] + end data with header (probably size_of_footer <= blockSize). } */ - PhySize2 = ((UInt64)h.NumBlocks + 2) << h.BlockSizeLog; - - UInt32 startBlock = Get16(p + 0x7C + 2); - UInt32 blockCount = Get16(p + 0x7C + 4); - SpecOffset = (UInt64)(1 + startBlock) << h.BlockSizeLog; - UInt64 phy = SpecOffset + ((UInt64)blockCount << h.BlockSizeLog); + // PhySize2 = ((UInt64)numBlocks + 2) * blockSize; + const unsigned sector_of_FirstBlock = Get16a(p + 0x1c); // drAlBlSt : first allocation block in volume + const UInt32 startBlock = Get16a(p + 0x7c + 2); + const UInt32 blockCount = Get16a(p + 0x7c + 4); + SpecOffset = (UInt32)sector_of_FirstBlock << 9; // it's 32-bit here + PhySize2 = SpecOffset + (UInt64)numBlocks * blockSize; + SpecOffset += (UInt64)startBlock * blockSize; + // before v24.09: // SpecOffset = (UInt64)(1 + startBlock) * blockSize; + const UInt64 phy = SpecOffset + (UInt64)blockCount * blockSize; if (PhySize2 < phy) - PhySize2 = phy; + PhySize2 = phy; + UInt32 tail = 1 << 10; // at least 1 KiB tail (for footer MDB) is expected. + if (tail < blockSize) + tail = blockSize; + RINOK(InStream_GetSize_SeekToEnd(inStream, ArcFileSize)) + if (ArcFileSize > PhySize2 && + ArcFileSize - PhySize2 <= tail) + { + // data after blocks[h.NumBlocks] must contain another copy of MDB. + // In example where blockSize is not power of 2, we have + // (ArcFileSize - PhySize2) < blockSize. + // We suppose that data after blocks[h.NumBlocks] is part of HFS archive. + // Maybe we should scan for footer MDB data (in last 1 KiB)? + PhySize2 = ArcFileSize; + } RINOK(InStream_SeekSet(inStream, SpecOffset)) - RINOK(ReadStream_FALSE(inStream, buf, kHfsHeaderSize)) + RINOK(ReadStream_FALSE(inStream, buf32, kHfsHeaderSize)) } - if (p[0] != 'H' || (p[1] != '+' && p[1] != 'X')) - return S_FALSE; - h.Version = Get16(p + 2); - if (h.Version < 4 || h.Version > 5) - return S_FALSE; - - // h.Attr = Get32(p + 4); - // h.LastMountedVersion = Get32(p + 8); - // h.JournalInfoBlock = Get32(p + 0xC); - - h.CTime = Get32(p + 0x10); - h.MTime = Get32(p + 0x14); - // h.BackupTime = Get32(p + 0x18); - // h.CheckedTime = Get32(p + 0x1C); - - h.NumFiles = Get32(p + 0x20); - h.NumFolders = Get32(p + 0x24); - - if (h.NumFolders > ((UInt32)1 << 29) || - h.NumFiles > ((UInt32)1 << 30)) - return S_FALSE; - - RINOK(InStream_GetSize_SeekToEnd(inStream, ArcFileSize)) - - if (progress) + // HFS+ / HFSX volume header (starting from offset==1024): { - const UInt64 numFiles = (UInt64)h.NumFiles + h.NumFolders + 1; - RINOK(progress->SetTotal(&numFiles, NULL)) + // v24.09: we use strict condition test for pair signature(Version): + // H+(4), HX(5): + const UInt32 sig = GetUi32a(p); + // h.Version = Get16(p + 2); + h.Is_Hsfx_ver5 = false; + if (sig != k_Signature_LE32_HFSP_VER4) + { + if (sig != k_Signature_LE32_HFSX_VER5) + return S_FALSE; + h.Is_Hsfx_ver5 = true; + } } - - UInt32 blockSize = Get32(p + 0x28); - { + const UInt32 blockSize = Get32a(p + 0x28); unsigned i; for (i = 9; ((UInt32)1 << i) != blockSize; i++) if (i == 31) return S_FALSE; h.BlockSizeLog = i; } +#if 1 + // HFS Plus DOCs: The first 1024 bytes are reserved for use as boot blocks + // v24.09: we don't check starting 1 KiB before old (HFS MDB) block ("BD" signture) . + // but we still check starting 1 KiB before HFS+ / HFSX volume header. + // are there HFS+ / HFSX images with non-zero data in this reserved area? + { + for (unsigned i = 0; i < kHeaderPadSize / 4; i++) + if (buf32[i] != 0) + return S_FALSE; + } +#endif + // h.Attr = Get32a(p + 4); + // h.LastMountedVersion = Get32a(p + 8); + // h.JournalInfoBlock = Get32a(p + 0xC); + h.CTime = Get32a(p + 0x10); + h.MTime = Get32a(p + 0x14); + // h.BackupTime = Get32a(p + 0x18); + // h.CheckedTime = Get32a(p + 0x1C); + h.NumFiles = Get32a(p + 0x20); + h.NumFolders = Get32a(p + 0x24); + if (h.NumFolders > ((UInt32)1 << 29) || + h.NumFiles > ((UInt32)1 << 30)) + return S_FALSE; - h.NumBlocks = Get32(p + 0x2C); - h.NumFreeBlocks = Get32(p + 0x30); + RINOK(InStream_GetSize_SeekToEnd(inStream, ArcFileSize)) + if (progress) + { + const UInt64 numFiles = (UInt64)h.NumFiles + h.NumFolders + 1; + RINOK(progress->SetTotal(&numFiles, NULL)) + } + h.NumBlocks = Get32a(p + 0x2C); + h.NumFreeBlocks = Get32a(p + 0x30); /* h.NextCalatlogNodeID = Get32(p + 0x40); h.WriteCount = Get32(p + 0x44); @@ -1495,7 +1529,7 @@ HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress) HeadersError = true; else { - HRESULT res = LoadExtentFile(extentsFork, inStream, overflowExtents); + const HRESULT res = LoadExtentFile(extentsFork, inStream, overflowExtents); if (res == S_FALSE) HeadersError = true; else if (res != S_OK) @@ -1515,7 +1549,7 @@ HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress) RINOK(LoadCatalog(catalogFork, overflowExtents, inStream, progress)) - PhySize = Header.GetPhySize(); + // PhySize = Header.GetPhySize(); return S_OK; } @@ -1591,7 +1625,7 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) case kpidCharacts: MethodsMaskToProp(MethodsMask, prop); break; case kpidPhySize: { - UInt64 v = SpecOffset + PhySize; + UInt64 v = SpecOffset + Header.GetPhySize(); // PhySize; if (v < PhySize2) v = PhySize2; prop = v; @@ -2529,7 +2563,7 @@ HRESULT CHandler::GetForkStream(const CFork &fork, ISequentialInStream **stream) return S_FALSE; } CSeekExtent se; - se.Phy = (UInt64)e.Pos << Header.BlockSizeLog; + se.Phy = SpecOffset + ((UInt64)e.Pos << Header.BlockSizeLog); se.Virt = virt; virt += cur; rem -= cur; @@ -2540,7 +2574,7 @@ HRESULT CHandler::GetForkStream(const CFork &fork, ISequentialInStream **stream) return S_FALSE; CSeekExtent se; - se.Phy = 0; + se.Phy = 0; // = SpecOffset ? se.Virt = virt; extentStream->Extents.Add(se); extentStream->Stream = _stream; diff --git a/CPP/7zip/Archive/LpHandler.cpp b/CPP/7zip/Archive/LpHandler.cpp index c1a76b4..926b654 100644 --- a/CPP/7zip/Archive/LpHandler.cpp +++ b/CPP/7zip/Archive/LpHandler.cpp @@ -460,9 +460,11 @@ struct LpMetadataHeader static bool CheckSha256(const Byte *data, size_t size, const Byte *checksum) { + MY_ALIGN (16) CSha256 sha; Sha256_Init(&sha); Sha256_Update(&sha, data, size); + MY_ALIGN (16) Byte calced[32]; Sha256_Final(&sha, calced); return memcmp(checksum, calced, 32) == 0; @@ -470,6 +472,7 @@ static bool CheckSha256(const Byte *data, size_t size, const Byte *checksum) static bool CheckSha256_csOffset(Byte *data, size_t size, unsigned hashOffset) { + MY_ALIGN (4) Byte checksum[32]; Byte *shaData = &data[hashOffset]; memcpy(checksum, shaData, 32); @@ -528,6 +531,7 @@ HRESULT CHandler::Open2(IInStream *stream) { RINOK(InStream_SeekSet(stream, LP_PARTITION_RESERVED_BYTES)) { + MY_ALIGN (4) Byte buf[k_Geometry_Size]; RINOK(ReadStream_FALSE(stream, buf, k_Geometry_Size)) if (memcmp(buf, k_Signature, k_SignatureSize) != 0) diff --git a/CPP/7zip/Archive/Rar/Rar5Handler.cpp b/CPP/7zip/Archive/Rar/Rar5Handler.cpp index 34615c2..7d75aae 100644 --- a/CPP/7zip/Archive/Rar/Rar5Handler.cpp +++ b/CPP/7zip/Archive/Rar/Rar5Handler.cpp @@ -658,6 +658,9 @@ HRESULT CInArchive::ReadBlockHeader(CHeader &h) RINOK(ReadStream_Check(_buf, AES_BLOCK_SIZE * 2)) memcpy(m_CryptoDecoder->_iv, _buf, AES_BLOCK_SIZE); RINOK(m_CryptoDecoder->Init()) + // we call RAR5_AES_Filter with: + // data_ptr == aligned_ptr + 16 + // data_size == 16 if (m_CryptoDecoder->Filter(_buf + AES_BLOCK_SIZE, AES_BLOCK_SIZE) != AES_BLOCK_SIZE) return E_FAIL; memcpy(buf, _buf + AES_BLOCK_SIZE, AES_BLOCK_SIZE); @@ -689,10 +692,14 @@ HRESULT CInArchive::ReadBlockHeader(CHeader &h) return E_OUTOFMEMORY; memcpy(_buf, buf, filled); const size_t rem = size - filled; + // if (m_CryptoMode), we add AES_BLOCK_SIZE here, because _iv is not included to size. AddToSeekValue(size + (m_CryptoMode ? AES_BLOCK_SIZE : 0)); RINOK(ReadStream_Check(_buf + filled, rem)) if (m_CryptoMode) { + // we call RAR5_AES_Filter with: + // data_ptr == aligned_ptr + 16 + // (rem) can be big if (m_CryptoDecoder->Filter(_buf + filled, (UInt32)rem) != rem) return E_FAIL; #if 1 @@ -1065,7 +1072,8 @@ HRESULT CUnpacker::Create(DECL_EXTERNAL_CODECS_LOC_VARS CMyComPtr csdp; RINOK(lzCoder.QueryInterface(IID_ICompressSetDecoderProperties2, &csdp)) - + if (!csdp) + return E_NOTIMPL; const unsigned ver = item.Get_AlgoVersion_HuffRev(); if (ver > 1) return E_NOTIMPL; @@ -3343,9 +3351,9 @@ Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVAR } else if (name.IsPrefixedBy_Ascii_NoCase("memx")) { - UInt64 memAvail; + size_t memAvail; if (!NWindows::NSystem::GetRamSize(memAvail)) - memAvail = (UInt64)(sizeof(size_t)) << 28; + memAvail = (size_t)sizeof(size_t) << 28; UInt64 v; if (!ParseSizeString(name.Ptr(4), prop, memAvail, v)) return E_INVALIDARG; diff --git a/CPP/7zip/Archive/XarHandler.cpp b/CPP/7zip/Archive/XarHandler.cpp index 5112a16..6ef8941 100644 --- a/CPP/7zip/Archive/XarHandler.cpp +++ b/CPP/7zip/Archive/XarHandler.cpp @@ -3,6 +3,7 @@ #include "StdAfx.h" #include "../../../C/Sha256.h" +#include "../../../C/Sha512.h" #include "../../../C/CpuArch.h" #include "../../Common/ComTry.h" @@ -41,22 +42,33 @@ Z7_CLASS_IMP_NOQIB_1( CInStreamWithSha256 , ISequentialInStream ) + bool _sha512Mode; CMyComPtr _stream; - CAlignedBuffer1 _sha; + CAlignedBuffer1 _sha256; + CAlignedBuffer1 _sha512; UInt64 _size; - CSha256 *Sha() { return (CSha256 *)(void *)(Byte *)_sha; } + CSha256 *Sha256() { return (CSha256 *)(void *)(Byte *)_sha256; } + CSha512 *Sha512() { return (CSha512 *)(void *)(Byte *)_sha512; } public: - CInStreamWithSha256(): _sha(sizeof(CSha256)) {} + CInStreamWithSha256(): + _sha256(sizeof(CSha256)), + _sha512(sizeof(CSha512)) + {} void SetStream(ISequentialInStream *stream) { _stream = stream; } - void Init() + void Init(bool sha512Mode) { + _sha512Mode = sha512Mode; _size = 0; - Sha256_Init(Sha()); + if (sha512Mode) + Sha512_Init(Sha512(), SHA512_DIGEST_SIZE); + else + Sha256_Init(Sha256()); } void ReleaseStream() { _stream.Release(); } UInt64 GetSize() const { return _size; } - void Final(Byte *digest) { Sha256_Final(Sha(), digest); } + void Final256(Byte *digest) { Sha256_Final(Sha256(), digest); } + void Final512(Byte *digest) { Sha512_Final(Sha512(), digest, SHA512_DIGEST_SIZE); } }; Z7_COM7F_IMF(CInStreamWithSha256::Read(void *data, UInt32 size, UInt32 *processedSize)) @@ -64,7 +76,10 @@ Z7_COM7F_IMF(CInStreamWithSha256::Read(void *data, UInt32 size, UInt32 *processe UInt32 realProcessedSize; const HRESULT result = _stream->Read(data, size, &realProcessedSize); _size += realProcessedSize; - Sha256_Update(Sha(), (const Byte *)data, realProcessedSize); + if (_sha512Mode) + Sha512_Update(Sha512(), (const Byte *)data, realProcessedSize); + else + Sha256_Update(Sha256(), (const Byte *)data, realProcessedSize); if (processedSize) *processedSize = realProcessedSize; return result; @@ -75,25 +90,33 @@ Z7_CLASS_IMP_NOQIB_1( COutStreamWithSha256 , ISequentialOutStream ) - // bool _calculate; + bool _sha512Mode; CMyComPtr _stream; - CAlignedBuffer1 _sha; + CAlignedBuffer1 _sha256; + CAlignedBuffer1 _sha512; UInt64 _size; - CSha256 *Sha() { return (CSha256 *)(void *)(Byte *)_sha; } + CSha256 *Sha256() { return (CSha256 *)(void *)(Byte *)_sha256; } + CSha512 *Sha512() { return (CSha512 *)(void *)(Byte *)_sha512; } public: - COutStreamWithSha256(): _sha(sizeof(CSha256)) {} + COutStreamWithSha256(): + _sha256(sizeof(CSha256)), + _sha512(sizeof(CSha512)) + {} void SetStream(ISequentialOutStream *stream) { _stream = stream; } void ReleaseStream() { _stream.Release(); } - void Init(/* bool calculate = true */ ) + void Init(bool sha512Mode) { - // _calculate = calculate; + _sha512Mode = sha512Mode; _size = 0; - Sha256_Init(Sha()); + if (sha512Mode) + Sha512_Init(Sha512(), SHA512_DIGEST_SIZE); + else + Sha256_Init(Sha256()); } - void InitSha256() { Sha256_Init(Sha()); } UInt64 GetSize() const { return _size; } - void Final(Byte *digest) { Sha256_Final(Sha(), digest); } + void Final256(Byte *digest) { Sha256_Final(Sha256(), digest); } + void Final512(Byte *digest) { Sha512_Final(Sha512(), digest, SHA512_DIGEST_SIZE); } }; Z7_COM7F_IMF(COutStreamWithSha256::Write(const void *data, UInt32 size, UInt32 *processedSize)) @@ -102,7 +125,10 @@ Z7_COM7F_IMF(COutStreamWithSha256::Write(const void *data, UInt32 size, UInt32 * if (_stream) result = _stream->Write(data, size, &size); // if (_calculate) - Sha256_Update(Sha(), (const Byte *)data, size); + if (_sha512Mode) + Sha512_Update(Sha512(), (const Byte *)data, size); + else + Sha256_Update(Sha256(), (const Byte *)data, size); _size += size; if (processedSize) *processedSize = size; @@ -521,10 +547,11 @@ void CInStreamWithHash::SetStreamAndInit(ISequentialInStream *stream, int algo) inStreamSha1->Init(); stream = inStreamSha1; } - else if (algo == XAR_CKSUM_SHA256) + else if (algo == XAR_CKSUM_SHA256 + || algo == XAR_CKSUM_SHA512) { inStreamSha256->SetStream(stream); - inStreamSha256->Init(); + inStreamSha256->Init(algo == XAR_CKSUM_SHA512); stream = inStreamSha256; } inStreamLim->SetStream(stream); @@ -542,7 +569,14 @@ bool CInStreamWithHash::CheckHash(int algo, const Byte *digest_from_arc) const else if (algo == XAR_CKSUM_SHA256) { Byte digest[SHA256_DIGEST_SIZE]; - inStreamSha256->Final(digest); + inStreamSha256->Final256(digest); + if (memcmp(digest, digest_from_arc, sizeof(digest)) != 0) + return false; + } + else if (algo == XAR_CKSUM_SHA512) + { + Byte digest[SHA512_DIGEST_SIZE]; + inStreamSha256->Final512(digest); if (memcmp(digest, digest_from_arc, sizeof(digest)) != 0) return false; } @@ -1151,11 +1185,12 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, outStreamSha1->SetStream(realOutStream); outStreamSha1->Init(); } - else if (checksum_method == XAR_CKSUM_SHA256) + else if (checksum_method == XAR_CKSUM_SHA256 + || checksum_method == XAR_CKSUM_SHA512) { outStreamLim->SetStream(outStreamSha256); outStreamSha256->SetStream(realOutStream); - outStreamSha256->Init(); + outStreamSha256->Init(checksum_method == XAR_CKSUM_SHA512); } else outStreamLim->SetStream(realOutStream); @@ -1209,8 +1244,15 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, else if (checksum_method == XAR_CKSUM_SHA256) { Byte digest[SHA256_DIGEST_SIZE]; - outStreamSha256->Final(digest); - if (memcmp(digest, item.extracted_checksum.Data, SHA256_DIGEST_SIZE) != 0) + outStreamSha256->Final256(digest); + if (memcmp(digest, item.extracted_checksum.Data, sizeof(digest)) != 0) + opRes = NExtract::NOperationResult::kCRCError; + } + else if (checksum_method == XAR_CKSUM_SHA512) + { + Byte digest[SHA512_DIGEST_SIZE]; + outStreamSha256->Final512(digest); + if (memcmp(digest, item.extracted_checksum.Data, sizeof(digest)) != 0) opRes = NExtract::NOperationResult::kCRCError; } if (opRes == NExtract::NOperationResult::kOK) diff --git a/CPP/7zip/Archive/XzHandler.cpp b/CPP/7zip/Archive/XzHandler.cpp index 7ced4e1..907376c 100644 --- a/CPP/7zip/Archive/XzHandler.cpp +++ b/CPP/7zip/Archive/XzHandler.cpp @@ -967,9 +967,9 @@ Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream)) || _maxBlocksSize != (size_t)_maxBlocksSize) return S_FALSE; - UInt64 memSize; + size_t memSize; if (!NSystem::GetRamSize(memSize)) - memSize = (UInt64)(sizeof(size_t)) << 28; + memSize = (size_t)sizeof(size_t) << 28; { if (_maxBlocksSize > memSize / 4) return S_FALSE; diff --git a/CPP/7zip/Bundles/Format7zF/Arc.mak b/CPP/7zip/Bundles/Format7zF/Arc.mak index 3d8a430..7166ab3 100644 --- a/CPP/7zip/Bundles/Format7zF/Arc.mak +++ b/CPP/7zip/Bundles/Format7zF/Arc.mak @@ -4,6 +4,7 @@ COMMON_OBJS = \ $O\DynLimBuf.obj \ $O\IntToString.obj \ $O\LzFindPrepare.obj \ + $O\Md5Reg.obj \ $O\MyMap.obj \ $O\MyString.obj \ $O\MyVector.obj \ @@ -11,6 +12,9 @@ COMMON_OBJS = \ $O\NewHandler.obj \ $O\Sha1Reg.obj \ $O\Sha256Reg.obj \ + $O\Sha3Reg.obj \ + $O\Sha512Reg.obj \ + $O\Sha512Prepare.obj \ $O\StringConvert.obj \ $O\StringToInt.obj \ $O\UTFConvert.obj \ @@ -274,6 +278,7 @@ C_OBJS = \ $O\Lzma2Enc.obj \ $O\LzmaDec.obj \ $O\LzmaEnc.obj \ + $O\Md5.obj \ $O\MtCoder.obj \ $O\MtDec.obj \ $O\Ppmd7.obj \ @@ -283,6 +288,9 @@ C_OBJS = \ $O\Ppmd8.obj \ $O\Ppmd8Dec.obj \ $O\Ppmd8Enc.obj \ + $O\Sha3.obj \ + $O\Sha512.obj \ + $O\Sha512Opt.obj \ $O\Sort.obj \ $O\SwapBytes.obj \ $O\Threads.obj \ diff --git a/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak b/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak index ff5a3f9..746aaff 100644 --- a/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak +++ b/CPP/7zip/Bundles/Format7zF/Arc_gcc.mak @@ -45,6 +45,7 @@ COMMON_OBJS = \ $O/DynLimBuf.o \ $O/IntToString.o \ $O/LzFindPrepare.o \ + $O/Md5Reg.o \ $O/MyMap.o \ $O/MyString.o \ $O/MyVector.o \ @@ -54,6 +55,9 @@ COMMON_OBJS = \ $O/Sha1Reg.o \ $O/Sha256Prepare.o \ $O/Sha256Reg.o \ + $O/Sha3Reg.o \ + $O/Sha512Prepare.o \ + $O/Sha512Reg.o \ $O/StringConvert.o \ $O/StringToInt.o \ $O/UTFConvert.o \ @@ -337,6 +341,7 @@ C_OBJS = \ $O/Lzma2Enc.o \ $O/LzmaDec.o \ $O/LzmaEnc.o \ + $O/Md5.o \ $O/MtCoder.o \ $O/MtDec.o \ $O/Ppmd7.o \ @@ -350,6 +355,9 @@ C_OBJS = \ $O/Sha1Opt.o \ $O/Sha256.o \ $O/Sha256Opt.o \ + $O/Sha3.o \ + $O/Sha512.o \ + $O/Sha512Opt.o \ $O/Sort.o \ $O/SwapBytes.o \ $O/Xxh64.o \ diff --git a/CPP/7zip/Bundles/Format7zF/Format7z.dsp b/CPP/7zip/Bundles/Format7zF/Format7z.dsp index 6e28288..0bf976c 100644 --- a/CPP/7zip/Bundles/Format7zF/Format7z.dsp +++ b/CPP/7zip/Bundles/Format7zF/Format7z.dsp @@ -287,6 +287,10 @@ SOURCE=..\..\..\Common\LzFindPrepare.cpp # End Source File # Begin Source File +SOURCE=..\..\..\Common\Md5Reg.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\MyBuffer.h # End Source File # Begin Source File @@ -383,6 +387,18 @@ SOURCE=..\..\..\Common\Sha256Reg.cpp # End Source File # Begin Source File +SOURCE=..\..\..\Common\Sha3Reg.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha512Prepare.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Sha512Reg.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\Common\StringConvert.cpp # End Source File # Begin Source File @@ -2029,6 +2045,26 @@ SOURCE=..\..\..\..\C\LzmaEnc.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Md5.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Md5.h +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\MtCoder.c # SUBTRACT CPP /YX /Yc /Yu # End Source File @@ -2230,6 +2266,62 @@ SOURCE=..\..\..\..\C\Sha256.h # End Source File # Begin Source File +SOURCE=..\..\..\..\C\Sha3.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha3.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha512.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha512.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sha512Opt.c + +!IF "$(CFG)" == "7z - Win32 Release" + +# ADD CPP /O2 +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "7z - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ENDIF + +# End Source File +# Begin Source File + SOURCE=..\..\..\..\C\Sort.c !IF "$(CFG)" == "7z - Win32 Release" diff --git a/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp b/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp index b4bd2de..e43e8b1 100644 --- a/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp +++ b/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp @@ -59,13 +59,13 @@ static const char * const kHelpString = " b : Benchmark\n" "\n" " -a{N} : set compression mode : [0, 1] : default = 1 (max)\n" - " -d{N} : set dictionary size : [12, 30] : default = 24 (16 MiB)\n" + " -d{N} : set dictionary size : [12, 31] : default = 24 (16 MiB)\n" " -fb{N} : set number of fast bytes : [5, 273] : default = 128\n" " -mc{N} : set number of cycles for match finder\n" " -lc{N} : set number of literal context bits : [0, 8] : default = 3\n" " -lp{N} : set number of literal pos bits : [0, 4] : default = 0\n" " -pb{N} : set number of pos bits : [0, 4] : default = 2\n" - " -mf{M} : set match finder: [hc4, bt2, bt3, bt4] : default = bt4\n" + " -mf{M} : set match finder: [hc4, hc5, bt2, bt3, bt4, bt5] : default = bt4\n" " -mt{N} : set number of CPU threads\n" " -eos : write end of stream marker\n" " -si : read data from stdin\n" @@ -372,8 +372,8 @@ static int main2(int numArgs, const char *args[]) return 0; } - bool stdInMode = parser[NKey::kStdIn].ThereIs; - bool stdOutMode = parser[NKey::kStdOut].ThereIs; + const bool stdInMode = parser[NKey::kStdIn].ThereIs; + const bool stdOutMode = parser[NKey::kStdOut].ThereIs; if (!stdOutMode) PrintTitle(); @@ -394,7 +394,16 @@ static int main2(int numArgs, const char *args[]) UInt32 dictLog; const UString &s = parser[NKey::kDict].PostStrings[0]; dictLog = GetNumber(s); - dict = 1 << dictLog; + if (dictLog >= 32) + throw "unsupported dictionary size"; + // we only want to use dictionary sizes that are powers of 2, + // because 7-zip only recognizes such dictionary sizes in the lzma header.#if 0 +#if 0 + if (dictLog == 32) + dict = (UInt32)3840 << 20; + else +#endif + dict = (UInt32)1 << dictLog; dictDefined = true; AddProp(props2, "d", s); } @@ -522,7 +531,7 @@ static int main2(int numArgs, const char *args[]) if (encodeMode && !dictDefined) { - dict = 1 << kDictSizeLog; + dict = (UInt32)1 << kDictSizeLog; if (fileSizeDefined) { unsigned i; diff --git a/CPP/7zip/Common/CreateCoder.cpp b/CPP/7zip/Common/CreateCoder.cpp index bf7b04e..93113a0 100644 --- a/CPP/7zip/Common/CreateCoder.cpp +++ b/CPP/7zip/Common/CreateCoder.cpp @@ -35,7 +35,7 @@ void RegisterCodec(const CCodecInfo *codecInfo) throw() g_Codecs[g_NumCodecs++] = codecInfo; } -static const unsigned kNumHashersMax = 16; +static const unsigned kNumHashersMax = 32; extern unsigned g_NumHashers; unsigned g_NumHashers = 0; diff --git a/CPP/7zip/Common/MethodProps.h b/CPP/7zip/Common/MethodProps.h index 3c332d6..a52f4bc 100644 --- a/CPP/7zip/Common/MethodProps.h +++ b/CPP/7zip/Common/MethodProps.h @@ -125,7 +125,7 @@ public: UInt32 Get_Lzma_Algo() const { - int i = FindProp(NCoderPropID::kAlgorithm); + const int i = FindProp(NCoderPropID::kAlgorithm); if (i >= 0) { const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; @@ -141,11 +141,11 @@ public: if (Get_DicSize(v)) return v; const unsigned level = GetLevel(); - const UInt32 dictSize = - ( level <= 3 ? ((UInt32)1 << (level * 2 + 16)) : - ( level <= 6 ? ((UInt32)1 << (level + 19)) : - ( level <= 7 ? ((UInt32)1 << 25) : ((UInt32)1 << 26) - ))); + const UInt32 dictSize = level <= 4 ? + (UInt32)1 << (level * 2 + 16) : + level <= sizeof(size_t) / 2 + 4 ? + (UInt32)1 << (level + 20) : + (UInt32)1 << (sizeof(size_t) / 2 + 24); return dictSize; } diff --git a/CPP/7zip/Crypto/Rar5Aes.cpp b/CPP/7zip/Crypto/Rar5Aes.cpp index 26c6100..34ea4ff 100644 --- a/CPP/7zip/Crypto/Rar5Aes.cpp +++ b/CPP/7zip/Crypto/Rar5Aes.cpp @@ -8,16 +8,17 @@ #include "../../Windows/Synchronization.h" #endif -#include "Rar5Aes.h" #include "HmacSha256.h" +#include "Rar5Aes.h" + +#define MY_ALIGN_FOR_SHA256 MY_ALIGN(16) namespace NCrypto { namespace NRar5 { static const unsigned kNumIterationsLog_Max = 24; - -static const unsigned kPswCheckCsumSize = 4; -static const unsigned kCheckSize = kPswCheckSize + kPswCheckCsumSize; +static const unsigned kPswCheckCsumSize32 = 1; +static const unsigned kCheckSize32 = kPswCheckSize32 + kPswCheckCsumSize32; CKey::CKey(): _needCalc(true), @@ -27,15 +28,29 @@ CKey::CKey(): _salt[i] = 0; } +CKey::~CKey() +{ + Wipe(); +} + +void CKey::Wipe() +{ + _password.Wipe(); + Z7_memset_0_ARRAY(_salt); + // Z7_memset_0_ARRAY(_key32); + // Z7_memset_0_ARRAY(_check_Calced32); + // Z7_memset_0_ARRAY(_hashKey32); + CKeyBase::Wipe(); +} + CDecoder::CDecoder(): CAesCbcDecoder(kAesKeySize) {} static unsigned ReadVarInt(const Byte *p, unsigned maxSize, UInt64 *val) { *val = 0; - for (unsigned i = 0; i < maxSize && i < 10;) { - Byte b = p[i]; + const Byte b = p[i]; *val |= (UInt64)(b & 0x7F) << (7 * i); i++; if ((b & 0x80) == 0) @@ -64,7 +79,7 @@ HRESULT CDecoder::SetDecoderProps(const Byte *p, unsigned size, bool includeIV, size -= num; bool isCheck = IsThereCheck(); - if (size != 1 + kSaltSize + (includeIV ? AES_BLOCK_SIZE : 0) + (unsigned)(isCheck ? kCheckSize : 0)) + if (size != 1 + kSaltSize + (includeIV ? AES_BLOCK_SIZE : 0) + (unsigned)(isCheck ? kCheckSize32 * 4 : 0)) return E_NOTIMPL; if (_numIterationsLog != p[0]) @@ -93,19 +108,21 @@ HRESULT CDecoder::SetDecoderProps(const Byte *p, unsigned size, bool includeIV, if (isCheck) { - memcpy(_check, p, kPswCheckSize); + memcpy(_check32, p, sizeof(_check32)); + MY_ALIGN_FOR_SHA256 CSha256 sha; + MY_ALIGN_FOR_SHA256 Byte digest[SHA256_DIGEST_SIZE]; Sha256_Init(&sha); - Sha256_Update(&sha, _check, kPswCheckSize); + Sha256_Update(&sha, (const Byte *)_check32, sizeof(_check32)); Sha256_Final(&sha, digest); - _canCheck = (memcmp(digest, p + kPswCheckSize, kPswCheckCsumSize) == 0); + _canCheck = (memcmp(digest, p + sizeof(_check32), kPswCheckCsumSize32 * 4) == 0); if (_canCheck && isService) { // There was bug in RAR 5.21- : PswCheck field in service records ("QO") contained zeros. // so we disable password checking for such bad records. _canCheck = false; - for (unsigned i = 0; i < kPswCheckSize; i++) + for (unsigned i = 0; i < kPswCheckSize32 * 4; i++) if (p[i] != 0) { _canCheck = true; @@ -132,7 +149,7 @@ void CDecoder::SetPassword(const Byte *data, size_t size) Z7_COM7F_IMF(CDecoder::Init()) { CalcKey_and_CheckPassword(); - RINOK(SetKey(_key, kAesKeySize)) + RINOK(SetKey((const Byte *)_key32, kAesKeySize)) RINOK(SetInitVector(_iv, AES_BLOCK_SIZE)) return CAesCoder::Init(); } @@ -140,27 +157,27 @@ Z7_COM7F_IMF(CDecoder::Init()) UInt32 CDecoder::Hmac_Convert_Crc32(UInt32 crc) const { - MY_ALIGN (16) + MY_ALIGN_FOR_SHA256 NSha256::CHmac ctx; - ctx.SetKey(_hashKey, NSha256::kDigestSize); + ctx.SetKey((const Byte *)_hashKey32, NSha256::kDigestSize); UInt32 v; - SetUi32(&v, crc) + SetUi32a(&v, crc) ctx.Update((const Byte *)&v, 4); - MY_ALIGN (16) + MY_ALIGN_FOR_SHA256 UInt32 h[SHA256_NUM_DIGEST_WORDS]; ctx.Final((Byte *)h); crc = 0; for (unsigned i = 0; i < SHA256_NUM_DIGEST_WORDS; i++) - crc ^= (UInt32)GetUi32(h + i); + crc ^= (UInt32)GetUi32a(h + i); return crc; } void CDecoder::Hmac_Convert_32Bytes(Byte *data) const { - MY_ALIGN (16) + MY_ALIGN_FOR_SHA256 NSha256::CHmac ctx; - ctx.SetKey(_hashKey, NSha256::kDigestSize); + ctx.SetKey((const Byte *)_hashKey32, NSha256::kDigestSize); ctx.Update(data, NSha256::kDigestSize); ctx.Final(data); } @@ -190,30 +207,31 @@ bool CDecoder::CalcKey_and_CheckPassword() if (_needCalc) { - Byte pswCheck[SHA256_DIGEST_SIZE]; - + MY_ALIGN_FOR_SHA256 + UInt32 pswCheck[SHA256_NUM_DIGEST_WORDS]; { // Pbkdf HMAC-SHA-256 - - MY_ALIGN (16) + MY_ALIGN_FOR_SHA256 NSha256::CHmac baseCtx; baseCtx.SetKey(_password, _password.Size()); - - NSha256::CHmac ctx = baseCtx; + MY_ALIGN_FOR_SHA256 + NSha256::CHmac ctx; + ctx = baseCtx; ctx.Update(_salt, sizeof(_salt)); - MY_ALIGN (16) - Byte u[NSha256::kDigestSize]; - MY_ALIGN (16) - Byte key[NSha256::kDigestSize]; + MY_ALIGN_FOR_SHA256 + UInt32 u[SHA256_NUM_DIGEST_WORDS]; + MY_ALIGN_FOR_SHA256 + UInt32 key[SHA256_NUM_DIGEST_WORDS]; - u[0] = 0; - u[1] = 0; - u[2] = 0; - u[3] = 1; + // u[0] = 0; + // u[1] = 0; + // u[2] = 0; + // u[3] = 1; + SetUi32a(u, 0x1000000) - ctx.Update(u, 4); - ctx.Final(u); + ctx.Update((const Byte *)(const void *)u, 4); + ctx.Final((Byte *)(void *)u); memcpy(key, u, NSha256::kDigestSize); @@ -221,35 +239,24 @@ bool CDecoder::CalcKey_and_CheckPassword() for (unsigned i = 0; i < 3; i++) { - UInt32 j = numIterations; - - for (; j != 0; j--) + for (; numIterations != 0; numIterations--) { ctx = baseCtx; - ctx.Update(u, NSha256::kDigestSize); - ctx.Final(u); - for (unsigned s = 0; s < NSha256::kDigestSize; s++) + ctx.Update((const Byte *)(const void *)u, NSha256::kDigestSize); + ctx.Final((Byte *)(void *)u); + for (unsigned s = 0; s < Z7_ARRAY_SIZE(u); s++) key[s] ^= u[s]; } // RAR uses additional iterations for additional keys - memcpy((i == 0 ? _key : (i == 1 ? _hashKey : pswCheck)), key, NSha256::kDigestSize); + memcpy(i == 0 ? _key32 : i == 1 ? _hashKey32 : pswCheck, + key, NSha256::kDigestSize); numIterations = 16; } } - - { - unsigned i; - - for (i = 0; i < kPswCheckSize; i++) - _check_Calced[i] = pswCheck[i]; - - for (i = kPswCheckSize; i < SHA256_DIGEST_SIZE; i++) - _check_Calced[i & (kPswCheckSize - 1)] ^= pswCheck[i]; - } - + _check_Calced32[0] = pswCheck[0] ^ pswCheck[2] ^ pswCheck[4] ^ pswCheck[6]; + _check_Calced32[1] = pswCheck[1] ^ pswCheck[3] ^ pswCheck[5] ^ pswCheck[7]; _needCalc = false; - { MT_LOCK g_Key = *this; @@ -258,7 +265,7 @@ bool CDecoder::CalcKey_and_CheckPassword() } if (IsThereCheck() && _canCheck) - return (memcmp(_check_Calced, _check, kPswCheckSize) == 0); + return memcmp(_check_Calced32, _check32, sizeof(_check32)) == 0; return true; } diff --git a/CPP/7zip/Crypto/Rar5Aes.h b/CPP/7zip/Crypto/Rar5Aes.h index 3cd7992..c6059aa 100644 --- a/CPP/7zip/Crypto/Rar5Aes.h +++ b/CPP/7zip/Crypto/Rar5Aes.h @@ -13,7 +13,7 @@ namespace NCrypto { namespace NRar5 { const unsigned kSaltSize = 16; -const unsigned kPswCheckSize = 8; +const unsigned kPswCheckSize32 = 2; const unsigned kAesKeySize = 32; namespace NCryptoFlags @@ -22,48 +22,47 @@ namespace NCryptoFlags const unsigned kUseMAC = 1 << 1; } -struct CKey +struct CKeyBase { - bool _needCalc; +protected: + UInt32 _key32[kAesKeySize / 4]; + UInt32 _hashKey32[SHA256_NUM_DIGEST_WORDS]; + UInt32 _check_Calced32[kPswCheckSize32]; - unsigned _numIterationsLog; - Byte _salt[kSaltSize]; - CByteBuffer _password; + void Wipe() + { + memset(this, 0, sizeof(*this)); + } - Byte _key[kAesKeySize]; - Byte _check_Calced[kPswCheckSize]; - Byte _hashKey[SHA256_DIGEST_SIZE]; - - void CopyCalcedKeysFrom(const CKey &k) + void CopyCalcedKeysFrom(const CKeyBase &k) { - memcpy(_key, k._key, sizeof(_key)); - memcpy(_check_Calced, k._check_Calced, sizeof(_check_Calced)); - memcpy(_hashKey, k._hashKey, sizeof(_hashKey)); + *this = k; } +}; +struct CKey: public CKeyBase +{ + CByteBuffer _password; + bool _needCalc; + unsigned _numIterationsLog; + Byte _salt[kSaltSize]; + bool IsKeyEqualTo(const CKey &key) { - return (_numIterationsLog == key._numIterationsLog + return _numIterationsLog == key._numIterationsLog && memcmp(_salt, key._salt, sizeof(_salt)) == 0 - && _password == key._password); + && _password == key._password; } - - CKey(); - void Wipe() - { - _password.Wipe(); - Z7_memset_0_ARRAY(_salt); - Z7_memset_0_ARRAY(_key); - Z7_memset_0_ARRAY(_check_Calced); - Z7_memset_0_ARRAY(_hashKey); - } + CKey(); + ~CKey(); + + void Wipe(); #ifdef Z7_CPP_IS_SUPPORTED_default // CKey(const CKey &) = default; CKey& operator =(const CKey &) = default; #endif - ~CKey() { Wipe(); } }; @@ -71,11 +70,11 @@ class CDecoder Z7_final: public CAesCbcDecoder, public CKey { - Byte _check[kPswCheckSize]; + UInt32 _check32[kPswCheckSize32]; bool _canCheck; UInt64 Flags; - bool IsThereCheck() const { return ((Flags & NCryptoFlags::kPswCheck) != 0); } + bool IsThereCheck() const { return (Flags & NCryptoFlags::kPswCheck) != 0; } public: Byte _iv[AES_BLOCK_SIZE]; diff --git a/CPP/7zip/Crypto/RarAes.cpp b/CPP/7zip/Crypto/RarAes.cpp index 878ea3a..e63f82c 100644 --- a/CPP/7zip/Crypto/RarAes.cpp +++ b/CPP/7zip/Crypto/RarAes.cpp @@ -111,7 +111,8 @@ static void UpdatePswDataSha1(Byte *data) for (i = 16; i < 80; i++) { - WW(i) = rotlFixed(WW((i)-3) ^ WW((i)-8) ^ WW((i)-14) ^ WW((i)-16), 1); + const UInt32 t = WW((i)-3) ^ WW((i)-8) ^ WW((i)-14) ^ WW((i)-16); + WW(i) = rotlFixed(t, 1); } for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++) @@ -128,6 +129,7 @@ void CDecoder::CalcKey() const unsigned kSaltSize = 8; + MY_ALIGN (16) Byte buf[kPasswordLen_Bytes_MAX + kSaltSize]; if (_password.Size() != 0) @@ -148,7 +150,7 @@ void CDecoder::CalcKey() MY_ALIGN (16) Byte digest[NSha1::kDigestSize]; // rar reverts hash for sha. - const UInt32 kNumRounds = ((UInt32)1 << 18); + const UInt32 kNumRounds = (UInt32)1 << 18; UInt32 pos = 0; UInt32 i; for (i = 0; i < kNumRounds; i++) @@ -171,8 +173,14 @@ void CDecoder::CalcKey() } } pos += (UInt32)rawSize; +#if 1 + UInt32 pswNum; + SetUi32a(&pswNum, i) + sha.Update((const Byte *)&pswNum, 3); +#else Byte pswNum[3] = { (Byte)i, (Byte)(i >> 8), (Byte)(i >> 16) }; sha.Update(pswNum, 3); +#endif pos += 3; if (i % (kNumRounds / 16) == 0) { diff --git a/CPP/7zip/Crypto/ZipStrong.cpp b/CPP/7zip/Crypto/ZipStrong.cpp index 59698d8..c4e8311 100644 --- a/CPP/7zip/Crypto/ZipStrong.cpp +++ b/CPP/7zip/Crypto/ZipStrong.cpp @@ -24,30 +24,31 @@ static const UInt16 kAES128 = 0x660E; if (method != AES && method != 3DES), probably we need another code. */ -static void DeriveKey2(const Byte *digest, Byte c, Byte *dest) +static void DeriveKey2(const UInt32 *digest32, Byte c, UInt32 *dest32) { + const unsigned kBufSize = 64; MY_ALIGN (16) - Byte buf[64]; - memset(buf, c, 64); - for (unsigned i = 0; i < NSha1::kDigestSize; i++) - buf[i] ^= digest[i]; + UInt32 buf32[kBufSize / 4]; + memset(buf32, c, kBufSize); + for (unsigned i = 0; i < NSha1::kNumDigestWords; i++) + buf32[i] ^= digest32[i]; MY_ALIGN (16) NSha1::CContext sha; sha.Init(); - sha.Update(buf, 64); - sha.Final(dest); + sha.Update((const Byte *)buf32, kBufSize); + sha.Final((Byte *)dest32); } static void DeriveKey(NSha1::CContext &sha, Byte *key) { MY_ALIGN (16) - Byte digest[NSha1::kDigestSize]; - sha.Final(digest); + UInt32 digest32[NSha1::kNumDigestWords]; + sha.Final((Byte *)digest32); MY_ALIGN (16) - Byte temp[NSha1::kDigestSize * 2]; - DeriveKey2(digest, 0x36, temp); - DeriveKey2(digest, 0x5C, temp + NSha1::kDigestSize); - memcpy(key, temp, 32); + UInt32 temp32[NSha1::kNumDigestWords * 2]; + DeriveKey2(digest32, 0x36, temp32); + DeriveKey2(digest32, 0x5C, temp32 + NSha1::kNumDigestWords); + memcpy(key, temp32, 32); } void CKeyInfo::SetPassword(const Byte *data, UInt32 size) @@ -122,24 +123,24 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK) passwOK = false; if (_remSize < 16) return E_NOTIMPL; - Byte *p = _bufAligned; - const unsigned format = GetUi16(p); + Byte * const p = _bufAligned; + const unsigned format = GetUi16a(p); if (format != 3) return E_NOTIMPL; - unsigned algId = GetUi16(p + 2); + unsigned algId = GetUi16a(p + 2); if (algId < kAES128) return E_NOTIMPL; algId -= kAES128; if (algId > 2) return E_NOTIMPL; - const unsigned bitLen = GetUi16(p + 4); - const unsigned flags = GetUi16(p + 6); + const unsigned bitLen = GetUi16a(p + 4); + const unsigned flags = GetUi16a(p + 6); if (algId * 64 + 128 != bitLen) return E_NOTIMPL; _key.KeySize = 16 + algId * 8; const bool cert = ((flags & 2) != 0); - if ((flags & 0x4000) != 0) + if (flags & 0x4000) { // Use 3DES for rd data return E_NOTIMPL; @@ -155,7 +156,7 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK) return E_NOTIMPL; } - UInt32 rdSize = GetUi16(p + 8); + UInt32 rdSize = GetUi16a(p + 8); if (rdSize + 16 > _remSize) return E_NOTIMPL; @@ -174,7 +175,7 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK) // PKCS7 padding if (rdSize < kPadSize) return E_NOTIMPL; - if ((rdSize & (kPadSize - 1)) != 0) + if (rdSize & (kPadSize - 1)) return E_NOTIMPL; } diff --git a/CPP/7zip/GuiCommon.rc b/CPP/7zip/GuiCommon.rc index 95654b6..bf8ad8b 100644 --- a/CPP/7zip/GuiCommon.rc +++ b/CPP/7zip/GuiCommon.rc @@ -115,5 +115,5 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US _x + _xSize, _y, 8, 12 // these values are unused -#define OPTIONS_PAGE_XC_SIZE 280 +#define OPTIONS_PAGE_XC_SIZE 300 #define OPTIONS_PAGE_YC_SIZE 280 diff --git a/CPP/7zip/Guid.txt b/CPP/7zip/Guid.txt index abbaf20..fbae89c 100644 --- a/CPP/7zip/Guid.txt +++ b/CPP/7zip/Guid.txt @@ -20,6 +20,8 @@ 10 IFolderArchiveUpdateCallback2 11 IFolderScanProgress 12 IFolderSetZoneIdMode + 13 IFolderSetZoneIdFile + 14 IFolderArchiveUpdateCallback_MoveArc 20 IFileExtractCallback.h::IGetProp 30 IFileExtractCallback.h::IFolderExtractToStreamCallback (old) diff --git a/CPP/7zip/UI/Agent/Agent.cpp b/CPP/7zip/UI/Agent/Agent.cpp index eb77f25..46b740a 100644 --- a/CPP/7zip/UI/Agent/Agent.cpp +++ b/CPP/7zip/UI/Agent/Agent.cpp @@ -1516,6 +1516,8 @@ Z7_COM7F_IMF(CAgentFolder::Extract(const UInt32 *indices, if (_zoneMode != NExtract::NZoneIdMode::kNone) { ReadZoneFile_Of_BaseFile(us2fs(_agentSpec->_archiveFilePath), extractCallbackSpec->ZoneBuf); + if (_zoneBuf.Size() != 0) + extractCallbackSpec->ZoneBuf = _zoneBuf; } #endif diff --git a/CPP/7zip/UI/Agent/Agent.h b/CPP/7zip/UI/Agent/Agent.h index ea81aa8..a63e459 100644 --- a/CPP/7zip/UI/Agent/Agent.h +++ b/CPP/7zip/UI/Agent/Agent.h @@ -60,6 +60,7 @@ class CAgentFolder Z7_final: public IArchiveFolderInternal, public IInArchiveGetStream, public IFolderSetZoneIdMode, + public IFolderSetZoneIdFile, public IFolderOperations, public IFolderSetFlatMode, public CMyUnknownImp @@ -75,6 +76,7 @@ class CAgentFolder Z7_final: Z7_COM_QI_ENTRY(IArchiveFolderInternal) Z7_COM_QI_ENTRY(IInArchiveGetStream) Z7_COM_QI_ENTRY(IFolderSetZoneIdMode) + Z7_COM_QI_ENTRY(IFolderSetZoneIdFile) Z7_COM_QI_ENTRY(IFolderOperations) Z7_COM_QI_ENTRY(IFolderSetFlatMode) Z7_COM_QI_END @@ -91,6 +93,7 @@ class CAgentFolder Z7_final: Z7_IFACE_COM7_IMP(IArchiveFolderInternal) Z7_IFACE_COM7_IMP(IInArchiveGetStream) Z7_IFACE_COM7_IMP(IFolderSetZoneIdMode) + Z7_IFACE_COM7_IMP(IFolderSetZoneIdFile) Z7_IFACE_COM7_IMP(IFolderOperations) Z7_IFACE_COM7_IMP(IFolderSetFlatMode) @@ -106,11 +109,11 @@ public: int CompareItems2(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw); CAgentFolder(): - _proxyDirIndex(0), _isAltStreamFolder(false), _flatMode(false), - _loadAltStreams(false) // _loadAltStreams alt streams works in flat mode, but we don't use it now - , _zoneMode(NExtract::NZoneIdMode::kNone) + _loadAltStreams(false), // _loadAltStreams alt streams works in flat mode, but we don't use it now + _proxyDirIndex(0), + _zoneMode(NExtract::NZoneIdMode::kNone) /* , _replaceAltStreamCharsMode(0) */ {} @@ -145,21 +148,23 @@ public: UString GetFullPrefix(UInt32 index) const; // relative too root folder of archive public: + bool _isAltStreamFolder; + bool _flatMode; + bool _loadAltStreams; // in Flat mode const CProxyArc *_proxy; const CProxyArc2 *_proxy2; unsigned _proxyDirIndex; - bool _isAltStreamFolder; + NExtract::NZoneIdMode::EEnum _zoneMode; + CByteBuffer _zoneBuf; + // Int32 _replaceAltStreamCharsMode; // CMyComPtr _parentFolder; CMyComPtr _agent; CAgent *_agentSpec; - CRecordVector _items; - bool _flatMode; - bool _loadAltStreams; // in Flat mode - // Int32 _replaceAltStreamCharsMode; - NExtract::NZoneIdMode::EEnum _zoneMode; }; + + class CAgent Z7_final: public IInFolderArchive, public IFolderArcProps, @@ -213,22 +218,22 @@ public: CProxyArc2 *_proxy2; CArchiveLink _archiveLink; - bool ThereIsPathProp; - // bool ThereIsAltStreamProp; - UString ArchiveType; FStringVector _names; FString _folderPrefix; // for new files from disk - bool _updatePathPrefix_is_AltFolder; UString _updatePathPrefix; CAgentFolder *_agentFolder; - UString _archiveFilePath; + UString _archiveFilePath; // it can be path of non-existing file if file is virtual + DWORD _attrib; + bool _updatePathPrefix_is_AltFolder; + bool ThereIsPathProp; bool _isDeviceFile; bool _isHashHandler; + FString _hashBaseFolderPrefix; #ifndef Z7_EXTRACT_ONLY diff --git a/CPP/7zip/UI/Agent/ArchiveFolder.cpp b/CPP/7zip/UI/Agent/ArchiveFolder.cpp index 89b20dc..eea681c 100644 --- a/CPP/7zip/UI/Agent/ArchiveFolder.cpp +++ b/CPP/7zip/UI/Agent/ArchiveFolder.cpp @@ -22,6 +22,12 @@ Z7_COM7F_IMF(CAgentFolder::SetZoneIdMode(NExtract::NZoneIdMode::EEnum zoneMode)) return S_OK; } +Z7_COM7F_IMF(CAgentFolder::SetZoneIdFile(const Byte *data, UInt32 size)) +{ + _zoneBuf.CopyFrom(data, size); + return S_OK; +} + Z7_COM7F_IMF(CAgentFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems, Int32 includeAltStreams, Int32 replaceAltStreamCharsMode, diff --git a/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp b/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp index 0189224..1da6601 100644 --- a/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp +++ b/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp @@ -62,6 +62,33 @@ static bool Delete_EmptyFolder_And_EmptySubFolders(const FString &path) return RemoveDir(path); } + + +struct C_CopyFileProgress_to_FolderCallback_MoveArc Z7_final: + public ICopyFileProgress +{ + IFolderArchiveUpdateCallback_MoveArc *Callback; + HRESULT CallbackResult; + + virtual DWORD CopyFileProgress(UInt64 total, UInt64 current) Z7_override + { + HRESULT res = Callback->MoveArc_Progress(total, current); + CallbackResult = res; + // we can ignore E_ABORT here, because we update archive, + // and we want to get correct archive after updating + if (res == E_ABORT) + res = S_OK; + return res == S_OK ? PROGRESS_CONTINUE : PROGRESS_CANCEL; + } + + C_CopyFileProgress_to_FolderCallback_MoveArc( + IFolderArchiveUpdateCallback_MoveArc *callback) : + Callback(callback), + CallbackResult(S_OK) + {} +}; + + HRESULT CAgentFolder::CommonUpdateOperation( AGENT_OP operation, bool moveMode, @@ -159,8 +186,51 @@ HRESULT CAgentFolder::CommonUpdateOperation( // now: we reopen archive after close // m_FolderItem = NULL; + _items.Clear(); + _proxyDirIndex = k_Proxy_RootDirIndex; + + CMyComPtr updateCallback_MoveArc; + if (progress) + progress->QueryInterface(IID_IFolderArchiveUpdateCallback_MoveArc, (void **)&updateCallback_MoveArc); - const HRESULT res = tempFile.MoveToOriginal(true); + HRESULT res; + if (updateCallback_MoveArc) + { + const FString &tempFilePath = tempFile.Get_TempFilePath(); + UInt64 totalSize = 0; + { + NFind::CFileInfo fi; + if (fi.Find(tempFilePath)) + totalSize = fi.Size; + } + RINOK(updateCallback_MoveArc->MoveArc_Start( + fs2us(tempFilePath), + fs2us(tempFile.Get_OriginalFilePath()), + totalSize, + 1)) // updateMode + + C_CopyFileProgress_to_FolderCallback_MoveArc prox(updateCallback_MoveArc); + res = tempFile.MoveToOriginal( + true, // deleteOriginal + &prox); + if (res == S_OK) + { + res = updateCallback_MoveArc->MoveArc_Finish(); + // we don't return after E_ABORT here, because + // we want to reopen new archive still. + } + else if (prox.CallbackResult != S_OK) + res = prox.CallbackResult; + + // if updating callback returned E_ABORT, + // then openCallback still can return E_ABORT also. + // So ReOpen() will return with E_ABORT. + // But we want to open archive still. + // And Before_ArcReopen() call will clear user break status in that case. + RINOK(updateCallback_MoveArc->Before_ArcReopen()) + } + else + res = tempFile.MoveToOriginal(true); // deleteOriginal // RINOK(res); if (res == S_OK) @@ -189,10 +259,10 @@ HRESULT CAgentFolder::CommonUpdateOperation( } // CAgent::ReOpen() deletes _proxy and _proxy2 - _items.Clear(); + // _items.Clear(); _proxy = NULL; _proxy2 = NULL; - _proxyDirIndex = k_Proxy_RootDirIndex; + // _proxyDirIndex = k_Proxy_RootDirIndex; _isAltStreamFolder = false; diff --git a/CPP/7zip/UI/Agent/IFolderArchive.h b/CPP/7zip/UI/Agent/IFolderArchive.h index 55f1423..12b900f 100644 --- a/CPP/7zip/UI/Agent/IFolderArchive.h +++ b/CPP/7zip/UI/Agent/IFolderArchive.h @@ -103,5 +103,21 @@ Z7_IFACE_CONSTR_FOLDERARC(IFolderScanProgress, 0x11) Z7_IFACE_CONSTR_FOLDERARC(IFolderSetZoneIdMode, 0x12) +#define Z7_IFACEM_IFolderSetZoneIdFile(x) \ + x(SetZoneIdFile(const Byte *data, UInt32 size)) \ + +Z7_IFACE_CONSTR_FOLDERARC(IFolderSetZoneIdFile, 0x13) + + +// if the caller calls Before_ArcReopen(), the callee must +// clear user break status, because the caller want to open archive still. +#define Z7_IFACEM_IFolderArchiveUpdateCallback_MoveArc(x) \ + x(MoveArc_Start(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 size, Int32 updateMode)) \ + x(MoveArc_Progress(UInt64 totalSize, UInt64 currentSize)) \ + x(MoveArc_Finish()) \ + x(Before_ArcReopen()) \ + +Z7_IFACE_CONSTR_FOLDERARC(IFolderArchiveUpdateCallback_MoveArc, 0x14) + Z7_PURE_INTERFACES_END #endif diff --git a/CPP/7zip/UI/Client7z/makefile.gcc b/CPP/7zip/UI/Client7z/makefile.gcc index 3f97205..fe27011 100644 --- a/CPP/7zip/UI/Client7z/makefile.gcc +++ b/CPP/7zip/UI/Client7z/makefile.gcc @@ -57,8 +57,11 @@ WIN_OBJS = \ 7ZIP_COMMON_OBJS = \ $O/FileStreams.o \ +C_OBJS = \ + $O/Alloc.o \ OBJS = \ + $(C_OBJS) \ $(COMMON_OBJS) \ $(WIN_OBJS) \ $(SYS_OBJS) \ diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp index 2d32694..67ea29c 100644 --- a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp +++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp @@ -140,21 +140,25 @@ static bool FindExt2(const char *p, const UString &name) } -static const FChar * const k_ZoneId_StreamName = FTEXT(":Zone.Identifier"); +static const char * const k_ZoneId_StreamName_With_Colon_Prefix = ":Zone.Identifier"; -void ReadZoneFile_Of_BaseFile(CFSTR fileName2, CByteBuffer &buf) +bool Is_ZoneId_StreamName(const wchar_t *s) { - FString fileName (fileName2); - fileName += k_ZoneId_StreamName; + return StringsAreEqualNoCase_Ascii(s, k_ZoneId_StreamName_With_Colon_Prefix + 1); +} +void ReadZoneFile_Of_BaseFile(CFSTR fileName, CByteBuffer &buf) +{ buf.Free(); + FString path (fileName); + path += k_ZoneId_StreamName_With_Colon_Prefix; NIO::CInFile file; - if (!file.Open(fileName)) + if (!file.Open(path)) return; UInt64 fileSize; if (!file.GetLength(fileSize)) return; - if (fileSize == 0 || fileSize >= ((UInt32)1 << 16)) + if (fileSize == 0 || fileSize >= (1u << 15)) return; buf.Alloc((size_t)fileSize); size_t processed; @@ -166,7 +170,7 @@ void ReadZoneFile_Of_BaseFile(CFSTR fileName2, CByteBuffer &buf) bool WriteZoneFile_To_BaseFile(CFSTR fileName, const CByteBuffer &buf) { FString path (fileName); - path += k_ZoneId_StreamName; + path += k_ZoneId_StreamName_With_Colon_Prefix; NIO::COutFile file; if (!file.Create_ALWAYS(path)) return false; @@ -275,16 +279,13 @@ HRESULT CArchiveExtractCallback::PrepareHardLinks(const CRecordVector *r CArchiveExtractCallback::CArchiveExtractCallback(): - _arc(NULL), - Write_CTime(true), - Write_ATime(true), - Write_MTime(true), + // Write_CTime(true), + // Write_ATime(true), + // Write_MTime(true), Is_elimPrefix_Mode(false), + _arc(NULL), _multiArchives(false) { - LocalProgressSpec = new CLocalProgress(); - _localProgress = LocalProgressSpec; - #ifdef Z7_USE_SECURITY_CODE _saclEnabled = InitLocalPrivileges(); #endif @@ -293,9 +294,9 @@ CArchiveExtractCallback::CArchiveExtractCallback(): void CArchiveExtractCallback::InitBeforeNewArchive() { - #if defined(_WIN32) && !defined(UNDER_CE) +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) ZoneBuf.Free(); - #endif +#endif } void CArchiveExtractCallback::Init( @@ -322,27 +323,20 @@ void CArchiveExtractCallback::Init( _ntOptions = ntOptions; _wildcardCensor = wildcardCensor; - _stdOutMode = stdOutMode; _testMode = testMode; - - // _progressTotal = 0; - // _progressTotal_Defined = false; - _packTotal = packSize; _progressTotal = packSize; - _progressTotal_Defined = true; - + // _progressTotal = 0; + // _progressTotal_Defined = false; + // _progressTotal_Defined = true; _extractCallback2 = extractCallback2; - /* _compressProgress.Release(); _extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress); - _callbackMessage.Release(); _extractCallback2.QueryInterface(IID_IArchiveExtractCallbackMessage2, &_callbackMessage); */ - _folderArchiveExtractCallback2.Release(); _extractCallback2.QueryInterface(IID_IFolderArchiveExtractCallback2, &_folderArchiveExtractCallback2); @@ -390,7 +384,7 @@ Z7_COM7F_IMF(CArchiveExtractCallback::SetTotal(UInt64 size)) { COM_TRY_BEGIN _progressTotal = size; - _progressTotal_Defined = true; + // _progressTotal_Defined = true; if (!_multiArchives && _extractCallback2) return _extractCallback2->SetTotal(size); return S_OK; @@ -430,7 +424,7 @@ Z7_COM7F_IMF(CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue)) if (_multiArchives) { packCur = LocalProgressSpec->InSize; - if (completeValue && _progressTotal_Defined) + if (completeValue /* && _progressTotal_Defined */) packCur += MyMultDiv64(*completeValue, _progressTotal, _packTotal); completeValue = &packCur; } @@ -443,7 +437,7 @@ Z7_COM7F_IMF(CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue)) Z7_COM7F_IMF(CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) { COM_TRY_BEGIN - return _localProgress->SetRatioInfo(inSize, outSize); + return LocalProgressSpec.Interface()->SetRatioInfo(inSize, outSize); COM_TRY_END } @@ -582,13 +576,23 @@ HRESULT CArchiveExtractCallback::SendMessageError2(HRESULT errorCode, const char #ifndef Z7_SFX +Z7_CLASS_IMP_COM_1( + CGetProp + , IGetProp +) +public: + UInt32 IndexInArc; + const CArc *Arc; + // UString BaseName; // relative path +}; + Z7_COM7F_IMF(CGetProp::GetProp(PROPID propID, PROPVARIANT *value)) { /* - if (propID == kpidName) + if (propID == kpidBaseName) { COM_TRY_BEGIN - NCOM::CPropVariant prop = Name; + NCOM::CPropVariant prop = BaseName; prop.Detach(value); return S_OK; COM_TRY_END @@ -1087,7 +1091,7 @@ void CArchiveExtractCallback::GetFiTimesCAM(CFiTimesCAM &pt) pt.ATime_Defined = false; pt.MTime_Defined = false; - if (Write_MTime) + // if (Write_MTime) { if (_fi.MTime.Def) { @@ -1101,13 +1105,13 @@ void CArchiveExtractCallback::GetFiTimesCAM(CFiTimesCAM &pt) } } - if (Write_CTime && _fi.CTime.Def) + if (/* Write_CTime && */ _fi.CTime.Def) { _fi.CTime.Write_To_FiTime(pt.CTime); pt.CTime_Defined = true; } - if (Write_ATime && _fi.ATime.Def) + if (/* Write_ATime && */ _fi.ATime.Def) { _fi.ATime.Write_To_FiTime(pt.ATime); pt.ATime_Defined = true; @@ -1302,7 +1306,7 @@ HRESULT CArchiveExtractCallback::CheckExistFile(FString &fullProcessedPath, bool { #if defined(_WIN32) && !defined(UNDER_CE) // we need to clear READ-ONLY of parent before creating alt stream - int colonPos = NName::FindAltStreamColon(fullProcessedPath); + const int colonPos = NName::FindAltStreamColon(fullProcessedPath); if (colonPos >= 0 && fullProcessedPath[(unsigned)colonPos + 1] != 0) { FString parentFsPath (fullProcessedPath); @@ -1311,7 +1315,11 @@ HRESULT CArchiveExtractCallback::CheckExistFile(FString &fullProcessedPath, bool if (parentFi.Find(parentFsPath)) { if (parentFi.IsReadOnly()) + { + _altStream_NeedRestore_Attrib_for_parentFsPath = parentFsPath; + _altStream_NeedRestore_AttribVal = parentFi.Attrib; SetFileAttrib(parentFsPath, parentFi.Attrib & ~(DWORD)FILE_ATTRIBUTE_READONLY); + } } } #endif // defined(_WIN32) && !defined(UNDER_CE) @@ -1607,37 +1615,37 @@ Z7_COM7F_IMF(CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre _bufPtrSeqOutStream.Release(); _encrypted = false; - _position = 0; _isSplit = false; - - _curSize = 0; _curSize_Defined = false; _fileLength_WasSet = false; - _fileLength_that_WasSet = 0; - _index = index; - - _diskFilePath.Empty(); - _isRenamed = false; - // _fi.Clear(); - + _extractMode = false; // _is_SymLink_in_Data = false; _is_SymLink_in_Data_Linux = false; - _needSetAttrib = false; _isSymLinkCreated = false; _itemFailure = false; - _some_pathParts_wereRemoved = false; // _op_WasReported = false; + _position = 0; + _curSize = 0; + _fileLength_that_WasSet = 0; + _index = index; + +#if defined(_WIN32) && !defined(UNDER_CE) + _altStream_NeedRestore_AttribVal = 0; + _altStream_NeedRestore_Attrib_for_parentFsPath.Empty(); +#endif + + _diskFilePath.Empty(); + #ifdef SUPPORT_LINKS // _copyFile_Path.Empty(); _link.Clear(); #endif - _extractMode = false; switch (askExtractMode) { @@ -1692,6 +1700,19 @@ Z7_COM7F_IMF(CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre return S_OK; } +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) + if (askExtractMode == NArchive::NExtract::NAskMode::kExtract + && !_testMode + && _item.IsAltStream + && ZoneBuf.Size() != 0 + && Is_ZoneId_StreamName(_item.AltStreamName)) + if (ZoneMode != NExtract::NZoneIdMode::kOffice + || _item.PathParts.IsEmpty() + || FindExt2(kOfficeExtensions, _item.PathParts.Back())) + return S_OK; +#endif + + #ifndef Z7_SFX if (_use_baseParentFolder_mode) { @@ -1810,15 +1831,11 @@ Z7_COM7F_IMF(CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre if (ExtractToStreamCallback) { - if (!GetProp) - { - GetProp_Spec = new CGetProp; - GetProp = GetProp_Spec; - } - GetProp_Spec->Arc = _arc; - GetProp_Spec->IndexInArc = index; + CMyComPtr2_Create GetProp; + GetProp->Arc = _arc; + GetProp->IndexInArc = index; UString name (MakePathFromParts(pathParts)); - + // GetProp->BaseName = name; #ifdef SUPPORT_ALT_STREAMS if (_item.IsAltStream) { @@ -1984,6 +2001,15 @@ HRESULT CArchiveExtractCallback::CloseFile() RINOK(_outFileStreamSpec->Close()) _outFileStream.Release(); + +#if defined(_WIN32) && !defined(UNDER_CE) + if (!_altStream_NeedRestore_Attrib_for_parentFsPath.IsEmpty()) + { + SetFileAttrib(_altStream_NeedRestore_Attrib_for_parentFsPath, _altStream_NeedRestore_AttribVal); + _altStream_NeedRestore_Attrib_for_parentFsPath.Empty(); + } +#endif + return hres; } diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.h b/CPP/7zip/UI/Common/ArchiveExtractCallback.h index 7eb2f67..f3ee01c 100644 --- a/CPP/7zip/UI/Common/ArchiveExtractCallback.h +++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.h @@ -90,25 +90,10 @@ struct CExtractNtOptions } }; -#ifndef Z7_SFX - -Z7_CLASS_IMP_COM_1( - CGetProp - , IGetProp -) -public: - UInt32 IndexInArc; - const CArc *Arc; - // UString Name; // relative path -}; - -#endif #ifndef Z7_SFX #ifndef UNDER_CE - #define SUPPORT_LINKS - #endif #endif @@ -282,46 +267,44 @@ class CArchiveExtractCallback Z7_final: Z7_IFACE_COM7_IMP(IArchiveRequestMemoryUseCallback) #endif + // bool Write_CTime; + // bool Write_ATime; + // bool Write_MTime; + bool _stdOutMode; + bool _testMode; + bool _removePartsForAltStreams; +public: + bool Is_elimPrefix_Mode; +private: + const CArc *_arc; CExtractNtOptions _ntOptions; + bool _encrypted; bool _isSplit; + bool _curSize_Defined; + bool _fileLength_WasSet; + bool _isRenamed; bool _extractMode; - - bool Write_CTime; - bool Write_ATime; - bool Write_MTime; - bool _keepAndReplaceEmptyDirPrefixes; // replace them to "_"; - - bool _encrypted; - // bool _is_SymLink_in_Data; bool _is_SymLink_in_Data_Linux; // false = WIN32, true = LINUX - bool _needSetAttrib; bool _isSymLinkCreated; bool _itemFailure; - bool _some_pathParts_wereRemoved; -public: - bool Is_elimPrefix_Mode; - -private: - bool _curSize_Defined; - bool _fileLength_WasSet; - - bool _removePartsForAltStreams; - bool _stdOutMode; - bool _testMode; bool _multiArchives; + bool _keepAndReplaceEmptyDirPrefixes; // replace them to "_"; +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) + bool _saclEnabled; +#endif NExtract::NPathMode::EEnum _pathMode; NExtract::NOverwriteMode::EEnum _overwriteMode; - const NWildcard::CCensorNode *_wildcardCensor; // we need wildcard for single pass mode (stdin) CMyComPtr _extractCallback2; + const NWildcard::CCensorNode *_wildcardCensor; // we need wildcard for single pass mode (stdin) // CMyComPtr _compressProgress; // CMyComPtr _callbackMessage; CMyComPtr _folderArchiveExtractCallback2; @@ -333,15 +316,12 @@ private: #ifndef Z7_SFX CMyComPtr ExtractToStreamCallback; - CGetProp *GetProp_Spec; - CMyComPtr GetProp; CMyComPtr _requestMemoryUseCallback; #endif CReadArcItem _item; FString _diskFilePath; - UInt64 _position; struct CProcessedFileInfo { @@ -387,9 +367,17 @@ private: } } _fi; - UInt32 _index; + UInt64 _position; UInt64 _curSize; UInt64 _fileLength_that_WasSet; + UInt32 _index; + +// #ifdef SUPPORT_ALT_STREAMS +#if defined(_WIN32) && !defined(UNDER_CE) + DWORD _altStream_NeedRestore_AttribVal; + FString _altStream_NeedRestore_Attrib_for_parentFsPath; +#endif +// #endif COutFileStream *_outFileStreamSpec; CMyComPtr _outFileStream; @@ -398,9 +386,7 @@ private: CBufPtrSeqOutStream *_bufPtrSeqOutStream_Spec; CMyComPtr _bufPtrSeqOutStream; - #ifndef Z7_SFX - COutStreamWithHash *_hashStreamSpec; CMyComPtr _hashStream; bool _hashStreamWasUsed; @@ -411,11 +397,9 @@ private: UStringVector _removePathParts; - CMyComPtr _localProgress; UInt64 _packTotal; - UInt64 _progressTotal; - bool _progressTotal_Defined; + // bool _progressTotal_Defined; CObjectVector _extractedFolders; @@ -423,10 +407,6 @@ private: // CObjectVector _delayedSymLinks; #endif - #if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) - bool _saclEnabled; - #endif - void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath); HRESULT GetTime(UInt32 index, PROPID propID, CArcTime &ft); HRESULT GetUnpackSize(); @@ -441,13 +421,12 @@ public: HRESULT SendMessageError_with_LastError(const char *message, const FString &path); HRESULT SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2); -public: - #if defined(_WIN32) && !defined(UNDER_CE) +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) NExtract::NZoneIdMode::EEnum ZoneMode; CByteBuffer ZoneBuf; - #endif +#endif - CLocalProgress *LocalProgressSpec; + CMyComPtr2_Create LocalProgressSpec; UInt64 NumFolders; UInt64 NumFiles; @@ -468,11 +447,11 @@ public: _multiArchives = multiArchives; _pathMode = pathMode; _overwriteMode = overwriteMode; - #if defined(_WIN32) && !defined(UNDER_CE) +#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX) ZoneMode = zoneMode; - #else +#else UNUSED_VAR(zoneMode) - #endif +#endif _keepAndReplaceEmptyDirPrefixes = keepAndReplaceEmptyDirPrefixes; NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0; } @@ -551,7 +530,6 @@ private: void GetFiTimesCAM(CFiTimesCAM &pt); void CreateFolders(); - bool _isRenamed; HRESULT CheckExistFile(FString &fullProcessedPath, bool &needExit); HRESULT GetExtractStream(CMyComPtr &outStreamLoc, bool &needExit); HRESULT GetItem(UInt32 index); @@ -599,7 +577,8 @@ struct CArchiveExtractCallback_Closer bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item); -void ReadZoneFile_Of_BaseFile(CFSTR fileName2, CByteBuffer &buf); +bool Is_ZoneId_StreamName(const wchar_t *s); +void ReadZoneFile_Of_BaseFile(CFSTR fileName, CByteBuffer &buf); bool WriteZoneFile_To_BaseFile(CFSTR fileName, const CByteBuffer &buf); #endif diff --git a/CPP/7zip/UI/Common/Bench.cpp b/CPP/7zip/UI/Common/Bench.cpp index e1ca846..05d66aa 100644 --- a/CPP/7zip/UI/Common/Bench.cpp +++ b/CPP/7zip/UI/Common/Bench.cpp @@ -2298,6 +2298,28 @@ HRESULT CCrcInfo_Base::Generate(const Byte *data, size_t size) } +#if 1 +#define HashUpdate(hf, data, size) hf->Update(data, size) +#else +// for debug: +static void HashUpdate(IHasher *hf, const void *data, UInt32 size) +{ + for (;;) + { + if (size == 0) + return; + UInt32 size2 = (size * 0x85EBCA87) % size / 8; + // UInt32 size2 = size / 2; + if (size2 == 0) + size2 = 1; + hf->Update(data, size2); + data = (const void *)((const Byte *)data + size2); + size -= size2; + } +} +#endif + + HRESULT CCrcInfo_Base::CrcProcess(UInt64 numIterations, const UInt32 *checkSum, IHasher *hf, IBenchPrintCallback *callback) @@ -2328,7 +2350,7 @@ HRESULT CCrcInfo_Base::CrcProcess(UInt64 numIterations, const size_t rem = size - pos; const UInt32 kStep = ((UInt32)1 << 31); const UInt32 curSize = (rem < kStep) ? (UInt32)rem : kStep; - hf->Update(buf + pos, curSize); + HashUpdate(hf, buf + pos, curSize); pos += curSize; } while (pos != size); @@ -2742,14 +2764,20 @@ static const CBenchHash g_Hash[] = { 2, 128 *ARM_CRC_MUL, 0x21e207bb, "CRC32:32" }, { 2, 64 *ARM_CRC_MUL, 0x21e207bb, "CRC32:64" }, { 10, 256, 0x41b901d1, "CRC64" }, - { 10, 64, 0x43eac94f, "XXH64" }, - - { 10, 5100, 0x7913ba03, "SHA256:1" }, - { 2, CMPLX((32 * 4 + 1) * 4 + 4), 0x7913ba03, "SHA256:2" }, - - { 10, 2340, 0xff769021, "SHA1:1" }, + { 5, 64, 0x43eac94f, "XXH64" }, + { 2, 2340, 0x3398a904, "MD5" }, + { 10, 2340, 0xff769021, "SHA1:1" }, { 2, CMPLX((20 * 6 + 1) * 4 + 4), 0xff769021, "SHA1:2" }, - + { 10, 5100, 0x7913ba03, "SHA256:1" }, + { 2, CMPLX((32 * 4 + 1) * 4 + 4), 0x7913ba03, "SHA256:2" }, + { 5, 3200, 0xe7aeb394, "SHA512:1" }, + { 2, CMPLX((40 * 4 + 1) * 4 + 4), 0xe7aeb394, "SHA512:2" }, + // { 10, 3428, 0x1cc99b18, "SHAKE128" }, + // { 10, 4235, 0x74eaddc3, "SHAKE256" }, + // { 10, 4000, 0xdf3e6863, "SHA3-224" }, + { 5, 4200, 0xcecac10d, "SHA3-256" }, + // { 10, 5538, 0x4e5d9163, "SHA3-384" }, + // { 10, 8000, 0x96a58289, "SHA3-512" }, { 2, 4096, 0x85189d02, "BLAKE2sp:1" }, { 2, 1024, 0x85189d02, "BLAKE2sp:2" }, // sse2-way4-fast { 2, 512, 0x85189d02, "BLAKE2sp:3" } // avx2-way8-fast @@ -3687,7 +3715,7 @@ HRESULT Bench( return E_FAIL; UInt32 numCPUs = 1; - UInt64 ramSize = (UInt64)(sizeof(size_t)) << 29; + size_t ramSize = (size_t)sizeof(size_t) << 29; NSystem::CProcessAffinity threadsInfo; threadsInfo.InitST(); @@ -4580,6 +4608,8 @@ HRESULT Bench( if (!dictIsDefined && !onlyHashBench) { + // we use dicSizeLog and dicSizeLog_Main for data size. + // also we use it to reduce dictionary size of LZMA encoder via NCoderPropID::kReduceSize. const unsigned dicSizeLog_Main = (totalBenchMode ? 24 : 25); unsigned dicSizeLog = dicSizeLog_Main; diff --git a/CPP/7zip/UI/Common/EnumDirItems.cpp b/CPP/7zip/UI/Common/EnumDirItems.cpp index 0758547..11643ae 100644 --- a/CPP/7zip/UI/Common/EnumDirItems.cpp +++ b/CPP/7zip/UI/Common/EnumDirItems.cpp @@ -671,7 +671,7 @@ static HRESULT EnumerateForItem( } #if defined(_WIN32) - if (needAltStreams && dirItems.ScanAltStreams) + if (needAltStreams && dirItems.ScanAltStreams && !fi.IsAltStream) { RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent, phyPrefix + fi.Name, // with (fi.Name) @@ -929,7 +929,7 @@ static HRESULT EnumerateDirItems( } #if defined(_WIN32) - if (needAltStreams && dirItems.ScanAltStreams) + if (needAltStreams && dirItems.ScanAltStreams && !fi.IsAltStream) { UStringVector pathParts; pathParts.Add(fs2us(fi.Name)); diff --git a/CPP/7zip/UI/Common/HashCalc.cpp b/CPP/7zip/UI/Common/HashCalc.cpp index f3d65ef..9caac36 100644 --- a/CPP/7zip/UI/Common/HashCalc.cpp +++ b/CPP/7zip/UI/Common/HashCalc.cpp @@ -773,13 +773,21 @@ static const char * const k_CsumMethodNames[] = { "sha256" , "sha224" -// , "sha512/224" -// , "sha512/256" - , "sha512" +// , "sha512-224" +// , "sha512-256" , "sha384" + , "sha512" +// , "sha3-224" + , "sha3-256" +// , "sha3-384" +// , "sha3-512" +// , "shake128" +// , "shake256" , "sha1" , "md5" + , "blake2sp" , "blake2b" + , "xxh64" , "crc64" , "crc32" , "cksum" @@ -2076,11 +2084,27 @@ void Codecs_AddHashArcHandler(CCodecs *codecs) // ubuntu uses "SHA256SUMS" file item.AddExts(UString ( - "sha256 sha512 sha224 sha384 sha1 sha md5" - // "b2sum" + "sha256" + " sha512" + " sha384" + " sha224" + // " sha512-224" + // " sha512-256" + // " sha3-224" + " sha3-256" + // " sha3-384" + // " sha3-512" + // " shake128" + // " shake256" + " sha1" + " sha" + " md5" + " blake2sp" + " xxh64" " crc32 crc64" " asc" " cksum" + // " b2sum" ), UString()); diff --git a/CPP/7zip/UI/Common/TempFiles.cpp b/CPP/7zip/UI/Common/TempFiles.cpp index 2f86838..ad16e36 100644 --- a/CPP/7zip/UI/Common/TempFiles.cpp +++ b/CPP/7zip/UI/Common/TempFiles.cpp @@ -13,7 +13,8 @@ void CTempFiles::Clear() { while (!Paths.IsEmpty()) { - NDir::DeleteFileAlways(Paths.Back()); + if (NeedDeleteFiles) + NDir::DeleteFileAlways(Paths.Back()); Paths.DeleteBack(); } } diff --git a/CPP/7zip/UI/Common/TempFiles.h b/CPP/7zip/UI/Common/TempFiles.h index dd4ac20..83c741f 100644 --- a/CPP/7zip/UI/Common/TempFiles.h +++ b/CPP/7zip/UI/Common/TempFiles.h @@ -10,6 +10,9 @@ class CTempFiles void Clear(); public: FStringVector Paths; + bool NeedDeleteFiles; + + CTempFiles(): NeedDeleteFiles(true) {} ~CTempFiles() { Clear(); } }; diff --git a/CPP/7zip/UI/Common/Update.cpp b/CPP/7zip/UI/Common/Update.cpp index ed48605..b959a3c 100644 --- a/CPP/7zip/UI/Common/Update.cpp +++ b/CPP/7zip/UI/Common/Update.cpp @@ -1096,6 +1096,30 @@ typedef Z7_WIN_MAPISENDMAILW FAR *Z7_WIN_LPMAPISENDMAILW; #endif // _WIN32 +struct C_CopyFileProgress_to_IUpdateCallbackUI2 Z7_final: + public ICopyFileProgress +{ + IUpdateCallbackUI2 *Callback; + HRESULT CallbackResult; + // bool Disable_Break; + + virtual DWORD CopyFileProgress(UInt64 total, UInt64 current) Z7_override + { + const HRESULT res = Callback->MoveArc_Progress(total, current); + CallbackResult = res; + // if (Disable_Break && res == E_ABORT) res = S_OK; + return res == S_OK ? PROGRESS_CONTINUE : PROGRESS_CANCEL; + } + + C_CopyFileProgress_to_IUpdateCallbackUI2( + IUpdateCallbackUI2 *callback) : + Callback(callback), + CallbackResult(S_OK) + // , Disable_Break(false) + {} +}; + + HRESULT UpdateArchive( CCodecs *codecs, const CObjectVector &types, @@ -1311,7 +1335,7 @@ HRESULT UpdateArchive( return E_NOTIMPL; } - bool thereIsInArchive = arcLink.IsOpen; + const bool thereIsInArchive = arcLink.IsOpen; if (!thereIsInArchive && renameMode) return E_FAIL; @@ -1588,7 +1612,14 @@ HRESULT UpdateArchive( multiStreams.DisableDeletion(); RINOK(multiStreams.Destruct()) - tempFiles.Paths.Clear(); + // here we disable deleting of temp archives. + // note: archive moving can fail, or it can be interrupted, + // if we move new temp update from another volume. + // And we still want to keep temp archive in that case, + // because we will have deleted original archive. + tempFiles.NeedDeleteFiles = false; + // tempFiles.Paths.Clear(); + if (createTempFile) { try @@ -1603,16 +1634,29 @@ HRESULT UpdateArchive( if (!DeleteFileAlways(us2fs(arcPath))) return errorInfo.SetFromLastError("cannot delete the file", us2fs(arcPath)); } - - if (!MyMoveFile(tempPath, us2fs(arcPath))) + + UInt64 totalArcSize = 0; + { + NFind::CFileInfo fi; + if (fi.Find(tempPath)) + totalArcSize = fi.Size; + } + RINOK(callback->MoveArc_Start(fs2us(tempPath), arcPath, + totalArcSize, BoolToInt(thereIsInArchive))) + + C_CopyFileProgress_to_IUpdateCallbackUI2 prox(callback); + // if we update archive, we have removed original archive. + // So if we break archive moving, we will have only temporary archive. + // We can disable breaking here: + // prox.Disable_Break = thereIsInArchive; + + if (!MyMoveFile_with_Progress(tempPath, us2fs(arcPath), &prox)) { errorInfo.SystemError = ::GetLastError(); errorInfo.Message = "cannot move the file"; if (errorInfo.SystemError == ERROR_INVALID_PARAMETER) { - NFind::CFileInfo fi; - if (fi.Find(tempPath) && - fi.Size > (UInt32)(Int32)-1) + if (totalArcSize > (UInt32)(Int32)-1) { // bool isFsDetected = false; // if (NSystem::Is_File_LimitedBy_4GB(us2fs(arcPath), isFsDetected) || !isFsDetected) @@ -1622,10 +1666,20 @@ HRESULT UpdateArchive( } } } + // if there was no input archive, and we have operation breaking. + // then we can remove temporary archive, because we still have original uncompressed files. + if (!thereIsInArchive + && prox.CallbackResult == E_ABORT) + tempFiles.NeedDeleteFiles = true; errorInfo.FileNames.Add(tempPath); errorInfo.FileNames.Add(us2fs(arcPath)); + RINOK(prox.CallbackResult) return errorInfo.Get_HRESULT_Error(); } + + // MoveArc_Finish() can return delayed user break (E_ABORT) status, + // if callback callee ignored interruption to finish archive creation operation. + RINOK(callback->MoveArc_Finish()) /* if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_READONLY)) diff --git a/CPP/7zip/UI/Common/Update.h b/CPP/7zip/UI/Common/Update.h index a9459ff..216339a 100644 --- a/CPP/7zip/UI/Common/Update.h +++ b/CPP/7zip/UI/Common/Update.h @@ -12,8 +12,6 @@ #include "UpdateAction.h" #include "UpdateCallback.h" -#include "DirItem.h" - enum EArcNameMode { k_ArcNameMode_Smart, @@ -195,6 +193,9 @@ Z7_PURE_INTERFACES_BEGIN virtual HRESULT FinishArchive(const CFinishArchiveStat &st) x \ virtual HRESULT DeletingAfterArchiving(const FString &path, bool isDir) x \ virtual HRESULT FinishDeletingAfterArchiving() x \ + virtual HRESULT MoveArc_Start(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 size, Int32 updateMode) x \ + virtual HRESULT MoveArc_Progress(UInt64 total, UInt64 current) x \ + virtual HRESULT MoveArc_Finish() x \ DECLARE_INTERFACE(IUpdateCallbackUI2): public IUpdateCallbackUI, diff --git a/CPP/7zip/UI/Common/WorkDir.cpp b/CPP/7zip/UI/Common/WorkDir.cpp index cfec635..a492967 100644 --- a/CPP/7zip/UI/Common/WorkDir.cpp +++ b/CPP/7zip/UI/Common/WorkDir.cpp @@ -63,24 +63,22 @@ HRESULT CWorkDirTempFile::CreateTempFile(const FString &originalPath) NWorkDir::CInfo workDirInfo; workDirInfo.Load(); FString namePart; - const FString workDir = GetWorkDir(workDirInfo, originalPath, namePart); - CreateComplexDir(workDir); + FString path = GetWorkDir(workDirInfo, originalPath, namePart); + CreateComplexDir(path); + path += namePart; _outStreamSpec = new COutFileStream; OutStream = _outStreamSpec; - if (!_tempFile.Create(workDir + namePart, &_outStreamSpec->File)) - { + if (!_tempFile.Create(path, &_outStreamSpec->File)) return GetLastError_noZero_HRESULT(); - } _originalPath = originalPath; return S_OK; } -HRESULT CWorkDirTempFile::MoveToOriginal(bool deleteOriginal) +HRESULT CWorkDirTempFile::MoveToOriginal(bool deleteOriginal, + NWindows::NFile::NDir::ICopyFileProgress *progress) { OutStream.Release(); - if (!_tempFile.MoveTo(_originalPath, deleteOriginal)) - { + if (!_tempFile.MoveTo(_originalPath, deleteOriginal, progress)) return GetLastError_noZero_HRESULT(); - } return S_OK; } diff --git a/CPP/7zip/UI/Common/WorkDir.h b/CPP/7zip/UI/Common/WorkDir.h index d32ab9d..fed8c4a 100644 --- a/CPP/7zip/UI/Common/WorkDir.h +++ b/CPP/7zip/UI/Common/WorkDir.h @@ -11,7 +11,7 @@ FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FString &fileName); -class CWorkDirTempFile +class CWorkDirTempFile MY_UNCOPYABLE { FString _originalPath; NWindows::NFile::NDir::CTempFile _tempFile; @@ -19,8 +19,12 @@ class CWorkDirTempFile public: CMyComPtr OutStream; + const FString &Get_OriginalFilePath() const { return _originalPath; } + const FString &Get_TempFilePath() const { return _tempFile.GetPath(); } + HRESULT CreateTempFile(const FString &originalPath); - HRESULT MoveToOriginal(bool deleteOriginal); + HRESULT MoveToOriginal(bool deleteOriginal, + NWindows::NFile::NDir::ICopyFileProgress *progress = NULL); }; #endif diff --git a/CPP/7zip/UI/Common/ZipRegistry.cpp b/CPP/7zip/UI/Common/ZipRegistry.cpp index 73c56cf..936b888 100644 --- a/CPP/7zip/UI/Common/ZipRegistry.cpp +++ b/CPP/7zip/UI/Common/ZipRegistry.cpp @@ -45,8 +45,8 @@ static void Key_Set_UInt32(CKey &key, LPCTSTR name, UInt32 value) static void Key_Get_UInt32(CKey &key, LPCTSTR name, UInt32 &value) { - if (key.QueryValue(name, value) != ERROR_SUCCESS) - value = (UInt32)(Int32)-1; + value = (UInt32)(Int32)-1; + key.GetValue_UInt32_IfOk(name, value); } @@ -59,7 +59,7 @@ static void Key_Set_BoolPair(CKey &key, LPCTSTR name, const CBoolPair &b) static void Key_Set_bool_if_Changed(CKey &key, LPCTSTR name, bool val) { bool oldVal = false; - if (key.GetValue_IfOk(name, oldVal) == ERROR_SUCCESS) + if (key.GetValue_bool_IfOk(name, oldVal) == ERROR_SUCCESS) if (val == oldVal) return; key.SetValue(name, val); @@ -76,13 +76,13 @@ static void Key_Set_BoolPair_Delete_IfNotDef(CKey &key, LPCTSTR name, const CBoo static void Key_Get_BoolPair(CKey &key, LPCTSTR name, CBoolPair &b) { b.Val = false; - b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS); + b.Def = (key.GetValue_bool_IfOk(name, b.Val) == ERROR_SUCCESS); } static void Key_Get_BoolPair_true(CKey &key, LPCTSTR name, CBoolPair &b) { b.Val = true; - b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS); + b.Def = (key.GetValue_bool_IfOk(name, b.Val) == ERROR_SUCCESS); } namespace NExtract @@ -155,12 +155,12 @@ void CInfo::Load() key.GetValue_Strings(kPathHistory, Paths); UInt32 v; - if (key.QueryValue(kExtractMode, v) == ERROR_SUCCESS && v <= NPathMode::kAbsPaths) + if (key.GetValue_UInt32_IfOk(kExtractMode, v) == ERROR_SUCCESS && v <= NPathMode::kAbsPaths) { PathMode = (NPathMode::EEnum)v; PathMode_Force = true; } - if (key.QueryValue(kOverwriteMode, v) == ERROR_SUCCESS && v <= NOverwriteMode::kRenameExisting) + if (key.GetValue_UInt32_IfOk(kOverwriteMode, v) == ERROR_SUCCESS && v <= NOverwriteMode::kRenameExisting) { OverwriteMode = (NOverwriteMode::EEnum)v; OverwriteMode_Force = true; @@ -181,7 +181,7 @@ bool Read_ShowPassword() bool showPassword = false; if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS) return showPassword; - key.GetValue_IfOk(kShowPassword, showPassword); + key.GetValue_bool_IfOk(kShowPassword, showPassword); return showPassword; } @@ -189,13 +189,10 @@ UInt32 Read_LimitGB() { CS_LOCK CKey key; + UInt32 v = (UInt32)(Int32)-1; if (OpenMainKey(key, kKeyName) == ERROR_SUCCESS) - { - UInt32 v; - if (key.QueryValue(kMemLimit, v) == ERROR_SUCCESS) - return v; - } - return (UInt32)(Int32)-1; + key.GetValue_UInt32_IfOk(kMemLimit, v); + return v; } } @@ -371,9 +368,9 @@ void CInfo::Load() UString a; if (key.QueryValue(kArchiver, a) == ERROR_SUCCESS) ArcType = a; - key.GetValue_IfOk(kLevel, Level); - key.GetValue_IfOk(kShowPassword, ShowPassword); - key.GetValue_IfOk(kEncryptHeaders, EncryptHeaders); + key.GetValue_UInt32_IfOk(kLevel, Level); + key.GetValue_bool_IfOk(kShowPassword, ShowPassword); + key.GetValue_bool_IfOk(kEncryptHeaders, EncryptHeaders); } @@ -517,7 +514,7 @@ void CInfo::Load() return; UInt32 dirType; - if (key.QueryValue(kWorkDirType, dirType) != ERROR_SUCCESS) + if (key.GetValue_UInt32_IfOk(kWorkDirType, dirType) != ERROR_SUCCESS) return; switch (dirType) { @@ -535,7 +532,7 @@ void CInfo::Load() if (Mode == NMode::kSpecified) Mode = NMode::kSystem; } - key.GetValue_IfOk(kTempRemovableOnly, ForRemovableOnly); + key.GetValue_bool_IfOk(kTempRemovableOnly, ForRemovableOnly); } } @@ -598,5 +595,5 @@ void CContextMenuInfo::Load() Key_Get_UInt32(key, kWriteZoneId, WriteZone); - Flags_Def = (key.GetValue_IfOk(kContextMenu, Flags) == ERROR_SUCCESS); + Flags_Def = (key.GetValue_UInt32_IfOk(kContextMenu, Flags) == ERROR_SUCCESS); } diff --git a/CPP/7zip/UI/Console/ConsoleClose.cpp b/CPP/7zip/UI/Console/ConsoleClose.cpp index 9e4c040..a184ffb 100644 --- a/CPP/7zip/UI/Console/ConsoleClose.cpp +++ b/CPP/7zip/UI/Console/ConsoleClose.cpp @@ -16,7 +16,7 @@ namespace NConsoleClose { unsigned g_BreakCounter = 0; -static const unsigned kBreakAbortThreshold = 2; +static const unsigned kBreakAbortThreshold = 3; #ifdef _WIN32 @@ -28,8 +28,7 @@ static BOOL WINAPI HandlerRoutine(DWORD ctrlType) return TRUE; } - g_BreakCounter++; - if (g_BreakCounter < kBreakAbortThreshold) + if (++g_BreakCounter < kBreakAbortThreshold) return TRUE; return FALSE; /* @@ -47,7 +46,7 @@ static BOOL WINAPI HandlerRoutine(DWORD ctrlType) CCtrlHandlerSetter::CCtrlHandlerSetter() { if (!SetConsoleCtrlHandler(HandlerRoutine, TRUE)) - throw "SetConsoleCtrlHandler fails"; + throw 1019; // "SetConsoleCtrlHandler fails"; } CCtrlHandlerSetter::~CCtrlHandlerSetter() @@ -63,8 +62,7 @@ CCtrlHandlerSetter::~CCtrlHandlerSetter() static void HandlerRoutine(int) { - g_BreakCounter++; - if (g_BreakCounter < kBreakAbortThreshold) + if (++g_BreakCounter < kBreakAbortThreshold) return; exit(EXIT_FAILURE); } diff --git a/CPP/7zip/UI/Console/ConsoleClose.h b/CPP/7zip/UI/Console/ConsoleClose.h index 25c5d0c..b0d99b4 100644 --- a/CPP/7zip/UI/Console/ConsoleClose.h +++ b/CPP/7zip/UI/Console/ConsoleClose.h @@ -5,7 +5,7 @@ namespace NConsoleClose { -class CCtrlBreakException {}; +// class CCtrlBreakException {}; #ifdef UNDER_CE diff --git a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp index f59d4c1..b127631 100644 --- a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp +++ b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp @@ -928,7 +928,7 @@ HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result) if (result == E_ABORT || result == HRESULT_FROM_WIN32(ERROR_DISK_FULL)) return result; - NumArcsWithError++; + NumArcsWithError++; if (_se) { diff --git a/CPP/7zip/UI/Console/MainAr.cpp b/CPP/7zip/UI/Console/MainAr.cpp index 602ab64..490950b 100644 --- a/CPP/7zip/UI/Console/MainAr.cpp +++ b/CPP/7zip/UI/Console/MainAr.cpp @@ -140,11 +140,13 @@ int Z7_CDECL main PrintError(kMemoryExceptionMessage); return (NExitCode::kMemoryError); } +/* catch(const NConsoleClose::CCtrlBreakException &) { PrintError(kUserBreakMessage); return (NExitCode::kUserBreak); } +*/ catch(const CMessagePathException &e) { PrintError(kException_CmdLine_Error_Message); diff --git a/CPP/7zip/UI/Console/PercentPrinter.h b/CPP/7zip/UI/Console/PercentPrinter.h index 46988a5..379aa1b 100644 --- a/CPP/7zip/UI/Console/PercentPrinter.h +++ b/CPP/7zip/UI/Console/PercentPrinter.h @@ -26,6 +26,13 @@ struct CPercentPrinterState class CPercentPrinter: public CPercentPrinterState { +public: + CStdOutStream *_so; + bool DisablePrint; + bool NeedFlush; + unsigned MaxLen; + +private: UInt32 _tickStep; DWORD _prevTick; @@ -41,18 +48,13 @@ class CPercentPrinter: public CPercentPrinterState void GetPercents(); public: - CStdOutStream *_so; - - bool DisablePrint; - bool NeedFlush; - unsigned MaxLen; CPercentPrinter(UInt32 tickStep = 200): - _tickStep(tickStep), - _prevTick(0), DisablePrint(false), NeedFlush(true), - MaxLen(80 - 1) + MaxLen(80 - 1), + _tickStep(tickStep), + _prevTick(0) {} ~CPercentPrinter(); diff --git a/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp index 3e79645..5185d5c 100644 --- a/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp +++ b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp @@ -361,6 +361,119 @@ HRESULT CUpdateCallbackConsole::WriteSfx(const wchar_t *name, UInt64 size) } + +HRESULT CUpdateCallbackConsole::MoveArc_UpdateStatus() +{ + if (NeedPercents()) + { + AString &s = _percent.Command; + s = " : "; + s.Add_UInt64(_arcMoving_percents); + s.Add_Char('%'); + const bool totalDefined = (_arcMoving_total != 0 && _arcMoving_total != (UInt64)(Int64)-1); + if (_arcMoving_current != 0 || totalDefined) + { + s += " : "; + s.Add_UInt64(_arcMoving_current >> 20); + s += " MiB"; + } + if (totalDefined) + { + s += " / "; + s.Add_UInt64((_arcMoving_total + ((1 << 20) - 1)) >> 20); + s += " MiB"; + } + s += " : temporary archive moving ..."; + _percent.Print(); + } + + // we ignore single Ctrl-C, if (_arcMoving_updateMode) mode + // because we want to get good final archive instead of temp archive. + if (NConsoleClose::g_BreakCounter == 1 && _arcMoving_updateMode) + return S_OK; + return CheckBreak(); +} + + +HRESULT CUpdateCallbackConsole::MoveArc_Start( + const wchar_t *srcTempPath, const wchar_t *destFinalPath, + UInt64 size, Int32 updateMode) +{ +#if 0 // 1 : for debug + if (LogLevel > 0 && _so) + { + ClosePercents_for_so(); + *_so << "Temporary archive moving:" << endl; + _tempU = srcTempPath; + _so->Normalize_UString_Path(_tempU); + _so->PrintUString(_tempU, _tempA); + *_so << endl; + _tempU = destFinalPath; + _so->Normalize_UString_Path(_tempU); + _so->PrintUString(_tempU, _tempA); + *_so << endl; + } +#else + UNUSED_VAR(srcTempPath) + UNUSED_VAR(destFinalPath) +#endif + + _arcMoving_updateMode = updateMode; + _arcMoving_total = size; + _arcMoving_current = 0; + _arcMoving_percents = 0; + return MoveArc_UpdateStatus(); +} + + +HRESULT CUpdateCallbackConsole::MoveArc_Progress(UInt64 totalSize, UInt64 currentSize) +{ +#if 0 // 1 : for debug + if (_so) + { + ClosePercents_for_so(); + *_so << totalSize << " : " << currentSize << endl; + } +#endif + + UInt64 percents = 0; + if (totalSize != 0) + { + if (totalSize < ((UInt64)1 << 57)) + percents = currentSize * 100 / totalSize; + else + percents = currentSize / (totalSize / 100); + } + +#ifdef _WIN32 + // Sleep(300); // for debug +#endif + // totalSize = (UInt64)(Int64)-1; // for debug + + if (percents == _arcMoving_percents) + return CheckBreak(); + _arcMoving_current = currentSize; + _arcMoving_total = totalSize; + _arcMoving_percents = percents; + return MoveArc_UpdateStatus(); +} + + +HRESULT CUpdateCallbackConsole::MoveArc_Finish() +{ + // _arcMoving_percents = 0; + if (NeedPercents()) + { + _percent.Command.Empty(); + _percent.Print(); + } + // it can return delayed user break (E_ABORT) status, + // if it ignored single CTRL+C in MoveArc_Progress(). + return CheckBreak(); +} + + + HRESULT CUpdateCallbackConsole::DeletingAfterArchiving(const FString &path, bool /* isDir */) { if (LogLevel > 0 && _so) diff --git a/CPP/7zip/UI/Console/UpdateCallbackConsole.h b/CPP/7zip/UI/Console/UpdateCallbackConsole.h index 276edba..a386371 100644 --- a/CPP/7zip/UI/Console/UpdateCallbackConsole.h +++ b/CPP/7zip/UI/Console/UpdateCallbackConsole.h @@ -29,30 +29,31 @@ struct CErrorPathCodes class CCallbackConsoleBase { -protected: - CPercentPrinter _percent; + void CommonError(const FString &path, DWORD systemError, bool isWarning); +protected: CStdOutStream *_so; CStdOutStream *_se; - void CommonError(const FString &path, DWORD systemError, bool isWarning); - // void CommonError(const char *message); - HRESULT ScanError_Base(const FString &path, DWORD systemError); HRESULT OpenFileError_Base(const FString &name, DWORD systemError); HRESULT ReadingFileError_Base(const FString &name, DWORD systemError); public: - bool NeedPercents() const { return _percent._so != NULL; } - bool StdOutMode; - bool NeedFlush; unsigned PercentsNameLevel; unsigned LogLevel; +protected: AString _tempA; UString _tempU; + CPercentPrinter _percent; + +public: + CErrorPathCodes FailedFiles; + CErrorPathCodes ScanErrors; + UInt64 NumNonOpenFiles; CCallbackConsoleBase(): StdOutMode(false), @@ -62,6 +63,7 @@ public: NumNonOpenFiles(0) {} + bool NeedPercents() const { return _percent._so != NULL; } void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; } void Init( @@ -90,10 +92,6 @@ public: _percent.ClosePrint(false); } - CErrorPathCodes FailedFiles; - CErrorPathCodes ScanErrors; - UInt64 NumNonOpenFiles; - HRESULT PrintProgress(const wchar_t *name, bool isDir, const char *command, bool showInLog); // void PrintInfoLine(const UString &s); @@ -109,6 +107,14 @@ class CUpdateCallbackConsole Z7_final: Z7_IFACE_IMP(IUpdateCallbackUI) Z7_IFACE_IMP(IDirItemsCallback) Z7_IFACE_IMP(IUpdateCallbackUI2) + + HRESULT MoveArc_UpdateStatus(); + + UInt64 _arcMoving_total; + UInt64 _arcMoving_current; + UInt64 _arcMoving_percents; + Int32 _arcMoving_updateMode; + public: bool DeleteMessageWasShown; @@ -119,7 +125,11 @@ public: #endif CUpdateCallbackConsole(): - DeleteMessageWasShown(false) + _arcMoving_total(0) + , _arcMoving_current(0) + , _arcMoving_percents(0) + , _arcMoving_updateMode(0) + , DeleteMessageWasShown(false) #ifndef Z7_NO_CRYPTO , PasswordIsDefined(false) , AskPassword(false) diff --git a/CPP/7zip/UI/Explorer/ContextMenu.cpp b/CPP/7zip/UI/Explorer/ContextMenu.cpp index fab3493..0630d78 100644 --- a/CPP/7zip/UI/Explorer/ContextMenu.cpp +++ b/CPP/7zip/UI/Explorer/ContextMenu.cpp @@ -295,9 +295,13 @@ static const CHashCommand g_HashCommands[] = { { CZipContextMenu::kHash_CRC32, "CRC-32", "CRC32" }, { CZipContextMenu::kHash_CRC64, "CRC-64", "CRC64" }, - { CZipContextMenu::kHash_XXH64, "XXH64", "XXH64" }, + { CZipContextMenu::kHash_XXH64, "XXH64", "XXH64" }, + { CZipContextMenu::kHash_MD5, "MD5", "MD5" }, { CZipContextMenu::kHash_SHA1, "SHA-1", "SHA1" }, { CZipContextMenu::kHash_SHA256, "SHA-256", "SHA256" }, + { CZipContextMenu::kHash_SHA384, "SHA-384", "SHA384" }, + { CZipContextMenu::kHash_SHA512, "SHA-512", "SHA512" }, + { CZipContextMenu::kHash_SHA3_256, "SHA3-256", "SHA3-256" }, { CZipContextMenu::kHash_BLAKE2SP, "BLAKE2sp", "BLAKE2sp" }, { CZipContextMenu::kHash_All, "*", "*" }, { CZipContextMenu::kHash_Generate_SHA256, "SHA-256 -> file.sha256", "SHA256" }, @@ -1338,8 +1342,12 @@ HRESULT CZipContextMenu::InvokeCommandCommon(const CCommandMapItem &cmi) case kHash_CRC32: case kHash_CRC64: case kHash_XXH64: + case kHash_MD5: case kHash_SHA1: case kHash_SHA256: + case kHash_SHA384: + case kHash_SHA512: + case kHash_SHA3_256: case kHash_BLAKE2SP: case kHash_All: case kHash_Generate_SHA256: diff --git a/CPP/7zip/UI/Explorer/ContextMenu.h b/CPP/7zip/UI/Explorer/ContextMenu.h index a68ba9d..2759967 100644 --- a/CPP/7zip/UI/Explorer/ContextMenu.h +++ b/CPP/7zip/UI/Explorer/ContextMenu.h @@ -88,8 +88,12 @@ public: kHash_CRC32, kHash_CRC64, kHash_XXH64, + kHash_MD5, kHash_SHA1, kHash_SHA256, + kHash_SHA384, + kHash_SHA512, + kHash_SHA3_256, kHash_BLAKE2SP, kHash_All, kHash_Generate_SHA256, diff --git a/CPP/7zip/UI/Far/Far.cpp b/CPP/7zip/UI/Far/Far.cpp index 211dde8..962af97 100644 --- a/CPP/7zip/UI/Far/Far.cpp +++ b/CPP/7zip/UI/Far/Far.cpp @@ -116,15 +116,16 @@ Z7_CLASS_IMP_COM_3( // DWORD m_StartTickValue; bool m_MessageBoxIsShown; - CProgressBox _progressBox; - bool _numFilesTotalDefined; bool _numBytesTotalDefined; - public: bool PasswordIsDefined; UString Password; +private: + CProgressBox _progressBox; +public: + COpenArchiveCallback() {} diff --git a/CPP/7zip/UI/Far/FarUtils.cpp b/CPP/7zip/UI/Far/FarUtils.cpp index ed61ccc..3c33d8e 100644 --- a/CPP/7zip/UI/Far/FarUtils.cpp +++ b/CPP/7zip/UI/Far/FarUtils.cpp @@ -281,7 +281,7 @@ UInt32 CStartupInfo::QueryRegKeyValue(HKEY parentKey, const char *keyName, return valueDefault; UInt32 value; - if (regKey.QueryValue(valueName, value) != ERROR_SUCCESS) + if (regKey.GetValue_UInt32_IfOk(valueName, value) != ERROR_SUCCESS) return valueDefault; return value; @@ -295,7 +295,7 @@ bool CStartupInfo::QueryRegKeyValue(HKEY parentKey, const char *keyName, return valueDefault; bool value; - if (regKey.QueryValue(valueName, value) != ERROR_SUCCESS) + if (regKey.GetValue_bool_IfOk(valueName, value) != ERROR_SUCCESS) return valueDefault; return value; diff --git a/CPP/7zip/UI/Far/ProgressBox.h b/CPP/7zip/UI/Far/ProgressBox.h index 6e8b487..f6b36c4 100644 --- a/CPP/7zip/UI/Far/ProgressBox.h +++ b/CPP/7zip/UI/Far/ProgressBox.h @@ -45,7 +45,12 @@ class CProgressBox: public CPercentPrinterState DWORD _prevElapsedSec; bool _wasPrinted; +public: + bool UseBytesForPercents; + DWORD StartTick; + unsigned MaxLen; +private: UString _tempU; UString _name1U; UString _name2U; @@ -64,15 +69,12 @@ class CProgressBox: public CPercentPrinterState void ReduceString(const UString &src, AString &dest); public: - DWORD StartTick; - bool UseBytesForPercents; - unsigned MaxLen; CProgressBox(UInt32 tickStep = 200): _tickStep(tickStep), _prevTick(0), - StartTick(0), UseBytesForPercents(true), + StartTick(0), MaxLen(60) {} diff --git a/CPP/7zip/UI/Far/UpdateCallbackFar.cpp b/CPP/7zip/UI/Far/UpdateCallbackFar.cpp index 94f0a47..16702d3 100644 --- a/CPP/7zip/UI/Far/UpdateCallbackFar.cpp +++ b/CPP/7zip/UI/Far/UpdateCallbackFar.cpp @@ -210,6 +210,96 @@ Z7_COM7F_IMF(CUpdateCallback100Imp::ReportUpdateOperation(UInt32 op, const wchar } +HRESULT CUpdateCallback100Imp::MoveArc_UpdateStatus() +{ + MT_LOCK + + if (_percent) + { + AString s; + s.Add_UInt64(_arcMoving_percents); + // status.Add_Space(); + s.Add_Char('%'); + const bool totalDefined = (_arcMoving_total != 0 && _arcMoving_total != (UInt64)(Int64)-1); + if (_arcMoving_current != 0 || totalDefined) + { + s += " : "; + s.Add_UInt64(_arcMoving_current >> 20); + s += " MiB"; + } + if (totalDefined) + { + s += " / "; + s.Add_UInt64((_arcMoving_total + ((1 << 20) - 1)) >> 20); + s += " MiB"; + } + s += " : temporary archive moving ..."; + _percent->Command = s; + _percent->Print(); + } + + return CheckBreak2(); +} + + +Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Start(const wchar_t *srcTempPath, const wchar_t * /* destFinalPath */ , UInt64 size, Int32 /* updateMode */)) +{ + MT_LOCK + + _arcMoving_total = size; + _arcMoving_current = 0; + _arcMoving_percents = 0; + // _arcMoving_updateMode = updateMode; + // _name2 = fs2us(destFinalPath); + if (_percent) + _percent->FileName = srcTempPath; + return MoveArc_UpdateStatus(); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Progress(UInt64 totalSize, UInt64 currentSize)) +{ + UInt64 percents = 0; + if (totalSize != 0) + { + if (totalSize < ((UInt64)1 << 57)) + percents = currentSize * 100 / totalSize; + else + percents = currentSize / (totalSize / 100); + } + +#ifdef _WIN32 + // Sleep(300); // for debug +#endif + if (percents == _arcMoving_percents) + return CheckBreak2(); + _arcMoving_total = totalSize; + _arcMoving_current = currentSize; + _arcMoving_percents = percents; + // if (_arcMoving_percents > 100) return E_FAIL; + return MoveArc_UpdateStatus(); +} + + +Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Finish()) +{ + // _arcMoving_percents = 0; + if (_percent) + { + _percent->Command.Empty(); + _percent->FileName.Empty(); + _percent->Print(); + } + return CheckBreak2(); +} + + +Z7_COM7F_IMF(CUpdateCallback100Imp::Before_ArcReopen()) +{ + // fixme: we can use Clear_Stop_Status() here + return CheckBreak2(); +} + + extern HRESULT GetPassword(UString &password); Z7_COM7F_IMF(CUpdateCallback100Imp::CryptoGetTextPassword(BSTR *password)) diff --git a/CPP/7zip/UI/Far/UpdateCallbackFar.h b/CPP/7zip/UI/Far/UpdateCallbackFar.h index 4ec5eed..8d2c8b8 100644 --- a/CPP/7zip/UI/Far/UpdateCallbackFar.h +++ b/CPP/7zip/UI/Far/UpdateCallbackFar.h @@ -11,10 +11,11 @@ #include "ProgressBox.h" -Z7_CLASS_IMP_COM_6( +Z7_CLASS_IMP_COM_7( CUpdateCallback100Imp , IFolderArchiveUpdateCallback , IFolderArchiveUpdateCallback2 + , IFolderArchiveUpdateCallback_MoveArc , IFolderScanProgress , ICryptoGetTextPassword2 , ICryptoGetTextPassword @@ -25,6 +26,15 @@ Z7_CLASS_IMP_COM_6( // CMyComPtr _archiveHandler; CProgressBox *_percent; // UInt64 _total; + + HRESULT MoveArc_UpdateStatus(); + +private: + UInt64 _arcMoving_total; + UInt64 _arcMoving_current; + UInt64 _arcMoving_percents; + // Int32 _arcMoving_updateMode; + public: bool PasswordIsDefined; UString Password; @@ -38,6 +48,10 @@ public: _percent = progressBox; PasswordIsDefined = false; Password.Empty(); + _arcMoving_total = 0; + _arcMoving_current = 0; + _arcMoving_percents = 0; + // _arcMoving_updateMode = 0; } }; diff --git a/CPP/7zip/UI/FileManager/App.cpp b/CPP/7zip/UI/FileManager/App.cpp index 06c2e8b..5b7d616 100644 --- a/CPP/7zip/UI/FileManager/App.cpp +++ b/CPP/7zip/UI/FileManager/App.cpp @@ -402,11 +402,17 @@ void CApp::Save() // Save_ShowDeleted(ShowDeletedFiles); } -void CApp::Release() +void CApp::ReleaseApp() { + // 24.09: ReleasePanel() will stop panel timer processing. + // but we want to stop timer processing for all panels + // before ReleasePanel() calling. + unsigned i; + for (i = 0; i < kNumPanelsMax; i++) + Panels[i].Disable_Processing_Timer_Notify_StatusBar(); // It's for unloading COM dll's: don't change it. - for (unsigned i = 0; i < kNumPanelsMax; i++) - Panels[i].Release(); + for (i = 0; i < kNumPanelsMax; i++) + Panels[i].ReleasePanel(); } // reduces path to part that exists on disk (or root prefix of path) @@ -644,7 +650,7 @@ void CApp::OnCopy(bool move, bool copyToSame, unsigned srcPanelIndex) destPath += correctName; #if defined(_WIN32) && !defined(UNDER_CE) - if (destPath.Len() > 0 && destPath[0] == '\\') + if (destPath.Len() != 0 && destPath[0] == '\\') if (destPath.Len() == 1 || destPath[1] != '\\') { srcPanel.MessageBox_Error_UnsupportOperation(); diff --git a/CPP/7zip/UI/FileManager/App.h b/CPP/7zip/UI/FileManager/App.h index 1e20532..cf74d6a 100644 --- a/CPP/7zip/UI/FileManager/App.h +++ b/CPP/7zip/UI/FileManager/App.h @@ -109,7 +109,7 @@ public: HRESULT Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool needOpenArc, COpenResult &openRes); void Read(); void Save(); - void Release(); + void ReleaseApp(); // void SetFocus(int panelIndex) { Panels[panelIndex].SetFocusToList(); } void SetFocusToLastItem() { Panels[LastFocusedPanel].SetFocusToLastRememberedItem(); } diff --git a/CPP/7zip/UI/FileManager/ExtractCallback.cpp b/CPP/7zip/UI/FileManager/ExtractCallback.cpp index 6ec6065..da25969 100644 --- a/CPP/7zip/UI/FileManager/ExtractCallback.cpp +++ b/CPP/7zip/UI/FileManager/ExtractCallback.cpp @@ -2,7 +2,6 @@ #include "StdAfx.h" - #include "../../../Common/ComTry.h" #include "../../../Common/IntToString.h" #include "../../../Common/Lang.h" @@ -27,11 +26,11 @@ #include "ExtractCallback.h" #include "FormatUtils.h" #include "LangUtils.h" +#include "MemDialog.h" #include "OverwriteDialog.h" #ifndef Z7_NO_CRYPTO #include "PasswordDialog.h" #endif -#include "MemDialog.h" #include "PropertyName.h" using namespace NWindows; @@ -44,9 +43,9 @@ CExtractCallbackImp::~CExtractCallbackImp() {} void CExtractCallbackImp::Init() { - _lang_Extracting = LangString(IDS_PROGRESS_EXTRACTING); - _lang_Testing = LangString(IDS_PROGRESS_TESTING); - _lang_Skipping = LangString(IDS_PROGRESS_SKIPPING); + LangString(IDS_PROGRESS_EXTRACTING, _lang_Extracting); + LangString(IDS_PROGRESS_TESTING, _lang_Testing); + LangString(IDS_PROGRESS_SKIPPING, _lang_Skipping); _lang_Reading = "Reading"; NumArchiveErrors = 0; @@ -107,19 +106,19 @@ HRESULT CExtractCallbackImp::Open_SetTotal(const UInt64 *files, const UInt64 *by { if (files) { - _totalFilesDefined = true; + _totalFiles_Defined = true; // res = ProgressDialog->Sync.Set_NumFilesTotal(*files); } else - _totalFilesDefined = false; + _totalFiles_Defined = false; if (bytes) { - _totalBytesDefined = true; + _totalBytes_Defined = true; ProgressDialog->Sync.Set_NumBytesTotal(*bytes); } else - _totalBytesDefined = false; + _totalBytes_Defined = false; } return res; @@ -217,7 +216,7 @@ Z7_COM7F_IMF(CExtractCallbackImp::AskOverwrite( dialog.NewFileInfo.Is_FileSystemFile = Src_Is_IO_FS_Folder; ProgressDialog->WaitCreating(); - INT_PTR writeAnswer = dialog.Create(*ProgressDialog); + const INT_PTR writeAnswer = dialog.Create(*ProgressDialog); switch (writeAnswer) { @@ -478,10 +477,10 @@ UString GetOpenArcErrorMessage(UInt32 errorFlags) for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_ErrorFlagsIds); i++) { - UInt32 f = ((UInt32)1 << i); + const UInt32 f = (UInt32)1 << i; if ((errorFlags & f) == 0) continue; - UInt32 id = k_ErrorFlagsIds[i]; + const UInt32 id = k_ErrorFlagsIds[i]; UString m = LangString(id); if (m.IsEmpty()) continue; @@ -512,8 +511,8 @@ UString GetOpenArcErrorMessage(UInt32 errorFlags) static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er) { - UInt32 errorFlags = er.GetErrorFlags(); - UInt32 warningFlags = er.GetWarningFlags(); + const UInt32 errorFlags = er.GetErrorFlags(); + const UInt32 warningFlags = er.GetWarningFlags(); if (errorFlags != 0) AddNewLineString(s, GetOpenArcErrorMessage(errorFlags)); @@ -524,7 +523,7 @@ static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er) if (warningFlags != 0) { s += GetNameOfProperty(kpidWarningFlags, L"Warnings"); - s += ":"; + s.Add_Colon(); s.Add_LF(); AddNewLineString(s, GetOpenArcErrorMessage(warningFlags)); } @@ -852,34 +851,35 @@ Z7_COM7F_IMF(CExtractCallbackImp::GetStream7(const wchar_t *name, _newVirtFileWasAdded = false; _hashStream_WasUsed = false; _needUpdateStat = false; + _isFolder = IntToBool(isDir); + _curSize_Defined = false; + _curSize = 0; if (_hashStream) _hashStream->ReleaseStream(); - GetItemBoolProp(getProp, kpidIsAltStream, _isAltStream); - - if (!ProcessAltStreams && _isAltStream) - return S_OK; - _filePath = name; - _isFolder = IntToBool(isDir); - _curSize = 0; - _curSize_Defined = false; UInt64 size = 0; - bool sizeDefined; + bool size_Defined; { NCOM::CPropVariant prop; RINOK(getProp->GetProp(kpidSize, &prop)) - sizeDefined = ConvertPropVariantToUInt64(prop, size); + size_Defined = ConvertPropVariantToUInt64(prop, size); } - - if (sizeDefined) + if (size_Defined) { _curSize = size; _curSize_Defined = true; } + GetItemBoolProp(getProp, kpidIsAltStream, _isAltStream); + if (!ProcessAltStreams && _isAltStream) + return S_OK; + + if (isDir) // we don't support dir items extraction in this code + return S_OK; + if (askExtractMode != NArchive::NExtract::NAskMode::kExtract && askExtractMode != NArchive::NExtract::NAskMode::kTest) return S_OK; @@ -890,40 +890,64 @@ Z7_COM7F_IMF(CExtractCallbackImp::GetStream7(const wchar_t *name, if (VirtFileSystem && askExtractMode == NArchive::NExtract::NAskMode::kExtract) { - CVirtFile &file = VirtFileSystemSpec->AddNewFile(); + if (!VirtFileSystemSpec->Files.IsEmpty()) + VirtFileSystemSpec->MaxTotalAllocSize -= VirtFileSystemSpec->Files.Back().Data.Size(); + CVirtFile &file = VirtFileSystemSpec->Files.AddNew(); _newVirtFileWasAdded = true; - file.Name = name; - file.IsDir = IntToBool(isDir); + // file.IsDir = _isFolder; file.IsAltStream = _isAltStream; - file.Size = 0; + file.WrittenSize = 0; + file.ExpectedSize = 0; + if (size_Defined) + file.ExpectedSize = size; - RINOK(GetTime(getProp, kpidCTime, file.CTime, file.CTimeDefined)) - RINOK(GetTime(getProp, kpidATime, file.ATime, file.ATimeDefined)) - RINOK(GetTime(getProp, kpidMTime, file.MTime, file.MTimeDefined)) + if (VirtFileSystemSpec->Index_of_MainExtractedFile_in_Files < 0) + if (!file.IsAltStream || VirtFileSystemSpec->IsAltStreamFile) + VirtFileSystemSpec->Index_of_MainExtractedFile_in_Files = + (int)(VirtFileSystemSpec->Files.Size() - 1); - NCOM::CPropVariant prop; - RINOK(getProp->GetProp(kpidAttrib, &prop)) - if (prop.vt == VT_UI4) + /* if we open only AltStream, then (name) contains only name without "fileName:" prefix */ + file.BaseName = name; + + if (file.IsAltStream + && !VirtFileSystemSpec->IsAltStreamFile + && file.BaseName.IsPrefixedBy_NoCase(VirtFileSystemSpec->FileName)) { - file.Attrib = prop.ulVal; - file.AttribDefined = true; + const unsigned colonPos = VirtFileSystemSpec->FileName.Len(); + if (file.BaseName[colonPos] == ':') + { + file.ColonWasUsed = true; + file.AltStreamName = name + (size_t)colonPos + 1; + file.BaseName.DeleteFrom(colonPos); + if (Is_ZoneId_StreamName(file.AltStreamName)) + { + if (VirtFileSystemSpec->Index_of_ZoneBuf_AltStream_in_Files < 0) + VirtFileSystemSpec->Index_of_ZoneBuf_AltStream_in_Files = + (int)(VirtFileSystemSpec->Files.Size() - 1); + } + } + } + RINOK(GetTime(getProp, kpidCTime, file.CTime, file.CTime_Defined)) + RINOK(GetTime(getProp, kpidATime, file.ATime, file.ATime_Defined)) + RINOK(GetTime(getProp, kpidMTime, file.MTime, file.MTime_Defined)) + { + NCOM::CPropVariant prop; + RINOK(getProp->GetProp(kpidAttrib, &prop)) + if (prop.vt == VT_UI4) + { + file.Attrib = prop.ulVal; + file.Attrib_Defined = true; + } } - // else if (isDir) file.Attrib = FILE_ATTRIBUTE_DIRECTORY; - - file.ExpectedSize = 0; - if (sizeDefined) - file.ExpectedSize = size; outStreamLoc = VirtFileSystem; } if (_hashStream) { - { - _hashStream->SetStream(outStreamLoc); - outStreamLoc = _hashStream; - _hashStream->Init(true); - _hashStream_WasUsed = true; - } + _hashStream->SetStream(outStreamLoc); + outStreamLoc = _hashStream; + _hashStream->Init(true); + _hashStream_WasUsed = true; } if (outStreamLoc) @@ -1077,10 +1101,10 @@ Z7_COM7F_IMF(CExtractCallbackImp::RequestMemoryUse( // if (indexType == NArchive::NEventIndexType::kNoIndex) if ((flags & NRequestMemoryUseFlags::k_SkipArc_IsExpected) || (flags & NRequestMemoryUseFlags::k_Report_SkipArc)) - s += LangString(IDS_MSG_ARC_UNPACKING_WAS_SKIPPED); + AddLangString(s, IDS_MSG_ARC_UNPACKING_WAS_SKIPPED); /* else - s += LangString(IDS_MSG_ARC_FILES_UNPACKING_WAS_SKIPPED); + AddLangString(, IDS_MSG_ARC_FILES_UNPACKING_WAS_SKIPPED); */ AddError_Message_ShowArcPath(s); } @@ -1093,88 +1117,154 @@ Z7_COM7F_IMF(CExtractCallbackImp::RequestMemoryUse( } - -// static const UInt32 kBlockSize = ((UInt32)1 << 31); - Z7_COM7F_IMF(CVirtFileSystem::Write(const void *data, UInt32 size, UInt32 *processedSize)) { if (processedSize) *processedSize = 0; if (size == 0) return S_OK; - if (!_fileMode) + if (!_wasSwitchedToFsMode) { CVirtFile &file = Files.Back(); - size_t rem = file.Data.Size() - (size_t)file.Size; + const size_t rem = file.Data.Size() - file.WrittenSize; bool useMem = true; if (rem < size) { UInt64 b = 0; if (file.Data.Size() == 0) b = file.ExpectedSize; - UInt64 a = file.Size + size; + UInt64 a = (UInt64)file.WrittenSize + size; if (b < a) b = a; a = (UInt64)file.Data.Size() * 2; if (b < a) b = a; useMem = false; - const size_t b_sizet = (size_t)b; - if (b == b_sizet && b <= MaxTotalAllocSize) - useMem = file.Data.ReAlloc_KeepData(b_sizet, (size_t)file.Size); + if (b <= MaxTotalAllocSize) + useMem = file.Data.ReAlloc_KeepData((size_t)b, file.WrittenSize); } + +#if 0 // 1 for debug : FLUSHING TO FS + useMem = false; +#endif + if (useMem) { - memcpy(file.Data + file.Size, data, size); - file.Size += size; + memcpy(file.Data + file.WrittenSize, data, size); + file.WrittenSize += size; if (processedSize) *processedSize = (UInt32)size; return S_OK; } - _fileMode = true; + _wasSwitchedToFsMode = true; + } + + if (!_newVirtFileStream_IsReadyToWrite) // we check for _newVirtFileStream_IsReadyToWrite to optimize execution + { + RINOK(FlushToDisk(false)) } - RINOK(FlushToDisk(false)) - return _outFileStream.Interface()->Write(data, size, processedSize); + + if (_needWriteToRealFile) + return _outFileStream.Interface()->Write(data, size, processedSize); + if (processedSize) + *processedSize = size; + return S_OK; } HRESULT CVirtFileSystem::FlushToDisk(bool closeLast) { - _outFileStream.Create_if_Empty(); while (_numFlushed < Files.Size()) { - const CVirtFile &file = Files[_numFlushed]; - const FString path = DirPrefix + us2fs(Get_Correct_FsFile_Name(file.Name)); - if (!_fileIsOpen) + CVirtFile &file = Files[_numFlushed]; + const FString basePath = DirPrefix + us2fs(Get_Correct_FsFile_Name(file.BaseName)); + FString path = basePath; + + if (file.ColonWasUsed) { - if (!_outFileStream->Create_NEW(path)) + if (ZoneBuf.Size() != 0 + && Is_ZoneId_StreamName(file.AltStreamName)) { - // do we need to release stream here? - // _outFileStream.Release(); - return E_FAIL; - // MessageBoxMyError(UString("Can't create file ") + fs2us(tempFilePath)); + // it's expected that + // CArchiveExtractCallback::GetStream() have excluded + // ZoneId alt stream from extraction already. + // But we exclude alt stream extraction here too. + _numFlushed++; + continue; } - _fileIsOpen = true; - RINOK(WriteStream(_outFileStream, file.Data, (size_t)file.Size)) + path.Add_Colon(); + path += us2fs(Get_Correct_FsFile_Name(file.AltStreamName)); } + + if (!_newVirtFileStream_IsReadyToWrite) + { + if (file.ColonWasUsed) + { + NFind::CFileInfo parentFi; + if (parentFi.Find(basePath) + && parentFi.IsReadOnly()) + { + _altStream_NeedRestore_Attrib_bool = true; + _altStream_NeedRestore_AttribVal = parentFi.Attrib; + NDir::SetFileAttrib(basePath, parentFi.Attrib & ~(DWORD)FILE_ATTRIBUTE_READONLY); + } + } + _outFileStream.Create_if_Empty(); + _needWriteToRealFile = _outFileStream->Create_NEW(path); + if (!_needWriteToRealFile) + { + if (!file.ColonWasUsed) + return GetLastError_noZero_HRESULT(); // it's main file and we can't ignore such error. + // (file.ColonWasUsed == true) + // So it's additional alt stream. + // And we ignore file creation error for additional alt stream. + // ShowErrorMessage(UString("Can't create file ") + fs2us(path)); + } + _newVirtFileStream_IsReadyToWrite = true; + // _openFilePath = path; + HRESULT hres = S_OK; + if (_needWriteToRealFile) + hres = WriteStream(_outFileStream, file.Data, file.WrittenSize); + // we free allocated memory buffer after data flushing: + file.WrittenSize = 0; + file.Data.Free(); + RINOK(hres) + } + if (_numFlushed == Files.Size() - 1 && !closeLast) break; - if (file.CTimeDefined || - file.ATimeDefined || - file.MTimeDefined) - _outFileStream->SetTime( - file.CTimeDefined ? &file.CTime : NULL, - file.ATimeDefined ? &file.ATime : NULL, - file.MTimeDefined ? &file.MTime : NULL); - _outFileStream->Close(); + + if (_needWriteToRealFile) + { + if (file.CTime_Defined || + file.ATime_Defined || + file.MTime_Defined) + _outFileStream->SetTime( + file.CTime_Defined ? &file.CTime : NULL, + file.ATime_Defined ? &file.ATime : NULL, + file.MTime_Defined ? &file.MTime : NULL); + _outFileStream->Close(); + } + _numFlushed++; - _fileIsOpen = false; + _newVirtFileStream_IsReadyToWrite = false; - if (ZoneBuf.Size() != 0) - WriteZoneFile_To_BaseFile(path, ZoneBuf); - - if (file.AttribDefined) - NDir::SetFileAttrib_PosixHighDetect(path, file.Attrib); + if (_needWriteToRealFile) + { + if (!file.ColonWasUsed + && ZoneBuf.Size() != 0) + WriteZoneFile_To_BaseFile(path, ZoneBuf); + if (file.Attrib_Defined) + NDir::SetFileAttrib_PosixHighDetect(path, file.Attrib); + // _openFilePath.Empty(); + _needWriteToRealFile = false; + } + + if (_altStream_NeedRestore_Attrib_bool) + { + _altStream_NeedRestore_Attrib_bool = false; + NDir::SetFileAttrib(basePath, _altStream_NeedRestore_AttribVal); + } } return S_OK; } diff --git a/CPP/7zip/UI/FileManager/ExtractCallback.h b/CPP/7zip/UI/FileManager/ExtractCallback.h index 5c459aa..8b4dcb3 100644 --- a/CPP/7zip/UI/FileManager/ExtractCallback.h +++ b/CPP/7zip/UI/FileManager/ExtractCallback.h @@ -25,10 +25,6 @@ #include "ProgressDialog2.h" -#ifdef Z7_LANG -// #include "LangUtils.h" -#endif - #ifndef Z7_SFX class CGrowBuf @@ -39,12 +35,24 @@ class CGrowBuf Z7_CLASS_NO_COPY(CGrowBuf) public: + void Free() + { + MyFree(_items); + _items = NULL; + _size = 0; + } + + // newSize >= keepSize bool ReAlloc_KeepData(size_t newSize, size_t keepSize) { - void *buf = MyAlloc(newSize); - if (!buf) - return false; - if (keepSize != 0) + void *buf = NULL; + if (newSize) + { + buf = MyAlloc(newSize); + if (!buf) + return false; + } + if (keepSize) memcpy(buf, _items, keepSize); MyFree(_items); _items = (Byte *)buf; @@ -60,23 +68,27 @@ public: size_t Size() const { return _size; } }; + struct CVirtFile { CGrowBuf Data; - UInt64 Size; // real size - UInt64 ExpectedSize; // the size from props request. 0 if unknown - - UString Name; - - bool CTimeDefined; - bool ATimeDefined; - bool MTimeDefined; - bool AttribDefined; + UInt64 ExpectedSize; // size from props request. 0 if unknown + size_t WrittenSize; // size of written data in (Data) buffer + // use (WrittenSize) only if (CVirtFileSystem::_newVirtFileStream_IsReadyToWrite == false) + UString BaseName; // original name of file inside archive, + // It's not path. So any path separators + // should be treated as part of name (or as incorrect chars) + UString AltStreamName; + + bool CTime_Defined; + bool ATime_Defined; + bool MTime_Defined; + bool Attrib_Defined; - bool IsDir; + // bool IsDir; bool IsAltStream; - + bool ColonWasUsed; DWORD Attrib; FILETIME CTime; @@ -84,82 +96,82 @@ struct CVirtFile FILETIME MTime; CVirtFile(): - CTimeDefined(false), - ATimeDefined(false), - MTimeDefined(false), - AttribDefined(false), - IsDir(false), - IsAltStream(false) {} + CTime_Defined(false), + ATime_Defined(false), + MTime_Defined(false), + Attrib_Defined(false), + // IsDir(false), + IsAltStream(false), + ColonWasUsed(false) + {} }; +/* + We use CVirtFileSystem only for single file extraction: + It supports the following cases and names: + - "fileName" : single file + - "fileName" item (main base file) and additional "fileName:altStream" items + - "altStream" : single item without "fileName:" prefix. + If file is flushed to disk, it uses Get_Correct_FsFile_Name(name). +*/ + Z7_CLASS_IMP_NOQIB_1( CVirtFileSystem, ISequentialOutStream ) - UInt64 _totalAllocSize; - - size_t _pos; unsigned _numFlushed; - bool _fileIsOpen; - bool _fileMode; +public: + bool IsAltStreamFile; // in: + // = true, if extracting file is alt stream without "fileName:" prefix. + // = false, if extracting file is normal file, but additional + // alt streams "fileName:altStream" items are possible. +private: + bool _newVirtFileStream_IsReadyToWrite; // it can non real file (if can't open alt stream) + bool _needWriteToRealFile; // we need real writing to open file. + bool _wasSwitchedToFsMode; + bool _altStream_NeedRestore_Attrib_bool; + DWORD _altStream_NeedRestore_AttribVal; + CMyComPtr2 _outFileStream; public: CObjectVector Files; - UInt64 MaxTotalAllocSize; - FString DirPrefix; + size_t MaxTotalAllocSize; // remain size, including Files.Back() + FString DirPrefix; // files will be flushed to this FS directory. + UString FileName; // name of file that will be extracted. + // it can be name of alt stream without "fileName:" prefix, if (IsAltStreamFile == trye). + // we use that name to detect altStream part in "FileName:altStream". CByteBuffer ZoneBuf; + int Index_of_MainExtractedFile_in_Files; // out: index in Files. == -1, if expected file was not extracted + int Index_of_ZoneBuf_AltStream_in_Files; // out: index in Files. == -1, if no zonbuf alt stream + - - CVirtFile &AddNewFile() + CVirtFileSystem() { - if (!Files.IsEmpty()) - { - MaxTotalAllocSize -= Files.Back().Data.Size(); - } - return Files.AddNew(); + _numFlushed = 0; + IsAltStreamFile = false; + _newVirtFileStream_IsReadyToWrite = false; + _needWriteToRealFile = false; + _wasSwitchedToFsMode = false; + _altStream_NeedRestore_Attrib_bool = false; + MaxTotalAllocSize = (size_t)0 - 1; + Index_of_MainExtractedFile_in_Files = -1; + Index_of_ZoneBuf_AltStream_in_Files = -1; } + + bool WasStreamFlushedToFS() const { return _wasSwitchedToFsMode; } + HRESULT CloseMemFile() { - if (_fileMode) - { - return FlushToDisk(true); - } + if (_wasSwitchedToFsMode) + return FlushToDisk(true); // closeLast CVirtFile &file = Files.Back(); - if (file.Data.Size() != file.Size) - { - file.Data.ReAlloc_KeepData((size_t)file.Size, (size_t)file.Size); - } + if (file.Data.Size() != file.WrittenSize) + file.Data.ReAlloc_KeepData(file.WrittenSize, file.WrittenSize); return S_OK; } - bool IsStreamInMem() const - { - if (_fileMode) - return false; - if (Files.Size() < 1 || /* Files[0].IsAltStream || */ Files[0].IsDir) - return false; - return true; - } - - size_t GetMemStreamWrittenSize() const { return _pos; } - - CVirtFileSystem(): - MaxTotalAllocSize((UInt64)0 - 1) - {} - - void Init() - { - _totalAllocSize = 0; - _fileMode = false; - _pos = 0; - _numFlushed = 0; - _fileIsOpen = false; - } - - HRESULT CloseFile(const FString &path); HRESULT FlushToDisk(bool closeLast); - size_t GetPos() const { return _pos; } }; #endif @@ -217,12 +229,12 @@ class CExtractCallbackImp Z7_final: bool _needWriteArchivePath; bool _isFolder; - bool _totalFilesDefined; - bool _totalBytesDefined; + bool _totalFiles_Defined; + bool _totalBytes_Defined; public: bool MultiArcMode; bool ProcessAltStreams; - bool StreamMode; + bool StreamMode; // set to true, if you want the callee to call GetStream7() bool ThereAreMessageErrors; bool Src_Is_IO_FS_Folder; @@ -246,9 +258,17 @@ private: bool _skipArc; #endif +public: + bool YesToAll; + bool TestMode; + + UInt32 NumArchiveErrors; + NExtract::NOverwriteMode::EEnum OverwriteMode; + +private: UString _currentArchivePath; UString _currentFilePath; - UString _filePath; + UString _filePath; // virtual path than will be sent via IFolderExtractToStreamCallback #ifndef Z7_SFX UInt64 _curSize; @@ -266,12 +286,6 @@ public: UInt64 NumFiles; #endif - UInt32 NumArchiveErrors; - NExtract::NOverwriteMode::EEnum OverwriteMode; - - bool YesToAll; - bool TestMode; - #ifndef Z7_NO_CRYPTO UString Password; #endif @@ -283,8 +297,8 @@ public: UString _lang_Empty; CExtractCallbackImp(): - _totalFilesDefined(false) - , _totalBytesDefined(false) + _totalFiles_Defined(false) + , _totalBytes_Defined(false) , MultiArcMode(false) , ProcessAltStreams(true) , StreamMode(false) @@ -297,11 +311,13 @@ public: #ifndef Z7_SFX , _remember(false) , _skipArc(false) - , _hashCalc(NULL) #endif - , OverwriteMode(NExtract::NOverwriteMode::kAsk) , YesToAll(false) , TestMode(false) + , OverwriteMode(NExtract::NOverwriteMode::kAsk) +#ifndef Z7_SFX + , _hashCalc(NULL) +#endif {} ~CExtractCallbackImp(); diff --git a/CPP/7zip/UI/FileManager/FM.cpp b/CPP/7zip/UI/FileManager/FM.cpp index fe4f2bd..7310802 100644 --- a/CPP/7zip/UI/FileManager/FM.cpp +++ b/CPP/7zip/UI/FileManager/FM.cpp @@ -63,8 +63,8 @@ bool g_LargePagesMode = false; static bool g_Maximized = false; extern -UInt64 g_RAM_Size; -UInt64 g_RAM_Size; +size_t g_RAM_Size; +size_t g_RAM_Size; #ifdef _WIN32 extern @@ -1025,8 +1025,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) break; } - case WM_DESTROY: + case WM_CLOSE: { + // why do we use WA_INACTIVE here ? + SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd); + g_ExitEventLauncher.Exit(false); // ::DragAcceptFiles(hWnd, FALSE); RevokeDragDrop(hWnd); g_App._dropTarget.Release(); @@ -1034,12 +1037,18 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) if (g_WindowWasCreated) g_App.Save(); - g_App.Release(); + g_App.ReleaseApp(); if (g_WindowWasCreated) SaveWindowInfo(hWnd); g_ExitEventLauncher.Exit(true); + // default DefWindowProc will call DestroyWindow / WM_DESTROY + break; + } + + case WM_DESTROY: + { PostQuitMessage(0); break; } diff --git a/CPP/7zip/UI/FileManager/MemDialog.cpp b/CPP/7zip/UI/FileManager/MemDialog.cpp index 1ba717e..5d26d3a 100644 --- a/CPP/7zip/UI/FileManager/MemDialog.cpp +++ b/CPP/7zip/UI/FileManager/MemDialog.cpp @@ -55,13 +55,13 @@ static void AddSize_GB(UString &s, UInt32 size_GB, UInt32 id) AddLangString(s, id); } -void CMemDialog::AddInfoMessage_To_String(UString &s, UInt64 *ramSize_GB) +void CMemDialog::AddInfoMessage_To_String(UString &s, const UInt32 *ramSize_GB) { AddLangString(s, IDS_MEM_REQUIRES_BIG_MEM); AddSize_GB(s, Required_GB, IDS_MEM_REQUIRED_MEM_SIZE); AddSize_GB(s, Limit_GB, IDS_MEM_CURRENT_MEM_LIMIT); if (ramSize_GB) - AddSize_GB(s, (UInt32)*ramSize_GB, IDS_MEM_RAM_SIZE); + AddSize_GB(s, *ramSize_GB, IDS_MEM_RAM_SIZE); if (!FilePath.IsEmpty()) { s.Add_LF(); @@ -88,11 +88,11 @@ bool CMemDialog::OnInit() // m_Action.Attach(GetItem(IDC_MEM_ACTION)); - UInt64 ramSize = (UInt64)sizeof(size_t) << 29; + size_t ramSize = (size_t)sizeof(size_t) << 29; const bool ramSize_defined = NWindows::NSystem::GetRamSize(ramSize); // ramSize *= 10; // for debug - UInt64 ramSize_GB = (ramSize + (1u << 29)) >> 30; + UInt32 ramSize_GB = (UInt32)(((UInt64)ramSize + (1u << 29)) >> 30); if (ramSize_GB == 0) ramSize_GB = 1; @@ -121,7 +121,7 @@ bool CMemDialog::OnInit() if (ramSize_defined) { s += " / "; - s.Add_UInt64(ramSize_GB); + s.Add_UInt32(ramSize_GB); s += " GB (RAM)"; } SetItemText(IDT_MEM_GB, s); diff --git a/CPP/7zip/UI/FileManager/MemDialog.h b/CPP/7zip/UI/FileManager/MemDialog.h index 79de658..67f6b33 100644 --- a/CPP/7zip/UI/FileManager/MemDialog.h +++ b/CPP/7zip/UI/FileManager/MemDialog.h @@ -30,7 +30,7 @@ public: UString ArcPath; UString FilePath; - void AddInfoMessage_To_String(UString &s, UInt64 *ramSize_GB = NULL); + void AddInfoMessage_To_String(UString &s, const UInt32 *ramSize_GB = NULL); CMemDialog(): NeedSave(false), diff --git a/CPP/7zip/UI/FileManager/MyLoadMenu.cpp b/CPP/7zip/UI/FileManager/MyLoadMenu.cpp index 51b8648..f190929 100644 --- a/CPP/7zip/UI/FileManager/MyLoadMenu.cpp +++ b/CPP/7zip/UI/FileManager/MyLoadMenu.cpp @@ -764,8 +764,12 @@ bool ExecuteFileCommand(unsigned id) case IDM_CRC32: g_App.CalculateCrc("CRC32"); break; case IDM_CRC64: g_App.CalculateCrc("CRC64"); break; case IDM_XXH64: g_App.CalculateCrc("XXH64"); break; + case IDM_MD5: g_App.CalculateCrc("MD5"); break; case IDM_SHA1: g_App.CalculateCrc("SHA1"); break; case IDM_SHA256: g_App.CalculateCrc("SHA256"); break; + case IDM_SHA384: g_App.CalculateCrc("SHA384"); break; + case IDM_SHA512: g_App.CalculateCrc("SHA512"); break; + case IDM_SHA3_256: g_App.CalculateCrc("SHA3-256"); break; case IDM_BLAKE2SP: g_App.CalculateCrc("BLAKE2sp"); break; case IDM_DIFF: g_App.DiffFiles(); break; @@ -807,8 +811,8 @@ bool OnMenuCommand(HWND hWnd, unsigned id) { // File case IDCLOSE: - SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd); - g_ExitEventLauncher.Exit(false); + // SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd); + // g_ExitEventLauncher.Exit(false); SendMessage(hWnd, WM_CLOSE, 0, 0); break; diff --git a/CPP/7zip/UI/FileManager/OpenCallback.cpp b/CPP/7zip/UI/FileManager/OpenCallback.cpp index 5b6df50..e3cb2ec 100644 --- a/CPP/7zip/UI/FileManager/OpenCallback.cpp +++ b/CPP/7zip/UI/FileManager/OpenCallback.cpp @@ -27,7 +27,7 @@ HRESULT COpenArchiveCallback::Open_SetTotal(const UInt64 *numFiles, const UInt64 ProgressDialog.Sync.Set_NumFilesTotal(numFiles ? *numFiles : (UInt64)(Int64)-1); // if (numFiles) { - ProgressDialog.Sync.Set_BytesProgressMode(numFiles == NULL); + ProgressDialog.Sync.Set_FilesProgressMode(numFiles != NULL); } if (numBytes) ProgressDialog.Sync.Set_NumBytesTotal(*numBytes); diff --git a/CPP/7zip/UI/FileManager/Panel.cpp b/CPP/7zip/UI/FileManager/Panel.cpp index f3fb38e..84bd88c 100644 --- a/CPP/7zip/UI/FileManager/Panel.cpp +++ b/CPP/7zip/UI/FileManager/Panel.cpp @@ -7,8 +7,8 @@ #include "../../../Common/IntToString.h" #include "../../../Common/StringConvert.h" -#include "../../../Windows/FileName.h" #include "../../../Windows/ErrorMsg.h" +#include "../../../Windows/FileName.h" #include "../../../Windows/PropVariant.h" #include "../../../Windows/Thread.h" @@ -49,8 +49,9 @@ static DWORD kStyles[4] = { LVS_ICON, LVS_SMALLICON, LVS_LIST, LVS_REPORT }; extern HINSTANCE g_hInstance; -void CPanel::Release() +void CPanel::ReleasePanel() { + Disable_Processing_Timer_Notify_StatusBar(); // It's for unloading COM dll's: don't change it. CloseOpenFolders(); _sevenZipContextMenu.Release(); @@ -893,7 +894,7 @@ void CPanel::SetListViewMode(UInt32 index) void CPanel::ChangeFlatMode() { _flatMode = !_flatMode; - if (_parentFolders.Size() > 0) + if (!_parentFolders.IsEmpty()) _flatModeForArc = _flatMode; else _flatModeForDisk = _flatMode; @@ -904,7 +905,7 @@ void CPanel::ChangeFlatMode() void CPanel::Change_ShowNtfsStrems_Mode() { _showNtfsStrems_Mode = !_showNtfsStrems_Mode; - if (_parentFolders.Size() > 0) + if (!_parentFolders.IsEmpty()) _showNtfsStrems_ModeForArc = _showNtfsStrems_Mode; else _showNtfsStrems_ModeForDisk = _showNtfsStrems_Mode; @@ -1006,7 +1007,7 @@ void CPanel::GetFilePaths(const CRecordVector &operatedIndices, UStringV void CPanel::ExtractArchives() { - if (_parentFolders.Size() > 0) + if (!_parentFolders.IsEmpty()) { _panelCallback->OnCopy(false, false); return; diff --git a/CPP/7zip/UI/FileManager/Panel.h b/CPP/7zip/UI/FileManager/Panel.h index 1b708f7..9c53048 100644 --- a/CPP/7zip/UI/FileManager/Panel.h +++ b/CPP/7zip/UI/FileManager/Panel.h @@ -162,32 +162,39 @@ struct CTempFileInfo NWindows::NFile::NDir::RemoveDir(FolderPath); } } - bool WasChanged(const NWindows::NFile::NFind::CFileInfo &newFileInfo) const + bool WasChanged_from_TempFileInfo(const NWindows::NFile::NFind::CFileInfo &newFileInfo) const { return newFileInfo.Size != FileInfo.Size || CompareFileTime(&newFileInfo.MTime, &FileInfo.MTime) != 0; } }; + struct CFolderLink: public CTempFileInfo { - bool IsVirtual; + bool IsVirtual; // == true (if archive was open via IInStream): + // archive was open from another archive, + // archive size meets the size conditions derived from g_RAM_Size. + // VirtFileSystem was used + // archive was fully extracted to memory. bool UsePassword; NWindows::NDLL::CLibrary Library; CMyComPtr ParentFolder; // can be NULL, if parent is FS folder (in _parentFolders[0]) UString ParentFolderPath; // including tail slash (doesn't include paths parts of parent in next level) UString Password; - UString VirtualPath; // without tail slash - CFolderLink(): IsVirtual(false), UsePassword(false) {} + CByteBuffer ZoneBuf; // ZoneBuf for virtaul stream (IsVirtual) - bool WasChanged(const NWindows::NFile::NFind::CFileInfo &newFileInfo) const + CFolderLink(): IsVirtual(false), UsePassword(false) {} + bool WasChanged_from_FolderLink(const NWindows::NFile::NFind::CFileInfo &newFileInfo) const { - return IsVirtual || CTempFileInfo::WasChanged(newFileInfo); + // we call it, if we have two real files. + // if archive was virtual, it means that we have updated that virtual to real file. + return IsVirtual || CTempFileInfo::WasChanged_from_TempFileInfo(newFileInfo); } - }; + enum MyMessages { // we can use WM_USER, since we have defined new window class. @@ -268,13 +275,14 @@ struct CCopyToOptions bool NeedRegistryZone; NExtract::NZoneIdMode::EEnum ZoneIdMode; + CByteBuffer ZoneBuf; UString folder; UStringVector hashMethods; CVirtFileSystem *VirtFileSystemSpec; - ISequentialOutStream *VirtFileSystem; + // ISequentialOutStream *VirtFileSystem; CCopyToOptions(): streamMode(false), @@ -285,8 +293,8 @@ struct CCopyToOptions showErrorMessages(false), NeedRegistryZone(true), ZoneIdMode(NExtract::NZoneIdMode::kNone), - VirtFileSystemSpec(NULL), - VirtFileSystem(NULL) + VirtFileSystemSpec(NULL) + // , VirtFileSystem(NULL) {} }; @@ -310,11 +318,60 @@ struct COpenResult class CPanel Z7_final: public NWindows::NControl::CWindow2 { + bool _thereAre_ListView_Items; + // bool _virtualMode; + bool _enableItemChangeNotify; + bool _thereAreDeletedItems; + bool _markDeletedItems; + bool _dontShowMode; + bool _needSaveInfo; + +public: + bool PanelCreated; + bool _mySelectMode; + bool _showDots; + bool _showRealFileIcons; + bool _flatMode; + bool _flatModeForArc; + bool _flatModeForDisk; + bool _selectionIsDefined; + // bool _showNtfsStrems_Mode; + // bool _showNtfsStrems_ModeForDisk; + // bool _showNtfsStrems_ModeForArc; + + bool _selectMark; + bool _lastFocusedIsList; + + bool _processTimer; + bool _processNotify; + bool _processStatusBar; + +public: + bool _ascending; + PROPID _sortID; + // int _sortIndex; + Int32 _isRawSortProp; + + CMyListView _listView; + CPanelCallback *_panelCallback; + +private: + // CExtToIconMap _extToIconMap; UINT _baseID; unsigned _comboBoxID; UINT _statusBarID; +public: + DWORD _exStyle; + // CUIntVector _realIndices; + int _timestampLevel; + UInt32 _listViewMode; + int _xSize; +private: + int _startGroupSelect; + int _prevFocusedItem; + CAppState *_appState; virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam, LRESULT &result) Z7_override; @@ -351,22 +408,7 @@ class CPanel Z7_final: public NWindows::NControl::CWindow2 bool OnCustomDraw(LPNMLVCUSTOMDRAW lplvcd, LRESULT &result); -public: - HWND _mainWindow; - CPanelCallback *_panelCallback; - - // void SysIconsWereChanged() { _extToIconMap.Clear(); } - - void DeleteItems(bool toRecycleBin); - void CreateFolder(); - void CreateFile(); - bool CorrectFsPath(const UString &path, UString &result); - // bool IsPathForPlugin(const UString &path); - -private: - void ChangeWindowSize(int xSize, int ySize); - HRESULT InitColumns(); void DeleteColumn(unsigned index); void AddColumn(const CPropColumn &prop); @@ -379,20 +421,13 @@ private: void OnInsert(); // void OnUpWithShift(); // void OnDownWithShift(); -public: - void UpdateSelection(); - void SelectSpec(bool selectMode); - void SelectByType(bool selectMode); - void SelectAll(bool selectMode); - void InvertSelection(); -private: - // UString GetFileType(UInt32 index); LRESULT SetItemText(LVITEMW &item); - // CRecordVector m_ColumnsPropIDs; public: + HWND _mainWindow; + NWindows::NControl::CReBar _headerReBar; NWindows::NControl::CToolBar _headerToolBar; NWindows::NControl:: @@ -405,42 +440,57 @@ public: UStringVector ComboBoxPaths; // CMyComboBox _headerComboBox; CMyComboBoxEdit _comboBoxEdit; - CMyListView _listView; - bool _thereAre_ListView_Items; NWindows::NControl::CStatusBar _statusBar; - bool _lastFocusedIsList; // NWindows::NControl::CStatusBar _statusBar2; - DWORD _exStyle; - bool _showDots; - bool _showRealFileIcons; - // bool _virtualMode; - // CUIntVector _realIndices; - bool _enableItemChangeNotify; - bool _mySelectMode; + CBoolVector _selectedStatusVector; + CSelectedState _selectedState; - int _timestampLevel; + UString _currentFolderPrefix; + + CObjectVector _parentFolders; + NWindows::NDLL::CLibrary _library; + + CMyComPtr _folder; + CBoolVector _isDirVector; + CMyComPtr _folderCompare; + CMyComPtr _folderGetItemName; + CMyComPtr _folderRawProps; + CMyComPtr _folderAltStreams; + CMyComPtr _folderOperations; + // for drag and drop highliting + int m_DropHighlighted_SelectionIndex; + // int m_SubFolderIndex; // realIndex of item in m_Panel list (if drop cursor to that item) + UString m_DropHighlighted_SubFolderName; // name of folder in m_Panel list (if drop cursor to that folder) + + // CMyComPtr _folderGetSystemIconIndex; + UStringVector _fastFolders; + + UString _typeIDString; + CListViewInfo _listViewInfo; + + CPropColumns _columns; + CPropColumns _visibleColumns; + + CMyComPtr _sevenZipContextMenu; + CMyComPtr _systemContextMenu; + + void UpdateSelection(); + void SelectSpec(bool selectMode); + void SelectByType(bool selectMode); + void SelectAll(bool selectMode); + void InvertSelection(); void RedrawListItems() { _listView.RedrawAllItems(); } - - - CBoolVector _selectedStatusVector; - - CSelectedState _selectedState; - bool _thereAreDeletedItems; - bool _markDeletedItems; - - bool PanelCreated; - void DeleteListItems() { if (_thereAre_ListView_Items) { - bool b = _enableItemChangeNotify; + const bool b = _enableItemChangeNotify; _enableItemChangeNotify = false; _listView.DeleteAllItems(); _thereAre_ListView_Items = false; @@ -448,6 +498,15 @@ public: } } + // void SysIconsWereChanged() { _extToIconMap.Clear(); } + + void DeleteItems(bool toRecycleBin); + void CreateFolder(); + void CreateFile(); + bool CorrectFsPath(const UString &path, UString &result); + // bool IsPathForPlugin(const UString &path); + + HWND GetParent() const; UInt32 GetRealIndex(const LVITEMW &item) const @@ -471,46 +530,8 @@ public: return (unsigned)param; } - UInt32 _listViewMode; - int _xSize; - - bool _flatMode; - bool _flatModeForDisk; - bool _flatModeForArc; - - // bool _showNtfsStrems_Mode; - // bool _showNtfsStrems_ModeForDisk; - // bool _showNtfsStrems_ModeForArc; - - bool _dontShowMode; - - - UString _currentFolderPrefix; - - CObjectVector _parentFolders; - NWindows::NDLL::CLibrary _library; - - CMyComPtr _folder; - CBoolVector _isDirVector; - CMyComPtr _folderCompare; - CMyComPtr _folderGetItemName; - CMyComPtr _folderRawProps; - CMyComPtr _folderAltStreams; - CMyComPtr _folderOperations; - - - // for drag and drop highliting - int m_DropHighlighted_SelectionIndex; - // int m_SubFolderIndex; // realIndex of item in m_Panel list (if drop cursor to that item) - UString m_DropHighlighted_SubFolderName; // name of folder in m_Panel list (if drop cursor to that folder) - void ReleaseFolder(); void SetNewFolder(IFolderFolder *newFolder); - - // CMyComPtr _folderGetSystemIconIndex; - - UStringVector _fastFolders; - void GetSelectedNames(UStringVector &selectedNames); void SaveSelectedState(CSelectedState &s); HRESULT RefreshListCtrl(const CSelectedState &s); @@ -575,61 +596,44 @@ public: CPanel() : _thereAre_ListView_Items(false), - _exStyle(0), - _showDots(false), - _showRealFileIcons(false), - // _virtualMode(flase), + // _virtualMode(false), _enableItemChangeNotify(true), - _mySelectMode(false), - _timestampLevel(kTimestampPrintLevel_MIN), - _thereAreDeletedItems(false), _markDeletedItems(true), - PanelCreated(false), - - _listViewMode(3), - _xSize(300), + _dontShowMode(false), + _needSaveInfo(false), + PanelCreated(false), + _mySelectMode(false), + _showDots(false), + _showRealFileIcons(false), _flatMode(false), - _flatModeForDisk(false), _flatModeForArc(false), - + _flatModeForDisk(false), + _selectionIsDefined(false), // _showNtfsStrems_Mode(false), // _showNtfsStrems_ModeForDisk(false), // _showNtfsStrems_ModeForArc(false), - _dontShowMode(false), - - m_DropHighlighted_SelectionIndex(-1), - - _needSaveInfo(false), + _exStyle(0), + _timestampLevel(kTimestampPrintLevel_MIN), + _listViewMode(3), + _xSize(300), _startGroupSelect(0), - _selectionIsDefined(false) + m_DropHighlighted_SelectionIndex(-1) {} + ~CPanel() Z7_DESTRUCTOR_override; + + void ReleasePanel(); + void SetExtendedStyle() { if (_listView) _listView.SetExtendedListViewStyle(_exStyle); } - - bool _needSaveInfo; - UString _typeIDString; - CListViewInfo _listViewInfo; - - CPropColumns _columns; - CPropColumns _visibleColumns; - - PROPID _sortID; - // int _sortIndex; - bool _ascending; - Int32 _isRawSortProp; - void SetSortRawStatus(); - - void Release(); - ~CPanel() Z7_DESTRUCTOR_override; void OnLeftClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate); bool OnRightClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate, LRESULT &result); void ShowColumnsContextMenu(int x, int y); @@ -638,9 +642,6 @@ public: void OnReload(bool onTimer = false); bool OnContextMenu(HANDLE windowHandle, int xPos, int yPos); - CMyComPtr _sevenZipContextMenu; - CMyComPtr _systemContextMenu; - HRESULT CreateShellContextMenu( const CRecordVector &operatedIndices, CMyComPtr &systemContextMenu); @@ -672,12 +673,6 @@ public: void EditCopy(); void EditPaste(); - int _startGroupSelect; - - bool _selectionIsDefined; - bool _selectMark; - int _prevFocusedItem; - // void SortItems(int index); void SortItemsWithPropID(PROPID propID); @@ -751,9 +746,12 @@ public: bool IsThereReadOnlyFolder() const; bool CheckBeforeUpdate(UINT resourceID); - bool _processTimer; - bool _processNotify; - bool _processStatusBar; + void Disable_Processing_Timer_Notify_StatusBar() + { + _processTimer = false; + _processNotify = false; + _processStatusBar = false; + } class CDisableTimerProcessing { @@ -926,6 +924,7 @@ public: void ExtractArchives(); void TestArchives(); + void Get_ZoneId_Stream_from_ParentFolders(CByteBuffer &buf); HRESULT CopyTo(CCopyToOptions &options, const CRecordVector &indices, @@ -939,7 +938,7 @@ public: { bool usePassword = false; UString password; - if (_parentFolders.Size() > 0) + if (!_parentFolders.IsEmpty()) { const CFolderLink &fl = _parentFolders.Back(); usePassword = fl.UsePassword; @@ -978,6 +977,7 @@ public: UString GetItemsInfoString(const CRecordVector &indices); }; + class CMyBuffer { void *_data; @@ -994,13 +994,12 @@ public: ~CMyBuffer() { ::MidFree(_data); } }; -class CExitEventLauncher +struct CExitEventLauncher { -public: NWindows::NSynchronization::CManualResetEvent _exitEvent; bool _needExit; - CRecordVector< ::CThread > _threads; unsigned _numActiveThreads; + CRecordVector< ::CThread > _threads; CExitEventLauncher() { diff --git a/CPP/7zip/UI/FileManager/PanelCopy.cpp b/CPP/7zip/UI/FileManager/PanelCopy.cpp index 36a0f6d..d4f1db7 100644 --- a/CPP/7zip/UI/FileManager/PanelCopy.cpp +++ b/CPP/7zip/UI/FileManager/PanelCopy.cpp @@ -75,11 +75,21 @@ HRESULT CPanelCopyThread::ProcessVirt() if (FolderOperations) { - CMyComPtr setZoneMode; - FolderOperations.QueryInterface(IID_IFolderSetZoneIdMode, &setZoneMode); - if (setZoneMode) { - RINOK(setZoneMode->SetZoneIdMode(options->ZoneIdMode)) + CMyComPtr setZoneMode; + FolderOperations.QueryInterface(IID_IFolderSetZoneIdMode, &setZoneMode); + if (setZoneMode) + { + RINOK(setZoneMode->SetZoneIdMode(options->ZoneIdMode)) + } + } + { + CMyComPtr setZoneFile; + FolderOperations.QueryInterface(IID_IFolderSetZoneIdFile, &setZoneFile); + if (setZoneFile) + { + RINOK(setZoneFile->SetZoneIdFile(options->ZoneBuf, (UInt32)options->ZoneBuf.Size())) + } } } @@ -143,6 +153,32 @@ static void ThrowException_if_Error(HRESULT res) #endif */ +void CPanel::Get_ZoneId_Stream_from_ParentFolders(CByteBuffer &buf) +{ + // we suppose that ZoneId of top parent has priority over ZoneId from childs. + FOR_VECTOR (i, _parentFolders) + { + // _parentFolders[0] = is top level archive + // _parentFolders[1 ... ].isVirtual == true is possible + // if extracted size meets size conditions derived from g_RAM_Size. + const CFolderLink &fl = _parentFolders[i]; + if (fl.IsVirtual) + { + if (fl.ZoneBuf.Size() != 0) + { + buf = fl.ZoneBuf; + return; + } + } + else if (!fl.FilePath.IsEmpty()) + { + ReadZoneFile_Of_BaseFile(fl.FilePath, buf); + if (buf.Size() != 0) + return; + } + } +} + HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector &indices, UStringVector *messages, @@ -157,6 +193,10 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, options.ZoneIdMode = (NExtract::NZoneIdMode::EEnum)(int)(Int32)ci.WriteZone; } + if (options.ZoneBuf.Size() == 0 + && options.ZoneIdMode != NExtract::NZoneIdMode::kNone) + Get_ZoneId_Stream_from_ParentFolders(options.ZoneBuf); + if (IsHashFolder()) { if (!options.testMode) @@ -205,9 +245,9 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, extracter.Hash.MainName = extracter.Hash.FirstFileName; } - if (options.VirtFileSystem) + if (options.VirtFileSystemSpec) { - extracter.ExtractCallbackSpec->VirtFileSystem = options.VirtFileSystem; + extracter.ExtractCallbackSpec->VirtFileSystem = options.VirtFileSystemSpec; extracter.ExtractCallbackSpec->VirtFileSystemSpec = options.VirtFileSystemSpec; } extracter.ExtractCallbackSpec->ProcessAltStreams = options.includeAltStreams; diff --git a/CPP/7zip/UI/FileManager/PanelDrag.cpp b/CPP/7zip/UI/FileManager/PanelDrag.cpp index 040444c..f9b0a6c 100644 --- a/CPP/7zip/UI/FileManager/PanelDrag.cpp +++ b/CPP/7zip/UI/FileManager/PanelDrag.cpp @@ -2614,11 +2614,11 @@ Z7_COMWF_B CDropTarget::Drop(IDataObject *dataObject, DWORD keyState, UString s = LangString(cmdEffect == DROPEFFECT_MOVE ? IDS_MOVE_TO : IDS_COPY_TO); s.Add_LF(); - s += "\'"; + // s += "\'"; s += m_Panel->_currentFolderPrefix; - s += "\'"; + // s += "\'"; s.Add_LF(); - s += LangString(IDS_WANT_TO_COPY_FILES); + AddLangString(s, IDS_WANT_TO_COPY_FILES); s += " ?"; const int res = ::MessageBoxW(*m_Panel, s, title, MB_YESNOCANCEL | MB_ICONQUESTION); if (res != IDYES) @@ -2954,7 +2954,7 @@ static unsigned Drag_OnContextMenu(int xPos, int yPos, UInt32 cmdFlags) name = MyFormatNew(name, destPath); */ name.Add_Space(); - name += LangString(IDS_CONTEXT_ARCHIVE); + AddLangString(name, IDS_CONTEXT_ARCHIVE); } if (cmdId == NDragMenu::k_Cancel) menu.AppendItem(MF_SEPARATOR, 0, (LPCTSTR)NULL); diff --git a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp index 244a962..aa56ef5 100644 --- a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp +++ b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp @@ -39,7 +39,7 @@ using namespace NFile; using namespace NDir; extern bool g_RAM_Size_Defined; -extern UInt64 g_RAM_Size; +extern size_t g_RAM_Size; #ifndef _UNICODE extern bool g_IsNT; @@ -606,9 +606,9 @@ HRESULT CPanel::OpenParentArchiveFolder() NFind::CFileInfo newFileInfo; if (newFileInfo.Find(folderLink.FilePath)) { - if (folderLink.WasChanged(newFileInfo)) + if (folderLink.WasChanged_from_FolderLink(newFileInfo)) { - UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, folderLink.RelPath); + const UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, folderLink.RelPath); if (::MessageBoxW((HWND)*this, message, L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION) == IDYES) { if (OnOpenItemChanged(folderLink.FileIndex, fs2us(folderLink.FilePath), @@ -1083,13 +1083,11 @@ void CExitEventLauncher::Exit(bool hardExit) FOR_VECTOR (i, _threads) { ::CThread &th = _threads[i]; - DWORD wait = (hardExit ? 100 : INFINITE); if (Thread_WasCreated(&th)) { - DWORD waitResult = WaitForSingleObject(th, wait); + const DWORD waitResult = WaitForSingleObject(th, hardExit ? 100 : INFINITE); // Thread_Wait(&th); - if (waitResult == WAIT_TIMEOUT) - wait = 1; + // if (waitResult == WAIT_TIMEOUT) wait = 1; if (!hardExit && waitResult != WAIT_OBJECT_0) continue; Thread_Close(&th); @@ -1107,7 +1105,7 @@ static THREAD_FUNC_DECL MyThreadFunction(void *param) CMyUniquePtr tpi((CTmpProcessInfo *)param); CChildProcesses &processes = tpi->Processes; - bool mainProcessWasSet = !processes.Handles.IsEmpty(); + const bool mainProcessWasSet = !processes.Handles.IsEmpty(); bool isComplexMode = true; @@ -1195,7 +1193,7 @@ static THREAD_FUNC_DECL MyThreadFunction(void *param) { NFind::CFileInfo newFileInfo; if (newFileInfo.Find(tpi->FilePath)) - if (tpi->WasChanged(newFileInfo)) + if (tpi->WasChanged_from_TempFileInfo(newFileInfo)) needFindProcessByPath = false; } @@ -1235,7 +1233,7 @@ static THREAD_FUNC_DECL MyThreadFunction(void *param) if (mainProcessWasSet) { - if (tpi->WasChanged(newFileInfo)) + if (tpi->WasChanged_from_TempFileInfo(newFileInfo)) { UString m = MyFormatNew(IDS_CANNOT_UPDATE_FILE, fs2us(tpi->FilePath)); if (tpi->ReadOnly) @@ -1279,10 +1277,10 @@ static THREAD_FUNC_DECL MyThreadFunction(void *param) { NFind::CFileInfo newFileInfo; - - bool finded = newFileInfo.Find(tpi->FilePath); - - if (!needCheckTimestamp || !finded || !tpi->WasChanged(newFileInfo)) + const bool finded = newFileInfo.Find(tpi->FilePath); + if (!needCheckTimestamp + || !finded + || !tpi->WasChanged_from_TempFileInfo(newFileInfo)) { DEBUG_PRINT("Delete Temp file"); tpi->DeleteDirAndFile(); @@ -1534,7 +1532,7 @@ void CPanel::OpenItemInArchive(unsigned index, bool tryInternal, bool tryExterna bool usePassword = false; UString password; - if (_parentFolders.Size() > 0) + if (!_parentFolders.IsEmpty()) { const CFolderLink &fl = _parentFolders.Back(); usePassword = fl.UsePassword; @@ -1547,7 +1545,7 @@ void CPanel::OpenItemInArchive(unsigned index, bool tryInternal, bool tryExterna #ifndef _UNICODE if (g_IsNT) #endif - if (_parentFolders.Size() > 0) + if (!_parentFolders.IsEmpty()) { const CFolderLink &fl = _parentFolders.Front(); if (!fl.IsVirtual && !fl.FilePath.IsEmpty()) @@ -1576,39 +1574,42 @@ void CPanel::OpenItemInArchive(unsigned index, bool tryInternal, bool tryExterna if (tryAsArchive) { + // actually we want to get sum: size of main file plus sizes of altStreams. + // but now there is no interface to get altStreams sizes. NCOM::CPropVariant prop; _folder->GetProperty(index, kpidSize, &prop); - UInt64 fileLimit = 1 << 22; - if (g_RAM_Size_Defined) - fileLimit = g_RAM_Size / 4; - + const size_t fileLimit = g_RAM_Size_Defined ? + g_RAM_Size >> MyMax(_parentFolders.Size() + 1, 8u): + 1u << 22; UInt64 fileSize = 0; if (!ConvertPropVariantToUInt64(prop, fileSize)) fileSize = fileLimit; - if (fileSize <= fileLimit && fileSize > 0) +#if 0 // 1 : for debug + fileLimit = 1; +#endif + + if (fileSize <= fileLimit) { options.streamMode = true; virtFileSystemSpec = new CVirtFileSystem; virtFileSystem = virtFileSystemSpec; + virtFileSystemSpec->FileName = name; + virtFileSystemSpec->IsAltStreamFile = isAltStream; #if defined(_WIN32) && !defined(UNDER_CE) #ifndef _UNICODE if (g_IsNT) #endif - if (_parentFolders.Size() > 0) { - const CFolderLink &fl = _parentFolders.Front(); - if (!fl.IsVirtual && !fl.FilePath.IsEmpty()) - ReadZoneFile_Of_BaseFile(fl.FilePath, virtFileSystemSpec->ZoneBuf); + Get_ZoneId_Stream_from_ParentFolders(virtFileSystemSpec->ZoneBuf); + options.ZoneBuf = virtFileSystemSpec->ZoneBuf; } #endif - // we allow additional total size for small alt streams; - virtFileSystemSpec->MaxTotalAllocSize = fileSize + (1 << 10); - + virtFileSystemSpec->MaxTotalAllocSize = (size_t)fileSize + + (1 << 16); // we allow additional total size for small alt streams. virtFileSystemSpec->DirPrefix = tempDirNorm; - virtFileSystemSpec->Init(); - options.VirtFileSystem = virtFileSystem; + // options.VirtFileSystem = virtFileSystem; options.VirtFileSystemSpec = virtFileSystemSpec; } } @@ -1618,7 +1619,7 @@ void CPanel::OpenItemInArchive(unsigned index, bool tryInternal, bool tryExterna const HRESULT result = CopyTo(options, indices, &messages, usePassword, password); - if (_parentFolders.Size() > 0) + if (!_parentFolders.IsEmpty()) { CFolderLink &fl = _parentFolders.Back(); fl.UsePassword = usePassword; @@ -1634,34 +1635,46 @@ void CPanel::OpenItemInArchive(unsigned index, bool tryInternal, bool tryExterna return; } - if (options.VirtFileSystem) + if (virtFileSystemSpec && !virtFileSystemSpec->WasStreamFlushedToFS()) { - if (virtFileSystemSpec->IsStreamInMem()) + int index_in_Files = virtFileSystemSpec->Index_of_MainExtractedFile_in_Files; + if (index_in_Files < 0) { - const CVirtFile &file = virtFileSystemSpec->Files[0]; - - size_t streamSize = (size_t)file.Size; - CBufInStream *bufInStreamSpec = new CBufInStream; - CMyComPtr bufInStream = bufInStreamSpec; - bufInStreamSpec->Init(file.Data, streamSize, virtFileSystem); - - HRESULT res = OpenAsArc_Msg(bufInStream, tempFileInfo, fullVirtPath, type ? type : L"" + if (virtFileSystemSpec->Files.Size() != 1) + { + MessageBox_Error_HRESULT(E_FAIL); + return; + } + // it's not expected case that index was not set, but we support that case + index_in_Files = 0; + } + { + const CVirtFile &file = virtFileSystemSpec->Files[index_in_Files]; + CMyComPtr2_Create bufInStream; + bufInStream->Init(file.Data, file.WrittenSize, virtFileSystem); + const HRESULT res = OpenAsArc_Msg(bufInStream, tempFileInfo, + fullVirtPath, type ? type : L"" // , encrypted // , true // showErrorMessage ); - if (res == S_OK) { + if (virtFileSystemSpec->Index_of_ZoneBuf_AltStream_in_Files >= 0 + && !_parentFolders.IsEmpty()) + { + const CVirtFile &fileZone = virtFileSystemSpec->Files[ + virtFileSystemSpec->Index_of_ZoneBuf_AltStream_in_Files]; + _parentFolders.Back().ZoneBuf.CopyFrom(fileZone.Data, fileZone.WrittenSize); + } + tempDirectory.DisableDeleting(); RefreshListCtrl(); return; } - if (res == E_ABORT || res != S_FALSE) return; if (!tryExternal) return; - tryAsArchive = false; if (virtFileSystemSpec->FlushToDisk(true) != S_OK) return; @@ -1684,7 +1697,7 @@ void CPanel::OpenItemInArchive(unsigned index, bool tryInternal, bool tryExterna if (tryAsArchive) { - HRESULT res = OpenAsArc_Msg(NULL, tempFileInfo, fullVirtPath, type ? type : L"" + const HRESULT res = OpenAsArc_Msg(NULL, tempFileInfo, fullVirtPath, type ? type : L"" // , encrypted // , true // showErrorMessage ); @@ -1732,7 +1745,7 @@ void CPanel::OpenItemInArchive(unsigned index, bool tryInternal, bool tryExterna return; } - tpi->Window = (HWND)(*this); + tpi->Window = (HWND)*this; tpi->FullPathFolderPrefix = _currentFolderPrefix; tpi->FileIndex = index; tpi->RelPath = relPath; diff --git a/CPP/7zip/UI/FileManager/PanelItems.cpp b/CPP/7zip/UI/FileManager/PanelItems.cpp index 544e9bf..868ad22 100644 --- a/CPP/7zip/UI/FileManager/PanelItems.cpp +++ b/CPP/7zip/UI/FileManager/PanelItems.cpp @@ -1438,13 +1438,16 @@ void CPanel::OnTimer() return; if (!AutoRefresh_Mode) return; - CMyComPtr folderWasChanged; - if (_folder.QueryInterface(IID_IFolderWasChanged, &folderWasChanged) != S_OK) - return; - Int32 wasChanged; - if (folderWasChanged->WasChanged(&wasChanged) != S_OK) - return; - if (wasChanged == 0) + if (!_folder) // it's unexpected case, but we use it as additional protection. return; + { + CMyComPtr folderWasChanged; + _folder.QueryInterface(IID_IFolderWasChanged, &folderWasChanged); + if (!folderWasChanged) + return; + Int32 wasChanged; + if (folderWasChanged->WasChanged(&wasChanged) != S_OK || wasChanged == 0) + return; + } OnReload(true); // onTimer } diff --git a/CPP/7zip/UI/FileManager/PanelListNotify.cpp b/CPP/7zip/UI/FileManager/PanelListNotify.cpp index 4dbd9f6..05ab36b 100644 --- a/CPP/7zip/UI/FileManager/PanelListNotify.cpp +++ b/CPP/7zip/UI/FileManager/PanelListNotify.cpp @@ -785,7 +785,7 @@ void CPanel::Refresh_StatusBar() wchar_t selectSizeString[32]; selectSizeString[0] = 0; - if (indices.Size() > 0) + if (!indices.IsEmpty()) { // for (unsigned ttt = 0; ttt < 1000; ttt++) { UInt64 totalSize = 0; diff --git a/CPP/7zip/UI/FileManager/PanelOperations.cpp b/CPP/7zip/UI/FileManager/PanelOperations.cpp index af313ff..8b16224 100644 --- a/CPP/7zip/UI/FileManager/PanelOperations.cpp +++ b/CPP/7zip/UI/FileManager/PanelOperations.cpp @@ -80,7 +80,7 @@ HRESULT CThreadFolderOperations::DoOperation(CPanel &panel, const UString &progr UpdateCallbackSpec->Init(); - if (panel._parentFolders.Size() > 0) + if (!panel._parentFolders.IsEmpty()) { const CFolderLink &fl = panel._parentFolders.Back(); UpdateCallbackSpec->PasswordIsDefined = fl.UsePassword; diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp index 690ebec..a070a0a 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp +++ b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp @@ -78,8 +78,9 @@ static const UInt32 kLangIDs_Colon[] = #define IS_DEFINED_VAL(v) ((v) != UNDEFINED_VAL) CProgressSync::CProgressSync(): - _stopped(false), _paused(false), - _bytesProgressMode(true), + _stopped(false), + _paused(false), + _filesProgressMode(false), _isDir(false), _totalBytes(UNDEFINED_VAL), _completedBytes(0), _totalFiles(UNDEFINED_VAL), _curFiles(0), @@ -108,6 +109,13 @@ HRESULT CProgressSync::CheckStop() } } +void CProgressSync::Clear_Stop_Status() +{ + CRITICAL_LOCK + if (_stopped) + _stopped = false; +} + HRESULT CProgressSync::ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir) { { @@ -242,27 +250,27 @@ void CProgressSync::AddError_Code_Name(HRESULT systemError, const wchar_t *name) } CProgressDialog::CProgressDialog(): - _timer(0), - CompressingMode(true), - MainWindow(NULL) + _isDir(false), + _wasCreated(false), + _needClose(false), + _errorsWereDisplayed(false), + _waitCloseByCancelButton(false), + _cancelWasPressed(false), + _inCancelMessageBox(false), + _externalCloseMessageWasReceived(false), + _background(false), + WaitMode(false), + MessagesDisplayed(false), + CompressingMode(true), + ShowCompressionInfo(true), + _numPostedMessages(0), + _numAutoSizeMessages(0), + _numMessages(0), + _timer(0), + IconID(-1), + MainWindow(NULL) { - _isDir = false; - - _numMessages = 0; - IconID = -1; - MessagesDisplayed = false; - _wasCreated = false; - _needClose = false; - _inCancelMessageBox = false; - _externalCloseMessageWasReceived = false; - - _numPostedMessages = 0; - _numAutoSizeMessages = 0; - _errorsWereDisplayed = false; - _waitCloseByCancelButton = false; - _cancelWasPressed = false; - ShowCompressionInfo = true; - WaitMode = false; + if (_dialogCreatedEvent.Create() != S_OK) throw 1334987; if (_createDialogEvent.Create() != S_OK) @@ -357,8 +365,6 @@ bool CProgressDialog::OnInit() _filesStr_Prev.Empty(); _filesTotStr_Prev.Empty(); - _foreground = true; - m_ProgressBar.Attach(GetItem(IDC_PROGRESS1)); _messageList.Attach(GetItem(IDL_PROGRESS_MESSAGES)); _messageList.SetUnicodeFormat(); @@ -388,9 +394,8 @@ bool CProgressDialog::OnInit() SetPauseText(); SetPriorityText(); - _messageList.InsertColumn(0, L"", 30); - _messageList.InsertColumn(1, L"", 600); - + _messageList.InsertColumn(0, L"", 40); + _messageList.InsertColumn(1, L"", 460); _messageList.SetColumnWidthAuto(0); _messageList.SetColumnWidthAuto(1); @@ -690,7 +695,7 @@ static UInt64 MyMultAndDiv(UInt64 mult1, UInt64 mult2, UInt64 divider) void CProgressDialog::UpdateStatInfo(bool showAll) { UInt64 total, completed, totalFiles, completedFiles, inSize, outSize; - bool bytesProgressMode; + bool filesProgressMode; bool titleFileName_Changed; bool curFilePath_Changed; @@ -704,7 +709,7 @@ void CProgressDialog::UpdateStatInfo(bool showAll) completedFiles = Sync._curFiles; inSize = Sync._inSize; outSize = Sync._outSize; - bytesProgressMode = Sync._bytesProgressMode; + filesProgressMode = Sync._filesProgressMode; GetChangedString(Sync._titleFileName, _titleFileName, titleFileName_Changed); GetChangedString(Sync._filePath, _filePath, curFilePath_Changed); @@ -719,8 +724,8 @@ void CProgressDialog::UpdateStatInfo(bool showAll) UInt32 curTime = ::GetTickCount(); - const UInt64 progressTotal = bytesProgressMode ? total : totalFiles; - const UInt64 progressCompleted = bytesProgressMode ? completed : completedFiles; + const UInt64 progressTotal = filesProgressMode ? totalFiles : total; + const UInt64 progressCompleted = filesProgressMode ? completedFiles : completed; { if (IS_UNDEFINED_VAL(progressTotal)) { @@ -900,7 +905,7 @@ void CProgressDialog::UpdateStatInfo(bool showAll) { UString s = _status; ReduceString(s, _numReduceSymbols); - SetItemText(IDT_PROGRESS_STATUS, _status); + SetItemText(IDT_PROGRESS_STATUS, s); } if (curFilePath_Changed) @@ -1086,12 +1091,10 @@ void CProgressDialog::SetTitleText() } if (IS_DEFINED_VAL(_prevPercentValue)) { - char temp[32]; - ConvertUInt64ToString(_prevPercentValue, temp); - s += temp; + s.Add_UInt64(_prevPercentValue); s.Add_Char('%'); } - if (!_foreground) + if (_background) { s.Add_Space(); s += _backgrounded_String; @@ -1138,17 +1141,17 @@ void CProgressDialog::OnPauseButton() void CProgressDialog::SetPriorityText() { - SetItemText(IDB_PROGRESS_BACKGROUND, _foreground ? - _background_String : - _foreground_String); + SetItemText(IDB_PROGRESS_BACKGROUND, _background ? + _foreground_String : + _background_String); SetTitleText(); } void CProgressDialog::OnPriorityButton() { - _foreground = !_foreground; + _background = !_background; #ifndef UNDER_CE - SetPriorityClass(GetCurrentProcess(), _foreground ? NORMAL_PRIORITY_CLASS: IDLE_PRIORITY_CLASS); + SetPriorityClass(GetCurrentProcess(), _background ? IDLE_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS); #endif SetPriorityText(); } @@ -1184,12 +1187,16 @@ void CProgressDialog::AddMessage(LPCWSTR message) _numMessages++; } -static unsigned GetNumDigits(UInt32 val) +static unsigned GetNumDigits(unsigned val) { - unsigned i; - for (i = 0; val >= 10; i++) + unsigned i = 0; + for (;;) + { + i++; val /= 10; - return i; + if (val == 0) + return i; + } } void CProgressDialog::UpdateMessagesDialog() @@ -1197,7 +1204,7 @@ void CProgressDialog::UpdateMessagesDialog() UStringVector messages; { NSynchronization::CCriticalSectionLock lock(Sync._cs); - unsigned num = Sync.Messages.Size(); + const unsigned num = Sync.Messages.Size(); if (num > _numPostedMessages) { messages.ClearAndReserve(num - _numPostedMessages); @@ -1210,7 +1217,11 @@ void CProgressDialog::UpdateMessagesDialog() { FOR_VECTOR (i, messages) AddMessage(messages[i]); - if (_numAutoSizeMessages < 256 || GetNumDigits(_numPostedMessages) > GetNumDigits(_numAutoSizeMessages)) + // SetColumnWidthAuto() can be slow for big number of files. + if (_numPostedMessages < 1000000 || _numAutoSizeMessages < 100) + if (_numAutoSizeMessages < 100 || + GetNumDigits(_numPostedMessages) > + GetNumDigits(_numAutoSizeMessages)) { _messageList.SetColumnWidthAuto(0); _messageList.SetColumnWidthAuto(1); diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.h b/CPP/7zip/UI/FileManager/ProgressDialog2.h index 4ca9be7..60a5ca6 100644 --- a/CPP/7zip/UI/FileManager/ProgressDialog2.h +++ b/CPP/7zip/UI/FileManager/ProgressDialog2.h @@ -33,9 +33,8 @@ class CProgressSync { bool _stopped; bool _paused; - public: - bool _bytesProgressMode; + bool _filesProgressMode; bool _isDir; UInt64 _totalBytes; UInt64 _completedBytes; @@ -73,13 +72,14 @@ public: _paused = val; } - void Set_BytesProgressMode(bool bytesProgressMode) + void Set_FilesProgressMode(bool filesProgressMode) { NWindows::NSynchronization::CCriticalSectionLock lock(_cs); - _bytesProgressMode = bytesProgressMode; + _filesProgressMode = filesProgressMode; } HRESULT CheckStop(); + void Clear_Stop_Status(); HRESULT ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir = false); HRESULT Set_NumFilesTotal(UInt64 val); @@ -102,12 +102,32 @@ public: bool ThereIsMessage() const { return !Messages.IsEmpty() || FinalMessage.ThereIsMessage(); } }; + class CProgressDialog: public NWindows::NControl::CModalDialog { + bool _isDir; + bool _wasCreated; + bool _needClose; + bool _errorsWereDisplayed; + bool _waitCloseByCancelButton; + bool _cancelWasPressed; + bool _inCancelMessageBox; + bool _externalCloseMessageWasReceived; + bool _background; +public: + bool WaitMode; + bool MessagesDisplayed; // = true if user pressed OK on all messages or there are no messages. + bool CompressingMode; + bool ShowCompressionInfo; + +private: + unsigned _numPostedMessages; + unsigned _numAutoSizeMessages; + unsigned _numMessages; + UString _titleFileName; UString _filePath; UString _status; - bool _isDir; UString _background_String; UString _backgrounded_String; @@ -152,7 +172,6 @@ class CProgressDialog: public NWindows::NControl::CModalDialog NWindows::NControl::CProgressBar m_ProgressBar; NWindows::NControl::CListView _messageList; - unsigned _numMessages; UStringVector _messageStrings; // #ifdef __ITaskbarList3_INTERFACE_DEFINED__ @@ -175,28 +194,10 @@ class CProgressDialog: public NWindows::NControl::CModalDialog UString _filesStr_Prev; UString _filesTotStr_Prev; + unsigned _numReduceSymbols; unsigned _prevSpeed_MoveBits; UInt64 _prevSpeed; - bool _foreground; - - unsigned _numReduceSymbols; - - bool _wasCreated; - bool _needClose; - - unsigned _numPostedMessages; - UInt32 _numAutoSizeMessages; - - bool _errorsWereDisplayed; - - bool _waitCloseByCancelButton; - bool _cancelWasPressed; - - bool _inCancelMessageBox; - bool _externalCloseMessageWasReceived; - - // #ifdef __ITaskbarList3_INTERFACE_DEFINED__ void SetTaskbarProgressState(TBPFLAG tbpFlags) { @@ -244,14 +245,10 @@ class CProgressDialog: public NWindows::NControl::CModalDialog void ShowAfterMessages(HWND wndParent); void CheckNeedClose(); + public: CProgressSync Sync; - bool CompressingMode; - bool WaitMode; - bool ShowCompressionInfo; - bool MessagesDisplayed; // = true if user pressed OK on all messages or there are no messages. int IconID; - HWND MainWindow; #ifndef Z7_SFX UString MainTitle; diff --git a/CPP/7zip/UI/FileManager/RegistryUtils.cpp b/CPP/7zip/UI/FileManager/RegistryUtils.cpp index 7e61998..0284591 100644 --- a/CPP/7zip/UI/FileManager/RegistryUtils.cpp +++ b/CPP/7zip/UI/FileManager/RegistryUtils.cpp @@ -86,17 +86,15 @@ static bool Read7ZipOption(LPCTSTR value, bool defaultValue) if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) == ERROR_SUCCESS) { bool enabled; - if (key.QueryValue(value, enabled) == ERROR_SUCCESS) + if (key.GetValue_bool_IfOk(value, enabled) == ERROR_SUCCESS) return enabled; } return defaultValue; } -static void ReadOption(CKey &key, LPCTSTR value, bool &dest) +static void ReadOption(CKey &key, LPCTSTR name, bool &dest) { - bool enabled = false; - if (key.QueryValue(value, enabled) == ERROR_SUCCESS) - dest = enabled; + key.GetValue_bool_IfOk(name, dest); } /* diff --git a/CPP/7zip/UI/FileManager/SettingsPage.cpp b/CPP/7zip/UI/FileManager/SettingsPage.cpp index a5117be..8b5983a 100644 --- a/CPP/7zip/UI/FileManager/SettingsPage.cpp +++ b/CPP/7zip/UI/FileManager/SettingsPage.cpp @@ -161,7 +161,7 @@ bool CSettingsPage::OnInit() needSetCur = false; } { - _ramSize = (UInt64)(sizeof(size_t)) << 29; + _ramSize = (size_t)sizeof(size_t) << 29; _ramSize_Defined = NSystem::GetRamSize(_ramSize); UString s; if (_ramSize_Defined) @@ -198,10 +198,10 @@ bool CSettingsPage::OnInit() { - UInt64 ramSize = (UInt64)sizeof(size_t) << 29; + size_t ramSize = (size_t)sizeof(size_t) << 29; const bool ramSize_defined = NWindows::NSystem::GetRamSize(ramSize); // ramSize *= 10; // for debug - UInt64 ramSize_GB = (ramSize + (1u << 29)) >> 30; + UInt32 ramSize_GB = (UInt32)(((UInt64)ramSize + (1u << 29)) >> 30); if (ramSize_GB == 0) ramSize_GB = 1; UString s ("GB"); diff --git a/CPP/7zip/UI/FileManager/SysIconUtils.cpp b/CPP/7zip/UI/FileManager/SysIconUtils.cpp index 406c9e1..72fe5e7 100644 --- a/CPP/7zip/UI/FileManager/SysIconUtils.cpp +++ b/CPP/7zip/UI/FileManager/SysIconUtils.cpp @@ -109,7 +109,7 @@ DWORD_PTR Shell_GetFileInfo_SysIconIndex_for_Path_attrib_iconIndexRef( iconIndex = shFileInfo.iIcon; // we use SHGFI_USEFILEATTRIBUTES, and // (res != 0) is expected for main cases, even if there are no such file. - // (res == 0) for path with kSuperPrefix \\?\ + // (res == 0) for path with kSuperPrefix "\\?\" // Also SHGFI_USEFILEATTRIBUTES still returns icon inside exe. // So we can use SHGFI_USEFILEATTRIBUTES for any case. // UString temp = fs2us(path); // for debug diff --git a/CPP/7zip/UI/FileManager/UpdateCallback100.cpp b/CPP/7zip/UI/FileManager/UpdateCallback100.cpp index 71ad710..0796eba 100644 --- a/CPP/7zip/UI/FileManager/UpdateCallback100.cpp +++ b/CPP/7zip/UI/FileManager/UpdateCallback100.cpp @@ -113,6 +113,29 @@ Z7_COM7F_IMF(CUpdateCallback100Imp::SetCompleted(const UInt64 * /* files */, con return ProgressDialog->Sync.CheckStop(); } + +Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Start(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 size, Int32 updateMode)) +{ + return MoveArc_Start_Base(srcTempPath, destFinalPath, size, updateMode); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Progress(UInt64 totalSize, UInt64 currentSize)) +{ + return MoveArc_Progress_Base(totalSize, currentSize); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Finish()) +{ + return MoveArc_Finish_Base(); +} + +Z7_COM7F_IMF(CUpdateCallback100Imp::Before_ArcReopen()) +{ + ProgressDialog->Sync.Clear_Stop_Status(); + return S_OK; +} + + Z7_COM7F_IMF(CUpdateCallback100Imp::CryptoGetTextPassword(BSTR *password)) { *password = NULL; diff --git a/CPP/7zip/UI/FileManager/UpdateCallback100.h b/CPP/7zip/UI/FileManager/UpdateCallback100.h index 5d56dfb..adae94f 100644 --- a/CPP/7zip/UI/FileManager/UpdateCallback100.h +++ b/CPP/7zip/UI/FileManager/UpdateCallback100.h @@ -16,6 +16,7 @@ class CUpdateCallback100Imp Z7_final: public IFolderArchiveUpdateCallback, public IFolderArchiveUpdateCallback2, + public IFolderArchiveUpdateCallback_MoveArc, public IFolderScanProgress, public ICryptoGetTextPassword2, public ICryptoGetTextPassword, @@ -24,9 +25,10 @@ class CUpdateCallback100Imp Z7_final: public CUpdateCallbackGUI2, public CMyUnknownImp { - Z7_COM_UNKNOWN_IMP_7( + Z7_COM_UNKNOWN_IMP_8( IFolderArchiveUpdateCallback, IFolderArchiveUpdateCallback2, + IFolderArchiveUpdateCallback_MoveArc, IFolderScanProgress, ICryptoGetTextPassword2, ICryptoGetTextPassword, @@ -36,6 +38,7 @@ class CUpdateCallback100Imp Z7_final: Z7_IFACE_COM7_IMP(IProgress) Z7_IFACE_COM7_IMP(IFolderArchiveUpdateCallback) Z7_IFACE_COM7_IMP(IFolderArchiveUpdateCallback2) + Z7_IFACE_COM7_IMP(IFolderArchiveUpdateCallback_MoveArc) Z7_IFACE_COM7_IMP(IFolderScanProgress) Z7_IFACE_COM7_IMP(ICryptoGetTextPassword2) Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) diff --git a/CPP/7zip/UI/FileManager/ViewSettings.cpp b/CPP/7zip/UI/FileManager/ViewSettings.cpp index 3d64602..4a8f58d 100644 --- a/CPP/7zip/UI/FileManager/ViewSettings.cpp +++ b/CPP/7zip/UI/FileManager/ViewSettings.cpp @@ -81,15 +81,15 @@ void CListViewInfo::Read(const UString &id) { Clear(); CByteBuffer buf; - UInt32 size; { NSynchronization::CCriticalSectionLock lock(g_CS); CKey key; if (key.Open(HKEY_CURRENT_USER, kCulumnsKeyName, KEY_READ) != ERROR_SUCCESS) return; - if (key.QueryValue(GetSystemString(id), buf, size) != ERROR_SUCCESS) + if (key.QueryValue_Binary(GetSystemString(id), buf) != ERROR_SUCCESS) return; } + unsigned size = (unsigned)buf.Size(); if (size < kListViewHeaderSize) return; UInt32 version; @@ -104,7 +104,9 @@ void CListViewInfo::Read(const UString &id) size -= kListViewHeaderSize; if (size % kColumnInfoSize != 0) return; - unsigned numItems = size / kColumnInfoSize; + if (size > 1000 * kColumnInfoSize) + return; + const unsigned numItems = size / kColumnInfoSize; Columns.ClearAndReserve(numItems); for (unsigned i = 0; i < numItems; i++) { @@ -161,8 +163,7 @@ void CWindowInfo::Save() const static bool QueryBuf(CKey &key, LPCTSTR name, CByteBuffer &buf, UInt32 dataSize) { - UInt32 size; - return key.QueryValue(name, buf, size) == ERROR_SUCCESS && size == dataSize; + return key.QueryValue_Binary(name, buf) == ERROR_SUCCESS && buf.Size() == dataSize; } void CWindowInfo::Read(bool &windowPosDefined, bool &panelInfoDefined) @@ -206,7 +207,7 @@ static bool ReadUi32Val(const TCHAR *name, UInt32 &value) CKey key; if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) return false; - return key.QueryValue(name, value) == ERROR_SUCCESS; + return key.GetValue_UInt32_IfOk(name, value) == ERROR_SUCCESS; } void SaveToolbarsMask(UInt32 toolbarMask) @@ -229,7 +230,7 @@ void CListMode::Save() const { UInt32 t = 0; for (int i = 0; i < 2; i++) - t |= ((Panels[i]) & 0xFF) << (i * 8); + t |= (Panels[i] & 0xFF) << (i * 8); SaveUi32Val(kListMode, t); } @@ -241,7 +242,7 @@ void CListMode::Read() return; for (int i = 0; i < 2; i++) { - Panels[i] = (t & 0xFF); + Panels[i] = t & 0xFF; t >>= 8; } } diff --git a/CPP/7zip/UI/FileManager/resource.h b/CPP/7zip/UI/FileManager/resource.h index 4e22230..36c4b53 100644 --- a/CPP/7zip/UI/FileManager/resource.h +++ b/CPP/7zip/UI/FileManager/resource.h @@ -25,9 +25,12 @@ #define IDM_CRC64 103 #define IDM_SHA1 104 #define IDM_SHA256 105 -#define IDM_XXH64 106 -#define IDM_BLAKE2SP 107 - +#define IDM_SHA384 106 +#define IDM_SHA512 107 +#define IDM_SHA3_256 108 +#define IDM_XXH64 120 +#define IDM_BLAKE2SP 121 +#define IDM_MD5 122 #define IDM_FILE 500 #define IDM_EDIT 501 @@ -134,7 +137,7 @@ #define IDS_COPY_TO 6002 #define IDS_MOVE_TO 6003 #define IDS_COPYING 6004 -#define IDS_MOVING 6005 +// #define IDS_MOVING 6005 #define IDS_RENAMING 6006 #define IDS_OPERATION_IS_NOT_SUPPORTED 6008 diff --git a/CPP/7zip/UI/FileManager/resource.rc b/CPP/7zip/UI/FileManager/resource.rc index feeeaf5..d9fc6f2 100644 --- a/CPP/7zip/UI/FileManager/resource.rc +++ b/CPP/7zip/UI/FileManager/resource.rc @@ -58,8 +58,12 @@ BEGIN MENUITEM "CRC-32", IDM_CRC32 MENUITEM "CRC-64", IDM_CRC64 MENUITEM "XXH64", IDM_XXH64 + MENUITEM "MD5", IDM_MD5 MENUITEM "SHA-1", IDM_SHA1 MENUITEM "SHA-256", IDM_SHA256 + MENUITEM "SHA-384", IDM_SHA384 + MENUITEM "SHA-512", IDM_SHA512 + MENUITEM "SHA3-256", IDM_SHA3_256 MENUITEM "BLAKE2sp", IDM_BLAKE2SP MENUITEM "*", IDM_HASH_ALL END @@ -202,7 +206,7 @@ BEGIN IDS_COPY_TO "Copy to:" IDS_MOVE_TO "Move to:" IDS_COPYING "Copying..." - IDS_MOVING "Moving..." +// IDS_MOVING "Moving..." IDS_RENAMING "Renaming..." IDS_OPERATION_IS_NOT_SUPPORTED "Operation is not supported." diff --git a/CPP/7zip/UI/FileManager/resourceGui.h b/CPP/7zip/UI/FileManager/resourceGui.h index 848b36f..2e1bab3 100644 --- a/CPP/7zip/UI/FileManager/resourceGui.h +++ b/CPP/7zip/UI/FileManager/resourceGui.h @@ -6,6 +6,8 @@ #define IDS_OPENNING 3303 #define IDS_SCANNING 3304 +#define IDS_MOVING 6005 + #define IDS_CHECKSUM_CALCULATING 7500 #define IDS_CHECKSUM_INFORMATION 7501 #define IDS_CHECKSUM_CRC_DATA 7502 diff --git a/CPP/7zip/UI/FileManager/resourceGui.rc b/CPP/7zip/UI/FileManager/resourceGui.rc index 143e9f6..ad0d1f4 100644 --- a/CPP/7zip/UI/FileManager/resourceGui.rc +++ b/CPP/7zip/UI/FileManager/resourceGui.rc @@ -6,6 +6,8 @@ BEGIN IDS_PROGRESS_TESTING "Testing" + IDS_MOVING "Moving..." + IDS_CHECKSUM_CALCULATING "Checksum calculating..." IDS_CHECKSUM_INFORMATION "Checksum information" IDS_CHECKSUM_CRC_DATA "CRC checksum for data:" diff --git a/CPP/7zip/UI/GUI/BenchmarkDialog.cpp b/CPP/7zip/UI/GUI/BenchmarkDialog.cpp index 7f2edfa..ce5473a 100644 --- a/CPP/7zip/UI/GUI/BenchmarkDialog.cpp +++ b/CPP/7zip/UI/GUI/BenchmarkDialog.cpp @@ -61,9 +61,9 @@ struct CBenchPassResult { CTotalBenchRes Enc; CTotalBenchRes Dec; - #ifdef PRINT_ITER_TIME +#ifdef PRINT_ITER_TIME DWORD Ticks; - #endif +#endif // CBenchInfo EncInfo; // for debug // CBenchPassResult() {}; }; @@ -97,21 +97,9 @@ struct CTotalBenchRes2: public CTotalBenchRes struct CSyncData { UInt32 NumPasses_Finished; - - // UInt64 NumEncProgress; // for debug - // UInt64 NumDecProgress; // for debug - // CBenchInfo EncInfo; // for debug - - CTotalBenchRes2 Enc_BenchRes_1; - CTotalBenchRes2 Enc_BenchRes; - - CTotalBenchRes2 Dec_BenchRes_1; - CTotalBenchRes2 Dec_BenchRes; - - #ifdef PRINT_ITER_TIME +#ifdef PRINT_ITER_TIME DWORD TotalTicks; - #endif - +#endif int RatingVector_DeletedIndex; // UInt64 RatingVector_NumDeleted; @@ -124,6 +112,16 @@ struct CSyncData bool NeedPrint_Dec; bool NeedPrint_Tot; // intermediate Total was updated after current pass + // UInt64 NumEncProgress; // for debug + // UInt64 NumDecProgress; // for debug + // CBenchInfo EncInfo; // for debug + + CTotalBenchRes2 Enc_BenchRes_1; + CTotalBenchRes2 Enc_BenchRes; + + CTotalBenchRes2 Dec_BenchRes_1; + CTotalBenchRes2 Dec_BenchRes; + void Init(); }; @@ -161,24 +159,18 @@ void CSyncData::Init() struct CBenchProgressSync { bool Exit; // GUI asks BenchThread to Exit, and BenchThread reads that variable + bool TextWasChanged; + UInt32 NumThreads; UInt64 DictSize; UInt32 NumPasses_Limit; int Level; - - // must be written by benchmark thread, read by GUI thread */ - CSyncData sd; - CRecordVector RatingVector; - - NWindows::NSynchronization::CCriticalSection CS; AString Text; - bool TextWasChanged; /* BenchFinish_Task_HRESULT - for result from benchmark code BenchFinish_Thread_HRESULT - for Exceptions and service errors these arreos must be shown even if user escapes benchmark */ - HRESULT BenchFinish_Task_HRESULT; HRESULT BenchFinish_Thread_HRESULT; @@ -186,6 +178,12 @@ struct CBenchProgressSync UString FreqString_Sync; UString FreqString_GUI; + // must be written by benchmark thread, read by GUI thread */ + CRecordVector RatingVector; + CSyncData sd; + + NWindows::NSynchronization::CCriticalSection CS; + CBenchProgressSync() { NumPasses_Limit = 1; @@ -258,6 +256,19 @@ struct CThreadBenchmark class CBenchmarkDialog: public NWindows::NControl::CModalDialog { + bool _finishTime_WasSet; + + bool WasStopped_in_GUI; + bool ExitWasAsked_in_GUI; + bool NeedRestart; + + bool RamSize_Defined; + +public: + bool TotalMode; + +private: + NWindows::NControl::CComboBox m_Dictionary; NWindows::NControl::CComboBox m_NumThreads; NWindows::NControl::CComboBox m_NumPasses; @@ -266,17 +277,11 @@ class CBenchmarkDialog: UInt32 _startTime; UInt32 _finishTime; - bool _finishTime_WasSet; - - bool WasStopped_in_GUI; - bool ExitWasAsked_in_GUI; - bool NeedRestart; CMyFont _font; - UInt64 RamSize; - UInt64 RamSize_Limit; - bool RamSize_Defined; + size_t RamSize; + size_t RamSize_Limit; UInt32 NumPasses_Finished_Prev; @@ -330,7 +335,6 @@ class CBenchmarkDialog: public: CBenchProgressSync Sync; - bool TotalMode; CObjectVector Props; CSysString Bench2Text; @@ -339,11 +343,11 @@ public: CThreadBenchmark _threadBenchmark; CBenchmarkDialog(): - _timer(0), WasStopped_in_GUI(false), ExitWasAsked_in_GUI(false), NeedRestart(false), - TotalMode(false) + TotalMode(false), + _timer(0) {} ~CBenchmarkDialog() Z7_DESTRUCTOR_override; @@ -504,7 +508,8 @@ bool CBenchmarkDialog::OnInit() SetItemTextA(IDT_BENCH_SYS2, s2); } { - GetCpuName_MultiLine(s); + AString registers; + GetCpuName_MultiLine(s, registers); SetItemTextA(IDT_BENCH_CPU, s); } { diff --git a/CPP/7zip/UI/GUI/CompressDialog.cpp b/CPP/7zip/UI/GUI/CompressDialog.cpp index fd53062..58f863e 100644 --- a/CPP/7zip/UI/GUI/CompressDialog.cpp +++ b/CPP/7zip/UI/GUI/CompressDialog.cpp @@ -211,11 +211,13 @@ static const EMethodID g_ZstdMethods[] = }; */ +/* static const EMethodID g_SwfcMethods[] = { kDeflate // kLZMA }; +*/ static const EMethodID g_TarMethods[] = { @@ -278,7 +280,8 @@ static const CFormatInfo g_Formats[] = }, { "7z", - (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), + // (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), + (1 << 10) - 1, METHODS_PAIR(g_7zMethods), kFF_Filter | kFF_Solid | kFF_MultiThread | kFF_Encrypt | kFF_EncryptFileNames | kFF_MemUse | kFF_SFX @@ -306,7 +309,8 @@ static const CFormatInfo g_Formats[] = }, { "xz", - (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), + // (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), + (1 << 10) - 1 - (1 << 0), // store (1 << 0) is not supported METHODS_PAIR(g_XzMethods), kFF_Solid | kFF_MultiThread | kFF_MemUse }, @@ -321,12 +325,14 @@ static const CFormatInfo g_Formats[] = | kFF_MemUse }, */ +/* { "Swfc", (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), METHODS_PAIR(g_SwfcMethods), 0 }, +*/ { "Tar", (1 << 0), @@ -429,22 +435,23 @@ bool CCompressDialog::OnInit() #endif { - UInt64 size = (UInt64)(sizeof(size_t)) << 29; + size_t size = (size_t)sizeof(size_t) << 29; _ramSize_Defined = NSystem::GetRamSize(size); // size = (UInt64)3 << 62; // for debug only; - _ramSize = size; - const UInt64 kMinUseSize = (1 << 26); - if (size < kMinUseSize) - size = kMinUseSize; - - unsigned bits = sizeof(size_t) * 8; - if (bits == 32) { - const UInt32 limit2 = (UInt32)7 << 28; - if (size > limit2) - size = limit2; + // we use reduced limit for 32-bit version: + unsigned bits = sizeof(size_t) * 8; + if (bits == 32) + { + const UInt32 limit2 = (UInt32)7 << 28; + if (size > limit2) + size = limit2; + } } - + _ramSize = size; + const size_t kMinUseSize = 1 << 26; + if (size < kMinUseSize) + size = kMinUseSize; _ramSize_Reduced = size; // 80% - is auto usage limit in handlers @@ -1580,24 +1587,26 @@ void CCompressDialog::SetLevel2() for (unsigned i = 0; i < sizeof(UInt32) * 8; i++) { - const UInt32 mask = (UInt32)1 << i; - if ((fi.LevelsMask & mask) != 0) + const UInt32 mask = fi.LevelsMask >> i; + // if (mask == 0) break; + if (mask & 1) { - const UInt32 langID = g_Levels[i]; UString s; s.Add_UInt32(i); - // if (fi.LevelsMask < (1 << (MY_ZSTD_LEVEL_MAX + 1)) - 1) - if (langID) - if (i != 0 || !isZstd) + if (i < Z7_ARRAY_SIZE(g_Levels)) { - s += " - "; - s += LangString(langID); + const UInt32 langID = g_Levels[i]; + // if (fi.LevelsMask < (1 << (MY_ZSTD_LEVEL_MAX + 1)) - 1) + if (langID) + if (i != 0 || !isZstd) + { + s += " - "; + AddLangString(s, langID); + } } const int index = (int)m_Level.AddString(s); m_Level.SetItemData(index, (LPARAM)i); } - if (fi.LevelsMask <= mask) - break; } SetNearestSelectComboBox(m_Level, level); } @@ -1931,11 +1940,11 @@ void CCompressDialog::SetDictionary2() case kLZMA2: { { - _auto_Dict = - ( level <= 3 ? ((UInt32)1 << (level * 2 + 16)) : - ( level <= 6 ? ((UInt32)1 << (level + 19)) : - ( level <= 7 ? ((UInt32)1 << 25) : ((UInt32)1 << 26) - ))); + _auto_Dict = level <= 4 ? + (UInt32)1 << (level * 2 + 16) : + level <= sizeof(size_t) / 2 + 4 ? + (UInt32)1 << (level + 20) : + (UInt32)1 << (sizeof(size_t) / 2 + 24); } // we use threshold 3.75 GiB to switch to kLzmaMaxDictSize. diff --git a/CPP/7zip/UI/GUI/CompressDialog.h b/CPP/7zip/UI/GUI/CompressDialog.h index c2d2699..e0f3aa5 100644 --- a/CPP/7zip/UI/GUI/CompressDialog.h +++ b/CPP/7zip/UI/GUI/CompressDialog.h @@ -141,6 +141,15 @@ struct CBool1 class CCompressDialog: public NWindows::NControl::CModalDialog { +public: + CBool1 SymLinks; + CBool1 HardLinks; + CBool1 AltStreams; + CBool1 NtSecurity; + CBool1 PreserveATime; +private: + bool _ramSize_Defined; + NWindows::NControl::CComboBox m_ArchivePath; NWindows::NControl::CComboBox m_Format; NWindows::NControl::CComboBox m_Level; @@ -179,20 +188,13 @@ class CCompressDialog: public NWindows::NControl::CModalDialog UString DirPrefix; UString StartDirPrefix; - bool _ramSize_Defined; - UInt64 _ramSize; // full RAM size avail - UInt64 _ramSize_Reduced; // full for 64-bit and reduced for 32-bit + size_t _ramSize; // full RAM size avail + size_t _ramSize_Reduced; // full for 64-bit and reduced for 32-bit UInt64 _ramUsage_Auto; public: NCompression::CInfo m_RegistryInfo; - CBool1 SymLinks; - CBool1 HardLinks; - CBool1 AltStreams; - CBool1 NtSecurity; - CBool1 PreserveATime; - void SetArchiveName(const UString &name); int FindRegistryFormat(const UString &name); unsigned FindRegistryFormat_Always(const UString &name); diff --git a/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp b/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp index 26057a7..424c6e4 100644 --- a/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp +++ b/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp @@ -252,6 +252,21 @@ HRESULT CUpdateCallbackGUI::DeletingAfterArchiving(const FString &path, bool isD return ProgressDialog->Sync.Set_Status2(_lang_Removing, fs2us(path), isDir); } + +HRESULT CUpdateCallbackGUI::MoveArc_Start(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 totalSize, Int32 updateMode) +{ + return MoveArc_Start_Base(srcTempPath, destFinalPath, totalSize, updateMode); +} +HRESULT CUpdateCallbackGUI::MoveArc_Progress(UInt64 totalSize, UInt64 currentSize) +{ + return MoveArc_Progress_Base(totalSize, currentSize); +} +HRESULT CUpdateCallbackGUI::MoveArc_Finish() +{ + return MoveArc_Finish_Base(); +} + + HRESULT CUpdateCallbackGUI::StartOpenArchive(const wchar_t * /* name */) { return S_OK; diff --git a/CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp b/CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp index 966f57e..53fed91 100644 --- a/CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp +++ b/CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp @@ -8,6 +8,7 @@ #include "resource2.h" #include "resource3.h" #include "ExtractRes.h" +#include "../FileManager/resourceGui.h" #include "UpdateCallbackGUI.h" @@ -29,7 +30,8 @@ void CUpdateCallbackGUI2::Init() { NumFiles = 0; - _lang_Removing = LangString(IDS_PROGRESS_REMOVE); + LangString(IDS_PROGRESS_REMOVE, _lang_Removing); + LangString(IDS_MOVING, _lang_Moving); _lang_Ops.Clear(); for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_UpdNotifyLangs); i++) _lang_Ops.Add(LangString(k_UpdNotifyLangs[i])); @@ -57,3 +59,72 @@ HRESULT CUpdateCallbackGUI2::ShowAskPasswordDialog() PasswordIsDefined = true; return S_OK; } + + +HRESULT CUpdateCallbackGUI2::MoveArc_UpdateStatus() +{ + UString s; + s.Add_UInt64(_arcMoving_percents); + s.Add_Char('%'); + + const bool totalDefined = (_arcMoving_total != 0 && _arcMoving_total != (UInt64)(Int64)-1); + if (totalDefined || _arcMoving_current != 0) + { + s += " : "; + s.Add_UInt64(_arcMoving_current >> 20); + s += " MiB"; + } + if (totalDefined) + { + s += " / "; + s.Add_UInt64((_arcMoving_total + ((1 << 20) - 1)) >> 20); + s += " MiB"; + } + + s += " : "; + s += _lang_Moving; + s += " : "; + // s.Add_Char('\"'); + s += _arcMoving_name1; + // s.Add_Char('\"'); + return ProgressDialog->Sync.Set_Status2(s, _arcMoving_name2, + false); // isDir +} + + +HRESULT CUpdateCallbackGUI2::MoveArc_Start_Base(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 totalSize, Int32 updateMode) +{ + _arcMoving_percents = 0; + _arcMoving_total = totalSize; + _arcMoving_current = 0; + _arcMoving_updateMode = updateMode; + _arcMoving_name1 = srcTempPath; + _arcMoving_name2 = destFinalPath; + return MoveArc_UpdateStatus(); +} + + +HRESULT CUpdateCallbackGUI2::MoveArc_Progress_Base(UInt64 totalSize, UInt64 currentSize) +{ + _arcMoving_total = totalSize; + _arcMoving_current = currentSize; + UInt64 percents = 0; + if (totalSize != 0) + { + if (totalSize < ((UInt64)1 << 57)) + percents = currentSize * 100 / totalSize; + else + percents = currentSize / (totalSize / 100); + } + if (percents == _arcMoving_percents) + return ProgressDialog->Sync.CheckStop(); + // Sleep(300); // for debug + _arcMoving_percents = percents; + return MoveArc_UpdateStatus(); +} + + +HRESULT CUpdateCallbackGUI2::MoveArc_Finish_Base() +{ + return ProgressDialog->Sync.Set_Status2(L"", L"", false); +} diff --git a/CPP/7zip/UI/GUI/UpdateCallbackGUI2.h b/CPP/7zip/UI/GUI/UpdateCallbackGUI2.h index e32b602..56747ff 100644 --- a/CPP/7zip/UI/GUI/UpdateCallbackGUI2.h +++ b/CPP/7zip/UI/GUI/UpdateCallbackGUI2.h @@ -7,17 +7,38 @@ class CUpdateCallbackGUI2 { - UStringVector _lang_Ops; - UString _emptyString; public: - UString Password; + CProgressDialog *ProgressDialog; +protected: + UString _arcMoving_name1; + UString _arcMoving_name2; + UInt64 _arcMoving_percents; + UInt64 _arcMoving_total; + UInt64 _arcMoving_current; + Int32 _arcMoving_updateMode; +public: bool PasswordIsDefined; bool PasswordWasAsked; UInt64 NumFiles; - + UString Password; +protected: + UStringVector _lang_Ops; UString _lang_Removing; + UString _lang_Moving; + UString _emptyString; + + HRESULT MoveArc_UpdateStatus(); + HRESULT MoveArc_Start_Base(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 /* totalSize */, Int32 updateMode); + HRESULT MoveArc_Progress_Base(UInt64 totalSize, UInt64 currentSize); + HRESULT MoveArc_Finish_Base(); + +public: CUpdateCallbackGUI2(): + _arcMoving_percents(0), + _arcMoving_total(0), + _arcMoving_current(0), + _arcMoving_updateMode(0), PasswordIsDefined(false), PasswordWasAsked(false), NumFiles(0) @@ -25,8 +46,6 @@ public: void Init(); - CProgressDialog *ProgressDialog; - HRESULT SetOperation_Base(UInt32 notifyOp, const wchar_t *name, bool isDir); HRESULT ShowAskPasswordDialog(); }; diff --git a/CPP/7zip/warn_gcc.mak b/CPP/7zip/warn_gcc.mak index b6ed9c3..6152ab1 100644 --- a/CPP/7zip/warn_gcc.mak +++ b/CPP/7zip/warn_gcc.mak @@ -11,16 +11,16 @@ CFLAGS_WARN_GCC_4_8 = \ -Wunused \ -Wunused-macros \ -CFLAGS_WARN_GCC_6 = $(CFLAGS_WARN_GCC_4_8)\ +CFLAGS_WARN_GCC_5 = $(CFLAGS_WARN_GCC_4_8)\ -Wbool-compare \ + +CFLAGS_WARN_GCC_6 = $(CFLAGS_WARN_GCC_5)\ -Wduplicated-cond \ # -Wno-strict-aliasing -CFLAGS_WARN_GCC_9 = $(CFLAGS_WARN_GCC_6)\ - -Waddress-of-packed-member \ +CFLAGS_WARN_GCC_7 = $(CFLAGS_WARN_GCC_6)\ -Wbool-operation \ - -Wcast-align=strict \ -Wconversion \ -Wdangling-else \ -Wduplicated-branches \ @@ -28,8 +28,14 @@ CFLAGS_WARN_GCC_9 = $(CFLAGS_WARN_GCC_6)\ -Wint-in-bool-context \ -Wmaybe-uninitialized \ -Wmisleading-indentation \ + +CFLAGS_WARN_GCC_8 = $(CFLAGS_WARN_GCC_7)\ + -Wcast-align=strict \ -Wmissing-attributes +CFLAGS_WARN_GCC_9 = $(CFLAGS_WARN_GCC_8)\ + -Waddress-of-packed-member \ + # In C: -Wsign-conversion enabled also by -Wconversion # -Wno-sign-conversion \ @@ -39,7 +45,10 @@ CFLAGS_WARN_GCC_PPMD_UNALIGNED = \ CFLAGS_WARN = $(CFLAGS_WARN_GCC_4_8) +CFLAGS_WARN = $(CFLAGS_WARN_GCC_5) CFLAGS_WARN = $(CFLAGS_WARN_GCC_6) +CFLAGS_WARN = $(CFLAGS_WARN_GCC_7) +CFLAGS_WARN = $(CFLAGS_WARN_GCC_8) CFLAGS_WARN = $(CFLAGS_WARN_GCC_9) # CXX_STD_FLAGS = -std=c++11 diff --git a/CPP/Common/Md5Reg.cpp b/CPP/Common/Md5Reg.cpp new file mode 100644 index 0000000..026fd41 --- /dev/null +++ b/CPP/Common/Md5Reg.cpp @@ -0,0 +1,44 @@ +// Md5Reg.cpp + +#include "StdAfx.h" + +#include "../../C/Md5.h" + +#include "../Common/MyBuffer2.h" +#include "../Common/MyCom.h" + +#include "../7zip/Common/RegisterCodec.h" + +Z7_CLASS_IMP_COM_1( + CMd5Hasher + , IHasher +) + CAlignedBuffer1 _buf; +public: + Byte _mtDummy[1 << 7]; + + CMd5 *Md5() { return (CMd5 *)(void *)(Byte *)_buf; } +public: + CMd5Hasher(): + _buf(sizeof(CMd5)) + { + Md5_Init(Md5()); + } +}; + +Z7_COM7F_IMF2(void, CMd5Hasher::Init()) +{ + Md5_Init(Md5()); +} + +Z7_COM7F_IMF2(void, CMd5Hasher::Update(const void *data, UInt32 size)) +{ + Md5_Update(Md5(), (const Byte *)data, size); +} + +Z7_COM7F_IMF2(void, CMd5Hasher::Final(Byte *digest)) +{ + Md5_Final(Md5(), digest); +} + +REGISTER_HASHER(CMd5Hasher, 0x208, "MD5", MD5_DIGEST_SIZE) diff --git a/CPP/Common/MyCom.h b/CPP/Common/MyCom.h index a3cc3c8..7dc21ba 100644 --- a/CPP/Common/MyCom.h +++ b/CPP/Common/MyCom.h @@ -468,6 +468,19 @@ EXTERN_C_END Z7_COM_QI_ENTRY(i7) \ ) +#define Z7_COM_UNKNOWN_IMP_8(i1, i2, i3, i4, i5, i6, i7, i8) \ + Z7_COM_UNKNOWN_IMP_SPEC( \ + Z7_COM_QI_ENTRY_UNKNOWN(i1) \ + Z7_COM_QI_ENTRY(i1) \ + Z7_COM_QI_ENTRY(i2) \ + Z7_COM_QI_ENTRY(i3) \ + Z7_COM_QI_ENTRY(i4) \ + Z7_COM_QI_ENTRY(i5) \ + Z7_COM_QI_ENTRY(i6) \ + Z7_COM_QI_ENTRY(i7) \ + Z7_COM_QI_ENTRY(i8) \ + ) + #define Z7_IFACES_IMP_UNK_1(i1) \ Z7_COM_UNKNOWN_IMP_1(i1) \ @@ -508,6 +521,16 @@ EXTERN_C_END Z7_IFACE_COM7_IMP(i5) \ Z7_IFACE_COM7_IMP(i6) \ +#define Z7_IFACES_IMP_UNK_7(i1, i2, i3, i4, i5, i6, i7) \ + Z7_COM_UNKNOWN_IMP_7(i1, i2, i3, i4, i5, i6, i7) \ + Z7_IFACE_COM7_IMP(i1) \ + Z7_IFACE_COM7_IMP(i2) \ + Z7_IFACE_COM7_IMP(i3) \ + Z7_IFACE_COM7_IMP(i4) \ + Z7_IFACE_COM7_IMP(i5) \ + Z7_IFACE_COM7_IMP(i6) \ + Z7_IFACE_COM7_IMP(i7) \ + #define Z7_CLASS_IMP_COM_0(c) \ Z7_class_final(c) : \ @@ -574,6 +597,20 @@ EXTERN_C_END private: +#define Z7_CLASS_IMP_COM_7(c, i1, i2, i3, i4, i5, i6, i7) \ + Z7_class_final(c) : \ + public i1, \ + public i2, \ + public i3, \ + public i4, \ + public i5, \ + public i6, \ + public i7, \ + public CMyUnknownImp { \ + Z7_IFACES_IMP_UNK_7(i1, i2, i3, i4, i5, i6, i7) \ + private: + + /* #define Z7_CLASS_IMP_NOQIB_0(c) \ Z7_class_final(c) : \ diff --git a/CPP/Common/Sha3Reg.cpp b/CPP/Common/Sha3Reg.cpp new file mode 100644 index 0000000..95db25e --- /dev/null +++ b/CPP/Common/Sha3Reg.cpp @@ -0,0 +1,76 @@ +// Sha3Reg.cpp + +#include "StdAfx.h" + +#include "../../C/Sha3.h" + +#include "../Common/MyBuffer2.h" +#include "../Common/MyCom.h" + +#include "../7zip/Common/RegisterCodec.h" + +Z7_CLASS_IMP_COM_1( + CSha3Hasher + , IHasher +) + unsigned _digestSize; + bool _isShake; + CAlignedBuffer1 _buf; +public: + Byte _mtDummy[1 << 7]; + + CSha3 *Sha() { return (CSha3 *)(void *)(Byte *)_buf; } +public: + CSha3Hasher(unsigned digestSize, bool isShake, unsigned blockSize): + _digestSize(digestSize), + _isShake(isShake), + _buf(sizeof(CSha3)) + { + CSha3 *p = Sha(); + Sha3_SET_blockSize(p, blockSize) + Sha3_Init(Sha()); + } +}; + +Z7_COM7F_IMF2(void, CSha3Hasher::Init()) +{ + Sha3_Init(Sha()); +} + +Z7_COM7F_IMF2(void, CSha3Hasher::Update(const void *data, UInt32 size)) +{ + Sha3_Update(Sha(), (const Byte *)data, size); +} + +Z7_COM7F_IMF2(void, CSha3Hasher::Final(Byte *digest)) +{ + Sha3_Final(Sha(), digest, _digestSize, _isShake); +} + +Z7_COM7F_IMF2(UInt32, CSha3Hasher::GetDigestSize()) +{ + return (UInt32)_digestSize; +} + + +#define REGISTER_SHA3_HASHER_2(cls, id, name, digestSize, isShake, digestSize_for_blockSize) \ + namespace N ## cls { \ + static IHasher *CreateHasherSpec() \ + { return new CSha3Hasher(digestSize / 8, isShake, \ + SHA3_BLOCK_SIZE_FROM_DIGEST_SIZE(digestSize_for_blockSize / 8)); } \ + static const CHasherInfo g_HasherInfo = { CreateHasherSpec, id, name, digestSize }; \ + struct REGISTER_HASHER_NAME(cls) { REGISTER_HASHER_NAME(cls)() { RegisterHasher(&g_HasherInfo); }}; \ + static REGISTER_HASHER_NAME(cls) g_RegisterHasher; } + +#define REGISTER_SHA3_HASHER( cls, id, name, size, isShake) \ + REGISTER_SHA3_HASHER_2(cls, id, name, size, isShake, size) + +// REGISTER_SHA3_HASHER (Sha3_224_Hasher, 0x230, "SHA3-224", 224, false) +REGISTER_SHA3_HASHER (Sha3_256_Hasher, 0x231, "SHA3-256", 256, false) +// REGISTER_SHA3_HASHER (Sha3_386_Hasher, 0x232, "SHA3-384", 384, false) +// REGISTER_SHA3_HASHER (Sha3_512_Hasher, 0x233, "SHA3-512", 512, false) +// REGISTER_SHA3_HASHER (Shake128_Hasher, 0x240, "SHAKE128", 128, true) +// REGISTER_SHA3_HASHER (Shake256_Hasher, 0x241, "SHAKE256", 256, true) +// REGISTER_SHA3_HASHER_2 (Shake128_512_Hasher, 0x248, "SHAKE128-256", 256, true, 128) // -1344 (max) +// REGISTER_SHA3_HASHER_2 (Shake256_512_Hasher, 0x249, "SHAKE256-512", 512, true, 256) // -1088 (max) +// Shake supports different digestSize values for same blockSize diff --git a/CPP/Common/Sha512Prepare.cpp b/CPP/Common/Sha512Prepare.cpp new file mode 100644 index 0000000..e7beff5 --- /dev/null +++ b/CPP/Common/Sha512Prepare.cpp @@ -0,0 +1,7 @@ +// Sha512Prepare.cpp + +#include "StdAfx.h" + +#include "../../C/Sha512.h" + +static struct CSha512Prepare { CSha512Prepare() { Sha512Prepare(); } } g_Sha512Prepare; diff --git a/CPP/Common/Sha512Reg.cpp b/CPP/Common/Sha512Reg.cpp new file mode 100644 index 0000000..21df6ba --- /dev/null +++ b/CPP/Common/Sha512Reg.cpp @@ -0,0 +1,83 @@ +// Sha512Reg.cpp + +#include "StdAfx.h" + +#include "../../C/Sha512.h" + +#include "../Common/MyBuffer2.h" +#include "../Common/MyCom.h" + +#include "../7zip/Common/RegisterCodec.h" + +Z7_CLASS_IMP_COM_2( + CSha512Hasher + , IHasher + , ICompressSetCoderProperties +) + unsigned _digestSize; + CAlignedBuffer1 _buf; +public: + Byte _mtDummy[1 << 7]; + + CSha512 *Sha() { return (CSha512 *)(void *)(Byte *)_buf; } +public: + CSha512Hasher(unsigned digestSize): + _digestSize(digestSize), + _buf(sizeof(CSha512)) + { + Sha512_SetFunction(Sha(), 0); + Sha512_InitState(Sha(), _digestSize); + } +}; + +Z7_COM7F_IMF2(void, CSha512Hasher::Init()) +{ + Sha512_InitState(Sha(), _digestSize); +} + +Z7_COM7F_IMF2(void, CSha512Hasher::Update(const void *data, UInt32 size)) +{ + Sha512_Update(Sha(), (const Byte *)data, size); +} + +Z7_COM7F_IMF2(void, CSha512Hasher::Final(Byte *digest)) +{ + Sha512_Final(Sha(), digest, _digestSize); +} + +Z7_COM7F_IMF2(UInt32, CSha512Hasher::GetDigestSize()) +{ + return (UInt32)_digestSize; +} + +Z7_COM7F_IMF(CSha512Hasher::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)) +{ + unsigned algo = 0; + for (UInt32 i = 0; i < numProps; i++) + { + if (propIDs[i] == NCoderPropID::kDefaultProp) + { + const PROPVARIANT &prop = coderProps[i]; + if (prop.vt != VT_UI4) + return E_INVALIDARG; + if (prop.ulVal > 2) + return E_NOTIMPL; + algo = (unsigned)prop.ulVal; + } + } + if (!Sha512_SetFunction(Sha(), algo)) + return E_NOTIMPL; + return S_OK; +} + +#define REGISTER_SHA512_HASHER(cls, id, name, size) \ + namespace N ## cls { \ + static IHasher *CreateHasherSpec() { return new CSha512Hasher(size); } \ + static const CHasherInfo g_HasherInfo = { CreateHasherSpec, id, name, size }; \ + struct REGISTER_HASHER_NAME(cls) { REGISTER_HASHER_NAME(cls)() { RegisterHasher(&g_HasherInfo); }}; \ + static REGISTER_HASHER_NAME(cls) g_RegisterHasher; } + +// REGISTER_SHA512_HASHER (Sha512_224_Hasher, 0x220, "SHA512-224", SHA512_224_DIGEST_SIZE) +// REGISTER_SHA512_HASHER (Sha512_256_Hasher, 0x221, "SHA512-256", SHA512_256_DIGEST_SIZE) +REGISTER_SHA512_HASHER (Sha384Hasher, 0x222, "SHA384", SHA512_384_DIGEST_SIZE) +REGISTER_SHA512_HASHER (Sha512Hasher, 0x223, "SHA512", SHA512_DIGEST_SIZE) diff --git a/CPP/Windows/FileDir.cpp b/CPP/Windows/FileDir.cpp index dfeed82..2cb83b2 100644 --- a/CPP/Windows/FileDir.cpp +++ b/CPP/Windows/FileDir.cpp @@ -15,8 +15,9 @@ #include #include -#include "../Common/StringConvert.h" #include "../Common/C_FileIO.h" +#include "../Common/MyBuffer2.h" +#include "../Common/StringConvert.h" #endif #include "FileDir.h" @@ -222,6 +223,8 @@ bool RemoveDir(CFSTR path) } +// When moving a directory, oldFile and newFile must be on the same drive. + bool MyMoveFile(CFSTR oldFile, CFSTR newFile) { #ifndef _UNICODE @@ -250,6 +253,59 @@ bool MyMoveFile(CFSTR oldFile, CFSTR newFile) return false; } +#if defined(Z7_WIN32_WINNT_MIN) && Z7_WIN32_WINNT_MIN >= 0x0500 +static DWORD WINAPI CopyProgressRoutine_to_ICopyFileProgress( + LARGE_INTEGER TotalFileSize, // file size + LARGE_INTEGER TotalBytesTransferred, // bytes transferred + LARGE_INTEGER /* StreamSize */, // bytes in stream + LARGE_INTEGER /* StreamBytesTransferred */, // bytes transferred for stream + DWORD /* dwStreamNumber */, // current stream + DWORD /* dwCallbackReason */, // callback reason + HANDLE /* hSourceFile */, // handle to source file + HANDLE /* hDestinationFile */, // handle to destination file + LPVOID lpData // from CopyFileEx +) +{ + return ((ICopyFileProgress *)lpData)->CopyFileProgress( + (UInt64)TotalFileSize.QuadPart, + (UInt64)TotalBytesTransferred.QuadPart); +} +#endif + +bool MyMoveFile_with_Progress(CFSTR oldFile, CFSTR newFile, + ICopyFileProgress *progress) +{ +#if defined(Z7_WIN32_WINNT_MIN) && Z7_WIN32_WINNT_MIN >= 0x0500 +#ifndef _UNICODE + if (g_IsNT) +#endif + if (progress) + { + IF_USE_MAIN_PATH_2(oldFile, newFile) + { + if (::MoveFileWithProgressW(fs2us(oldFile), fs2us(newFile), + CopyProgressRoutine_to_ICopyFileProgress, progress, MOVEFILE_COPY_ALLOWED)) + return true; + if (::GetLastError() == ERROR_REQUEST_ABORTED) + return false; + } + #ifdef Z7_LONG_PATH + if (USE_SUPER_PATH_2) + { + UString d1, d2; + if (GetSuperPaths(oldFile, newFile, d1, d2, USE_MAIN_PATH_2)) + return BOOLToBool(::MoveFileWithProgressW(d1, d2, + CopyProgressRoutine_to_ICopyFileProgress, progress, MOVEFILE_COPY_ALLOWED)); + } + #endif + return false; + } +#else + UNUSED_VAR(progress) +#endif + return MyMoveFile(oldFile, newFile); +} + #ifndef UNDER_CE #if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0500 // Win2000 #define Z7_USE_DYN_CreateHardLink @@ -878,9 +934,9 @@ bool CTempFile::Remove() return !_mustBeDeleted; } -bool CTempFile::MoveTo(CFSTR name, bool deleteDestBefore) +bool CTempFile::MoveTo(CFSTR name, bool deleteDestBefore, + ICopyFileProgress *progress) { - // DWORD attrib = 0; if (deleteDestBefore) { if (NFind::DoesFileExist_Raw(name)) @@ -891,8 +947,8 @@ bool CTempFile::MoveTo(CFSTR name, bool deleteDestBefore) } } DisableDeleting(); - return MyMoveFile(_path, name); - + // if (!progress) return MyMoveFile(_path, name); + return MyMoveFile_with_Progress(_path, name, progress); /* if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_READONLY)) { @@ -941,34 +997,59 @@ bool RemoveDir(CFSTR path) } -static BOOL My_CopyFile(CFSTR oldFile, CFSTR newFile) +static BOOL My_CopyFile(CFSTR oldFile, CFSTR newFile, ICopyFileProgress *progress) { - NWindows::NFile::NIO::COutFile outFile; - if (!outFile.Create_NEW(newFile)) - return FALSE; - - NWindows::NFile::NIO::CInFile inFile; - if (!inFile.Open(oldFile)) - return FALSE; - - char buf[1 << 14]; - - for (;;) { - const ssize_t num = inFile.read_part(buf, sizeof(buf)); - if (num == 0) - return TRUE; - if (num < 0) + NIO::COutFile outFile; + if (!outFile.Create_NEW(newFile)) return FALSE; - size_t processed; - const ssize_t num2 = outFile.write_full(buf, (size_t)num, processed); - if (num2 != num || processed != (size_t)num) + NIO::CInFile inFile; + if (!inFile.Open(oldFile)) return FALSE; + + const size_t k_BufSize = 1 << 16; + CAlignedBuffer1 buf(k_BufSize); + + UInt64 length = 0; + if (progress && !inFile.GetLength(length)) + length = 0; + UInt64 prev = 0; + UInt64 cur = 0; + for (;;) + { + const ssize_t num = inFile.read_part(buf, k_BufSize); + if (num == 0) + return TRUE; + if (num < 0) + break; + size_t processed; + const ssize_t num2 = outFile.write_full(buf, (size_t)num, processed); + if (num2 != num || processed != (size_t)num) + break; + cur += (size_t)num2; + if (progress && cur - prev >= (1u << 20)) + { + prev = cur; + if (progress->CopyFileProgress(length, cur) != PROGRESS_CONTINUE) + { + errno = EINTR; // instead of WIN32::ERROR_REQUEST_ABORTED + break; + } + } + } } + // There is file IO error or process was interrupted by user. + // We close output file and delete it. + // DeleteFileAlways doesn't change errno (if successed), but we restore errno. + const int errno_save = errno; + DeleteFileAlways(newFile); + errno = errno_save; + return FALSE; } -bool MyMoveFile(CFSTR oldFile, CFSTR newFile) +bool MyMoveFile_with_Progress(CFSTR oldFile, CFSTR newFile, + ICopyFileProgress *progress) { int res = rename(oldFile, newFile); if (res == 0) @@ -976,7 +1057,7 @@ bool MyMoveFile(CFSTR oldFile, CFSTR newFile) if (errno != EXDEV) // (oldFile and newFile are not on the same mounted filesystem) return false; - if (My_CopyFile(oldFile, newFile) == FALSE) + if (My_CopyFile(oldFile, newFile, progress) == FALSE) return false; struct stat info_file; @@ -990,6 +1071,11 @@ bool MyMoveFile(CFSTR oldFile, CFSTR newFile) return (unlink(oldFile) == 0); } +bool MyMoveFile(CFSTR oldFile, CFSTR newFile) +{ + return MyMoveFile_with_Progress(oldFile, newFile, NULL); +} + bool CreateDir(CFSTR path) { diff --git a/CPP/Windows/FileDir.h b/CPP/Windows/FileDir.h index 573ffa2..74675ee 100644 --- a/CPP/Windows/FileDir.h +++ b/CPP/Windows/FileDir.h @@ -41,7 +41,26 @@ int my_chown(CFSTR path, uid_t owner, gid_t group); bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib); +#ifndef _WIN32 +#define PROGRESS_CONTINUE 0 +#define PROGRESS_CANCEL 1 +// #define PROGRESS_STOP 2 +// #define PROGRESS_QUIET 3 +#endif +Z7_PURE_INTERFACES_BEGIN +DECLARE_INTERFACE(ICopyFileProgress) +{ + // in: total, current: include all/processed alt streams. + // it returns PROGRESS_CONTINUE or PROGRESS_CANCEL. + virtual DWORD CopyFileProgress(UInt64 total, UInt64 current) = 0; +}; +Z7_PURE_INTERFACES_END + bool MyMoveFile(CFSTR existFileName, CFSTR newFileName); +// (progress == NULL) is allowed +bool MyMoveFile_with_Progress(CFSTR oldFile, CFSTR newFile, + ICopyFileProgress *progress); + #ifndef UNDER_CE bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName); @@ -87,7 +106,9 @@ public: bool Create(CFSTR pathPrefix, NIO::COutFile *outFile); // pathPrefix is not folder prefix bool CreateRandomInTempFolder(CFSTR namePrefix, NIO::COutFile *outFile); bool Remove(); - bool MoveTo(CFSTR name, bool deleteDestBefore); + // bool MoveTo(CFSTR name, bool deleteDestBefore); + bool MoveTo(CFSTR name, bool deleteDestBefore, + ICopyFileProgress *progress); }; diff --git a/CPP/Windows/FileName.cpp b/CPP/Windows/FileName.cpp index c16b3d4..1f4a6da 100644 --- a/CPP/Windows/FileName.cpp +++ b/CPP/Windows/FileName.cpp @@ -278,12 +278,14 @@ bool IsAbsolutePath(const wchar_t *s) throw() int FindAltStreamColon(CFSTR path) throw() { unsigned i = 0; - if (IsDrivePath2(path)) - i = 2; + if (IsSuperPath(path)) + i = kSuperPathPrefixSize; + if (IsDrivePath2(path + i)) + i += 2; int colonPos = -1; for (;; i++) { - FChar c = path[i]; + const FChar c = path[i]; if (c == 0) return colonPos; if (c == ':') diff --git a/CPP/Windows/Registry.cpp b/CPP/Windows/Registry.cpp index c8b1709..a94a50f 100644 --- a/CPP/Windows/Registry.cpp +++ b/CPP/Windows/Registry.cpp @@ -78,7 +78,7 @@ LONG CKey::Close() throw() return res; } -// win95, win98: deletes sunkey and all its subkeys +// win95, win98: deletes subkey and all its subkeys // winNT to be deleted must not have subkeys LONG CKey::DeleteSubKey(LPCTSTR subKeyName) throw() { @@ -88,22 +88,36 @@ LONG CKey::DeleteSubKey(LPCTSTR subKeyName) throw() LONG CKey::RecurseDeleteKey(LPCTSTR subKeyName) throw() { - CKey key; - LONG res = key.Open(_object, subKeyName, KEY_READ | KEY_WRITE); - if (res != ERROR_SUCCESS) - return res; - FILETIME fileTime; - const UInt32 kBufSize = MAX_PATH + 1; // 256 in ATL - DWORD size = kBufSize; - TCHAR buffer[kBufSize]; - while (RegEnumKeyEx(key._object, 0, buffer, &size, NULL, NULL, NULL, &fileTime) == ERROR_SUCCESS) { - res = key.RecurseDeleteKey(buffer); + CKey key; + LONG res = key.Open(_object, subKeyName, KEY_READ | KEY_WRITE); if (res != ERROR_SUCCESS) return res; - size = kBufSize; + FILETIME fileTime; + const UInt32 kBufSize = MAX_PATH + 1; // 256 in ATL + TCHAR buffer[kBufSize]; + // we use loop limit here for some unexpected code failure + for (unsigned loop_cnt = 0; loop_cnt < (1u << 26); loop_cnt++) + { + DWORD size = kBufSize; + // we always request starting item (index==0) in each iteration, + // because we remove starting item (index==0) in each loop iteration. + res = RegEnumKeyEx(key._object, 0, buffer, &size, NULL, NULL, NULL, &fileTime); + if (res != ERROR_SUCCESS) + { + // possible return codes: + // ERROR_NO_MORE_ITEMS : are no more subkeys available + // ERROR_MORE_DATA : name buffer is too small + // we can try to remove (subKeyName), even if there is non ERROR_NO_MORE_ITEMS error. + // if (res != ERROR_NO_MORE_ITEMS) return res; + break; + } + res = key.RecurseDeleteKey(buffer); + if (res != ERROR_SUCCESS) + return res; + } + // key.Close(); } - key.Close(); return DeleteSubKey(subKeyName); } @@ -127,7 +141,7 @@ LONG CKey::DeleteValue(LPCWSTR name) MY_ASSUME(_object != NULL); if (g_IsNT) return ::RegDeleteValueW(_object, name); - return DeleteValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name)); + return DeleteValue(name == NULL ? NULL : (LPCSTR)GetSystemString(name)); } #endif @@ -143,12 +157,15 @@ LONG CKey::SetValue(LPCTSTR name, bool value) throw() return SetValue(name, BoolToUINT32(value)); } + +// value must be string that is NULL terminated LONG CKey::SetValue(LPCTSTR name, LPCTSTR value) throw() { MYASSERT(value != NULL); MY_ASSUME(_object != NULL); + // note: RegSetValueEx supports (value == NULL), if (cbData == 0) return RegSetValueEx(_object, name, 0, REG_SZ, - (const BYTE *)value, ((DWORD)lstrlen(value) + 1) * sizeof(TCHAR)); + (const BYTE *)value, (DWORD)(((DWORD)lstrlen(value) + 1) * sizeof(TCHAR))); } /* @@ -156,7 +173,7 @@ LONG CKey::SetValue(LPCTSTR name, const CSysString &value) { MYASSERT(value != NULL); MY_ASSUME(_object != NULL); - return RegSetValueEx(_object, name, NULL, REG_SZ, + return RegSetValueEx(_object, name, 0, REG_SZ, (const BYTE *)(const TCHAR *)value, (value.Len() + 1) * sizeof(TCHAR)); } */ @@ -169,9 +186,10 @@ LONG CKey::SetValue(LPCWSTR name, LPCWSTR value) MY_ASSUME(_object != NULL); if (g_IsNT) return RegSetValueExW(_object, name, 0, REG_SZ, - (const BYTE * )value, (DWORD)((wcslen(value) + 1) * sizeof(wchar_t))); - return SetValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name), - value == 0 ? 0 : (LPCSTR)GetSystemString(value)); + (const BYTE *)value, (DWORD)(((DWORD)wcslen(value) + 1) * sizeof(wchar_t))); + return SetValue(name == NULL ? NULL : + (LPCSTR)GetSystemString(name), + (LPCSTR)GetSystemString(value)); } #endif @@ -205,99 +223,137 @@ LONG CKey::SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value) throw( return res; } -LONG CKey::QueryValue(LPCTSTR name, UInt32 &value) throw() -{ - DWORD type = 0; - DWORD count = sizeof(DWORD); - LONG res = RegQueryValueEx(_object, name, NULL, &type, - (LPBYTE)&value, &count); - MYASSERT((res != ERROR_SUCCESS) || (type == REG_DWORD)); - MYASSERT((res != ERROR_SUCCESS) || (count == sizeof(UInt32))); - return res; -} -LONG CKey::QueryValue(LPCTSTR name, bool &value) throw() +LONG CKey::GetValue_UInt32_IfOk(LPCTSTR name, UInt32 &value) throw() { - UInt32 uintValue = BoolToUINT32(value); - LONG res = QueryValue(name, uintValue); - value = UINT32ToBool(uintValue); + DWORD type = 0; + DWORD count = sizeof(value); + UInt32 value2; // = value; + const LONG res = QueryValueEx(name, &type, (LPBYTE)&value2, &count); + if (res == ERROR_SUCCESS) + { + // ERROR_UNSUPPORTED_TYPE + if (count != sizeof(value) || type != REG_DWORD) + return ERROR_UNSUPPORTED_TYPE; // ERROR_INVALID_DATA; + value = value2; + } return res; } -LONG CKey::GetValue_IfOk(LPCTSTR name, UInt32 &value) throw() +LONG CKey::GetValue_UInt64_IfOk(LPCTSTR name, UInt64 &value) throw() { - UInt32 newVal; - LONG res = QueryValue(name, newVal); + DWORD type = 0; + DWORD count = sizeof(value); + UInt64 value2; // = value; + const LONG res = QueryValueEx(name, &type, (LPBYTE)&value2, &count); if (res == ERROR_SUCCESS) - value = newVal; + { + if (count != sizeof(value) || type != REG_QWORD) + return ERROR_UNSUPPORTED_TYPE; + value = value2; + } return res; } -LONG CKey::GetValue_IfOk(LPCTSTR name, bool &value) throw() +LONG CKey::GetValue_bool_IfOk(LPCTSTR name, bool &value) throw() { - bool newVal = false; - LONG res = QueryValue(name, newVal); + UInt32 uintValue; + const LONG res = GetValue_UInt32_IfOk(name, uintValue); if (res == ERROR_SUCCESS) - value = newVal; + value = UINT32ToBool(uintValue); return res; } -LONG CKey::QueryValue(LPCTSTR name, LPTSTR value, UInt32 &count) throw() -{ - DWORD type = 0; - LONG res = RegQueryValueEx(_object, name, NULL, &type, (LPBYTE)value, (DWORD *)&count); - MYASSERT((res != ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ)); - return res; -} + LONG CKey::QueryValue(LPCTSTR name, CSysString &value) { value.Empty(); - DWORD type = 0; - DWORD curSize = 0; - LONG res = RegQueryValueEx(_object, name, NULL, &type, NULL, &curSize); - if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) - return res; - UInt32 curSize2 = curSize; - res = QueryValue(name, value.GetBuf(curSize), curSize2); - if (curSize > curSize2) - curSize = curSize2; - value.ReleaseBuf_CalcLen(curSize / sizeof(TCHAR)); + LONG res = ERROR_SUCCESS; + { + // if we don't want multiple calls here, + // we can use big value (264) here. + // 3 is default available length in new string. + DWORD size_prev = 3 * sizeof(TCHAR); + // at least 2 attempts are required. But we use more attempts for cases, + // where string can be changed by anothner process + for (unsigned i = 0; i < 2 + 2; i++) + { + DWORD type = 0; + DWORD size = size_prev; + { + LPBYTE buf = (LPBYTE)value.GetBuf(size / sizeof(TCHAR)); + res = QueryValueEx(name, &type, size == 0 ? NULL : buf, &size); + // if (size_prev == 0), then (res == ERROR_SUCCESS) is expected here, because we requested only size. + } + if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA) + { + if (type != REG_SZ && type != REG_EXPAND_SZ) + { + res = ERROR_UNSUPPORTED_TYPE; + size = 0; + } + } + else + size = 0; + if (size > size_prev) + { + size_prev = size; + size = 0; + res = ERROR_MORE_DATA; + } + value.ReleaseBuf_CalcLen(size / sizeof(TCHAR)); + if (res != ERROR_MORE_DATA) + return res; + } + } return res; } #ifndef _UNICODE -LONG CKey::QueryValue(LPCWSTR name, LPWSTR value, UInt32 &count) -{ - DWORD type = 0; - LONG res = RegQueryValueExW(_object, name, NULL, &type, (LPBYTE)value, (DWORD *)&count); - MYASSERT((res != ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ)); - return res; -} - LONG CKey::QueryValue(LPCWSTR name, UString &value) { value.Empty(); - DWORD type = 0; - DWORD curSize = 0; - LONG res; + LONG res = ERROR_SUCCESS; if (g_IsNT) { - res = RegQueryValueExW(_object, name, NULL, &type, NULL, &curSize); - if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) - return res; - UInt32 curSize2 = curSize; - res = QueryValue(name, value.GetBuf(curSize), curSize2); - if (curSize > curSize2) - curSize = curSize2; - value.ReleaseBuf_CalcLen(curSize / sizeof(wchar_t)); + DWORD size_prev = 3 * sizeof(wchar_t); + for (unsigned i = 0; i < 2 + 2; i++) + { + DWORD type = 0; + DWORD size = size_prev; + { + LPBYTE buf = (LPBYTE)value.GetBuf(size / sizeof(wchar_t)); + res = RegQueryValueExW(_object, name, NULL, &type, + size == 0 ? NULL : buf, &size); + } + if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA) + { + if (type != REG_SZ && type != REG_EXPAND_SZ) + { + res = ERROR_UNSUPPORTED_TYPE; + size = 0; + } + } + else + size = 0; + if (size > size_prev) + { + size_prev = size; + size = 0; + res = ERROR_MORE_DATA; + } + value.ReleaseBuf_CalcLen(size / sizeof(wchar_t)); + if (res != ERROR_MORE_DATA) + return res; + } } else { AString vTemp; - res = QueryValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name), vTemp); + res = QueryValue(name == NULL ? NULL : (LPCSTR)GetSystemString(name), vTemp); value = GetUnicodeString(vTemp); } return res; @@ -306,26 +362,43 @@ LONG CKey::QueryValue(LPCWSTR name, UString &value) #endif -LONG CKey::QueryValue(LPCTSTR name, void *value, UInt32 &count) throw() +LONG CKey::QueryValue_Binary(LPCTSTR name, CByteBuffer &value) { - DWORD type = 0; - LONG res = RegQueryValueEx(_object, name, NULL, &type, (LPBYTE)value, (DWORD *)&count); - MYASSERT((res != ERROR_SUCCESS) || (type == REG_BINARY)); + // value.Free(); + DWORD size_prev = 0; + LONG res = ERROR_SUCCESS; + for (unsigned i = 0; i < 2 + 2; i++) + { + DWORD type = 0; + DWORD size = size_prev; + value.Alloc(size_prev); + res = QueryValueEx(name, &type, value.NonConstData(), &size); + // if (size_prev == 0), then (res == ERROR_SUCCESS) is expected here, because we requested only size. + if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA) + { + if (type != REG_BINARY) + { + res = ERROR_UNSUPPORTED_TYPE; + size = 0; + } + } + else + size = 0; + if (size > size_prev) + { + size_prev = size; + size = 0; + res = ERROR_MORE_DATA; + } + if (size < value.Size()) + value.ChangeSize_KeepData(size, size); + if (res != ERROR_MORE_DATA) + return res; + } return res; } -LONG CKey::QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize) -{ - DWORD type = 0; - dataSize = 0; - LONG res = RegQueryValueEx(_object, name, NULL, &type, NULL, (DWORD *)&dataSize); - if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) - return res; - value.Alloc(dataSize); - return QueryValue(name, (BYTE *)value, dataSize); -} - LONG CKey::EnumKeys(CSysStringVector &keyNames) { keyNames.Clear(); @@ -334,23 +407,23 @@ LONG CKey::EnumKeys(CSysStringVector &keyNames) { const unsigned kBufSize = MAX_PATH + 1; // 256 in ATL FILETIME lastWriteTime; - UInt32 nameSize = kBufSize; - LONG result = ::RegEnumKeyEx(_object, index, keyName.GetBuf(kBufSize), - (DWORD *)&nameSize, NULL, NULL, NULL, &lastWriteTime); + DWORD nameSize = kBufSize; + const LONG res = ::RegEnumKeyEx(_object, index, + keyName.GetBuf(kBufSize), &nameSize, + NULL, NULL, NULL, &lastWriteTime); keyName.ReleaseBuf_CalcLen(kBufSize); - if (result == ERROR_NO_MORE_ITEMS) - break; - if (result != ERROR_SUCCESS) - return result; + if (res == ERROR_NO_MORE_ITEMS) + return ERROR_SUCCESS; + if (res != ERROR_SUCCESS) + return res; keyNames.Add(keyName); } - return ERROR_SUCCESS; } + LONG CKey::SetValue_Strings(LPCTSTR valueName, const UStringVector &strings) { size_t numChars = 0; - unsigned i; for (i = 0; i < strings.Size(); i++) @@ -362,10 +435,11 @@ LONG CKey::SetValue_Strings(LPCTSTR valueName, const UStringVector &strings) for (i = 0; i < strings.Size(); i++) { const UString &s = strings[i]; - size_t size = s.Len() + 1; + const size_t size = s.Len() + 1; wmemcpy(buffer + pos, s, size); pos += size; } + // if (pos != numChars) return E_FAIL; return SetValue(valueName, buffer, (UInt32)numChars * sizeof(wchar_t)); } @@ -373,20 +447,18 @@ LONG CKey::GetValue_Strings(LPCTSTR valueName, UStringVector &strings) { strings.Clear(); CByteBuffer buffer; - UInt32 dataSize = 0; - const LONG res = QueryValue(valueName, buffer, dataSize); + const LONG res = QueryValue_Binary(valueName, buffer); if (res != ERROR_SUCCESS) return res; - if (dataSize > buffer.Size()) - return E_FAIL; - if (dataSize % sizeof(wchar_t) != 0) - return E_FAIL; - + const size_t dataSize = buffer.Size(); + if (dataSize % sizeof(wchar_t)) + return ERROR_INVALID_DATA; const wchar_t *data = (const wchar_t *)(const void *)(const Byte *)buffer; const size_t numChars = dataSize / sizeof(wchar_t); + // we can check that all names are finished + // if (numChars != 0 && data[numChars - 1] != 0) return ERROR_INVALID_DATA; size_t prev = 0; UString s; - for (size_t i = 0; i < numChars; i++) { if (data[i] == 0) @@ -396,7 +468,6 @@ LONG CKey::GetValue_Strings(LPCTSTR valueName, UStringVector &strings) prev = i + 1; } } - return res; } diff --git a/CPP/Windows/Registry.h b/CPP/Windows/Registry.h index 0d3b4fc..74ee919 100644 --- a/CPP/Windows/Registry.h +++ b/CPP/Windows/Registry.h @@ -14,6 +14,13 @@ LONG SetValue(HKEY parentKey, LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value) class CKey { HKEY _object; + + LONG QueryValueEx(LPCTSTR lpValueName, LPDWORD lpType, + LPBYTE lpData, LPDWORD lpcbData) + { + return RegQueryValueEx(_object, lpValueName, NULL, lpType, lpData, lpcbData); + } + public: CKey(): _object(NULL) {} ~CKey() { Close(); } @@ -22,13 +29,14 @@ public: void Attach(HKEY key) { _object = key; } HKEY Detach() { - HKEY key = _object; + const HKEY key = _object; _object = NULL; return key; } LONG Create(HKEY parentKey, LPCTSTR keyName, - LPTSTR keyClass = REG_NONE, DWORD options = REG_OPTION_NON_VOLATILE, + LPTSTR keyClass = REG_NONE, + DWORD options = REG_OPTION_NON_VOLATILE, REGSAM accessMask = KEY_ALL_ACCESS, LPSECURITY_ATTRIBUTES securityAttributes = NULL, LPDWORD disposition = NULL) throw(); @@ -40,18 +48,18 @@ public: LONG RecurseDeleteKey(LPCTSTR subKeyName) throw(); LONG DeleteValue(LPCTSTR name) throw(); - #ifndef _UNICODE +#ifndef _UNICODE LONG DeleteValue(LPCWSTR name); - #endif +#endif LONG SetValue(LPCTSTR valueName, UInt32 value) throw(); LONG SetValue(LPCTSTR valueName, bool value) throw(); LONG SetValue(LPCTSTR valueName, LPCTSTR value) throw(); // LONG SetValue(LPCTSTR valueName, const CSysString &value); - #ifndef _UNICODE +#ifndef _UNICODE LONG SetValue(LPCWSTR name, LPCWSTR value); // LONG SetValue(LPCWSTR name, const UString &value); - #endif +#endif LONG SetValue(LPCTSTR name, const void *value, UInt32 size) throw(); @@ -60,21 +68,25 @@ public: LONG SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value) throw(); - LONG QueryValue(LPCTSTR name, UInt32 &value) throw(); - LONG QueryValue(LPCTSTR name, bool &value) throw(); - LONG QueryValue(LPCTSTR name, LPTSTR value, UInt32 &dataSize) throw(); - LONG QueryValue(LPCTSTR name, CSysString &value); - - LONG GetValue_IfOk(LPCTSTR name, UInt32 &value) throw(); - LONG GetValue_IfOk(LPCTSTR name, bool &value) throw(); + // GetValue_[type]_IfOk(): + // if (return_result == ERROR_SUCCESS), (value) variable was read from registry + // if (return_result != ERROR_SUCCESS), (value) variable was not changed + LONG GetValue_UInt32_IfOk(LPCTSTR name, UInt32 &value) throw(); + LONG GetValue_UInt64_IfOk(LPCTSTR name, UInt64 &value) throw(); + LONG GetValue_bool_IfOk(LPCTSTR name, bool &value) throw(); - #ifndef _UNICODE - LONG QueryValue(LPCWSTR name, LPWSTR value, UInt32 &dataSize); + // QueryValue(): + // if (return_result == ERROR_SUCCESS), (value) string was read from registry + // if (return_result != ERROR_SUCCESS), (value) string was cleared + LONG QueryValue(LPCTSTR name, CSysString &value); +#ifndef _UNICODE LONG QueryValue(LPCWSTR name, UString &value); - #endif +#endif - LONG QueryValue(LPCTSTR name, void *value, UInt32 &dataSize) throw(); - LONG QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize); + // QueryValue_Binary(): + // if (return_result == ERROR_SUCCESS), (value) buffer was read from registry (BINARY data) + // if (return_result != ERROR_SUCCESS), (value) buffer was cleared + LONG QueryValue_Binary(LPCTSTR name, CByteBuffer &value); LONG EnumKeys(CSysStringVector &keyNames); }; diff --git a/CPP/Windows/System.cpp b/CPP/Windows/System.cpp index 03c8988..5fa87f3 100644 --- a/CPP/Windows/System.cpp +++ b/CPP/Windows/System.cpp @@ -142,9 +142,9 @@ typedef BOOL (WINAPI *Func_GlobalMemoryStatusEx)(MY_LPMEMORYSTATUSEX lpBuffer); #endif // !UNDER_CE -bool GetRamSize(UInt64 &size) +bool GetRamSize(size_t &size) { - size = (UInt64)(sizeof(size_t)) << 29; + size = (size_t)sizeof(size_t) << 29; #ifndef UNDER_CE MY_MEMORYSTATUSEX stat; @@ -167,11 +167,23 @@ bool GetRamSize(UInt64 &size) "GlobalMemoryStatusEx"); if (fn && fn(&stat)) { - size = MyMin(stat.ullTotalVirtual, stat.ullTotalPhys); + // (MY_MEMORYSTATUSEX::ullTotalVirtual) < 4 GiB in 32-bit mode + size_t size2 = (size_t)0 - 1; + if (size2 > stat.ullTotalPhys) + size2 = (size_t)stat.ullTotalPhys; + if (size2 > stat.ullTotalVirtual) + size2 = (size_t)stat.ullTotalVirtual; + size = size2; return true; } #endif + // On computers with more than 4 GB of memory: + // new docs : GlobalMemoryStatus can report (-1) value to indicate an overflow. + // some old docs : GlobalMemoryStatus can report (modulo 4 GiB) value. + // (for example, if 5 GB total memory, it could report 1 GB). + // We don't want to get (modulo 4 GiB) value. + // So we use GlobalMemoryStatusEx() instead. { MEMORYSTATUS stat2; stat2.dwLength = sizeof(stat2); @@ -187,9 +199,11 @@ bool GetRamSize(UInt64 &size) // POSIX // #include -bool GetRamSize(UInt64 &size) +bool GetRamSize(size_t &size) { - size = (UInt64)(sizeof(size_t)) << 29; + UInt64 size64; + size = (size_t)sizeof(size_t) << 29; + size64 = size; #if defined(__APPLE__) || defined(__DragonFly__) || \ defined(BSD) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) @@ -215,7 +229,7 @@ bool GetRamSize(UInt64 &size) // we use strict check (size_sys == sizeof(val)) for returned value // because big-endian encoding is possible: if (res == 0 && size_sys == sizeof(val) && val) - size = val; + size64 = val; else { uint32_t val32 = 0; @@ -223,12 +237,12 @@ bool GetRamSize(UInt64 &size) res = sysctl(mib, 2, &val32, &size_sys, NULL, 0); // printf("\n sysctl res=%d val=%llx size_sys = %d, %d\n", res, (long long int)val32, (int)size_sys, errno); if (res == 0 && size_sys == sizeof(val32) && val32) - size = val32; + size64 = val32; } #elif defined(_AIX) #if defined(_SC_AIX_REALMEM) // AIX - size = (UInt64)sysconf(_SC_AIX_REALMEM) * 1024; + size64 = (UInt64)sysconf(_SC_AIX_REALMEM) * 1024; #endif #elif 0 || defined(__sun) #if defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE) @@ -240,7 +254,7 @@ bool GetRamSize(UInt64 &size) // printf("\n_SC_PHYS_PAGES (hex) = %lx", (unsigned long)phys_pages); // printf("\n_SC_PAGESIZE = %lu\n", (unsigned long)page_size); if (phys_pages != -1 && page_size != -1) - size = (UInt64)(Int64)phys_pages * (UInt64)(Int64)page_size; + size64 = (UInt64)(Int64)phys_pages * (UInt64)(Int64)page_size; } #endif #elif defined(__gnu_hurd__) @@ -253,7 +267,7 @@ bool GetRamSize(UInt64 &size) struct sysinfo info; if (::sysinfo(&info) != 0) return false; - size = (UInt64)info.mem_unit * info.totalram; + size64 = (UInt64)info.mem_unit * info.totalram; /* printf("\n mem_unit = %lld", (UInt64)info.mem_unit); printf("\n totalram = %lld", (UInt64)info.totalram); @@ -262,10 +276,9 @@ bool GetRamSize(UInt64 &size) #endif - const UInt64 kLimit = (UInt64)1 << (sizeof(size_t) * 8 - 1); - if (size > kLimit) - size = kLimit; - + size = (size_t)1 << (sizeof(size_t) * 8 - 1); + if (size > size64) + size = (size_t)size64; return true; } diff --git a/CPP/Windows/System.h b/CPP/Windows/System.h index b17111c..9951b8b 100644 --- a/CPP/Windows/System.h +++ b/CPP/Windows/System.h @@ -122,7 +122,7 @@ struct CProcessAffinity UInt32 GetNumberOfProcessors(); -bool GetRamSize(UInt64 &size); // returns false, if unknown ram size +bool GetRamSize(size_t &size); // returns false, if unknown ram size unsigned long Get_File_OPEN_MAX(); unsigned Get_File_OPEN_MAX_Reduced_for_3_tasks(); diff --git a/CPP/Windows/SystemInfo.cpp b/CPP/Windows/SystemInfo.cpp index cfc6a90..35846e0 100644 --- a/CPP/Windows/SystemInfo.cpp +++ b/CPP/Windows/SystemInfo.cpp @@ -530,6 +530,28 @@ struct CCpuName AString Microcode; AString LargePages; +#ifdef _WIN32 + UInt32 MHz; + +#ifdef MY_CPU_ARM64 +#define Z7_SYS_INFO_SHOW_ARM64_REGS +#endif +#ifdef Z7_SYS_INFO_SHOW_ARM64_REGS + bool Arm64_ISAR0_EL1_Defined; + UInt64 Arm64_ISAR0_EL1; +#endif +#endif + +#ifdef _WIN32 + CCpuName(): + MHz(0) +#ifdef Z7_SYS_INFO_SHOW_ARM64_REGS + , Arm64_ISAR0_EL1_Defined(false) + , Arm64_ISAR0_EL1(0) +#endif + {} +#endif + void Fill(); void Get_Revision_Microcode_LargePages(AString &s) @@ -537,16 +559,46 @@ struct CCpuName s.Empty(); AddBracedString(s, Revision); AddBracedString(s, Microcode); - s.Add_OptSpaced(LargePages); +#ifdef _WIN32 + if (MHz != 0) + { + s.Add_Space_if_NotEmpty(); + s.Add_UInt32(MHz); + s += " MHz"; + } +#endif + if (!LargePages.IsEmpty()) + s.Add_OptSpaced(LargePages); + } + +#ifdef Z7_SYS_INFO_SHOW_ARM64_REGS + void Get_Registers(AString &s) + { + if (Arm64_ISAR0_EL1_Defined) + { + // ID_AA64ISAR0_EL1 + s.Add_OptSpaced("cp4030:"); + PrintHex(s, Arm64_ISAR0_EL1); + { + const unsigned sha2 = ((unsigned)(Arm64_ISAR0_EL1 >> 12) & 0xf) - 1; + if (sha2 < 2) + { + s += ":SHA256"; + if (sha2) + s += ":SHA512"; + } + } + } } +#endif }; void CCpuName::Fill() { - CpuName.Empty(); - Revision.Empty(); - Microcode.Empty(); - LargePages.Empty(); + // CpuName.Empty(); + // Revision.Empty(); + // Microcode.Empty(); + // LargePages.Empty(); AString &s = CpuName; @@ -600,21 +652,32 @@ void CCpuName::Fill() Revision += GetAnsiString(name); } } +#ifdef _WIN32 + key.GetValue_UInt32_IfOk(TEXT("~MHz"), MHz); +#ifdef Z7_SYS_INFO_SHOW_ARM64_REGS +/* +mapping arm64 registers to Windows registry: +CP 4000: MIDR_EL1 +CP 4020: ID_AA64PFR0_EL1 +CP 4021: ID_AA64PFR1_EL1 +CP 4028: ID_AA64DFR0_EL1 +CP 4029: ID_AA64DFR1_EL1 +CP 402C: ID_AA64AFR0_EL1 +CP 402D: ID_AA64AFR1_EL1 +CP 4030: ID_AA64ISAR0_EL1 +CP 4031: ID_AA64ISAR1_EL1 +CP 4038: ID_AA64MMFR0_EL1 +CP 4039: ID_AA64MMFR1_EL1 +CP 403A: ID_AA64MMFR2_EL1 +*/ + if (key.GetValue_UInt64_IfOk(TEXT("CP 4030"), Arm64_ISAR0_EL1) == ERROR_SUCCESS) + Arm64_ISAR0_EL1_Defined = true; +#endif +#endif LONG res[2]; CByteBuffer bufs[2]; - { - for (unsigned i = 0; i < 2; i++) - { - UInt32 size = 0; - res[i] = key.QueryValue(i == 0 ? - TEXT("Previous Update Revision") : - TEXT("Update Revision"), - bufs[i], size); - if (res[i] == ERROR_SUCCESS) - if (size != bufs[i].Size()) - res[i] = ERROR_SUCCESS + 1; - } - } + res[0] = key.QueryValue_Binary(TEXT("Previous Update Revision"), bufs[0]); + res[1] = key.QueryValue_Binary(TEXT("Update Revision"), bufs[1]); if (res[0] == ERROR_SUCCESS || res[1] == ERROR_SUCCESS) { for (unsigned i = 0; i < 2; i++) @@ -747,9 +810,18 @@ void AddCpuFeatures(AString &s) unsigned long h = MY_getauxval(AT_HWCAP); PrintHex(s, h); #ifdef MY_CPU_ARM64 +#ifndef HWCAP_SHA3 +#define HWCAP_SHA3 (1 << 17) +#endif +#ifndef HWCAP_SHA512 +#define HWCAP_SHA512 (1 << 21) +// #pragma message("=== HWCAP_SHA512 define === ") +#endif if (h & HWCAP_CRC32) s += ":CRC32"; if (h & HWCAP_SHA1) s += ":SHA1"; if (h & HWCAP_SHA2) s += ":SHA2"; + if (h & HWCAP_SHA3) s += ":SHA3"; + if (h & HWCAP_SHA512) s += ":SHA512"; if (h & HWCAP_AES) s += ":AES"; if (h & HWCAP_ASIMD) s += ":ASIMD"; #elif defined(MY_CPU_ARM) @@ -908,13 +980,18 @@ void GetSystemInfoText(AString &sRes) } } { - AString s; - GetCpuName_MultiLine(s); + AString s, registers; + GetCpuName_MultiLine(s, registers); if (!s.IsEmpty()) { sRes += s; sRes.Add_LF(); } + if (!registers.IsEmpty()) + { + sRes += registers; + sRes.Add_LF(); + } } /* #ifdef MY_CPU_X86_OR_AMD64 @@ -932,8 +1009,8 @@ void GetSystemInfoText(AString &sRes) } -void GetCpuName_MultiLine(AString &s); -void GetCpuName_MultiLine(AString &s) +void GetCpuName_MultiLine(AString &s, AString ®isters); +void GetCpuName_MultiLine(AString &s, AString ®isters) { CCpuName cpuName; cpuName.Fill(); @@ -945,6 +1022,10 @@ void GetCpuName_MultiLine(AString &s) s.Add_LF(); s += s2; } + registers.Empty(); +#ifdef Z7_SYS_INFO_SHOW_ARM64_REGS + cpuName.Get_Registers(registers); +#endif } diff --git a/CPP/Windows/SystemInfo.h b/CPP/Windows/SystemInfo.h index c2e2e3b..4601685 100644 --- a/CPP/Windows/SystemInfo.h +++ b/CPP/Windows/SystemInfo.h @@ -6,7 +6,7 @@ #include "../Common/MyString.h" -void GetCpuName_MultiLine(AString &s); +void GetCpuName_MultiLine(AString &s, AString ®isters); void GetOsInfoText(AString &sRes); void GetSystemInfoText(AString &s); -- cgit v1.2.3-55-g6feb