aboutsummaryrefslogtreecommitdiff
path: root/CPP
diff options
context:
space:
mode:
authorIgor Pavlov <87184205+ip7z@users.noreply.github.com>2024-11-29 00:00:00 +0000
committerIgor Pavlov <87184205+ip7z@users.noreply.github.com>2024-11-30 15:27:15 +0500
commite5431fa6f5505e385c6f9367260717e9c47dc2ee (patch)
tree4cd2c2c3b225b48c8e7053432c41d7b6b6a3d5f8 /CPP
parente008ce3976c087bfd21344af8f00a23cf69d4174 (diff)
download7zip-e5431fa6f5505e385c6f9367260717e9c47dc2ee.tar.gz
7zip-e5431fa6f5505e385c6f9367260717e9c47dc2ee.tar.bz2
7zip-e5431fa6f5505e385c6f9367260717e9c47dc2ee.zip
Diffstat (limited to 'CPP')
-rw-r--r--CPP/7zip/7zip_gcc.mak16
-rw-r--r--CPP/7zip/Archive/ApmHandler.cpp182
-rw-r--r--CPP/7zip/Archive/Common/HandlerOut.h4
-rw-r--r--CPP/7zip/Archive/HfsHandler.cpp256
-rw-r--r--CPP/7zip/Archive/LpHandler.cpp4
-rw-r--r--CPP/7zip/Archive/Rar/Rar5Handler.cpp14
-rw-r--r--CPP/7zip/Archive/XarHandler.cpp90
-rw-r--r--CPP/7zip/Archive/XzHandler.cpp4
-rw-r--r--CPP/7zip/Bundles/Format7zF/Arc.mak8
-rw-r--r--CPP/7zip/Bundles/Format7zF/Arc_gcc.mak8
-rw-r--r--CPP/7zip/Bundles/Format7zF/Format7z.dsp92
-rw-r--r--CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp21
-rw-r--r--CPP/7zip/Common/CreateCoder.cpp2
-rw-r--r--CPP/7zip/Common/MethodProps.h12
-rw-r--r--CPP/7zip/Crypto/Rar5Aes.cpp117
-rw-r--r--CPP/7zip/Crypto/Rar5Aes.h57
-rw-r--r--CPP/7zip/Crypto/RarAes.cpp12
-rw-r--r--CPP/7zip/Crypto/ZipStrong.cpp43
-rw-r--r--CPP/7zip/GuiCommon.rc2
-rw-r--r--CPP/7zip/Guid.txt2
-rw-r--r--CPP/7zip/UI/Agent/Agent.cpp2
-rw-r--r--CPP/7zip/UI/Agent/Agent.h33
-rw-r--r--CPP/7zip/UI/Agent/ArchiveFolder.cpp6
-rw-r--r--CPP/7zip/UI/Agent/ArchiveFolderOut.cpp76
-rw-r--r--CPP/7zip/UI/Agent/IFolderArchive.h16
-rw-r--r--CPP/7zip/UI/Client7z/makefile.gcc3
-rw-r--r--CPP/7zip/UI/Common/ArchiveExtractCallback.cpp138
-rw-r--r--CPP/7zip/UI/Common/ArchiveExtractCallback.h95
-rw-r--r--CPP/7zip/UI/Common/Bench.cpp48
-rw-r--r--CPP/7zip/UI/Common/EnumDirItems.cpp4
-rw-r--r--CPP/7zip/UI/Common/HashCalc.cpp34
-rw-r--r--CPP/7zip/UI/Common/TempFiles.cpp3
-rw-r--r--CPP/7zip/UI/Common/TempFiles.h3
-rw-r--r--CPP/7zip/UI/Common/Update.cpp68
-rw-r--r--CPP/7zip/UI/Common/Update.h5
-rw-r--r--CPP/7zip/UI/Common/WorkDir.cpp16
-rw-r--r--CPP/7zip/UI/Common/WorkDir.h8
-rw-r--r--CPP/7zip/UI/Common/ZipRegistry.cpp37
-rw-r--r--CPP/7zip/UI/Console/ConsoleClose.cpp10
-rw-r--r--CPP/7zip/UI/Console/ConsoleClose.h2
-rw-r--r--CPP/7zip/UI/Console/ExtractCallbackConsole.cpp2
-rw-r--r--CPP/7zip/UI/Console/MainAr.cpp2
-rw-r--r--CPP/7zip/UI/Console/PercentPrinter.h18
-rw-r--r--CPP/7zip/UI/Console/UpdateCallbackConsole.cpp113
-rw-r--r--CPP/7zip/UI/Console/UpdateCallbackConsole.h36
-rw-r--r--CPP/7zip/UI/Explorer/ContextMenu.cpp10
-rw-r--r--CPP/7zip/UI/Explorer/ContextMenu.h4
-rw-r--r--CPP/7zip/UI/Far/Far.cpp7
-rw-r--r--CPP/7zip/UI/Far/FarUtils.cpp4
-rw-r--r--CPP/7zip/UI/Far/ProgressBox.h10
-rw-r--r--CPP/7zip/UI/Far/UpdateCallbackFar.cpp90
-rw-r--r--CPP/7zip/UI/Far/UpdateCallbackFar.h16
-rw-r--r--CPP/7zip/UI/FileManager/App.cpp14
-rw-r--r--CPP/7zip/UI/FileManager/App.h2
-rw-r--r--CPP/7zip/UI/FileManager/ExtractCallback.cpp272
-rw-r--r--CPP/7zip/UI/FileManager/ExtractCallback.h190
-rw-r--r--CPP/7zip/UI/FileManager/FM.cpp17
-rw-r--r--CPP/7zip/UI/FileManager/MemDialog.cpp10
-rw-r--r--CPP/7zip/UI/FileManager/MemDialog.h2
-rw-r--r--CPP/7zip/UI/FileManager/MyLoadMenu.cpp8
-rw-r--r--CPP/7zip/UI/FileManager/OpenCallback.cpp2
-rw-r--r--CPP/7zip/UI/FileManager/Panel.cpp11
-rw-r--r--CPP/7zip/UI/FileManager/Panel.h289
-rw-r--r--CPP/7zip/UI/FileManager/PanelCopy.cpp52
-rw-r--r--CPP/7zip/UI/FileManager/PanelDrag.cpp8
-rw-r--r--CPP/7zip/UI/FileManager/PanelItemOpen.cpp105
-rw-r--r--CPP/7zip/UI/FileManager/PanelItems.cpp17
-rw-r--r--CPP/7zip/UI/FileManager/PanelListNotify.cpp2
-rw-r--r--CPP/7zip/UI/FileManager/PanelOperations.cpp2
-rw-r--r--CPP/7zip/UI/FileManager/ProgressDialog2.cpp105
-rw-r--r--CPP/7zip/UI/FileManager/ProgressDialog2.h57
-rw-r--r--CPP/7zip/UI/FileManager/RegistryUtils.cpp8
-rw-r--r--CPP/7zip/UI/FileManager/SettingsPage.cpp6
-rw-r--r--CPP/7zip/UI/FileManager/SysIconUtils.cpp2
-rw-r--r--CPP/7zip/UI/FileManager/UpdateCallback100.cpp23
-rw-r--r--CPP/7zip/UI/FileManager/UpdateCallback100.h5
-rw-r--r--CPP/7zip/UI/FileManager/ViewSettings.cpp17
-rw-r--r--CPP/7zip/UI/FileManager/resource.h11
-rw-r--r--CPP/7zip/UI/FileManager/resource.rc6
-rw-r--r--CPP/7zip/UI/FileManager/resourceGui.h2
-rw-r--r--CPP/7zip/UI/FileManager/resourceGui.rc2
-rw-r--r--CPP/7zip/UI/GUI/BenchmarkDialog.cpp77
-rw-r--r--CPP/7zip/UI/GUI/CompressDialog.cpp67
-rw-r--r--CPP/7zip/UI/GUI/CompressDialog.h20
-rw-r--r--CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp15
-rw-r--r--CPP/7zip/UI/GUI/UpdateCallbackGUI2.cpp73
-rw-r--r--CPP/7zip/UI/GUI/UpdateCallbackGUI2.h31
-rw-r--r--CPP/7zip/warn_gcc.mak17
-rw-r--r--CPP/Common/Md5Reg.cpp44
-rw-r--r--CPP/Common/MyCom.h37
-rw-r--r--CPP/Common/Sha3Reg.cpp76
-rw-r--r--CPP/Common/Sha512Prepare.cpp7
-rw-r--r--CPP/Common/Sha512Reg.cpp83
-rw-r--r--CPP/Windows/FileDir.cpp138
-rw-r--r--CPP/Windows/FileDir.h23
-rw-r--r--CPP/Windows/FileName.cpp8
-rw-r--r--CPP/Windows/Registry.cpp295
-rw-r--r--CPP/Windows/Registry.h48
-rw-r--r--CPP/Windows/System.cpp41
-rw-r--r--CPP/Windows/System.h2
-rw-r--r--CPP/Windows/SystemInfo.cpp125
-rw-r--r--CPP/Windows/SystemInfo.h2
102 files changed, 2996 insertions, 1345 deletions
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
302 $(CXX) $(CXXFLAGS) $< 302 $(CXX) $(CXXFLAGS) $<
303$O/LzFindPrepare.o: ../../../Common/LzFindPrepare.cpp 303$O/LzFindPrepare.o: ../../../Common/LzFindPrepare.cpp
304 $(CXX) $(CXXFLAGS) $< 304 $(CXX) $(CXXFLAGS) $<
305$O/Md5Reg.o: ../../../Common/Md5Reg.cpp
306 $(CXX) $(CXXFLAGS) $<
305$O/MyMap.o: ../../../Common/MyMap.cpp 307$O/MyMap.o: ../../../Common/MyMap.cpp
306 $(CXX) $(CXXFLAGS) $< 308 $(CXX) $(CXXFLAGS) $<
307$O/MyString.o: ../../../Common/MyString.cpp 309$O/MyString.o: ../../../Common/MyString.cpp
@@ -326,6 +328,12 @@ $O/Sha256Prepare.o: ../../../Common/Sha256Prepare.cpp
326 $(CXX) $(CXXFLAGS) $< 328 $(CXX) $(CXXFLAGS) $<
327$O/Sha256Reg.o: ../../../Common/Sha256Reg.cpp 329$O/Sha256Reg.o: ../../../Common/Sha256Reg.cpp
328 $(CXX) $(CXXFLAGS) $< 330 $(CXX) $(CXXFLAGS) $<
331$O/Sha3Reg.o: ../../../Common/Sha3Reg.cpp
332 $(CXX) $(CXXFLAGS) $<
333$O/Sha512Prepare.o: ../../../Common/Sha512Prepare.cpp
334 $(CXX) $(CXXFLAGS) $<
335$O/Sha512Reg.o: ../../../Common/Sha512Reg.cpp
336 $(CXX) $(CXXFLAGS) $<
329$O/StdInStream.o: ../../../Common/StdInStream.cpp 337$O/StdInStream.o: ../../../Common/StdInStream.cpp
330 $(CXX) $(CXXFLAGS) $< 338 $(CXX) $(CXXFLAGS) $<
331$O/StdOutStream.o: ../../../Common/StdOutStream.cpp 339$O/StdOutStream.o: ../../../Common/StdOutStream.cpp
@@ -1207,6 +1215,8 @@ $O/Lzma2Enc.o: ../../../../C/Lzma2Enc.c
1207 $(CC) $(CFLAGS) $< 1215 $(CC) $(CFLAGS) $<
1208$O/LzmaLib.o: ../../../../C/LzmaLib.c 1216$O/LzmaLib.o: ../../../../C/LzmaLib.c
1209 $(CC) $(CFLAGS) $< 1217 $(CC) $(CFLAGS) $<
1218$O/Md5.o: ../../../../C/Md5.c
1219 $(CC) $(CFLAGS) $<
1210$O/MtCoder.o: ../../../../C/MtCoder.c 1220$O/MtCoder.o: ../../../../C/MtCoder.c
1211 $(CC) $(CFLAGS) $< 1221 $(CC) $(CFLAGS) $<
1212$O/MtDec.o: ../../../../C/MtDec.c 1222$O/MtDec.o: ../../../../C/MtDec.c
@@ -1229,6 +1239,12 @@ $O/Sha1.o: ../../../../C/Sha1.c
1229 $(CC) $(CFLAGS) $< 1239 $(CC) $(CFLAGS) $<
1230$O/Sha256.o: ../../../../C/Sha256.c 1240$O/Sha256.o: ../../../../C/Sha256.c
1231 $(CC) $(CFLAGS) $< 1241 $(CC) $(CFLAGS) $<
1242$O/Sha3.o: ../../../../C/Sha3.c
1243 $(CC) $(CFLAGS) $<
1244$O/Sha512.o: ../../../../C/Sha512.c
1245 $(CC) $(CFLAGS) $<
1246$O/Sha512Opt.o: ../../../../C/Sha512Opt.c
1247 $(CC) $(CFLAGS) $<
1232$O/Sort.o: ../../../../C/Sort.c 1248$O/Sort.o: ../../../../C/Sort.c
1233 $(CC) $(CFLAGS) $< 1249 $(CC) $(CFLAGS) $<
1234$O/SwapBytes.o: ../../../../C/SwapBytes.c 1250$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 @@
6 6
7#include "../../Common/ComTry.h" 7#include "../../Common/ComTry.h"
8 8
9#include "../../Windows/PropVariant.h"
10#include "../../Windows/PropVariantUtils.h" 9#include "../../Windows/PropVariantUtils.h"
11 10
12#include "../Common/RegisterArc.h" 11#include "../Common/RegisterArc.h"
@@ -14,8 +13,7 @@
14 13
15#include "HandlerCont.h" 14#include "HandlerCont.h"
16 15
17// #define Get16(p) GetBe16(p) 16#define Get32(p) GetBe32a(p)
18#define Get32(p) GetBe32(p)
19 17
20using namespace NWindows; 18using namespace NWindows;
21 19
@@ -41,8 +39,8 @@ static const CUInt32PCharPair k_Flags[] =
41 { 5, "WRITABLE" }, 39 { 5, "WRITABLE" },
42 { 6, "OS_PIC_CODE" }, 40 { 6, "OS_PIC_CODE" },
43 // { 7, "OS_SPECIFIC_2" }, // "Unused" 41 // { 7, "OS_SPECIFIC_2" }, // "Unused"
44 // { 8, "ChainCompatible" }, // "OS_SPECIFIC_1" 42 { 8, "ChainCompatible" }, // "OS_SPECIFIC_1"
45 // { 9, "RealDeviceDriver" }, 43 { 9, "RealDeviceDriver" },
46 // { 10, "CanChainToNext" }, 44 // { 10, "CanChainToNext" },
47 { 30, "MOUNTED_AT_STARTUP" }, 45 { 30, "MOUNTED_AT_STARTUP" },
48 { 31, "STARTUP" } 46 { 31, "STARTUP" }
@@ -74,16 +72,16 @@ struct CItem
74 bool Is_Valid_and_Allocated() const 72 bool Is_Valid_and_Allocated() const
75 { return (Flags & (DPME_FLAGS_VALID | DPME_FLAGS_ALLOCATED)) != 0; } 73 { return (Flags & (DPME_FLAGS_VALID | DPME_FLAGS_ALLOCATED)) != 0; }
76 74
77 bool Parse(const Byte *p, UInt32 &numBlocksInMap) 75 bool Parse(const UInt32 *p32, UInt32 &numBlocksInMap)
78 { 76 {
79 numBlocksInMap = Get32(p + 4); 77 if (GetUi32a(p32) != 0x4d50) // "PM"
80 StartBlock = Get32(p + 8);
81 NumBlocks = Get32(p + 0xc);
82 Flags = Get32(p + 0x58);
83 memcpy(Name, p + 0x10, k_Str_Size);
84 memcpy(Type, p + 0x30, k_Str_Size);
85 if (GetUi32(p) != 0x4d50) // "PM"
86 return false; 78 return false;
79 numBlocksInMap = Get32(p32 + 4 / 4);
80 StartBlock = Get32(p32 + 8 / 4);
81 NumBlocks = Get32(p32 + 0xc / 4);
82 Flags = Get32(p32 + 0x58 / 4);
83 memcpy(Name, p32 + 0x10 / 4, k_Str_Size);
84 memcpy(Type, p32 + 0x30 / 4, k_Str_Size);
87 /* 85 /*
88 DataStartBlock = Get32(p + 0x50); 86 DataStartBlock = Get32(p + 0x50);
89 NumDataBlocks = Get32(p + 0x54); 87 NumDataBlocks = Get32(p + 0x54);
@@ -96,7 +94,7 @@ struct CItem
96 if (Get32(p + 0x70) != 0) 94 if (Get32(p + 0x70) != 0)
97 return false; 95 return false;
98 BootChecksum = Get32(p + 0x74); 96 BootChecksum = Get32(p + 0x74);
99 memcpy(Processor, p + 0x78, 16); 97 memcpy(Processor, p32 + 0x78 / 4, 16);
100 */ 98 */
101 return true; 99 return true;
102 } 100 }
@@ -109,9 +107,9 @@ Z7_class_CHandler_final: public CHandlerCont
109 107
110 CRecordVector<CItem> _items; 108 CRecordVector<CItem> _items;
111 unsigned _blockSizeLog; 109 unsigned _blockSizeLog;
112 UInt32 _numBlocks;
113 UInt64 _phySize;
114 bool _isArc; 110 bool _isArc;
111 // UInt32 _numBlocks;
112 UInt64 _phySize;
115 113
116 UInt64 BlocksToBytes(UInt32 i) const { return (UInt64)i << _blockSizeLog; } 114 UInt64 BlocksToBytes(UInt32 i) const { return (UInt64)i << _blockSizeLog; }
117 115
@@ -132,11 +130,11 @@ API_FUNC_static_IsArc IsArc_Apm(const Byte *p, size_t size)
132{ 130{
133 if (size < kSectorSize) 131 if (size < kSectorSize)
134 return k_IsArc_Res_NEED_MORE; 132 return k_IsArc_Res_NEED_MORE;
135 if (GetUi64(p + 8) != 0) 133 if (GetUi32(p + 12) != 0)
136 return k_IsArc_Res_NO; 134 return k_IsArc_Res_NO;
137 UInt32 v = GetUi32(p); // we read as little-endian 135 UInt32 v = GetUi32(p); // we read as little-endian
138 v ^= (kSig0 | (unsigned)kSig1 << 8); 136 v ^= kSig0 | (unsigned)kSig1 << 8;
139 if ((v & ~((UInt32)0xf << 17))) 137 if (v & ~((UInt32)0xf << 17))
140 return k_IsArc_Res_NO; 138 return k_IsArc_Res_NO;
141 if ((0x116u >> (v >> 17)) & 1) 139 if ((0x116u >> (v >> 17)) & 1)
142 return k_IsArc_Res_YES; 140 return k_IsArc_Res_YES;
@@ -149,55 +147,103 @@ Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallb
149 COM_TRY_BEGIN 147 COM_TRY_BEGIN
150 Close(); 148 Close();
151 149
152 Byte buf[kSectorSize]; 150 UInt32 buf32[kSectorSize / 4];
153 unsigned numSectors_in_Cluster; 151 unsigned numPadSectors, blockSizeLog_from_Header;
154 { 152 {
155 RINOK(ReadStream_FALSE(stream, buf, kSectorSize)) 153 // Driver Descriptor Map (DDM)
156 if (GetUi64(buf + 8) != 0) 154 RINOK(ReadStream_FALSE(stream, buf32, kSectorSize))
155 // 8: UInt16 sbDevType : =0 (usually), =1 in Apple Mac OS X 10.3.0 iso
156 // 10: UInt16 sbDevId : =0 (usually), =1 in Apple Mac OS X 10.3.0 iso
157 // 12: UInt32 sbData : =0
158 if (buf32[3] != 0)
157 return S_FALSE; 159 return S_FALSE;
158 UInt32 v = GetUi32(buf); // we read as little-endian 160 UInt32 v = GetUi32a(buf32); // we read as little-endian
159 v ^= (kSig0 | (unsigned)kSig1 << 8); 161 v ^= kSig0 | (unsigned)kSig1 << 8;
160 if ((v & ~((UInt32)0xf << 17))) 162 if (v & ~((UInt32)0xf << 17))
161 return S_FALSE; 163 return S_FALSE;
162 v >>= 16; 164 v >>= 16;
163 if (v == 0) 165 if (v == 0)
164 return S_FALSE; 166 return S_FALSE;
165 if (v & (v - 1)) 167 if (v & (v - 1))
166 return S_FALSE; 168 return S_FALSE;
167 const unsigned a = (0x30210u >> v) & 3; 169 // v == { 16,8,4,2 } : block size (x256 bytes)
168 // a = 0; // for debug 170 const unsigned a =
169 numSectors_in_Cluster = 1u << a; 171#if 1
170 _blockSizeLog = 9 + a; 172 (0x30210u >> v) & 3;
173#else
174 0; // for debug : hardcoded switch to 512-bytes mode
175#endif
176 numPadSectors = (1u << a) - 1;
177 _blockSizeLog = blockSizeLog_from_Header = 9 + a;
171 } 178 }
172 179
173 UInt32 numBlocks = Get32(buf + 4); 180/*
174 _numBlocks = numBlocks; 181 some APMs (that are ".iso" macOS installation files) contain
175 182 (blockSizeLog == 11) in DDM header,
183 and contain 2 overlapping maps:
184 1) map for 512-bytes-step
185 2) map for 2048-bytes-step
186 512-bytes-step map is correct.
187 2048-bytes-step map can be incorrect in some cases.
188
189 macos 8 / OSX DP2 iso:
190 There is shared "hfs" item in both maps.
191 And correct (offset/size) values for "hfs" partition
192 can be calculated only in 512-bytes mode (ignoring blockSizeLog == 11).
193 But some records (Macintosh.Apple_Driver*_)
194 can be correct on both modes: 512-bytes mode / 2048-bytes-step.
195
196 macos 921 ppc / Apple Mac OS X 10.3.0 iso:
197 Both maps are correct.
198 If we use 512-bytes-step, each 4th item is (Apple_Void) with zero size.
199 And these zero size (Apple_Void) items will be first items in 2048-bytes-step map.
200*/
201
202// we define Z7_APM_SWITCH_TO_512_BYTES, because
203// we want to support old MACOS APMs that contain correct value only
204// for 512-bytes-step mode
205#define Z7_APM_SWITCH_TO_512_BYTES
206
207 const UInt32 numBlocks_from_Header = Get32(buf32 + 1);
208 UInt32 numBlocks = 0;
176 { 209 {
177 for (unsigned k = numSectors_in_Cluster; --k != 0;) 210 for (unsigned k = 0; k < numPadSectors; k++)
178 { 211 {
179 RINOK(ReadStream_FALSE(stream, buf, kSectorSize)) 212 RINOK(ReadStream_FALSE(stream, buf32, kSectorSize))
213#ifdef Z7_APM_SWITCH_TO_512_BYTES
214 if (k == 0)
215 {
216 if (GetUi32a(buf32) == 0x4d50 // "PM"
217 // && (Get32(buf32 + 0x58 / 4) & 1) // Flags::VALID
218 // some old APMs don't use VALID flag for Apple_partition_map item
219 && Get32(buf32 + 8 / 4) == 1) // StartBlock
220 {
221 // we switch the mode to 512-bytes-step map reading:
222 numPadSectors = 0;
223 _blockSizeLog = 9;
224 break;
225 }
226 }
227#endif
180 } 228 }
181 } 229 }
182 230
183 UInt32 numBlocksInMap = 0;
184
185 for (unsigned i = 0;;) 231 for (unsigned i = 0;;)
186 { 232 {
187 RINOK(ReadStream_FALSE(stream, buf, kSectorSize)) 233#ifdef Z7_APM_SWITCH_TO_512_BYTES
234 if (i != 0 || _blockSizeLog == blockSizeLog_from_Header)
235#endif
236 {
237 RINOK(ReadStream_FALSE(stream, buf32, kSectorSize))
238 }
188 239
189 CItem item; 240 CItem item;
190 241 UInt32 numBlocksInMap = 0;
191 UInt32 numBlocksInMap2 = 0; 242 if (!item.Parse(buf32, numBlocksInMap))
192 if (!item.Parse(buf, numBlocksInMap2))
193 return S_FALSE; 243 return S_FALSE;
194 if (i == 0) 244 // v24.09: we don't check that all entries have same (numBlocksInMap) values,
195 { 245 // because some APMs have different (numBlocksInMap) values, if (Apple_Void) is used.
196 numBlocksInMap = numBlocksInMap2; 246 if (numBlocksInMap > (1 << 8) || numBlocksInMap <= i)
197 if (numBlocksInMap > (1 << 8) || numBlocksInMap == 0)
198 return S_FALSE;
199 }
200 else if (numBlocksInMap2 != numBlocksInMap)
201 return S_FALSE; 247 return S_FALSE;
202 248
203 const UInt32 finish = item.StartBlock + item.NumBlocks; 249 const UInt32 finish = item.StartBlock + item.NumBlocks;
@@ -207,15 +253,19 @@ Z7_COM7F_IMF(CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallb
207 numBlocks = finish; 253 numBlocks = finish;
208 254
209 _items.Add(item); 255 _items.Add(item);
210 for (unsigned k = numSectors_in_Cluster; --k != 0;) 256 if (numPadSectors != 0)
211 { 257 {
212 RINOK(ReadStream_FALSE(stream, buf, kSectorSize)) 258 RINOK(stream->Seek(numPadSectors << 9, STREAM_SEEK_CUR, NULL))
213 } 259 }
214 if (++i == numBlocksInMap) 260 if (++i == numBlocksInMap)
215 break; 261 break;
216 } 262 }
217 263
218 _phySize = BlocksToBytes(numBlocks); 264 _phySize = BlocksToBytes(numBlocks);
265 // _numBlocks = numBlocks;
266 const UInt64 physSize = (UInt64)numBlocks_from_Header << blockSizeLog_from_Header;
267 if (_phySize < physSize)
268 _phySize = physSize;
219 _isArc = true; 269 _isArc = true;
220 _stream = stream; 270 _stream = stream;
221 271
@@ -240,22 +290,21 @@ static const Byte kProps[] =
240 kpidSize, 290 kpidSize,
241 kpidOffset, 291 kpidOffset,
242 kpidCharacts 292 kpidCharacts
293 // , kpidCpu
243}; 294};
244 295
245static const Byte kArcProps[] = 296static const Byte kArcProps[] =
246{ 297{
247 kpidClusterSize, 298 kpidClusterSize
248 kpidNumBlocks 299 // , kpidNumBlocks
249}; 300};
250 301
251IMP_IInArchive_Props 302IMP_IInArchive_Props
252IMP_IInArchive_ArcProps 303IMP_IInArchive_ArcProps
253 304
254static AString GetString(const char *s) 305static void GetString(AString &dest, const char *src)
255{ 306{
256 AString res; 307 dest.SetFrom_CalcLen(src, k_Str_Size);
257 res.SetFrom_CalcLen(s, k_Str_Size);
258 return res;
259} 308}
260 309
261Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) 310Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
@@ -272,7 +321,8 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
272 const CItem &item = _items[i]; 321 const CItem &item = _items[i];
273 if (!item.Is_Valid_and_Allocated()) 322 if (!item.Is_Valid_and_Allocated())
274 continue; 323 continue;
275 AString s (GetString(item.Type)); 324 AString s;
325 GetString(s, item.Type);
276 if (NDmg::Is_Apple_FS_Or_Unknown(s)) 326 if (NDmg::Is_Apple_FS_Or_Unknown(s))
277 { 327 {
278 if (mainIndex != -1) 328 if (mainIndex != -1)
@@ -289,7 +339,7 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
289 } 339 }
290 case kpidClusterSize: prop = (UInt32)1 << _blockSizeLog; break; 340 case kpidClusterSize: prop = (UInt32)1 << _blockSizeLog; break;
291 case kpidPhySize: prop = _phySize; break; 341 case kpidPhySize: prop = _phySize; break;
292 case kpidNumBlocks: prop = _numBlocks; break; 342 // case kpidNumBlocks: prop = _numBlocks; break;
293 343
294 case kpidErrorFlags: 344 case kpidErrorFlags:
295 { 345 {
@@ -319,10 +369,12 @@ Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
319 { 369 {
320 case kpidPath: 370 case kpidPath:
321 { 371 {
322 AString s (GetString(item.Name)); 372 AString s;
373 GetString(s, item.Name);
323 if (s.IsEmpty()) 374 if (s.IsEmpty())
324 s.Add_UInt32(index); 375 s.Add_UInt32(index);
325 AString type (GetString(item.Type)); 376 AString type;
377 GetString(type, item.Type);
326 { 378 {
327 const char *ext = NDmg::Find_Apple_FS_Ext(type); 379 const char *ext = NDmg::Find_Apple_FS_Ext(type);
328 if (ext) 380 if (ext)
@@ -336,6 +388,16 @@ Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
336 prop = s; 388 prop = s;
337 break; 389 break;
338 } 390 }
391/*
392 case kpidCpu:
393 {
394 AString s;
395 s.SetFrom_CalcLen(item.Processor, sizeof(item.Processor));
396 if (!s.IsEmpty())
397 prop = s;
398 break;
399 }
400*/
339 case kpidSize: 401 case kpidSize:
340 case kpidPackSize: 402 case kpidPackSize:
341 prop = BlocksToBytes(item.NumBlocks); 403 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:
22 _numThreads_WasForced = false; 22 _numThreads_WasForced = false;
23 #endif 23 #endif
24 24
25 UInt64 memAvail = (UInt64)(sizeof(size_t)) << 28; 25 size_t memAvail = (size_t)sizeof(size_t) << 28;
26 _memAvail = memAvail; 26 _memAvail = memAvail;
27 _memUsage_Compress = memAvail; 27 _memUsage_Compress = memAvail;
28 _memUsage_Decompress = memAvail; 28 _memUsage_Decompress = memAvail;
@@ -55,7 +55,7 @@ public:
55 bool _memUsage_WasSet; 55 bool _memUsage_WasSet;
56 UInt64 _memUsage_Compress; 56 UInt64 _memUsage_Compress;
57 UInt64 _memUsage_Decompress; 57 UInt64 _memUsage_Decompress;
58 UInt64 _memAvail; 58 size_t _memAvail;
59 59
60 bool SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres); 60 bool SetCommonProperty(const UString &name, const PROPVARIANT &value, HRESULT &hres);
61 61
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 @@
25#define Get32(p) GetBe32(p) 25#define Get32(p) GetBe32(p)
26#define Get64(p) GetBe64(p) 26#define Get64(p) GetBe64(p)
27 27
28#define Get16a(p) GetBe16a(p)
29#define Get32a(p) GetBe32a(p)
30
28namespace NArchive { 31namespace NArchive {
29namespace NHfs { 32namespace NHfs {
30 33
@@ -104,23 +107,21 @@ UInt32 CFork::Calc_NumBlocks_from_Extents() const
104{ 107{
105 UInt32 num = 0; 108 UInt32 num = 0;
106 FOR_VECTOR (i, Extents) 109 FOR_VECTOR (i, Extents)
107 {
108 num += Extents[i].NumBlocks; 110 num += Extents[i].NumBlocks;
109 }
110 return num; 111 return num;
111} 112}
112 113
113bool CFork::Check_NumBlocks() const 114bool CFork::Check_NumBlocks() const
114{ 115{
115 UInt32 num = 0; 116 UInt32 num = NumBlocks;
116 FOR_VECTOR (i, Extents) 117 FOR_VECTOR (i, Extents)
117 { 118 {
118 UInt32 next = num + Extents[i].NumBlocks; 119 const UInt32 cur = Extents[i].NumBlocks;
119 if (next < num) 120 if (num < cur)
120 return false; 121 return false;
121 num = next; 122 num -= cur;
122 } 123 }
123 return num == NumBlocks; 124 return num == 0;
124} 125}
125 126
126struct CIdIndexPair 127struct CIdIndexPair
@@ -175,7 +176,7 @@ static int Find_in_IdExtents(const CObjectVector<CIdExtents> &items, UInt32 id)
175 176
176bool CFork::Upgrade(const CObjectVector<CIdExtents> &items, UInt32 id) 177bool CFork::Upgrade(const CObjectVector<CIdExtents> &items, UInt32 id)
177{ 178{
178 int index = Find_in_IdExtents(items, id); 179 const int index = Find_in_IdExtents(items, id);
179 if (index < 0) 180 if (index < 0)
180 return true; 181 return true;
181 const CIdExtents &item = items[index]; 182 const CIdExtents &item = items[index];
@@ -188,8 +189,13 @@ bool CFork::Upgrade(const CObjectVector<CIdExtents> &items, UInt32 id)
188 189
189struct CVolHeader 190struct CVolHeader
190{ 191{
191 Byte Header[2]; 192 unsigned BlockSizeLog;
192 UInt16 Version; 193 UInt32 NumFiles;
194 UInt32 NumFolders;
195 UInt32 NumBlocks;
196 UInt32 NumFreeBlocks;
197
198 bool Is_Hsfx_ver5;
193 // UInt32 Attr; 199 // UInt32 Attr;
194 // UInt32 LastMountedVersion; 200 // UInt32 LastMountedVersion;
195 // UInt32 JournalInfoBlock; 201 // UInt32 JournalInfoBlock;
@@ -199,19 +205,13 @@ struct CVolHeader
199 // UInt32 BackupTime; 205 // UInt32 BackupTime;
200 // UInt32 CheckedTime; 206 // UInt32 CheckedTime;
201 207
202 UInt32 NumFiles;
203 UInt32 NumFolders;
204 unsigned BlockSizeLog;
205 UInt32 NumBlocks;
206 UInt32 NumFreeBlocks;
207
208 // UInt32 WriteCount; 208 // UInt32 WriteCount;
209 // UInt32 FinderInfo[8]; 209 // UInt32 FinderInfo[8];
210 // UInt64 VolID; 210 // UInt64 VolID;
211 211
212 UInt64 GetPhySize() const { return (UInt64)NumBlocks << BlockSizeLog; } 212 UInt64 GetPhySize() const { return (UInt64)NumBlocks << BlockSizeLog; }
213 UInt64 GetFreeSize() const { return (UInt64)NumFreeBlocks << BlockSizeLog; } 213 UInt64 GetFreeSize() const { return (UInt64)NumFreeBlocks << BlockSizeLog; }
214 bool IsHfsX() const { return Version > 4; } 214 bool IsHfsX() const { return Is_Hsfx_ver5; }
215}; 215};
216 216
217inline void HfsTimeToFileTime(UInt32 hfsTime, FILETIME &ft) 217inline void HfsTimeToFileTime(UInt32 hfsTime, FILETIME &ft)
@@ -463,18 +463,18 @@ public:
463 bool UnsupportedFeature; 463 bool UnsupportedFeature;
464 bool ThereAreAltStreams; 464 bool ThereAreAltStreams;
465 // bool CaseSensetive; 465 // bool CaseSensetive;
466 UInt32 MethodsMask;
466 UString ResFileName; 467 UString ResFileName;
467 468
468 UInt64 SpecOffset; 469 UInt64 SpecOffset;
469 UInt64 PhySize; 470 // UInt64 PhySize;
470 UInt64 PhySize2; 471 UInt64 PhySize2;
471 UInt64 ArcFileSize; 472 UInt64 ArcFileSize;
472 UInt32 MethodsMask;
473 473
474 void Clear() 474 void Clear()
475 { 475 {
476 SpecOffset = 0; 476 SpecOffset = 0;
477 PhySize = 0; 477 // PhySize = 0;
478 PhySize2 = 0; 478 PhySize2 = 0;
479 ArcFileSize = 0; 479 ArcFileSize = 0;
480 MethodsMask = 0; 480 MethodsMask = 0;
@@ -596,7 +596,7 @@ HRESULT CDatabase::ReadFile(const CFork &fork, CByteBuffer &buf, IInStream *inSt
596{ 596{
597 if (fork.NumBlocks >= Header.NumBlocks) 597 if (fork.NumBlocks >= Header.NumBlocks)
598 return S_FALSE; 598 return S_FALSE;
599 if ((ArcFileSize >> Header.BlockSizeLog) + 1 < fork.NumBlocks) 599 if (((ArcFileSize - SpecOffset) >> Header.BlockSizeLog) + 1 < fork.NumBlocks)
600 return S_FALSE; 600 return S_FALSE;
601 601
602 const size_t totalSize = (size_t)fork.NumBlocks << Header.BlockSizeLog; 602 const size_t totalSize = (size_t)fork.NumBlocks << Header.BlockSizeLog;
@@ -1328,28 +1328,26 @@ HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector<CIdExtents
1328 return S_OK; 1328 return S_OK;
1329} 1329}
1330 1330
1331static const unsigned kHeaderPadSize = (1 << 10); 1331static const unsigned kHeaderPadSize = 1 << 10;
1332static const unsigned kMainHeaderSize = 512; 1332static const unsigned kMainHeaderSize = 512;
1333static const unsigned kHfsHeaderSize = kHeaderPadSize + kMainHeaderSize; 1333static const unsigned kHfsHeaderSize = kHeaderPadSize + kMainHeaderSize;
1334 1334
1335static const unsigned k_Signature_LE16_HFS_BD = 'B' + ((unsigned)'D' << 8);
1336static const unsigned k_Signature_LE16_HPLUS = 'H' + ((unsigned)'+' << 8);
1337static const UInt32 k_Signature_LE32_HFSP_VER4 = 'H' + ((UInt32)'+' << 8) + ((UInt32)4 << 24);
1338static const UInt32 k_Signature_LE32_HFSX_VER5 = 'H' + ((UInt32)'X' << 8) + ((UInt32)5 << 24);
1339
1335API_FUNC_static_IsArc IsArc_HFS(const Byte *p, size_t size) 1340API_FUNC_static_IsArc IsArc_HFS(const Byte *p, size_t size)
1336{ 1341{
1337 if (size < kHfsHeaderSize) 1342 if (size < kHfsHeaderSize)
1338 return k_IsArc_Res_NEED_MORE; 1343 return k_IsArc_Res_NEED_MORE;
1339 p += kHeaderPadSize; 1344 p += kHeaderPadSize;
1340 if (p[0] == 'B' && p[1] == 'D') 1345 const UInt32 sig = GetUi32(p);
1341 { 1346 if (sig != k_Signature_LE32_HFSP_VER4)
1342 if (p[0x7C] != 'H' || p[0x7C + 1] != '+') 1347 if (sig != k_Signature_LE32_HFSX_VER5)
1343 return k_IsArc_Res_NO; 1348 if ((UInt16)sig != k_Signature_LE16_HFS_BD
1344 } 1349 || GetUi16(p + 0x7c) != k_Signature_LE16_HPLUS)
1345 else 1350 return k_IsArc_Res_NO;
1346 {
1347 if (p[0] != 'H' || (p[1] != '+' && p[1] != 'X'))
1348 return k_IsArc_Res_NO;
1349 UInt32 version = Get16(p + 2);
1350 if (version < 4 || version > 5)
1351 return k_IsArc_Res_NO;
1352 }
1353 return k_IsArc_Res_YES; 1351 return k_IsArc_Res_YES;
1354} 1352}
1355} 1353}
@@ -1357,30 +1355,42 @@ API_FUNC_static_IsArc IsArc_HFS(const Byte *p, size_t size)
1357HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress) 1355HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress)
1358{ 1356{
1359 Clear(); 1357 Clear();
1360 Byte buf[kHfsHeaderSize]; 1358 UInt32 buf32[kHfsHeaderSize / 4];
1361 RINOK(ReadStream_FALSE(inStream, buf, kHfsHeaderSize)) 1359 RINOK(ReadStream_FALSE(inStream, buf32, kHfsHeaderSize))
1362 { 1360 const Byte *p = (const Byte *)buf32 + kHeaderPadSize;
1363 for (unsigned i = 0; i < kHeaderPadSize; i++)
1364 if (buf[i] != 0)
1365 return S_FALSE;
1366 }
1367 const Byte *p = buf + kHeaderPadSize;
1368 CVolHeader &h = Header; 1361 CVolHeader &h = Header;
1369 1362
1370 h.Header[0] = p[0]; 1363 if (GetUi16a(p) == k_Signature_LE16_HFS_BD)
1371 h.Header[1] = p[1];
1372
1373 if (p[0] == 'B' && p[1] == 'D')
1374 { 1364 {
1375 /* 1365 /*
1376 It's header for old HFS format. 1366 It's header for old HFS format.
1377 We don't support old HFS format, but we support 1367 We don't support old HFS format, but we support
1378 special HFS volume that contains embedded HFS+ volume 1368 special HFS volume that contains embedded HFS+ volume.
1369 HFS MDB : Master directory block
1370 HFS VIB : Volume information block
1371 some old images contain boot data with "LK" signature at start of buf32.
1379 */ 1372 */
1380 1373#if 1
1381 if (p[0x7C] != 'H' || p[0x7C + 1] != '+') 1374 // here we check first bytes of archive,
1375 // because start data can contain signature of some another
1376 // archive type that could have priority over HFS.
1377 const void *buf_ptr = (const void *)buf32;
1378 const unsigned sig = GetUi16a(buf_ptr);
1379 if (sig != 'L' + ((unsigned)'K' << 8))
1380 {
1381 // some old HFS (non HFS+) files have no "LK" signature,
1382 // but have non-zero data after 2 first bytes in start 1 KiB.
1383 if (sig != 0)
1384 return S_FALSE;
1385/*
1386 for (unsigned i = 0; i < kHeaderPadSize / 4; i++)
1387 if (buf32[i] != 0)
1388 return S_FALSE;
1389*/
1390 }
1391#endif
1392 if (GetUi16a(p + 0x7c) != k_Signature_LE16_HPLUS) // signature of embedded HFS+ volume
1382 return S_FALSE; 1393 return S_FALSE;
1383
1384 /* 1394 /*
1385 h.CTime = Get32(p + 0x2); 1395 h.CTime = Get32(p + 0x2);
1386 h.MTime = Get32(p + 0x6); 1396 h.MTime = Get32(p + 0x6);
@@ -1399,80 +1409,104 @@ HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress)
1399 h.NumFreeBlocks = Get16(p + 0x22); 1409 h.NumFreeBlocks = Get16(p + 0x22);
1400 */ 1410 */
1401 1411
1402 UInt32 blockSize = Get32(p + 0x14); 1412 // v24.09: blockSize in old HFS image can be non-power of 2.
1403 1413 const UInt32 blockSize = Get32a(p + 0x14); // drAlBlkSiz
1404 { 1414 if (blockSize == 0 || (blockSize & 0x1ff))
1405 unsigned i; 1415 return S_FALSE;
1406 for (i = 9; ((UInt32)1 << i) != blockSize; i++) 1416 const unsigned numBlocks = Get16a(p + 0x12); // drNmAlBlks
1407 if (i == 31) 1417 // UInt16 drFreeBks = Get16a(p + 0x22); // number of unused allocation blocks
1408 return S_FALSE;
1409 h.BlockSizeLog = i;
1410 }
1411
1412 h.NumBlocks = Get16(p + 0x12);
1413 /* 1418 /*
1414 we suppose that it has the follwing layout 1419 we suppose that it has the following layout:
1415 { 1420 {
1416 start block with header 1421 start data with header
1417 [h.NumBlocks] 1422 blocks[h.NumBlocks]
1418 end block with header 1423 end data with header (probably size_of_footer <= blockSize).
1419 } 1424 }
1420 */ 1425 */
1421 PhySize2 = ((UInt64)h.NumBlocks + 2) << h.BlockSizeLog; 1426 // PhySize2 = ((UInt64)numBlocks + 2) * blockSize;
1422 1427 const unsigned sector_of_FirstBlock = Get16a(p + 0x1c); // drAlBlSt : first allocation block in volume
1423 UInt32 startBlock = Get16(p + 0x7C + 2); 1428 const UInt32 startBlock = Get16a(p + 0x7c + 2);
1424 UInt32 blockCount = Get16(p + 0x7C + 4); 1429 const UInt32 blockCount = Get16a(p + 0x7c + 4);
1425 SpecOffset = (UInt64)(1 + startBlock) << h.BlockSizeLog; 1430 SpecOffset = (UInt32)sector_of_FirstBlock << 9; // it's 32-bit here
1426 UInt64 phy = SpecOffset + ((UInt64)blockCount << h.BlockSizeLog); 1431 PhySize2 = SpecOffset + (UInt64)numBlocks * blockSize;
1432 SpecOffset += (UInt64)startBlock * blockSize;
1433 // before v24.09: // SpecOffset = (UInt64)(1 + startBlock) * blockSize;
1434 const UInt64 phy = SpecOffset + (UInt64)blockCount * blockSize;
1427 if (PhySize2 < phy) 1435 if (PhySize2 < phy)
1428 PhySize2 = phy; 1436 PhySize2 = phy;
1437 UInt32 tail = 1 << 10; // at least 1 KiB tail (for footer MDB) is expected.
1438 if (tail < blockSize)
1439 tail = blockSize;
1440 RINOK(InStream_GetSize_SeekToEnd(inStream, ArcFileSize))
1441 if (ArcFileSize > PhySize2 &&
1442 ArcFileSize - PhySize2 <= tail)
1443 {
1444 // data after blocks[h.NumBlocks] must contain another copy of MDB.
1445 // In example where blockSize is not power of 2, we have
1446 // (ArcFileSize - PhySize2) < blockSize.
1447 // We suppose that data after blocks[h.NumBlocks] is part of HFS archive.
1448 // Maybe we should scan for footer MDB data (in last 1 KiB)?
1449 PhySize2 = ArcFileSize;
1450 }
1429 RINOK(InStream_SeekSet(inStream, SpecOffset)) 1451 RINOK(InStream_SeekSet(inStream, SpecOffset))
1430 RINOK(ReadStream_FALSE(inStream, buf, kHfsHeaderSize)) 1452 RINOK(ReadStream_FALSE(inStream, buf32, kHfsHeaderSize))
1431 } 1453 }
1432 1454
1433 if (p[0] != 'H' || (p[1] != '+' && p[1] != 'X')) 1455 // HFS+ / HFSX volume header (starting from offset==1024):
1434 return S_FALSE;
1435 h.Version = Get16(p + 2);
1436 if (h.Version < 4 || h.Version > 5)
1437 return S_FALSE;
1438
1439 // h.Attr = Get32(p + 4);
1440 // h.LastMountedVersion = Get32(p + 8);
1441 // h.JournalInfoBlock = Get32(p + 0xC);
1442
1443 h.CTime = Get32(p + 0x10);
1444 h.MTime = Get32(p + 0x14);
1445 // h.BackupTime = Get32(p + 0x18);
1446 // h.CheckedTime = Get32(p + 0x1C);
1447
1448 h.NumFiles = Get32(p + 0x20);
1449 h.NumFolders = Get32(p + 0x24);
1450
1451 if (h.NumFolders > ((UInt32)1 << 29) ||
1452 h.NumFiles > ((UInt32)1 << 30))
1453 return S_FALSE;
1454
1455 RINOK(InStream_GetSize_SeekToEnd(inStream, ArcFileSize))
1456
1457 if (progress)
1458 { 1456 {
1459 const UInt64 numFiles = (UInt64)h.NumFiles + h.NumFolders + 1; 1457 // v24.09: we use strict condition test for pair signature(Version):
1460 RINOK(progress->SetTotal(&numFiles, NULL)) 1458 // H+(4), HX(5):
1459 const UInt32 sig = GetUi32a(p);
1460 // h.Version = Get16(p + 2);
1461 h.Is_Hsfx_ver5 = false;
1462 if (sig != k_Signature_LE32_HFSP_VER4)
1463 {
1464 if (sig != k_Signature_LE32_HFSX_VER5)
1465 return S_FALSE;
1466 h.Is_Hsfx_ver5 = true;
1467 }
1461 } 1468 }
1462
1463 UInt32 blockSize = Get32(p + 0x28);
1464
1465 { 1469 {
1470 const UInt32 blockSize = Get32a(p + 0x28);
1466 unsigned i; 1471 unsigned i;
1467 for (i = 9; ((UInt32)1 << i) != blockSize; i++) 1472 for (i = 9; ((UInt32)1 << i) != blockSize; i++)
1468 if (i == 31) 1473 if (i == 31)
1469 return S_FALSE; 1474 return S_FALSE;
1470 h.BlockSizeLog = i; 1475 h.BlockSizeLog = i;
1471 } 1476 }
1477#if 1
1478 // HFS Plus DOCs: The first 1024 bytes are reserved for use as boot blocks
1479 // v24.09: we don't check starting 1 KiB before old (HFS MDB) block ("BD" signture) .
1480 // but we still check starting 1 KiB before HFS+ / HFSX volume header.
1481 // are there HFS+ / HFSX images with non-zero data in this reserved area?
1482 {
1483 for (unsigned i = 0; i < kHeaderPadSize / 4; i++)
1484 if (buf32[i] != 0)
1485 return S_FALSE;
1486 }
1487#endif
1488 // h.Attr = Get32a(p + 4);
1489 // h.LastMountedVersion = Get32a(p + 8);
1490 // h.JournalInfoBlock = Get32a(p + 0xC);
1491 h.CTime = Get32a(p + 0x10);
1492 h.MTime = Get32a(p + 0x14);
1493 // h.BackupTime = Get32a(p + 0x18);
1494 // h.CheckedTime = Get32a(p + 0x1C);
1495 h.NumFiles = Get32a(p + 0x20);
1496 h.NumFolders = Get32a(p + 0x24);
1497 if (h.NumFolders > ((UInt32)1 << 29) ||
1498 h.NumFiles > ((UInt32)1 << 30))
1499 return S_FALSE;
1472 1500
1473 h.NumBlocks = Get32(p + 0x2C); 1501 RINOK(InStream_GetSize_SeekToEnd(inStream, ArcFileSize))
1474 h.NumFreeBlocks = Get32(p + 0x30); 1502 if (progress)
1503 {
1504 const UInt64 numFiles = (UInt64)h.NumFiles + h.NumFolders + 1;
1505 RINOK(progress->SetTotal(&numFiles, NULL))
1506 }
1475 1507
1508 h.NumBlocks = Get32a(p + 0x2C);
1509 h.NumFreeBlocks = Get32a(p + 0x30);
1476 /* 1510 /*
1477 h.NextCalatlogNodeID = Get32(p + 0x40); 1511 h.NextCalatlogNodeID = Get32(p + 0x40);
1478 h.WriteCount = Get32(p + 0x44); 1512 h.WriteCount = Get32(p + 0x44);
@@ -1495,7 +1529,7 @@ HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress)
1495 HeadersError = true; 1529 HeadersError = true;
1496 else 1530 else
1497 { 1531 {
1498 HRESULT res = LoadExtentFile(extentsFork, inStream, overflowExtents); 1532 const HRESULT res = LoadExtentFile(extentsFork, inStream, overflowExtents);
1499 if (res == S_FALSE) 1533 if (res == S_FALSE)
1500 HeadersError = true; 1534 HeadersError = true;
1501 else if (res != S_OK) 1535 else if (res != S_OK)
@@ -1515,7 +1549,7 @@ HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress)
1515 1549
1516 RINOK(LoadCatalog(catalogFork, overflowExtents, inStream, progress)) 1550 RINOK(LoadCatalog(catalogFork, overflowExtents, inStream, progress))
1517 1551
1518 PhySize = Header.GetPhySize(); 1552 // PhySize = Header.GetPhySize();
1519 return S_OK; 1553 return S_OK;
1520} 1554}
1521 1555
@@ -1591,7 +1625,7 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
1591 case kpidCharacts: MethodsMaskToProp(MethodsMask, prop); break; 1625 case kpidCharacts: MethodsMaskToProp(MethodsMask, prop); break;
1592 case kpidPhySize: 1626 case kpidPhySize:
1593 { 1627 {
1594 UInt64 v = SpecOffset + PhySize; 1628 UInt64 v = SpecOffset + Header.GetPhySize(); // PhySize;
1595 if (v < PhySize2) 1629 if (v < PhySize2)
1596 v = PhySize2; 1630 v = PhySize2;
1597 prop = v; 1631 prop = v;
@@ -2529,7 +2563,7 @@ HRESULT CHandler::GetForkStream(const CFork &fork, ISequentialInStream **stream)
2529 return S_FALSE; 2563 return S_FALSE;
2530 } 2564 }
2531 CSeekExtent se; 2565 CSeekExtent se;
2532 se.Phy = (UInt64)e.Pos << Header.BlockSizeLog; 2566 se.Phy = SpecOffset + ((UInt64)e.Pos << Header.BlockSizeLog);
2533 se.Virt = virt; 2567 se.Virt = virt;
2534 virt += cur; 2568 virt += cur;
2535 rem -= cur; 2569 rem -= cur;
@@ -2540,7 +2574,7 @@ HRESULT CHandler::GetForkStream(const CFork &fork, ISequentialInStream **stream)
2540 return S_FALSE; 2574 return S_FALSE;
2541 2575
2542 CSeekExtent se; 2576 CSeekExtent se;
2543 se.Phy = 0; 2577 se.Phy = 0; // = SpecOffset ?
2544 se.Virt = virt; 2578 se.Virt = virt;
2545 extentStream->Extents.Add(se); 2579 extentStream->Extents.Add(se);
2546 extentStream->Stream = _stream; 2580 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
460 460
461static bool CheckSha256(const Byte *data, size_t size, const Byte *checksum) 461static bool CheckSha256(const Byte *data, size_t size, const Byte *checksum)
462{ 462{
463 MY_ALIGN (16)
463 CSha256 sha; 464 CSha256 sha;
464 Sha256_Init(&sha); 465 Sha256_Init(&sha);
465 Sha256_Update(&sha, data, size); 466 Sha256_Update(&sha, data, size);
467 MY_ALIGN (16)
466 Byte calced[32]; 468 Byte calced[32];
467 Sha256_Final(&sha, calced); 469 Sha256_Final(&sha, calced);
468 return memcmp(checksum, calced, 32) == 0; 470 return memcmp(checksum, calced, 32) == 0;
@@ -470,6 +472,7 @@ static bool CheckSha256(const Byte *data, size_t size, const Byte *checksum)
470 472
471static bool CheckSha256_csOffset(Byte *data, size_t size, unsigned hashOffset) 473static bool CheckSha256_csOffset(Byte *data, size_t size, unsigned hashOffset)
472{ 474{
475 MY_ALIGN (4)
473 Byte checksum[32]; 476 Byte checksum[32];
474 Byte *shaData = &data[hashOffset]; 477 Byte *shaData = &data[hashOffset];
475 memcpy(checksum, shaData, 32); 478 memcpy(checksum, shaData, 32);
@@ -528,6 +531,7 @@ HRESULT CHandler::Open2(IInStream *stream)
528{ 531{
529 RINOK(InStream_SeekSet(stream, LP_PARTITION_RESERVED_BYTES)) 532 RINOK(InStream_SeekSet(stream, LP_PARTITION_RESERVED_BYTES))
530 { 533 {
534 MY_ALIGN (4)
531 Byte buf[k_Geometry_Size]; 535 Byte buf[k_Geometry_Size];
532 RINOK(ReadStream_FALSE(stream, buf, k_Geometry_Size)) 536 RINOK(ReadStream_FALSE(stream, buf, k_Geometry_Size))
533 if (memcmp(buf, k_Signature, k_SignatureSize) != 0) 537 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)
658 RINOK(ReadStream_Check(_buf, AES_BLOCK_SIZE * 2)) 658 RINOK(ReadStream_Check(_buf, AES_BLOCK_SIZE * 2))
659 memcpy(m_CryptoDecoder->_iv, _buf, AES_BLOCK_SIZE); 659 memcpy(m_CryptoDecoder->_iv, _buf, AES_BLOCK_SIZE);
660 RINOK(m_CryptoDecoder->Init()) 660 RINOK(m_CryptoDecoder->Init())
661 // we call RAR5_AES_Filter with:
662 // data_ptr == aligned_ptr + 16
663 // data_size == 16
661 if (m_CryptoDecoder->Filter(_buf + AES_BLOCK_SIZE, AES_BLOCK_SIZE) != AES_BLOCK_SIZE) 664 if (m_CryptoDecoder->Filter(_buf + AES_BLOCK_SIZE, AES_BLOCK_SIZE) != AES_BLOCK_SIZE)
662 return E_FAIL; 665 return E_FAIL;
663 memcpy(buf, _buf + AES_BLOCK_SIZE, AES_BLOCK_SIZE); 666 memcpy(buf, _buf + AES_BLOCK_SIZE, AES_BLOCK_SIZE);
@@ -689,10 +692,14 @@ HRESULT CInArchive::ReadBlockHeader(CHeader &h)
689 return E_OUTOFMEMORY; 692 return E_OUTOFMEMORY;
690 memcpy(_buf, buf, filled); 693 memcpy(_buf, buf, filled);
691 const size_t rem = size - filled; 694 const size_t rem = size - filled;
695 // if (m_CryptoMode), we add AES_BLOCK_SIZE here, because _iv is not included to size.
692 AddToSeekValue(size + (m_CryptoMode ? AES_BLOCK_SIZE : 0)); 696 AddToSeekValue(size + (m_CryptoMode ? AES_BLOCK_SIZE : 0));
693 RINOK(ReadStream_Check(_buf + filled, rem)) 697 RINOK(ReadStream_Check(_buf + filled, rem))
694 if (m_CryptoMode) 698 if (m_CryptoMode)
695 { 699 {
700 // we call RAR5_AES_Filter with:
701 // data_ptr == aligned_ptr + 16
702 // (rem) can be big
696 if (m_CryptoDecoder->Filter(_buf + filled, (UInt32)rem) != rem) 703 if (m_CryptoDecoder->Filter(_buf + filled, (UInt32)rem) != rem)
697 return E_FAIL; 704 return E_FAIL;
698#if 1 705#if 1
@@ -1065,7 +1072,8 @@ HRESULT CUnpacker::Create(DECL_EXTERNAL_CODECS_LOC_VARS
1065 1072
1066 CMyComPtr<ICompressSetDecoderProperties2> csdp; 1073 CMyComPtr<ICompressSetDecoderProperties2> csdp;
1067 RINOK(lzCoder.QueryInterface(IID_ICompressSetDecoderProperties2, &csdp)) 1074 RINOK(lzCoder.QueryInterface(IID_ICompressSetDecoderProperties2, &csdp))
1068 1075 if (!csdp)
1076 return E_NOTIMPL;
1069 const unsigned ver = item.Get_AlgoVersion_HuffRev(); 1077 const unsigned ver = item.Get_AlgoVersion_HuffRev();
1070 if (ver > 1) 1078 if (ver > 1)
1071 return E_NOTIMPL; 1079 return E_NOTIMPL;
@@ -3343,9 +3351,9 @@ Z7_COM7F_IMF(CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
3343 } 3351 }
3344 else if (name.IsPrefixedBy_Ascii_NoCase("memx")) 3352 else if (name.IsPrefixedBy_Ascii_NoCase("memx"))
3345 { 3353 {
3346 UInt64 memAvail; 3354 size_t memAvail;
3347 if (!NWindows::NSystem::GetRamSize(memAvail)) 3355 if (!NWindows::NSystem::GetRamSize(memAvail))
3348 memAvail = (UInt64)(sizeof(size_t)) << 28; 3356 memAvail = (size_t)sizeof(size_t) << 28;
3349 UInt64 v; 3357 UInt64 v;
3350 if (!ParseSizeString(name.Ptr(4), prop, memAvail, v)) 3358 if (!ParseSizeString(name.Ptr(4), prop, memAvail, v))
3351 return E_INVALIDARG; 3359 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 @@
3#include "StdAfx.h" 3#include "StdAfx.h"
4 4
5#include "../../../C/Sha256.h" 5#include "../../../C/Sha256.h"
6#include "../../../C/Sha512.h"
6#include "../../../C/CpuArch.h" 7#include "../../../C/CpuArch.h"
7 8
8#include "../../Common/ComTry.h" 9#include "../../Common/ComTry.h"
@@ -41,22 +42,33 @@ Z7_CLASS_IMP_NOQIB_1(
41 CInStreamWithSha256 42 CInStreamWithSha256
42 , ISequentialInStream 43 , ISequentialInStream
43) 44)
45 bool _sha512Mode;
44 CMyComPtr<ISequentialInStream> _stream; 46 CMyComPtr<ISequentialInStream> _stream;
45 CAlignedBuffer1 _sha; 47 CAlignedBuffer1 _sha256;
48 CAlignedBuffer1 _sha512;
46 UInt64 _size; 49 UInt64 _size;
47 50
48 CSha256 *Sha() { return (CSha256 *)(void *)(Byte *)_sha; } 51 CSha256 *Sha256() { return (CSha256 *)(void *)(Byte *)_sha256; }
52 CSha512 *Sha512() { return (CSha512 *)(void *)(Byte *)_sha512; }
49public: 53public:
50 CInStreamWithSha256(): _sha(sizeof(CSha256)) {} 54 CInStreamWithSha256():
55 _sha256(sizeof(CSha256)),
56 _sha512(sizeof(CSha512))
57 {}
51 void SetStream(ISequentialInStream *stream) { _stream = stream; } 58 void SetStream(ISequentialInStream *stream) { _stream = stream; }
52 void Init() 59 void Init(bool sha512Mode)
53 { 60 {
61 _sha512Mode = sha512Mode;
54 _size = 0; 62 _size = 0;
55 Sha256_Init(Sha()); 63 if (sha512Mode)
64 Sha512_Init(Sha512(), SHA512_DIGEST_SIZE);
65 else
66 Sha256_Init(Sha256());
56 } 67 }
57 void ReleaseStream() { _stream.Release(); } 68 void ReleaseStream() { _stream.Release(); }
58 UInt64 GetSize() const { return _size; } 69 UInt64 GetSize() const { return _size; }
59 void Final(Byte *digest) { Sha256_Final(Sha(), digest); } 70 void Final256(Byte *digest) { Sha256_Final(Sha256(), digest); }
71 void Final512(Byte *digest) { Sha512_Final(Sha512(), digest, SHA512_DIGEST_SIZE); }
60}; 72};
61 73
62Z7_COM7F_IMF(CInStreamWithSha256::Read(void *data, UInt32 size, UInt32 *processedSize)) 74Z7_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
64 UInt32 realProcessedSize; 76 UInt32 realProcessedSize;
65 const HRESULT result = _stream->Read(data, size, &realProcessedSize); 77 const HRESULT result = _stream->Read(data, size, &realProcessedSize);
66 _size += realProcessedSize; 78 _size += realProcessedSize;
67 Sha256_Update(Sha(), (const Byte *)data, realProcessedSize); 79 if (_sha512Mode)
80 Sha512_Update(Sha512(), (const Byte *)data, realProcessedSize);
81 else
82 Sha256_Update(Sha256(), (const Byte *)data, realProcessedSize);
68 if (processedSize) 83 if (processedSize)
69 *processedSize = realProcessedSize; 84 *processedSize = realProcessedSize;
70 return result; 85 return result;
@@ -75,25 +90,33 @@ Z7_CLASS_IMP_NOQIB_1(
75 COutStreamWithSha256 90 COutStreamWithSha256
76 , ISequentialOutStream 91 , ISequentialOutStream
77) 92)
78 // bool _calculate; 93 bool _sha512Mode;
79 CMyComPtr<ISequentialOutStream> _stream; 94 CMyComPtr<ISequentialOutStream> _stream;
80 CAlignedBuffer1 _sha; 95 CAlignedBuffer1 _sha256;
96 CAlignedBuffer1 _sha512;
81 UInt64 _size; 97 UInt64 _size;
82 98
83 CSha256 *Sha() { return (CSha256 *)(void *)(Byte *)_sha; } 99 CSha256 *Sha256() { return (CSha256 *)(void *)(Byte *)_sha256; }
100 CSha512 *Sha512() { return (CSha512 *)(void *)(Byte *)_sha512; }
84public: 101public:
85 COutStreamWithSha256(): _sha(sizeof(CSha256)) {} 102 COutStreamWithSha256():
103 _sha256(sizeof(CSha256)),
104 _sha512(sizeof(CSha512))
105 {}
86 void SetStream(ISequentialOutStream *stream) { _stream = stream; } 106 void SetStream(ISequentialOutStream *stream) { _stream = stream; }
87 void ReleaseStream() { _stream.Release(); } 107 void ReleaseStream() { _stream.Release(); }
88 void Init(/* bool calculate = true */ ) 108 void Init(bool sha512Mode)
89 { 109 {
90 // _calculate = calculate; 110 _sha512Mode = sha512Mode;
91 _size = 0; 111 _size = 0;
92 Sha256_Init(Sha()); 112 if (sha512Mode)
113 Sha512_Init(Sha512(), SHA512_DIGEST_SIZE);
114 else
115 Sha256_Init(Sha256());
93 } 116 }
94 void InitSha256() { Sha256_Init(Sha()); }
95 UInt64 GetSize() const { return _size; } 117 UInt64 GetSize() const { return _size; }
96 void Final(Byte *digest) { Sha256_Final(Sha(), digest); } 118 void Final256(Byte *digest) { Sha256_Final(Sha256(), digest); }
119 void Final512(Byte *digest) { Sha512_Final(Sha512(), digest, SHA512_DIGEST_SIZE); }
97}; 120};
98 121
99Z7_COM7F_IMF(COutStreamWithSha256::Write(const void *data, UInt32 size, UInt32 *processedSize)) 122Z7_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 *
102 if (_stream) 125 if (_stream)
103 result = _stream->Write(data, size, &size); 126 result = _stream->Write(data, size, &size);
104 // if (_calculate) 127 // if (_calculate)
105 Sha256_Update(Sha(), (const Byte *)data, size); 128 if (_sha512Mode)
129 Sha512_Update(Sha512(), (const Byte *)data, size);
130 else
131 Sha256_Update(Sha256(), (const Byte *)data, size);
106 _size += size; 132 _size += size;
107 if (processedSize) 133 if (processedSize)
108 *processedSize = size; 134 *processedSize = size;
@@ -521,10 +547,11 @@ void CInStreamWithHash::SetStreamAndInit(ISequentialInStream *stream, int algo)
521 inStreamSha1->Init(); 547 inStreamSha1->Init();
522 stream = inStreamSha1; 548 stream = inStreamSha1;
523 } 549 }
524 else if (algo == XAR_CKSUM_SHA256) 550 else if (algo == XAR_CKSUM_SHA256
551 || algo == XAR_CKSUM_SHA512)
525 { 552 {
526 inStreamSha256->SetStream(stream); 553 inStreamSha256->SetStream(stream);
527 inStreamSha256->Init(); 554 inStreamSha256->Init(algo == XAR_CKSUM_SHA512);
528 stream = inStreamSha256; 555 stream = inStreamSha256;
529 } 556 }
530 inStreamLim->SetStream(stream); 557 inStreamLim->SetStream(stream);
@@ -542,7 +569,14 @@ bool CInStreamWithHash::CheckHash(int algo, const Byte *digest_from_arc) const
542 else if (algo == XAR_CKSUM_SHA256) 569 else if (algo == XAR_CKSUM_SHA256)
543 { 570 {
544 Byte digest[SHA256_DIGEST_SIZE]; 571 Byte digest[SHA256_DIGEST_SIZE];
545 inStreamSha256->Final(digest); 572 inStreamSha256->Final256(digest);
573 if (memcmp(digest, digest_from_arc, sizeof(digest)) != 0)
574 return false;
575 }
576 else if (algo == XAR_CKSUM_SHA512)
577 {
578 Byte digest[SHA512_DIGEST_SIZE];
579 inStreamSha256->Final512(digest);
546 if (memcmp(digest, digest_from_arc, sizeof(digest)) != 0) 580 if (memcmp(digest, digest_from_arc, sizeof(digest)) != 0)
547 return false; 581 return false;
548 } 582 }
@@ -1151,11 +1185,12 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
1151 outStreamSha1->SetStream(realOutStream); 1185 outStreamSha1->SetStream(realOutStream);
1152 outStreamSha1->Init(); 1186 outStreamSha1->Init();
1153 } 1187 }
1154 else if (checksum_method == XAR_CKSUM_SHA256) 1188 else if (checksum_method == XAR_CKSUM_SHA256
1189 || checksum_method == XAR_CKSUM_SHA512)
1155 { 1190 {
1156 outStreamLim->SetStream(outStreamSha256); 1191 outStreamLim->SetStream(outStreamSha256);
1157 outStreamSha256->SetStream(realOutStream); 1192 outStreamSha256->SetStream(realOutStream);
1158 outStreamSha256->Init(); 1193 outStreamSha256->Init(checksum_method == XAR_CKSUM_SHA512);
1159 } 1194 }
1160 else 1195 else
1161 outStreamLim->SetStream(realOutStream); 1196 outStreamLim->SetStream(realOutStream);
@@ -1209,8 +1244,15 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
1209 else if (checksum_method == XAR_CKSUM_SHA256) 1244 else if (checksum_method == XAR_CKSUM_SHA256)
1210 { 1245 {
1211 Byte digest[SHA256_DIGEST_SIZE]; 1246 Byte digest[SHA256_DIGEST_SIZE];
1212 outStreamSha256->Final(digest); 1247 outStreamSha256->Final256(digest);
1213 if (memcmp(digest, item.extracted_checksum.Data, SHA256_DIGEST_SIZE) != 0) 1248 if (memcmp(digest, item.extracted_checksum.Data, sizeof(digest)) != 0)
1249 opRes = NExtract::NOperationResult::kCRCError;
1250 }
1251 else if (checksum_method == XAR_CKSUM_SHA512)
1252 {
1253 Byte digest[SHA512_DIGEST_SIZE];
1254 outStreamSha256->Final512(digest);
1255 if (memcmp(digest, item.extracted_checksum.Data, sizeof(digest)) != 0)
1214 opRes = NExtract::NOperationResult::kCRCError; 1256 opRes = NExtract::NOperationResult::kCRCError;
1215 } 1257 }
1216 if (opRes == NExtract::NOperationResult::kOK) 1258 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))
967 || _maxBlocksSize != (size_t)_maxBlocksSize) 967 || _maxBlocksSize != (size_t)_maxBlocksSize)
968 return S_FALSE; 968 return S_FALSE;
969 969
970 UInt64 memSize; 970 size_t memSize;
971 if (!NSystem::GetRamSize(memSize)) 971 if (!NSystem::GetRamSize(memSize))
972 memSize = (UInt64)(sizeof(size_t)) << 28; 972 memSize = (size_t)sizeof(size_t) << 28;
973 { 973 {
974 if (_maxBlocksSize > memSize / 4) 974 if (_maxBlocksSize > memSize / 4)
975 return S_FALSE; 975 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 = \
4 $O\DynLimBuf.obj \ 4 $O\DynLimBuf.obj \
5 $O\IntToString.obj \ 5 $O\IntToString.obj \
6 $O\LzFindPrepare.obj \ 6 $O\LzFindPrepare.obj \
7 $O\Md5Reg.obj \
7 $O\MyMap.obj \ 8 $O\MyMap.obj \
8 $O\MyString.obj \ 9 $O\MyString.obj \
9 $O\MyVector.obj \ 10 $O\MyVector.obj \
@@ -11,6 +12,9 @@ COMMON_OBJS = \
11 $O\NewHandler.obj \ 12 $O\NewHandler.obj \
12 $O\Sha1Reg.obj \ 13 $O\Sha1Reg.obj \
13 $O\Sha256Reg.obj \ 14 $O\Sha256Reg.obj \
15 $O\Sha3Reg.obj \
16 $O\Sha512Reg.obj \
17 $O\Sha512Prepare.obj \
14 $O\StringConvert.obj \ 18 $O\StringConvert.obj \
15 $O\StringToInt.obj \ 19 $O\StringToInt.obj \
16 $O\UTFConvert.obj \ 20 $O\UTFConvert.obj \
@@ -274,6 +278,7 @@ C_OBJS = \
274 $O\Lzma2Enc.obj \ 278 $O\Lzma2Enc.obj \
275 $O\LzmaDec.obj \ 279 $O\LzmaDec.obj \
276 $O\LzmaEnc.obj \ 280 $O\LzmaEnc.obj \
281 $O\Md5.obj \
277 $O\MtCoder.obj \ 282 $O\MtCoder.obj \
278 $O\MtDec.obj \ 283 $O\MtDec.obj \
279 $O\Ppmd7.obj \ 284 $O\Ppmd7.obj \
@@ -283,6 +288,9 @@ C_OBJS = \
283 $O\Ppmd8.obj \ 288 $O\Ppmd8.obj \
284 $O\Ppmd8Dec.obj \ 289 $O\Ppmd8Dec.obj \
285 $O\Ppmd8Enc.obj \ 290 $O\Ppmd8Enc.obj \
291 $O\Sha3.obj \
292 $O\Sha512.obj \
293 $O\Sha512Opt.obj \
286 $O\Sort.obj \ 294 $O\Sort.obj \
287 $O\SwapBytes.obj \ 295 $O\SwapBytes.obj \
288 $O\Threads.obj \ 296 $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 = \
45 $O/DynLimBuf.o \ 45 $O/DynLimBuf.o \
46 $O/IntToString.o \ 46 $O/IntToString.o \
47 $O/LzFindPrepare.o \ 47 $O/LzFindPrepare.o \
48 $O/Md5Reg.o \
48 $O/MyMap.o \ 49 $O/MyMap.o \
49 $O/MyString.o \ 50 $O/MyString.o \
50 $O/MyVector.o \ 51 $O/MyVector.o \
@@ -54,6 +55,9 @@ COMMON_OBJS = \
54 $O/Sha1Reg.o \ 55 $O/Sha1Reg.o \
55 $O/Sha256Prepare.o \ 56 $O/Sha256Prepare.o \
56 $O/Sha256Reg.o \ 57 $O/Sha256Reg.o \
58 $O/Sha3Reg.o \
59 $O/Sha512Prepare.o \
60 $O/Sha512Reg.o \
57 $O/StringConvert.o \ 61 $O/StringConvert.o \
58 $O/StringToInt.o \ 62 $O/StringToInt.o \
59 $O/UTFConvert.o \ 63 $O/UTFConvert.o \
@@ -337,6 +341,7 @@ C_OBJS = \
337 $O/Lzma2Enc.o \ 341 $O/Lzma2Enc.o \
338 $O/LzmaDec.o \ 342 $O/LzmaDec.o \
339 $O/LzmaEnc.o \ 343 $O/LzmaEnc.o \
344 $O/Md5.o \
340 $O/MtCoder.o \ 345 $O/MtCoder.o \
341 $O/MtDec.o \ 346 $O/MtDec.o \
342 $O/Ppmd7.o \ 347 $O/Ppmd7.o \
@@ -350,6 +355,9 @@ C_OBJS = \
350 $O/Sha1Opt.o \ 355 $O/Sha1Opt.o \
351 $O/Sha256.o \ 356 $O/Sha256.o \
352 $O/Sha256Opt.o \ 357 $O/Sha256Opt.o \
358 $O/Sha3.o \
359 $O/Sha512.o \
360 $O/Sha512Opt.o \
353 $O/Sort.o \ 361 $O/Sort.o \
354 $O/SwapBytes.o \ 362 $O/SwapBytes.o \
355 $O/Xxh64.o \ 363 $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
287# End Source File 287# End Source File
288# Begin Source File 288# Begin Source File
289 289
290SOURCE=..\..\..\Common\Md5Reg.cpp
291# End Source File
292# Begin Source File
293
290SOURCE=..\..\..\Common\MyBuffer.h 294SOURCE=..\..\..\Common\MyBuffer.h
291# End Source File 295# End Source File
292# Begin Source File 296# Begin Source File
@@ -383,6 +387,18 @@ SOURCE=..\..\..\Common\Sha256Reg.cpp
383# End Source File 387# End Source File
384# Begin Source File 388# Begin Source File
385 389
390SOURCE=..\..\..\Common\Sha3Reg.cpp
391# End Source File
392# Begin Source File
393
394SOURCE=..\..\..\Common\Sha512Prepare.cpp
395# End Source File
396# Begin Source File
397
398SOURCE=..\..\..\Common\Sha512Reg.cpp
399# End Source File
400# Begin Source File
401
386SOURCE=..\..\..\Common\StringConvert.cpp 402SOURCE=..\..\..\Common\StringConvert.cpp
387# End Source File 403# End Source File
388# Begin Source File 404# Begin Source File
@@ -2029,6 +2045,26 @@ SOURCE=..\..\..\..\C\LzmaEnc.h
2029# End Source File 2045# End Source File
2030# Begin Source File 2046# Begin Source File
2031 2047
2048SOURCE=..\..\..\..\C\Md5.c
2049
2050!IF "$(CFG)" == "7z - Win32 Release"
2051
2052# ADD CPP /O2
2053# SUBTRACT CPP /YX /Yc /Yu
2054
2055!ELSEIF "$(CFG)" == "7z - Win32 Debug"
2056
2057# SUBTRACT CPP /YX /Yc /Yu
2058
2059!ENDIF
2060
2061# End Source File
2062# Begin Source File
2063
2064SOURCE=..\..\..\..\C\Md5.h
2065# End Source File
2066# Begin Source File
2067
2032SOURCE=..\..\..\..\C\MtCoder.c 2068SOURCE=..\..\..\..\C\MtCoder.c
2033# SUBTRACT CPP /YX /Yc /Yu 2069# SUBTRACT CPP /YX /Yc /Yu
2034# End Source File 2070# End Source File
@@ -2230,6 +2266,62 @@ SOURCE=..\..\..\..\C\Sha256.h
2230# End Source File 2266# End Source File
2231# Begin Source File 2267# Begin Source File
2232 2268
2269SOURCE=..\..\..\..\C\Sha3.c
2270
2271!IF "$(CFG)" == "7z - Win32 Release"
2272
2273# ADD CPP /O2
2274# SUBTRACT CPP /YX /Yc /Yu
2275
2276!ELSEIF "$(CFG)" == "7z - Win32 Debug"
2277
2278# SUBTRACT CPP /YX /Yc /Yu
2279
2280!ENDIF
2281
2282# End Source File
2283# Begin Source File
2284
2285SOURCE=..\..\..\..\C\Sha3.h
2286# End Source File
2287# Begin Source File
2288
2289SOURCE=..\..\..\..\C\Sha512.c
2290
2291!IF "$(CFG)" == "7z - Win32 Release"
2292
2293# ADD CPP /O2
2294# SUBTRACT CPP /YX /Yc /Yu
2295
2296!ELSEIF "$(CFG)" == "7z - Win32 Debug"
2297
2298# SUBTRACT CPP /YX /Yc /Yu
2299
2300!ENDIF
2301
2302# End Source File
2303# Begin Source File
2304
2305SOURCE=..\..\..\..\C\Sha512.h
2306# End Source File
2307# Begin Source File
2308
2309SOURCE=..\..\..\..\C\Sha512Opt.c
2310
2311!IF "$(CFG)" == "7z - Win32 Release"
2312
2313# ADD CPP /O2
2314# SUBTRACT CPP /YX /Yc /Yu
2315
2316!ELSEIF "$(CFG)" == "7z - Win32 Debug"
2317
2318# SUBTRACT CPP /YX /Yc /Yu
2319
2320!ENDIF
2321
2322# End Source File
2323# Begin Source File
2324
2233SOURCE=..\..\..\..\C\Sort.c 2325SOURCE=..\..\..\..\C\Sort.c
2234 2326
2235!IF "$(CFG)" == "7z - Win32 Release" 2327!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 =
59 " b : Benchmark\n" 59 " b : Benchmark\n"
60 "<switches>\n" 60 "<switches>\n"
61 " -a{N} : set compression mode : [0, 1] : default = 1 (max)\n" 61 " -a{N} : set compression mode : [0, 1] : default = 1 (max)\n"
62 " -d{N} : set dictionary size : [12, 30] : default = 24 (16 MiB)\n" 62 " -d{N} : set dictionary size : [12, 31] : default = 24 (16 MiB)\n"
63 " -fb{N} : set number of fast bytes : [5, 273] : default = 128\n" 63 " -fb{N} : set number of fast bytes : [5, 273] : default = 128\n"
64 " -mc{N} : set number of cycles for match finder\n" 64 " -mc{N} : set number of cycles for match finder\n"
65 " -lc{N} : set number of literal context bits : [0, 8] : default = 3\n" 65 " -lc{N} : set number of literal context bits : [0, 8] : default = 3\n"
66 " -lp{N} : set number of literal pos bits : [0, 4] : default = 0\n" 66 " -lp{N} : set number of literal pos bits : [0, 4] : default = 0\n"
67 " -pb{N} : set number of pos bits : [0, 4] : default = 2\n" 67 " -pb{N} : set number of pos bits : [0, 4] : default = 2\n"
68 " -mf{M} : set match finder: [hc4, bt2, bt3, bt4] : default = bt4\n" 68 " -mf{M} : set match finder: [hc4, hc5, bt2, bt3, bt4, bt5] : default = bt4\n"
69 " -mt{N} : set number of CPU threads\n" 69 " -mt{N} : set number of CPU threads\n"
70 " -eos : write end of stream marker\n" 70 " -eos : write end of stream marker\n"
71 " -si : read data from stdin\n" 71 " -si : read data from stdin\n"
@@ -372,8 +372,8 @@ static int main2(int numArgs, const char *args[])
372 return 0; 372 return 0;
373 } 373 }
374 374
375 bool stdInMode = parser[NKey::kStdIn].ThereIs; 375 const bool stdInMode = parser[NKey::kStdIn].ThereIs;
376 bool stdOutMode = parser[NKey::kStdOut].ThereIs; 376 const bool stdOutMode = parser[NKey::kStdOut].ThereIs;
377 377
378 if (!stdOutMode) 378 if (!stdOutMode)
379 PrintTitle(); 379 PrintTitle();
@@ -394,7 +394,16 @@ static int main2(int numArgs, const char *args[])
394 UInt32 dictLog; 394 UInt32 dictLog;
395 const UString &s = parser[NKey::kDict].PostStrings[0]; 395 const UString &s = parser[NKey::kDict].PostStrings[0];
396 dictLog = GetNumber(s); 396 dictLog = GetNumber(s);
397 dict = 1 << dictLog; 397 if (dictLog >= 32)
398 throw "unsupported dictionary size";
399 // we only want to use dictionary sizes that are powers of 2,
400 // because 7-zip only recognizes such dictionary sizes in the lzma header.#if 0
401#if 0
402 if (dictLog == 32)
403 dict = (UInt32)3840 << 20;
404 else
405#endif
406 dict = (UInt32)1 << dictLog;
398 dictDefined = true; 407 dictDefined = true;
399 AddProp(props2, "d", s); 408 AddProp(props2, "d", s);
400 } 409 }
@@ -522,7 +531,7 @@ static int main2(int numArgs, const char *args[])
522 531
523 if (encodeMode && !dictDefined) 532 if (encodeMode && !dictDefined)
524 { 533 {
525 dict = 1 << kDictSizeLog; 534 dict = (UInt32)1 << kDictSizeLog;
526 if (fileSizeDefined) 535 if (fileSizeDefined)
527 { 536 {
528 unsigned i; 537 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()
35 g_Codecs[g_NumCodecs++] = codecInfo; 35 g_Codecs[g_NumCodecs++] = codecInfo;
36} 36}
37 37
38static const unsigned kNumHashersMax = 16; 38static const unsigned kNumHashersMax = 32;
39extern 39extern
40unsigned g_NumHashers; 40unsigned g_NumHashers;
41unsigned g_NumHashers = 0; 41unsigned 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:
125 125
126 UInt32 Get_Lzma_Algo() const 126 UInt32 Get_Lzma_Algo() const
127 { 127 {
128 int i = FindProp(NCoderPropID::kAlgorithm); 128 const int i = FindProp(NCoderPropID::kAlgorithm);
129 if (i >= 0) 129 if (i >= 0)
130 { 130 {
131 const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value; 131 const NWindows::NCOM::CPropVariant &val = Props[(unsigned)i].Value;
@@ -141,11 +141,11 @@ public:
141 if (Get_DicSize(v)) 141 if (Get_DicSize(v))
142 return v; 142 return v;
143 const unsigned level = GetLevel(); 143 const unsigned level = GetLevel();
144 const UInt32 dictSize = 144 const UInt32 dictSize = level <= 4 ?
145 ( level <= 3 ? ((UInt32)1 << (level * 2 + 16)) : 145 (UInt32)1 << (level * 2 + 16) :
146 ( level <= 6 ? ((UInt32)1 << (level + 19)) : 146 level <= sizeof(size_t) / 2 + 4 ?
147 ( level <= 7 ? ((UInt32)1 << 25) : ((UInt32)1 << 26) 147 (UInt32)1 << (level + 20) :
148 ))); 148 (UInt32)1 << (sizeof(size_t) / 2 + 24);
149 return dictSize; 149 return dictSize;
150 } 150 }
151 151
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 @@
8#include "../../Windows/Synchronization.h" 8#include "../../Windows/Synchronization.h"
9#endif 9#endif
10 10
11#include "Rar5Aes.h"
12#include "HmacSha256.h" 11#include "HmacSha256.h"
12#include "Rar5Aes.h"
13
14#define MY_ALIGN_FOR_SHA256 MY_ALIGN(16)
13 15
14namespace NCrypto { 16namespace NCrypto {
15namespace NRar5 { 17namespace NRar5 {
16 18
17static const unsigned kNumIterationsLog_Max = 24; 19static const unsigned kNumIterationsLog_Max = 24;
18 20static const unsigned kPswCheckCsumSize32 = 1;
19static const unsigned kPswCheckCsumSize = 4; 21static const unsigned kCheckSize32 = kPswCheckSize32 + kPswCheckCsumSize32;
20static const unsigned kCheckSize = kPswCheckSize + kPswCheckCsumSize;
21 22
22CKey::CKey(): 23CKey::CKey():
23 _needCalc(true), 24 _needCalc(true),
@@ -27,15 +28,29 @@ CKey::CKey():
27 _salt[i] = 0; 28 _salt[i] = 0;
28} 29}
29 30
31CKey::~CKey()
32{
33 Wipe();
34}
35
36void CKey::Wipe()
37{
38 _password.Wipe();
39 Z7_memset_0_ARRAY(_salt);
40 // Z7_memset_0_ARRAY(_key32);
41 // Z7_memset_0_ARRAY(_check_Calced32);
42 // Z7_memset_0_ARRAY(_hashKey32);
43 CKeyBase::Wipe();
44}
45
30CDecoder::CDecoder(): CAesCbcDecoder(kAesKeySize) {} 46CDecoder::CDecoder(): CAesCbcDecoder(kAesKeySize) {}
31 47
32static unsigned ReadVarInt(const Byte *p, unsigned maxSize, UInt64 *val) 48static unsigned ReadVarInt(const Byte *p, unsigned maxSize, UInt64 *val)
33{ 49{
34 *val = 0; 50 *val = 0;
35
36 for (unsigned i = 0; i < maxSize && i < 10;) 51 for (unsigned i = 0; i < maxSize && i < 10;)
37 { 52 {
38 Byte b = p[i]; 53 const Byte b = p[i];
39 *val |= (UInt64)(b & 0x7F) << (7 * i); 54 *val |= (UInt64)(b & 0x7F) << (7 * i);
40 i++; 55 i++;
41 if ((b & 0x80) == 0) 56 if ((b & 0x80) == 0)
@@ -64,7 +79,7 @@ HRESULT CDecoder::SetDecoderProps(const Byte *p, unsigned size, bool includeIV,
64 size -= num; 79 size -= num;
65 80
66 bool isCheck = IsThereCheck(); 81 bool isCheck = IsThereCheck();
67 if (size != 1 + kSaltSize + (includeIV ? AES_BLOCK_SIZE : 0) + (unsigned)(isCheck ? kCheckSize : 0)) 82 if (size != 1 + kSaltSize + (includeIV ? AES_BLOCK_SIZE : 0) + (unsigned)(isCheck ? kCheckSize32 * 4 : 0))
68 return E_NOTIMPL; 83 return E_NOTIMPL;
69 84
70 if (_numIterationsLog != p[0]) 85 if (_numIterationsLog != p[0])
@@ -93,19 +108,21 @@ HRESULT CDecoder::SetDecoderProps(const Byte *p, unsigned size, bool includeIV,
93 108
94 if (isCheck) 109 if (isCheck)
95 { 110 {
96 memcpy(_check, p, kPswCheckSize); 111 memcpy(_check32, p, sizeof(_check32));
112 MY_ALIGN_FOR_SHA256
97 CSha256 sha; 113 CSha256 sha;
114 MY_ALIGN_FOR_SHA256
98 Byte digest[SHA256_DIGEST_SIZE]; 115 Byte digest[SHA256_DIGEST_SIZE];
99 Sha256_Init(&sha); 116 Sha256_Init(&sha);
100 Sha256_Update(&sha, _check, kPswCheckSize); 117 Sha256_Update(&sha, (const Byte *)_check32, sizeof(_check32));
101 Sha256_Final(&sha, digest); 118 Sha256_Final(&sha, digest);
102 _canCheck = (memcmp(digest, p + kPswCheckSize, kPswCheckCsumSize) == 0); 119 _canCheck = (memcmp(digest, p + sizeof(_check32), kPswCheckCsumSize32 * 4) == 0);
103 if (_canCheck && isService) 120 if (_canCheck && isService)
104 { 121 {
105 // There was bug in RAR 5.21- : PswCheck field in service records ("QO") contained zeros. 122 // There was bug in RAR 5.21- : PswCheck field in service records ("QO") contained zeros.
106 // so we disable password checking for such bad records. 123 // so we disable password checking for such bad records.
107 _canCheck = false; 124 _canCheck = false;
108 for (unsigned i = 0; i < kPswCheckSize; i++) 125 for (unsigned i = 0; i < kPswCheckSize32 * 4; i++)
109 if (p[i] != 0) 126 if (p[i] != 0)
110 { 127 {
111 _canCheck = true; 128 _canCheck = true;
@@ -132,7 +149,7 @@ void CDecoder::SetPassword(const Byte *data, size_t size)
132Z7_COM7F_IMF(CDecoder::Init()) 149Z7_COM7F_IMF(CDecoder::Init())
133{ 150{
134 CalcKey_and_CheckPassword(); 151 CalcKey_and_CheckPassword();
135 RINOK(SetKey(_key, kAesKeySize)) 152 RINOK(SetKey((const Byte *)_key32, kAesKeySize))
136 RINOK(SetInitVector(_iv, AES_BLOCK_SIZE)) 153 RINOK(SetInitVector(_iv, AES_BLOCK_SIZE))
137 return CAesCoder::Init(); 154 return CAesCoder::Init();
138} 155}
@@ -140,27 +157,27 @@ Z7_COM7F_IMF(CDecoder::Init())
140 157
141UInt32 CDecoder::Hmac_Convert_Crc32(UInt32 crc) const 158UInt32 CDecoder::Hmac_Convert_Crc32(UInt32 crc) const
142{ 159{
143 MY_ALIGN (16) 160 MY_ALIGN_FOR_SHA256
144 NSha256::CHmac ctx; 161 NSha256::CHmac ctx;
145 ctx.SetKey(_hashKey, NSha256::kDigestSize); 162 ctx.SetKey((const Byte *)_hashKey32, NSha256::kDigestSize);
146 UInt32 v; 163 UInt32 v;
147 SetUi32(&v, crc) 164 SetUi32a(&v, crc)
148 ctx.Update((const Byte *)&v, 4); 165 ctx.Update((const Byte *)&v, 4);
149 MY_ALIGN (16) 166 MY_ALIGN_FOR_SHA256
150 UInt32 h[SHA256_NUM_DIGEST_WORDS]; 167 UInt32 h[SHA256_NUM_DIGEST_WORDS];
151 ctx.Final((Byte *)h); 168 ctx.Final((Byte *)h);
152 crc = 0; 169 crc = 0;
153 for (unsigned i = 0; i < SHA256_NUM_DIGEST_WORDS; i++) 170 for (unsigned i = 0; i < SHA256_NUM_DIGEST_WORDS; i++)
154 crc ^= (UInt32)GetUi32(h + i); 171 crc ^= (UInt32)GetUi32a(h + i);
155 return crc; 172 return crc;
156} 173}
157 174
158 175
159void CDecoder::Hmac_Convert_32Bytes(Byte *data) const 176void CDecoder::Hmac_Convert_32Bytes(Byte *data) const
160{ 177{
161 MY_ALIGN (16) 178 MY_ALIGN_FOR_SHA256
162 NSha256::CHmac ctx; 179 NSha256::CHmac ctx;
163 ctx.SetKey(_hashKey, NSha256::kDigestSize); 180 ctx.SetKey((const Byte *)_hashKey32, NSha256::kDigestSize);
164 ctx.Update(data, NSha256::kDigestSize); 181 ctx.Update(data, NSha256::kDigestSize);
165 ctx.Final(data); 182 ctx.Final(data);
166} 183}
@@ -190,30 +207,31 @@ bool CDecoder::CalcKey_and_CheckPassword()
190 207
191 if (_needCalc) 208 if (_needCalc)
192 { 209 {
193 Byte pswCheck[SHA256_DIGEST_SIZE]; 210 MY_ALIGN_FOR_SHA256
194 211 UInt32 pswCheck[SHA256_NUM_DIGEST_WORDS];
195 { 212 {
196 // Pbkdf HMAC-SHA-256 213 // Pbkdf HMAC-SHA-256
197 214 MY_ALIGN_FOR_SHA256
198 MY_ALIGN (16)
199 NSha256::CHmac baseCtx; 215 NSha256::CHmac baseCtx;
200 baseCtx.SetKey(_password, _password.Size()); 216 baseCtx.SetKey(_password, _password.Size());
201 217 MY_ALIGN_FOR_SHA256
202 NSha256::CHmac ctx = baseCtx; 218 NSha256::CHmac ctx;
219 ctx = baseCtx;
203 ctx.Update(_salt, sizeof(_salt)); 220 ctx.Update(_salt, sizeof(_salt));
204 221
205 MY_ALIGN (16) 222 MY_ALIGN_FOR_SHA256
206 Byte u[NSha256::kDigestSize]; 223 UInt32 u[SHA256_NUM_DIGEST_WORDS];
207 MY_ALIGN (16) 224 MY_ALIGN_FOR_SHA256
208 Byte key[NSha256::kDigestSize]; 225 UInt32 key[SHA256_NUM_DIGEST_WORDS];
209 226
210 u[0] = 0; 227 // u[0] = 0;
211 u[1] = 0; 228 // u[1] = 0;
212 u[2] = 0; 229 // u[2] = 0;
213 u[3] = 1; 230 // u[3] = 1;
231 SetUi32a(u, 0x1000000)
214 232
215 ctx.Update(u, 4); 233 ctx.Update((const Byte *)(const void *)u, 4);
216 ctx.Final(u); 234 ctx.Final((Byte *)(void *)u);
217 235
218 memcpy(key, u, NSha256::kDigestSize); 236 memcpy(key, u, NSha256::kDigestSize);
219 237
@@ -221,35 +239,24 @@ bool CDecoder::CalcKey_and_CheckPassword()
221 239
222 for (unsigned i = 0; i < 3; i++) 240 for (unsigned i = 0; i < 3; i++)
223 { 241 {
224 UInt32 j = numIterations; 242 for (; numIterations != 0; numIterations--)
225
226 for (; j != 0; j--)
227 { 243 {
228 ctx = baseCtx; 244 ctx = baseCtx;
229 ctx.Update(u, NSha256::kDigestSize); 245 ctx.Update((const Byte *)(const void *)u, NSha256::kDigestSize);
230 ctx.Final(u); 246 ctx.Final((Byte *)(void *)u);
231 for (unsigned s = 0; s < NSha256::kDigestSize; s++) 247 for (unsigned s = 0; s < Z7_ARRAY_SIZE(u); s++)
232 key[s] ^= u[s]; 248 key[s] ^= u[s];
233 } 249 }
234 250
235 // RAR uses additional iterations for additional keys 251 // RAR uses additional iterations for additional keys
236 memcpy((i == 0 ? _key : (i == 1 ? _hashKey : pswCheck)), key, NSha256::kDigestSize); 252 memcpy(i == 0 ? _key32 : i == 1 ? _hashKey32 : pswCheck,
253 key, NSha256::kDigestSize);
237 numIterations = 16; 254 numIterations = 16;
238 } 255 }
239 } 256 }
240 257 _check_Calced32[0] = pswCheck[0] ^ pswCheck[2] ^ pswCheck[4] ^ pswCheck[6];
241 { 258 _check_Calced32[1] = pswCheck[1] ^ pswCheck[3] ^ pswCheck[5] ^ pswCheck[7];
242 unsigned i;
243
244 for (i = 0; i < kPswCheckSize; i++)
245 _check_Calced[i] = pswCheck[i];
246
247 for (i = kPswCheckSize; i < SHA256_DIGEST_SIZE; i++)
248 _check_Calced[i & (kPswCheckSize - 1)] ^= pswCheck[i];
249 }
250
251 _needCalc = false; 259 _needCalc = false;
252
253 { 260 {
254 MT_LOCK 261 MT_LOCK
255 g_Key = *this; 262 g_Key = *this;
@@ -258,7 +265,7 @@ bool CDecoder::CalcKey_and_CheckPassword()
258 } 265 }
259 266
260 if (IsThereCheck() && _canCheck) 267 if (IsThereCheck() && _canCheck)
261 return (memcmp(_check_Calced, _check, kPswCheckSize) == 0); 268 return memcmp(_check_Calced32, _check32, sizeof(_check32)) == 0;
262 return true; 269 return true;
263} 270}
264 271
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 {
13namespace NRar5 { 13namespace NRar5 {
14 14
15const unsigned kSaltSize = 16; 15const unsigned kSaltSize = 16;
16const unsigned kPswCheckSize = 8; 16const unsigned kPswCheckSize32 = 2;
17const unsigned kAesKeySize = 32; 17const unsigned kAesKeySize = 32;
18 18
19namespace NCryptoFlags 19namespace NCryptoFlags
@@ -22,48 +22,47 @@ namespace NCryptoFlags
22 const unsigned kUseMAC = 1 << 1; 22 const unsigned kUseMAC = 1 << 1;
23} 23}
24 24
25struct CKey 25struct CKeyBase
26{ 26{
27 bool _needCalc; 27protected:
28 UInt32 _key32[kAesKeySize / 4];
29 UInt32 _hashKey32[SHA256_NUM_DIGEST_WORDS];
30 UInt32 _check_Calced32[kPswCheckSize32];
28 31
29 unsigned _numIterationsLog; 32 void Wipe()
30 Byte _salt[kSaltSize]; 33 {
31 CByteBuffer _password; 34 memset(this, 0, sizeof(*this));
35 }
32 36
33 Byte _key[kAesKeySize]; 37 void CopyCalcedKeysFrom(const CKeyBase &k)
34 Byte _check_Calced[kPswCheckSize];
35 Byte _hashKey[SHA256_DIGEST_SIZE];
36
37 void CopyCalcedKeysFrom(const CKey &k)
38 { 38 {
39 memcpy(_key, k._key, sizeof(_key)); 39 *this = k;
40 memcpy(_check_Calced, k._check_Calced, sizeof(_check_Calced));
41 memcpy(_hashKey, k._hashKey, sizeof(_hashKey));
42 } 40 }
41};
43 42
43struct CKey: public CKeyBase
44{
45 CByteBuffer _password;
46 bool _needCalc;
47 unsigned _numIterationsLog;
48 Byte _salt[kSaltSize];
49
44 bool IsKeyEqualTo(const CKey &key) 50 bool IsKeyEqualTo(const CKey &key)
45 { 51 {
46 return (_numIterationsLog == key._numIterationsLog 52 return _numIterationsLog == key._numIterationsLog
47 && memcmp(_salt, key._salt, sizeof(_salt)) == 0 53 && memcmp(_salt, key._salt, sizeof(_salt)) == 0
48 && _password == key._password); 54 && _password == key._password;
49 } 55 }
50
51 CKey();
52 56
53 void Wipe() 57 CKey();
54 { 58 ~CKey();
55 _password.Wipe(); 59
56 Z7_memset_0_ARRAY(_salt); 60 void Wipe();
57 Z7_memset_0_ARRAY(_key);
58 Z7_memset_0_ARRAY(_check_Calced);
59 Z7_memset_0_ARRAY(_hashKey);
60 }
61 61
62#ifdef Z7_CPP_IS_SUPPORTED_default 62#ifdef Z7_CPP_IS_SUPPORTED_default
63 // CKey(const CKey &) = default; 63 // CKey(const CKey &) = default;
64 CKey& operator =(const CKey &) = default; 64 CKey& operator =(const CKey &) = default;
65#endif 65#endif
66 ~CKey() { Wipe(); }
67}; 66};
68 67
69 68
@@ -71,11 +70,11 @@ class CDecoder Z7_final:
71 public CAesCbcDecoder, 70 public CAesCbcDecoder,
72 public CKey 71 public CKey
73{ 72{
74 Byte _check[kPswCheckSize]; 73 UInt32 _check32[kPswCheckSize32];
75 bool _canCheck; 74 bool _canCheck;
76 UInt64 Flags; 75 UInt64 Flags;
77 76
78 bool IsThereCheck() const { return ((Flags & NCryptoFlags::kPswCheck) != 0); } 77 bool IsThereCheck() const { return (Flags & NCryptoFlags::kPswCheck) != 0; }
79public: 78public:
80 Byte _iv[AES_BLOCK_SIZE]; 79 Byte _iv[AES_BLOCK_SIZE];
81 80
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)
111 111
112 for (i = 16; i < 80; i++) 112 for (i = 16; i < 80; i++)
113 { 113 {
114 WW(i) = rotlFixed(WW((i)-3) ^ WW((i)-8) ^ WW((i)-14) ^ WW((i)-16), 1); 114 const UInt32 t = WW((i)-3) ^ WW((i)-8) ^ WW((i)-14) ^ WW((i)-16);
115 WW(i) = rotlFixed(t, 1);
115 } 116 }
116 117
117 for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++) 118 for (i = 0; i < SHA1_NUM_BLOCK_WORDS; i++)
@@ -128,6 +129,7 @@ void CDecoder::CalcKey()
128 129
129 const unsigned kSaltSize = 8; 130 const unsigned kSaltSize = 8;
130 131
132 MY_ALIGN (16)
131 Byte buf[kPasswordLen_Bytes_MAX + kSaltSize]; 133 Byte buf[kPasswordLen_Bytes_MAX + kSaltSize];
132 134
133 if (_password.Size() != 0) 135 if (_password.Size() != 0)
@@ -148,7 +150,7 @@ void CDecoder::CalcKey()
148 MY_ALIGN (16) 150 MY_ALIGN (16)
149 Byte digest[NSha1::kDigestSize]; 151 Byte digest[NSha1::kDigestSize];
150 // rar reverts hash for sha. 152 // rar reverts hash for sha.
151 const UInt32 kNumRounds = ((UInt32)1 << 18); 153 const UInt32 kNumRounds = (UInt32)1 << 18;
152 UInt32 pos = 0; 154 UInt32 pos = 0;
153 UInt32 i; 155 UInt32 i;
154 for (i = 0; i < kNumRounds; i++) 156 for (i = 0; i < kNumRounds; i++)
@@ -171,8 +173,14 @@ void CDecoder::CalcKey()
171 } 173 }
172 } 174 }
173 pos += (UInt32)rawSize; 175 pos += (UInt32)rawSize;
176#if 1
177 UInt32 pswNum;
178 SetUi32a(&pswNum, i)
179 sha.Update((const Byte *)&pswNum, 3);
180#else
174 Byte pswNum[3] = { (Byte)i, (Byte)(i >> 8), (Byte)(i >> 16) }; 181 Byte pswNum[3] = { (Byte)i, (Byte)(i >> 8), (Byte)(i >> 16) };
175 sha.Update(pswNum, 3); 182 sha.Update(pswNum, 3);
183#endif
176 pos += 3; 184 pos += 3;
177 if (i % (kNumRounds / 16) == 0) 185 if (i % (kNumRounds / 16) == 0)
178 { 186 {
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;
24 if (method != AES && method != 3DES), probably we need another code. 24 if (method != AES && method != 3DES), probably we need another code.
25*/ 25*/
26 26
27static void DeriveKey2(const Byte *digest, Byte c, Byte *dest) 27static void DeriveKey2(const UInt32 *digest32, Byte c, UInt32 *dest32)
28{ 28{
29 const unsigned kBufSize = 64;
29 MY_ALIGN (16) 30 MY_ALIGN (16)
30 Byte buf[64]; 31 UInt32 buf32[kBufSize / 4];
31 memset(buf, c, 64); 32 memset(buf32, c, kBufSize);
32 for (unsigned i = 0; i < NSha1::kDigestSize; i++) 33 for (unsigned i = 0; i < NSha1::kNumDigestWords; i++)
33 buf[i] ^= digest[i]; 34 buf32[i] ^= digest32[i];
34 MY_ALIGN (16) 35 MY_ALIGN (16)
35 NSha1::CContext sha; 36 NSha1::CContext sha;
36 sha.Init(); 37 sha.Init();
37 sha.Update(buf, 64); 38 sha.Update((const Byte *)buf32, kBufSize);
38 sha.Final(dest); 39 sha.Final((Byte *)dest32);
39} 40}
40 41
41static void DeriveKey(NSha1::CContext &sha, Byte *key) 42static void DeriveKey(NSha1::CContext &sha, Byte *key)
42{ 43{
43 MY_ALIGN (16) 44 MY_ALIGN (16)
44 Byte digest[NSha1::kDigestSize]; 45 UInt32 digest32[NSha1::kNumDigestWords];
45 sha.Final(digest); 46 sha.Final((Byte *)digest32);
46 MY_ALIGN (16) 47 MY_ALIGN (16)
47 Byte temp[NSha1::kDigestSize * 2]; 48 UInt32 temp32[NSha1::kNumDigestWords * 2];
48 DeriveKey2(digest, 0x36, temp); 49 DeriveKey2(digest32, 0x36, temp32);
49 DeriveKey2(digest, 0x5C, temp + NSha1::kDigestSize); 50 DeriveKey2(digest32, 0x5C, temp32 + NSha1::kNumDigestWords);
50 memcpy(key, temp, 32); 51 memcpy(key, temp32, 32);
51} 52}
52 53
53void CKeyInfo::SetPassword(const Byte *data, UInt32 size) 54void CKeyInfo::SetPassword(const Byte *data, UInt32 size)
@@ -122,24 +123,24 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
122 passwOK = false; 123 passwOK = false;
123 if (_remSize < 16) 124 if (_remSize < 16)
124 return E_NOTIMPL; 125 return E_NOTIMPL;
125 Byte *p = _bufAligned; 126 Byte * const p = _bufAligned;
126 const unsigned format = GetUi16(p); 127 const unsigned format = GetUi16a(p);
127 if (format != 3) 128 if (format != 3)
128 return E_NOTIMPL; 129 return E_NOTIMPL;
129 unsigned algId = GetUi16(p + 2); 130 unsigned algId = GetUi16a(p + 2);
130 if (algId < kAES128) 131 if (algId < kAES128)
131 return E_NOTIMPL; 132 return E_NOTIMPL;
132 algId -= kAES128; 133 algId -= kAES128;
133 if (algId > 2) 134 if (algId > 2)
134 return E_NOTIMPL; 135 return E_NOTIMPL;
135 const unsigned bitLen = GetUi16(p + 4); 136 const unsigned bitLen = GetUi16a(p + 4);
136 const unsigned flags = GetUi16(p + 6); 137 const unsigned flags = GetUi16a(p + 6);
137 if (algId * 64 + 128 != bitLen) 138 if (algId * 64 + 128 != bitLen)
138 return E_NOTIMPL; 139 return E_NOTIMPL;
139 _key.KeySize = 16 + algId * 8; 140 _key.KeySize = 16 + algId * 8;
140 const bool cert = ((flags & 2) != 0); 141 const bool cert = ((flags & 2) != 0);
141 142
142 if ((flags & 0x4000) != 0) 143 if (flags & 0x4000)
143 { 144 {
144 // Use 3DES for rd data 145 // Use 3DES for rd data
145 return E_NOTIMPL; 146 return E_NOTIMPL;
@@ -155,7 +156,7 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
155 return E_NOTIMPL; 156 return E_NOTIMPL;
156 } 157 }
157 158
158 UInt32 rdSize = GetUi16(p + 8); 159 UInt32 rdSize = GetUi16a(p + 8);
159 160
160 if (rdSize + 16 > _remSize) 161 if (rdSize + 16 > _remSize)
161 return E_NOTIMPL; 162 return E_NOTIMPL;
@@ -174,7 +175,7 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
174 // PKCS7 padding 175 // PKCS7 padding
175 if (rdSize < kPadSize) 176 if (rdSize < kPadSize)
176 return E_NOTIMPL; 177 return E_NOTIMPL;
177 if ((rdSize & (kPadSize - 1)) != 0) 178 if (rdSize & (kPadSize - 1))
178 return E_NOTIMPL; 179 return E_NOTIMPL;
179 } 180 }
180 181
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
115 _x + _xSize, _y, 8, 12 // these values are unused 115 _x + _xSize, _y, 8, 12 // these values are unused
116 116
117 117
118#define OPTIONS_PAGE_XC_SIZE 280 118#define OPTIONS_PAGE_XC_SIZE 300
119#define OPTIONS_PAGE_YC_SIZE 280 119#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 @@
20 10 IFolderArchiveUpdateCallback2 20 10 IFolderArchiveUpdateCallback2
21 11 IFolderScanProgress 21 11 IFolderScanProgress
22 12 IFolderSetZoneIdMode 22 12 IFolderSetZoneIdMode
23 13 IFolderSetZoneIdFile
24 14 IFolderArchiveUpdateCallback_MoveArc
23 25
24 20 IFileExtractCallback.h::IGetProp 26 20 IFileExtractCallback.h::IGetProp
25 30 IFileExtractCallback.h::IFolderExtractToStreamCallback (old) 27 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,
1516 if (_zoneMode != NExtract::NZoneIdMode::kNone) 1516 if (_zoneMode != NExtract::NZoneIdMode::kNone)
1517 { 1517 {
1518 ReadZoneFile_Of_BaseFile(us2fs(_agentSpec->_archiveFilePath), extractCallbackSpec->ZoneBuf); 1518 ReadZoneFile_Of_BaseFile(us2fs(_agentSpec->_archiveFilePath), extractCallbackSpec->ZoneBuf);
1519 if (_zoneBuf.Size() != 0)
1520 extractCallbackSpec->ZoneBuf = _zoneBuf;
1519 } 1521 }
1520 #endif 1522 #endif
1521 1523
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:
60 public IArchiveFolderInternal, 60 public IArchiveFolderInternal,
61 public IInArchiveGetStream, 61 public IInArchiveGetStream,
62 public IFolderSetZoneIdMode, 62 public IFolderSetZoneIdMode,
63 public IFolderSetZoneIdFile,
63 public IFolderOperations, 64 public IFolderOperations,
64 public IFolderSetFlatMode, 65 public IFolderSetFlatMode,
65 public CMyUnknownImp 66 public CMyUnknownImp
@@ -75,6 +76,7 @@ class CAgentFolder Z7_final:
75 Z7_COM_QI_ENTRY(IArchiveFolderInternal) 76 Z7_COM_QI_ENTRY(IArchiveFolderInternal)
76 Z7_COM_QI_ENTRY(IInArchiveGetStream) 77 Z7_COM_QI_ENTRY(IInArchiveGetStream)
77 Z7_COM_QI_ENTRY(IFolderSetZoneIdMode) 78 Z7_COM_QI_ENTRY(IFolderSetZoneIdMode)
79 Z7_COM_QI_ENTRY(IFolderSetZoneIdFile)
78 Z7_COM_QI_ENTRY(IFolderOperations) 80 Z7_COM_QI_ENTRY(IFolderOperations)
79 Z7_COM_QI_ENTRY(IFolderSetFlatMode) 81 Z7_COM_QI_ENTRY(IFolderSetFlatMode)
80 Z7_COM_QI_END 82 Z7_COM_QI_END
@@ -91,6 +93,7 @@ class CAgentFolder Z7_final:
91 Z7_IFACE_COM7_IMP(IArchiveFolderInternal) 93 Z7_IFACE_COM7_IMP(IArchiveFolderInternal)
92 Z7_IFACE_COM7_IMP(IInArchiveGetStream) 94 Z7_IFACE_COM7_IMP(IInArchiveGetStream)
93 Z7_IFACE_COM7_IMP(IFolderSetZoneIdMode) 95 Z7_IFACE_COM7_IMP(IFolderSetZoneIdMode)
96 Z7_IFACE_COM7_IMP(IFolderSetZoneIdFile)
94 Z7_IFACE_COM7_IMP(IFolderOperations) 97 Z7_IFACE_COM7_IMP(IFolderOperations)
95 Z7_IFACE_COM7_IMP(IFolderSetFlatMode) 98 Z7_IFACE_COM7_IMP(IFolderSetFlatMode)
96 99
@@ -106,11 +109,11 @@ public:
106 int CompareItems2(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw); 109 int CompareItems2(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw);
107 110
108 CAgentFolder(): 111 CAgentFolder():
109 _proxyDirIndex(0),
110 _isAltStreamFolder(false), 112 _isAltStreamFolder(false),
111 _flatMode(false), 113 _flatMode(false),
112 _loadAltStreams(false) // _loadAltStreams alt streams works in flat mode, but we don't use it now 114 _loadAltStreams(false), // _loadAltStreams alt streams works in flat mode, but we don't use it now
113 , _zoneMode(NExtract::NZoneIdMode::kNone) 115 _proxyDirIndex(0),
116 _zoneMode(NExtract::NZoneIdMode::kNone)
114 /* , _replaceAltStreamCharsMode(0) */ 117 /* , _replaceAltStreamCharsMode(0) */
115 {} 118 {}
116 119
@@ -145,21 +148,23 @@ public:
145 UString GetFullPrefix(UInt32 index) const; // relative too root folder of archive 148 UString GetFullPrefix(UInt32 index) const; // relative too root folder of archive
146 149
147public: 150public:
151 bool _isAltStreamFolder;
152 bool _flatMode;
153 bool _loadAltStreams; // in Flat mode
148 const CProxyArc *_proxy; 154 const CProxyArc *_proxy;
149 const CProxyArc2 *_proxy2; 155 const CProxyArc2 *_proxy2;
150 unsigned _proxyDirIndex; 156 unsigned _proxyDirIndex;
151 bool _isAltStreamFolder; 157 NExtract::NZoneIdMode::EEnum _zoneMode;
158 CByteBuffer _zoneBuf;
159 // Int32 _replaceAltStreamCharsMode;
152 // CMyComPtr<IFolderFolder> _parentFolder; 160 // CMyComPtr<IFolderFolder> _parentFolder;
153 CMyComPtr<IInFolderArchive> _agent; 161 CMyComPtr<IInFolderArchive> _agent;
154 CAgent *_agentSpec; 162 CAgent *_agentSpec;
155
156 CRecordVector<CProxyItem> _items; 163 CRecordVector<CProxyItem> _items;
157 bool _flatMode;
158 bool _loadAltStreams; // in Flat mode
159 // Int32 _replaceAltStreamCharsMode;
160 NExtract::NZoneIdMode::EEnum _zoneMode;
161}; 164};
162 165
166
167
163class CAgent Z7_final: 168class CAgent Z7_final:
164 public IInFolderArchive, 169 public IInFolderArchive,
165 public IFolderArcProps, 170 public IFolderArcProps,
@@ -213,22 +218,22 @@ public:
213 CProxyArc2 *_proxy2; 218 CProxyArc2 *_proxy2;
214 CArchiveLink _archiveLink; 219 CArchiveLink _archiveLink;
215 220
216 bool ThereIsPathProp;
217 // bool ThereIsAltStreamProp;
218
219 UString ArchiveType; 221 UString ArchiveType;
220 222
221 FStringVector _names; 223 FStringVector _names;
222 FString _folderPrefix; // for new files from disk 224 FString _folderPrefix; // for new files from disk
223 225
224 bool _updatePathPrefix_is_AltFolder;
225 UString _updatePathPrefix; 226 UString _updatePathPrefix;
226 CAgentFolder *_agentFolder; 227 CAgentFolder *_agentFolder;
227 228
228 UString _archiveFilePath; 229 UString _archiveFilePath; // it can be path of non-existing file if file is virtual
230
229 DWORD _attrib; 231 DWORD _attrib;
232 bool _updatePathPrefix_is_AltFolder;
233 bool ThereIsPathProp;
230 bool _isDeviceFile; 234 bool _isDeviceFile;
231 bool _isHashHandler; 235 bool _isHashHandler;
236
232 FString _hashBaseFolderPrefix; 237 FString _hashBaseFolderPrefix;
233 238
234 #ifndef Z7_EXTRACT_ONLY 239 #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))
22 return S_OK; 22 return S_OK;
23} 23}
24 24
25Z7_COM7F_IMF(CAgentFolder::SetZoneIdFile(const Byte *data, UInt32 size))
26{
27 _zoneBuf.CopyFrom(data, size);
28 return S_OK;
29}
30
25 31
26Z7_COM7F_IMF(CAgentFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems, 32Z7_COM7F_IMF(CAgentFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems,
27 Int32 includeAltStreams, Int32 replaceAltStreamCharsMode, 33 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)
62 return RemoveDir(path); 62 return RemoveDir(path);
63} 63}
64 64
65
66
67struct C_CopyFileProgress_to_FolderCallback_MoveArc Z7_final:
68 public ICopyFileProgress
69{
70 IFolderArchiveUpdateCallback_MoveArc *Callback;
71 HRESULT CallbackResult;
72
73 virtual DWORD CopyFileProgress(UInt64 total, UInt64 current) Z7_override
74 {
75 HRESULT res = Callback->MoveArc_Progress(total, current);
76 CallbackResult = res;
77 // we can ignore E_ABORT here, because we update archive,
78 // and we want to get correct archive after updating
79 if (res == E_ABORT)
80 res = S_OK;
81 return res == S_OK ? PROGRESS_CONTINUE : PROGRESS_CANCEL;
82 }
83
84 C_CopyFileProgress_to_FolderCallback_MoveArc(
85 IFolderArchiveUpdateCallback_MoveArc *callback) :
86 Callback(callback),
87 CallbackResult(S_OK)
88 {}
89};
90
91
65HRESULT CAgentFolder::CommonUpdateOperation( 92HRESULT CAgentFolder::CommonUpdateOperation(
66 AGENT_OP operation, 93 AGENT_OP operation,
67 bool moveMode, 94 bool moveMode,
@@ -159,8 +186,51 @@ HRESULT CAgentFolder::CommonUpdateOperation(
159 // now: we reopen archive after close 186 // now: we reopen archive after close
160 187
161 // m_FolderItem = NULL; 188 // m_FolderItem = NULL;
189 _items.Clear();
190 _proxyDirIndex = k_Proxy_RootDirIndex;
191
192 CMyComPtr<IFolderArchiveUpdateCallback_MoveArc> updateCallback_MoveArc;
193 if (progress)
194 progress->QueryInterface(IID_IFolderArchiveUpdateCallback_MoveArc, (void **)&updateCallback_MoveArc);
162 195
163 const HRESULT res = tempFile.MoveToOriginal(true); 196 HRESULT res;
197 if (updateCallback_MoveArc)
198 {
199 const FString &tempFilePath = tempFile.Get_TempFilePath();
200 UInt64 totalSize = 0;
201 {
202 NFind::CFileInfo fi;
203 if (fi.Find(tempFilePath))
204 totalSize = fi.Size;
205 }
206 RINOK(updateCallback_MoveArc->MoveArc_Start(
207 fs2us(tempFilePath),
208 fs2us(tempFile.Get_OriginalFilePath()),
209 totalSize,
210 1)) // updateMode
211
212 C_CopyFileProgress_to_FolderCallback_MoveArc prox(updateCallback_MoveArc);
213 res = tempFile.MoveToOriginal(
214 true, // deleteOriginal
215 &prox);
216 if (res == S_OK)
217 {
218 res = updateCallback_MoveArc->MoveArc_Finish();
219 // we don't return after E_ABORT here, because
220 // we want to reopen new archive still.
221 }
222 else if (prox.CallbackResult != S_OK)
223 res = prox.CallbackResult;
224
225 // if updating callback returned E_ABORT,
226 // then openCallback still can return E_ABORT also.
227 // So ReOpen() will return with E_ABORT.
228 // But we want to open archive still.
229 // And Before_ArcReopen() call will clear user break status in that case.
230 RINOK(updateCallback_MoveArc->Before_ArcReopen())
231 }
232 else
233 res = tempFile.MoveToOriginal(true); // deleteOriginal
164 234
165 // RINOK(res); 235 // RINOK(res);
166 if (res == S_OK) 236 if (res == S_OK)
@@ -189,10 +259,10 @@ HRESULT CAgentFolder::CommonUpdateOperation(
189 } 259 }
190 260
191 // CAgent::ReOpen() deletes _proxy and _proxy2 261 // CAgent::ReOpen() deletes _proxy and _proxy2
192 _items.Clear(); 262 // _items.Clear();
193 _proxy = NULL; 263 _proxy = NULL;
194 _proxy2 = NULL; 264 _proxy2 = NULL;
195 _proxyDirIndex = k_Proxy_RootDirIndex; 265 // _proxyDirIndex = k_Proxy_RootDirIndex;
196 _isAltStreamFolder = false; 266 _isAltStreamFolder = false;
197 267
198 268
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)
103 103
104Z7_IFACE_CONSTR_FOLDERARC(IFolderSetZoneIdMode, 0x12) 104Z7_IFACE_CONSTR_FOLDERARC(IFolderSetZoneIdMode, 0x12)
105 105
106#define Z7_IFACEM_IFolderSetZoneIdFile(x) \
107 x(SetZoneIdFile(const Byte *data, UInt32 size)) \
108
109Z7_IFACE_CONSTR_FOLDERARC(IFolderSetZoneIdFile, 0x13)
110
111
112// if the caller calls Before_ArcReopen(), the callee must
113// clear user break status, because the caller want to open archive still.
114#define Z7_IFACEM_IFolderArchiveUpdateCallback_MoveArc(x) \
115 x(MoveArc_Start(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 size, Int32 updateMode)) \
116 x(MoveArc_Progress(UInt64 totalSize, UInt64 currentSize)) \
117 x(MoveArc_Finish()) \
118 x(Before_ArcReopen()) \
119
120Z7_IFACE_CONSTR_FOLDERARC(IFolderArchiveUpdateCallback_MoveArc, 0x14)
121
106Z7_PURE_INTERFACES_END 122Z7_PURE_INTERFACES_END
107#endif 123#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 = \
577ZIP_COMMON_OBJS = \ 577ZIP_COMMON_OBJS = \
58 $O/FileStreams.o \ 58 $O/FileStreams.o \
59 59
60C_OBJS = \
61 $O/Alloc.o \
60 62
61OBJS = \ 63OBJS = \
64 $(C_OBJS) \
62 $(COMMON_OBJS) \ 65 $(COMMON_OBJS) \
63 $(WIN_OBJS) \ 66 $(WIN_OBJS) \
64 $(SYS_OBJS) \ 67 $(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)
140} 140}
141 141
142 142
143static const FChar * const k_ZoneId_StreamName = FTEXT(":Zone.Identifier"); 143static const char * const k_ZoneId_StreamName_With_Colon_Prefix = ":Zone.Identifier";
144 144
145void ReadZoneFile_Of_BaseFile(CFSTR fileName2, CByteBuffer &buf) 145bool Is_ZoneId_StreamName(const wchar_t *s)
146{ 146{
147 FString fileName (fileName2); 147 return StringsAreEqualNoCase_Ascii(s, k_ZoneId_StreamName_With_Colon_Prefix + 1);
148 fileName += k_ZoneId_StreamName; 148}
149 149
150void ReadZoneFile_Of_BaseFile(CFSTR fileName, CByteBuffer &buf)
151{
150 buf.Free(); 152 buf.Free();
153 FString path (fileName);
154 path += k_ZoneId_StreamName_With_Colon_Prefix;
151 NIO::CInFile file; 155 NIO::CInFile file;
152 if (!file.Open(fileName)) 156 if (!file.Open(path))
153 return; 157 return;
154 UInt64 fileSize; 158 UInt64 fileSize;
155 if (!file.GetLength(fileSize)) 159 if (!file.GetLength(fileSize))
156 return; 160 return;
157 if (fileSize == 0 || fileSize >= ((UInt32)1 << 16)) 161 if (fileSize == 0 || fileSize >= (1u << 15))
158 return; 162 return;
159 buf.Alloc((size_t)fileSize); 163 buf.Alloc((size_t)fileSize);
160 size_t processed; 164 size_t processed;
@@ -166,7 +170,7 @@ void ReadZoneFile_Of_BaseFile(CFSTR fileName2, CByteBuffer &buf)
166bool WriteZoneFile_To_BaseFile(CFSTR fileName, const CByteBuffer &buf) 170bool WriteZoneFile_To_BaseFile(CFSTR fileName, const CByteBuffer &buf)
167{ 171{
168 FString path (fileName); 172 FString path (fileName);
169 path += k_ZoneId_StreamName; 173 path += k_ZoneId_StreamName_With_Colon_Prefix;
170 NIO::COutFile file; 174 NIO::COutFile file;
171 if (!file.Create_ALWAYS(path)) 175 if (!file.Create_ALWAYS(path))
172 return false; 176 return false;
@@ -275,16 +279,13 @@ HRESULT CArchiveExtractCallback::PrepareHardLinks(const CRecordVector<UInt32> *r
275 279
276 280
277CArchiveExtractCallback::CArchiveExtractCallback(): 281CArchiveExtractCallback::CArchiveExtractCallback():
278 _arc(NULL), 282 // Write_CTime(true),
279 Write_CTime(true), 283 // Write_ATime(true),
280 Write_ATime(true), 284 // Write_MTime(true),
281 Write_MTime(true),
282 Is_elimPrefix_Mode(false), 285 Is_elimPrefix_Mode(false),
286 _arc(NULL),
283 _multiArchives(false) 287 _multiArchives(false)
284{ 288{
285 LocalProgressSpec = new CLocalProgress();
286 _localProgress = LocalProgressSpec;
287
288 #ifdef Z7_USE_SECURITY_CODE 289 #ifdef Z7_USE_SECURITY_CODE
289 _saclEnabled = InitLocalPrivileges(); 290 _saclEnabled = InitLocalPrivileges();
290 #endif 291 #endif
@@ -293,9 +294,9 @@ CArchiveExtractCallback::CArchiveExtractCallback():
293 294
294void CArchiveExtractCallback::InitBeforeNewArchive() 295void CArchiveExtractCallback::InitBeforeNewArchive()
295{ 296{
296 #if defined(_WIN32) && !defined(UNDER_CE) 297#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX)
297 ZoneBuf.Free(); 298 ZoneBuf.Free();
298 #endif 299#endif
299} 300}
300 301
301void CArchiveExtractCallback::Init( 302void CArchiveExtractCallback::Init(
@@ -322,27 +323,20 @@ void CArchiveExtractCallback::Init(
322 323
323 _ntOptions = ntOptions; 324 _ntOptions = ntOptions;
324 _wildcardCensor = wildcardCensor; 325 _wildcardCensor = wildcardCensor;
325
326 _stdOutMode = stdOutMode; 326 _stdOutMode = stdOutMode;
327 _testMode = testMode; 327 _testMode = testMode;
328
329 // _progressTotal = 0;
330 // _progressTotal_Defined = false;
331
332 _packTotal = packSize; 328 _packTotal = packSize;
333 _progressTotal = packSize; 329 _progressTotal = packSize;
334 _progressTotal_Defined = true; 330 // _progressTotal = 0;
335 331 // _progressTotal_Defined = false;
332 // _progressTotal_Defined = true;
336 _extractCallback2 = extractCallback2; 333 _extractCallback2 = extractCallback2;
337
338 /* 334 /*
339 _compressProgress.Release(); 335 _compressProgress.Release();
340 _extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress); 336 _extractCallback2.QueryInterface(IID_ICompressProgressInfo, &_compressProgress);
341
342 _callbackMessage.Release(); 337 _callbackMessage.Release();
343 _extractCallback2.QueryInterface(IID_IArchiveExtractCallbackMessage2, &_callbackMessage); 338 _extractCallback2.QueryInterface(IID_IArchiveExtractCallbackMessage2, &_callbackMessage);
344 */ 339 */
345
346 _folderArchiveExtractCallback2.Release(); 340 _folderArchiveExtractCallback2.Release();
347 _extractCallback2.QueryInterface(IID_IFolderArchiveExtractCallback2, &_folderArchiveExtractCallback2); 341 _extractCallback2.QueryInterface(IID_IFolderArchiveExtractCallback2, &_folderArchiveExtractCallback2);
348 342
@@ -390,7 +384,7 @@ Z7_COM7F_IMF(CArchiveExtractCallback::SetTotal(UInt64 size))
390{ 384{
391 COM_TRY_BEGIN 385 COM_TRY_BEGIN
392 _progressTotal = size; 386 _progressTotal = size;
393 _progressTotal_Defined = true; 387 // _progressTotal_Defined = true;
394 if (!_multiArchives && _extractCallback2) 388 if (!_multiArchives && _extractCallback2)
395 return _extractCallback2->SetTotal(size); 389 return _extractCallback2->SetTotal(size);
396 return S_OK; 390 return S_OK;
@@ -430,7 +424,7 @@ Z7_COM7F_IMF(CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue))
430 if (_multiArchives) 424 if (_multiArchives)
431 { 425 {
432 packCur = LocalProgressSpec->InSize; 426 packCur = LocalProgressSpec->InSize;
433 if (completeValue && _progressTotal_Defined) 427 if (completeValue /* && _progressTotal_Defined */)
434 packCur += MyMultDiv64(*completeValue, _progressTotal, _packTotal); 428 packCur += MyMultDiv64(*completeValue, _progressTotal, _packTotal);
435 completeValue = &packCur; 429 completeValue = &packCur;
436 } 430 }
@@ -443,7 +437,7 @@ Z7_COM7F_IMF(CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue))
443Z7_COM7F_IMF(CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)) 437Z7_COM7F_IMF(CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize))
444{ 438{
445 COM_TRY_BEGIN 439 COM_TRY_BEGIN
446 return _localProgress->SetRatioInfo(inSize, outSize); 440 return LocalProgressSpec.Interface()->SetRatioInfo(inSize, outSize);
447 COM_TRY_END 441 COM_TRY_END
448} 442}
449 443
@@ -582,13 +576,23 @@ HRESULT CArchiveExtractCallback::SendMessageError2(HRESULT errorCode, const char
582 576
583#ifndef Z7_SFX 577#ifndef Z7_SFX
584 578
579Z7_CLASS_IMP_COM_1(
580 CGetProp
581 , IGetProp
582)
583public:
584 UInt32 IndexInArc;
585 const CArc *Arc;
586 // UString BaseName; // relative path
587};
588
585Z7_COM7F_IMF(CGetProp::GetProp(PROPID propID, PROPVARIANT *value)) 589Z7_COM7F_IMF(CGetProp::GetProp(PROPID propID, PROPVARIANT *value))
586{ 590{
587 /* 591 /*
588 if (propID == kpidName) 592 if (propID == kpidBaseName)
589 { 593 {
590 COM_TRY_BEGIN 594 COM_TRY_BEGIN
591 NCOM::CPropVariant prop = Name; 595 NCOM::CPropVariant prop = BaseName;
592 prop.Detach(value); 596 prop.Detach(value);
593 return S_OK; 597 return S_OK;
594 COM_TRY_END 598 COM_TRY_END
@@ -1087,7 +1091,7 @@ void CArchiveExtractCallback::GetFiTimesCAM(CFiTimesCAM &pt)
1087 pt.ATime_Defined = false; 1091 pt.ATime_Defined = false;
1088 pt.MTime_Defined = false; 1092 pt.MTime_Defined = false;
1089 1093
1090 if (Write_MTime) 1094 // if (Write_MTime)
1091 { 1095 {
1092 if (_fi.MTime.Def) 1096 if (_fi.MTime.Def)
1093 { 1097 {
@@ -1101,13 +1105,13 @@ void CArchiveExtractCallback::GetFiTimesCAM(CFiTimesCAM &pt)
1101 } 1105 }
1102 } 1106 }
1103 1107
1104 if (Write_CTime && _fi.CTime.Def) 1108 if (/* Write_CTime && */ _fi.CTime.Def)
1105 { 1109 {
1106 _fi.CTime.Write_To_FiTime(pt.CTime); 1110 _fi.CTime.Write_To_FiTime(pt.CTime);
1107 pt.CTime_Defined = true; 1111 pt.CTime_Defined = true;
1108 } 1112 }
1109 1113
1110 if (Write_ATime && _fi.ATime.Def) 1114 if (/* Write_ATime && */ _fi.ATime.Def)
1111 { 1115 {
1112 _fi.ATime.Write_To_FiTime(pt.ATime); 1116 _fi.ATime.Write_To_FiTime(pt.ATime);
1113 pt.ATime_Defined = true; 1117 pt.ATime_Defined = true;
@@ -1302,7 +1306,7 @@ HRESULT CArchiveExtractCallback::CheckExistFile(FString &fullProcessedPath, bool
1302 { 1306 {
1303 #if defined(_WIN32) && !defined(UNDER_CE) 1307 #if defined(_WIN32) && !defined(UNDER_CE)
1304 // we need to clear READ-ONLY of parent before creating alt stream 1308 // we need to clear READ-ONLY of parent before creating alt stream
1305 int colonPos = NName::FindAltStreamColon(fullProcessedPath); 1309 const int colonPos = NName::FindAltStreamColon(fullProcessedPath);
1306 if (colonPos >= 0 && fullProcessedPath[(unsigned)colonPos + 1] != 0) 1310 if (colonPos >= 0 && fullProcessedPath[(unsigned)colonPos + 1] != 0)
1307 { 1311 {
1308 FString parentFsPath (fullProcessedPath); 1312 FString parentFsPath (fullProcessedPath);
@@ -1311,7 +1315,11 @@ HRESULT CArchiveExtractCallback::CheckExistFile(FString &fullProcessedPath, bool
1311 if (parentFi.Find(parentFsPath)) 1315 if (parentFi.Find(parentFsPath))
1312 { 1316 {
1313 if (parentFi.IsReadOnly()) 1317 if (parentFi.IsReadOnly())
1318 {
1319 _altStream_NeedRestore_Attrib_for_parentFsPath = parentFsPath;
1320 _altStream_NeedRestore_AttribVal = parentFi.Attrib;
1314 SetFileAttrib(parentFsPath, parentFi.Attrib & ~(DWORD)FILE_ATTRIBUTE_READONLY); 1321 SetFileAttrib(parentFsPath, parentFi.Attrib & ~(DWORD)FILE_ATTRIBUTE_READONLY);
1322 }
1315 } 1323 }
1316 } 1324 }
1317 #endif // defined(_WIN32) && !defined(UNDER_CE) 1325 #endif // defined(_WIN32) && !defined(UNDER_CE)
@@ -1607,37 +1615,37 @@ Z7_COM7F_IMF(CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
1607 _bufPtrSeqOutStream.Release(); 1615 _bufPtrSeqOutStream.Release();
1608 1616
1609 _encrypted = false; 1617 _encrypted = false;
1610 _position = 0;
1611 _isSplit = false; 1618 _isSplit = false;
1612
1613 _curSize = 0;
1614 _curSize_Defined = false; 1619 _curSize_Defined = false;
1615 _fileLength_WasSet = false; 1620 _fileLength_WasSet = false;
1616 _fileLength_that_WasSet = 0;
1617 _index = index;
1618
1619 _diskFilePath.Empty();
1620
1621 _isRenamed = false; 1621 _isRenamed = false;
1622
1623 // _fi.Clear(); 1622 // _fi.Clear();
1624 1623 _extractMode = false;
1625 // _is_SymLink_in_Data = false; 1624 // _is_SymLink_in_Data = false;
1626 _is_SymLink_in_Data_Linux = false; 1625 _is_SymLink_in_Data_Linux = false;
1627
1628 _needSetAttrib = false; 1626 _needSetAttrib = false;
1629 _isSymLinkCreated = false; 1627 _isSymLinkCreated = false;
1630 _itemFailure = false; 1628 _itemFailure = false;
1631
1632 _some_pathParts_wereRemoved = false; 1629 _some_pathParts_wereRemoved = false;
1633 // _op_WasReported = false; 1630 // _op_WasReported = false;
1634 1631
1632 _position = 0;
1633 _curSize = 0;
1634 _fileLength_that_WasSet = 0;
1635 _index = index;
1636
1637#if defined(_WIN32) && !defined(UNDER_CE)
1638 _altStream_NeedRestore_AttribVal = 0;
1639 _altStream_NeedRestore_Attrib_for_parentFsPath.Empty();
1640#endif
1641
1642 _diskFilePath.Empty();
1643
1635 #ifdef SUPPORT_LINKS 1644 #ifdef SUPPORT_LINKS
1636 // _copyFile_Path.Empty(); 1645 // _copyFile_Path.Empty();
1637 _link.Clear(); 1646 _link.Clear();
1638 #endif 1647 #endif
1639 1648
1640 _extractMode = false;
1641 1649
1642 switch (askExtractMode) 1650 switch (askExtractMode)
1643 { 1651 {
@@ -1692,6 +1700,19 @@ Z7_COM7F_IMF(CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
1692 return S_OK; 1700 return S_OK;
1693 } 1701 }
1694 1702
1703#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX)
1704 if (askExtractMode == NArchive::NExtract::NAskMode::kExtract
1705 && !_testMode
1706 && _item.IsAltStream
1707 && ZoneBuf.Size() != 0
1708 && Is_ZoneId_StreamName(_item.AltStreamName))
1709 if (ZoneMode != NExtract::NZoneIdMode::kOffice
1710 || _item.PathParts.IsEmpty()
1711 || FindExt2(kOfficeExtensions, _item.PathParts.Back()))
1712 return S_OK;
1713#endif
1714
1715
1695 #ifndef Z7_SFX 1716 #ifndef Z7_SFX
1696 if (_use_baseParentFolder_mode) 1717 if (_use_baseParentFolder_mode)
1697 { 1718 {
@@ -1810,15 +1831,11 @@ Z7_COM7F_IMF(CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
1810 1831
1811 if (ExtractToStreamCallback) 1832 if (ExtractToStreamCallback)
1812 { 1833 {
1813 if (!GetProp) 1834 CMyComPtr2_Create<IGetProp, CGetProp> GetProp;
1814 { 1835 GetProp->Arc = _arc;
1815 GetProp_Spec = new CGetProp; 1836 GetProp->IndexInArc = index;
1816 GetProp = GetProp_Spec;
1817 }
1818 GetProp_Spec->Arc = _arc;
1819 GetProp_Spec->IndexInArc = index;
1820 UString name (MakePathFromParts(pathParts)); 1837 UString name (MakePathFromParts(pathParts));
1821 1838 // GetProp->BaseName = name;
1822 #ifdef SUPPORT_ALT_STREAMS 1839 #ifdef SUPPORT_ALT_STREAMS
1823 if (_item.IsAltStream) 1840 if (_item.IsAltStream)
1824 { 1841 {
@@ -1984,6 +2001,15 @@ HRESULT CArchiveExtractCallback::CloseFile()
1984 2001
1985 RINOK(_outFileStreamSpec->Close()) 2002 RINOK(_outFileStreamSpec->Close())
1986 _outFileStream.Release(); 2003 _outFileStream.Release();
2004
2005#if defined(_WIN32) && !defined(UNDER_CE)
2006 if (!_altStream_NeedRestore_Attrib_for_parentFsPath.IsEmpty())
2007 {
2008 SetFileAttrib(_altStream_NeedRestore_Attrib_for_parentFsPath, _altStream_NeedRestore_AttribVal);
2009 _altStream_NeedRestore_Attrib_for_parentFsPath.Empty();
2010 }
2011#endif
2012
1987 return hres; 2013 return hres;
1988} 2014}
1989 2015
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
90 } 90 }
91}; 91};
92 92
93#ifndef Z7_SFX
94
95Z7_CLASS_IMP_COM_1(
96 CGetProp
97 , IGetProp
98)
99public:
100 UInt32 IndexInArc;
101 const CArc *Arc;
102 // UString Name; // relative path
103};
104
105#endif
106 93
107#ifndef Z7_SFX 94#ifndef Z7_SFX
108#ifndef UNDER_CE 95#ifndef UNDER_CE
109
110#define SUPPORT_LINKS 96#define SUPPORT_LINKS
111
112#endif 97#endif
113#endif 98#endif
114 99
@@ -282,46 +267,44 @@ class CArchiveExtractCallback Z7_final:
282 Z7_IFACE_COM7_IMP(IArchiveRequestMemoryUseCallback) 267 Z7_IFACE_COM7_IMP(IArchiveRequestMemoryUseCallback)
283#endif 268#endif
284 269
270 // bool Write_CTime;
271 // bool Write_ATime;
272 // bool Write_MTime;
273 bool _stdOutMode;
274 bool _testMode;
275 bool _removePartsForAltStreams;
276public:
277 bool Is_elimPrefix_Mode;
278private:
279
285 const CArc *_arc; 280 const CArc *_arc;
286 CExtractNtOptions _ntOptions; 281 CExtractNtOptions _ntOptions;
287 282
283 bool _encrypted;
288 bool _isSplit; 284 bool _isSplit;
285 bool _curSize_Defined;
286 bool _fileLength_WasSet;
289 287
288 bool _isRenamed;
290 bool _extractMode; 289 bool _extractMode;
291
292 bool Write_CTime;
293 bool Write_ATime;
294 bool Write_MTime;
295 bool _keepAndReplaceEmptyDirPrefixes; // replace them to "_";
296
297 bool _encrypted;
298
299 // bool _is_SymLink_in_Data; 290 // bool _is_SymLink_in_Data;
300 bool _is_SymLink_in_Data_Linux; // false = WIN32, true = LINUX 291 bool _is_SymLink_in_Data_Linux; // false = WIN32, true = LINUX
301
302 bool _needSetAttrib; 292 bool _needSetAttrib;
303 bool _isSymLinkCreated; 293 bool _isSymLinkCreated;
304 bool _itemFailure; 294 bool _itemFailure;
305
306 bool _some_pathParts_wereRemoved; 295 bool _some_pathParts_wereRemoved;
307public:
308 bool Is_elimPrefix_Mode;
309
310private:
311 bool _curSize_Defined;
312 bool _fileLength_WasSet;
313
314 bool _removePartsForAltStreams;
315 296
316 bool _stdOutMode;
317 bool _testMode;
318 bool _multiArchives; 297 bool _multiArchives;
298 bool _keepAndReplaceEmptyDirPrefixes; // replace them to "_";
299#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX)
300 bool _saclEnabled;
301#endif
319 302
320 NExtract::NPathMode::EEnum _pathMode; 303 NExtract::NPathMode::EEnum _pathMode;
321 NExtract::NOverwriteMode::EEnum _overwriteMode; 304 NExtract::NOverwriteMode::EEnum _overwriteMode;
322 305
323 const NWildcard::CCensorNode *_wildcardCensor; // we need wildcard for single pass mode (stdin)
324 CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2; 306 CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2;
307 const NWildcard::CCensorNode *_wildcardCensor; // we need wildcard for single pass mode (stdin)
325 // CMyComPtr<ICompressProgressInfo> _compressProgress; 308 // CMyComPtr<ICompressProgressInfo> _compressProgress;
326 // CMyComPtr<IArchiveExtractCallbackMessage2> _callbackMessage; 309 // CMyComPtr<IArchiveExtractCallbackMessage2> _callbackMessage;
327 CMyComPtr<IFolderArchiveExtractCallback2> _folderArchiveExtractCallback2; 310 CMyComPtr<IFolderArchiveExtractCallback2> _folderArchiveExtractCallback2;
@@ -333,15 +316,12 @@ private:
333 #ifndef Z7_SFX 316 #ifndef Z7_SFX
334 317
335 CMyComPtr<IFolderExtractToStreamCallback> ExtractToStreamCallback; 318 CMyComPtr<IFolderExtractToStreamCallback> ExtractToStreamCallback;
336 CGetProp *GetProp_Spec;
337 CMyComPtr<IGetProp> GetProp;
338 CMyComPtr<IArchiveRequestMemoryUseCallback> _requestMemoryUseCallback; 319 CMyComPtr<IArchiveRequestMemoryUseCallback> _requestMemoryUseCallback;
339 320
340 #endif 321 #endif
341 322
342 CReadArcItem _item; 323 CReadArcItem _item;
343 FString _diskFilePath; 324 FString _diskFilePath;
344 UInt64 _position;
345 325
346 struct CProcessedFileInfo 326 struct CProcessedFileInfo
347 { 327 {
@@ -387,9 +367,17 @@ private:
387 } 367 }
388 } _fi; 368 } _fi;
389 369
390 UInt32 _index; 370 UInt64 _position;
391 UInt64 _curSize; 371 UInt64 _curSize;
392 UInt64 _fileLength_that_WasSet; 372 UInt64 _fileLength_that_WasSet;
373 UInt32 _index;
374
375// #ifdef SUPPORT_ALT_STREAMS
376#if defined(_WIN32) && !defined(UNDER_CE)
377 DWORD _altStream_NeedRestore_AttribVal;
378 FString _altStream_NeedRestore_Attrib_for_parentFsPath;
379#endif
380// #endif
393 381
394 COutFileStream *_outFileStreamSpec; 382 COutFileStream *_outFileStreamSpec;
395 CMyComPtr<ISequentialOutStream> _outFileStream; 383 CMyComPtr<ISequentialOutStream> _outFileStream;
@@ -398,9 +386,7 @@ private:
398 CBufPtrSeqOutStream *_bufPtrSeqOutStream_Spec; 386 CBufPtrSeqOutStream *_bufPtrSeqOutStream_Spec;
399 CMyComPtr<ISequentialOutStream> _bufPtrSeqOutStream; 387 CMyComPtr<ISequentialOutStream> _bufPtrSeqOutStream;
400 388
401
402 #ifndef Z7_SFX 389 #ifndef Z7_SFX
403
404 COutStreamWithHash *_hashStreamSpec; 390 COutStreamWithHash *_hashStreamSpec;
405 CMyComPtr<ISequentialOutStream> _hashStream; 391 CMyComPtr<ISequentialOutStream> _hashStream;
406 bool _hashStreamWasUsed; 392 bool _hashStreamWasUsed;
@@ -411,11 +397,9 @@ private:
411 397
412 UStringVector _removePathParts; 398 UStringVector _removePathParts;
413 399
414 CMyComPtr<ICompressProgressInfo> _localProgress;
415 UInt64 _packTotal; 400 UInt64 _packTotal;
416
417 UInt64 _progressTotal; 401 UInt64 _progressTotal;
418 bool _progressTotal_Defined; 402 // bool _progressTotal_Defined;
419 403
420 CObjectVector<CDirPathTime> _extractedFolders; 404 CObjectVector<CDirPathTime> _extractedFolders;
421 405
@@ -423,10 +407,6 @@ private:
423 // CObjectVector<NWindows::NFile::NDir::CDelayedSymLink> _delayedSymLinks; 407 // CObjectVector<NWindows::NFile::NDir::CDelayedSymLink> _delayedSymLinks;
424 #endif 408 #endif
425 409
426 #if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX)
427 bool _saclEnabled;
428 #endif
429
430 void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath); 410 void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath);
431 HRESULT GetTime(UInt32 index, PROPID propID, CArcTime &ft); 411 HRESULT GetTime(UInt32 index, PROPID propID, CArcTime &ft);
432 HRESULT GetUnpackSize(); 412 HRESULT GetUnpackSize();
@@ -441,13 +421,12 @@ public:
441 HRESULT SendMessageError_with_LastError(const char *message, const FString &path); 421 HRESULT SendMessageError_with_LastError(const char *message, const FString &path);
442 HRESULT SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2); 422 HRESULT SendMessageError2(HRESULT errorCode, const char *message, const FString &path1, const FString &path2);
443 423
444public: 424#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX)
445 #if defined(_WIN32) && !defined(UNDER_CE)
446 NExtract::NZoneIdMode::EEnum ZoneMode; 425 NExtract::NZoneIdMode::EEnum ZoneMode;
447 CByteBuffer ZoneBuf; 426 CByteBuffer ZoneBuf;
448 #endif 427#endif
449 428
450 CLocalProgress *LocalProgressSpec; 429 CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> LocalProgressSpec;
451 430
452 UInt64 NumFolders; 431 UInt64 NumFolders;
453 UInt64 NumFiles; 432 UInt64 NumFiles;
@@ -468,11 +447,11 @@ public:
468 _multiArchives = multiArchives; 447 _multiArchives = multiArchives;
469 _pathMode = pathMode; 448 _pathMode = pathMode;
470 _overwriteMode = overwriteMode; 449 _overwriteMode = overwriteMode;
471 #if defined(_WIN32) && !defined(UNDER_CE) 450#if defined(_WIN32) && !defined(UNDER_CE) && !defined(Z7_SFX)
472 ZoneMode = zoneMode; 451 ZoneMode = zoneMode;
473 #else 452#else
474 UNUSED_VAR(zoneMode) 453 UNUSED_VAR(zoneMode)
475 #endif 454#endif
476 _keepAndReplaceEmptyDirPrefixes = keepAndReplaceEmptyDirPrefixes; 455 _keepAndReplaceEmptyDirPrefixes = keepAndReplaceEmptyDirPrefixes;
477 NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0; 456 NumFolders = NumFiles = NumAltStreams = UnpackSize = AltStreams_UnpackSize = 0;
478 } 457 }
@@ -551,7 +530,6 @@ private:
551 void GetFiTimesCAM(CFiTimesCAM &pt); 530 void GetFiTimesCAM(CFiTimesCAM &pt);
552 void CreateFolders(); 531 void CreateFolders();
553 532
554 bool _isRenamed;
555 HRESULT CheckExistFile(FString &fullProcessedPath, bool &needExit); 533 HRESULT CheckExistFile(FString &fullProcessedPath, bool &needExit);
556 HRESULT GetExtractStream(CMyComPtr<ISequentialOutStream> &outStreamLoc, bool &needExit); 534 HRESULT GetExtractStream(CMyComPtr<ISequentialOutStream> &outStreamLoc, bool &needExit);
557 HRESULT GetItem(UInt32 index); 535 HRESULT GetItem(UInt32 index);
@@ -599,7 +577,8 @@ struct CArchiveExtractCallback_Closer
599 577
600bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item); 578bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item);
601 579
602void ReadZoneFile_Of_BaseFile(CFSTR fileName2, CByteBuffer &buf); 580bool Is_ZoneId_StreamName(const wchar_t *s);
581void ReadZoneFile_Of_BaseFile(CFSTR fileName, CByteBuffer &buf);
603bool WriteZoneFile_To_BaseFile(CFSTR fileName, const CByteBuffer &buf); 582bool WriteZoneFile_To_BaseFile(CFSTR fileName, const CByteBuffer &buf);
604 583
605#endif 584#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)
2298} 2298}
2299 2299
2300 2300
2301#if 1
2302#define HashUpdate(hf, data, size) hf->Update(data, size)
2303#else
2304// for debug:
2305static void HashUpdate(IHasher *hf, const void *data, UInt32 size)
2306{
2307 for (;;)
2308 {
2309 if (size == 0)
2310 return;
2311 UInt32 size2 = (size * 0x85EBCA87) % size / 8;
2312 // UInt32 size2 = size / 2;
2313 if (size2 == 0)
2314 size2 = 1;
2315 hf->Update(data, size2);
2316 data = (const void *)((const Byte *)data + size2);
2317 size -= size2;
2318 }
2319}
2320#endif
2321
2322
2301HRESULT CCrcInfo_Base::CrcProcess(UInt64 numIterations, 2323HRESULT CCrcInfo_Base::CrcProcess(UInt64 numIterations,
2302 const UInt32 *checkSum, IHasher *hf, 2324 const UInt32 *checkSum, IHasher *hf,
2303 IBenchPrintCallback *callback) 2325 IBenchPrintCallback *callback)
@@ -2328,7 +2350,7 @@ HRESULT CCrcInfo_Base::CrcProcess(UInt64 numIterations,
2328 const size_t rem = size - pos; 2350 const size_t rem = size - pos;
2329 const UInt32 kStep = ((UInt32)1 << 31); 2351 const UInt32 kStep = ((UInt32)1 << 31);
2330 const UInt32 curSize = (rem < kStep) ? (UInt32)rem : kStep; 2352 const UInt32 curSize = (rem < kStep) ? (UInt32)rem : kStep;
2331 hf->Update(buf + pos, curSize); 2353 HashUpdate(hf, buf + pos, curSize);
2332 pos += curSize; 2354 pos += curSize;
2333 } 2355 }
2334 while (pos != size); 2356 while (pos != size);
@@ -2742,14 +2764,20 @@ static const CBenchHash g_Hash[] =
2742 { 2, 128 *ARM_CRC_MUL, 0x21e207bb, "CRC32:32" }, 2764 { 2, 128 *ARM_CRC_MUL, 0x21e207bb, "CRC32:32" },
2743 { 2, 64 *ARM_CRC_MUL, 0x21e207bb, "CRC32:64" }, 2765 { 2, 64 *ARM_CRC_MUL, 0x21e207bb, "CRC32:64" },
2744 { 10, 256, 0x41b901d1, "CRC64" }, 2766 { 10, 256, 0x41b901d1, "CRC64" },
2745 { 10, 64, 0x43eac94f, "XXH64" }, 2767 { 5, 64, 0x43eac94f, "XXH64" },
2746 2768 { 2, 2340, 0x3398a904, "MD5" },
2747 { 10, 5100, 0x7913ba03, "SHA256:1" }, 2769 { 10, 2340, 0xff769021, "SHA1:1" },
2748 { 2, CMPLX((32 * 4 + 1) * 4 + 4), 0x7913ba03, "SHA256:2" },
2749
2750 { 10, 2340, 0xff769021, "SHA1:1" },
2751 { 2, CMPLX((20 * 6 + 1) * 4 + 4), 0xff769021, "SHA1:2" }, 2770 { 2, CMPLX((20 * 6 + 1) * 4 + 4), 0xff769021, "SHA1:2" },
2752 2771 { 10, 5100, 0x7913ba03, "SHA256:1" },
2772 { 2, CMPLX((32 * 4 + 1) * 4 + 4), 0x7913ba03, "SHA256:2" },
2773 { 5, 3200, 0xe7aeb394, "SHA512:1" },
2774 { 2, CMPLX((40 * 4 + 1) * 4 + 4), 0xe7aeb394, "SHA512:2" },
2775 // { 10, 3428, 0x1cc99b18, "SHAKE128" },
2776 // { 10, 4235, 0x74eaddc3, "SHAKE256" },
2777 // { 10, 4000, 0xdf3e6863, "SHA3-224" },
2778 { 5, 4200, 0xcecac10d, "SHA3-256" },
2779 // { 10, 5538, 0x4e5d9163, "SHA3-384" },
2780 // { 10, 8000, 0x96a58289, "SHA3-512" },
2753 { 2, 4096, 0x85189d02, "BLAKE2sp:1" }, 2781 { 2, 4096, 0x85189d02, "BLAKE2sp:1" },
2754 { 2, 1024, 0x85189d02, "BLAKE2sp:2" }, // sse2-way4-fast 2782 { 2, 1024, 0x85189d02, "BLAKE2sp:2" }, // sse2-way4-fast
2755 { 2, 512, 0x85189d02, "BLAKE2sp:3" } // avx2-way8-fast 2783 { 2, 512, 0x85189d02, "BLAKE2sp:3" } // avx2-way8-fast
@@ -3687,7 +3715,7 @@ HRESULT Bench(
3687 return E_FAIL; 3715 return E_FAIL;
3688 3716
3689 UInt32 numCPUs = 1; 3717 UInt32 numCPUs = 1;
3690 UInt64 ramSize = (UInt64)(sizeof(size_t)) << 29; 3718 size_t ramSize = (size_t)sizeof(size_t) << 29;
3691 3719
3692 NSystem::CProcessAffinity threadsInfo; 3720 NSystem::CProcessAffinity threadsInfo;
3693 threadsInfo.InitST(); 3721 threadsInfo.InitST();
@@ -4580,6 +4608,8 @@ HRESULT Bench(
4580 4608
4581 if (!dictIsDefined && !onlyHashBench) 4609 if (!dictIsDefined && !onlyHashBench)
4582 { 4610 {
4611 // we use dicSizeLog and dicSizeLog_Main for data size.
4612 // also we use it to reduce dictionary size of LZMA encoder via NCoderPropID::kReduceSize.
4583 const unsigned dicSizeLog_Main = (totalBenchMode ? 24 : 25); 4613 const unsigned dicSizeLog_Main = (totalBenchMode ? 24 : 25);
4584 unsigned dicSizeLog = dicSizeLog_Main; 4614 unsigned dicSizeLog = dicSizeLog_Main;
4585 4615
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(
671 } 671 }
672 672
673 #if defined(_WIN32) 673 #if defined(_WIN32)
674 if (needAltStreams && dirItems.ScanAltStreams) 674 if (needAltStreams && dirItems.ScanAltStreams && !fi.IsAltStream)
675 { 675 {
676 RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent, 676 RINOK(EnumerateAltStreams(fi, curNode, phyParent, logParent,
677 phyPrefix + fi.Name, // with (fi.Name) 677 phyPrefix + fi.Name, // with (fi.Name)
@@ -929,7 +929,7 @@ static HRESULT EnumerateDirItems(
929 } 929 }
930 930
931 #if defined(_WIN32) 931 #if defined(_WIN32)
932 if (needAltStreams && dirItems.ScanAltStreams) 932 if (needAltStreams && dirItems.ScanAltStreams && !fi.IsAltStream)
933 { 933 {
934 UStringVector pathParts; 934 UStringVector pathParts;
935 pathParts.Add(fs2us(fi.Name)); 935 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[] =
773{ 773{
774 "sha256" 774 "sha256"
775 , "sha224" 775 , "sha224"
776// , "sha512/224" 776// , "sha512-224"
777// , "sha512/256" 777// , "sha512-256"
778 , "sha512"
779 , "sha384" 778 , "sha384"
779 , "sha512"
780// , "sha3-224"
781 , "sha3-256"
782// , "sha3-384"
783// , "sha3-512"
784// , "shake128"
785// , "shake256"
780 , "sha1" 786 , "sha1"
781 , "md5" 787 , "md5"
788 , "blake2sp"
782 , "blake2b" 789 , "blake2b"
790 , "xxh64"
783 , "crc64" 791 , "crc64"
784 , "crc32" 792 , "crc32"
785 , "cksum" 793 , "cksum"
@@ -2076,11 +2084,27 @@ void Codecs_AddHashArcHandler(CCodecs *codecs)
2076 2084
2077 // ubuntu uses "SHA256SUMS" file 2085 // ubuntu uses "SHA256SUMS" file
2078 item.AddExts(UString ( 2086 item.AddExts(UString (
2079 "sha256 sha512 sha224 sha384 sha1 sha md5" 2087 "sha256"
2080 // "b2sum" 2088 " sha512"
2089 " sha384"
2090 " sha224"
2091 // " sha512-224"
2092 // " sha512-256"
2093 // " sha3-224"
2094 " sha3-256"
2095 // " sha3-384"
2096 // " sha3-512"
2097 // " shake128"
2098 // " shake256"
2099 " sha1"
2100 " sha"
2101 " md5"
2102 " blake2sp"
2103 " xxh64"
2081 " crc32 crc64" 2104 " crc32 crc64"
2082 " asc" 2105 " asc"
2083 " cksum" 2106 " cksum"
2107 // " b2sum"
2084 ), 2108 ),
2085 UString()); 2109 UString());
2086 2110
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()
13{ 13{
14 while (!Paths.IsEmpty()) 14 while (!Paths.IsEmpty())
15 { 15 {
16 NDir::DeleteFileAlways(Paths.Back()); 16 if (NeedDeleteFiles)
17 NDir::DeleteFileAlways(Paths.Back());
17 Paths.DeleteBack(); 18 Paths.DeleteBack();
18 } 19 }
19} 20}
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
10 void Clear(); 10 void Clear();
11public: 11public:
12 FStringVector Paths; 12 FStringVector Paths;
13 bool NeedDeleteFiles;
14
15 CTempFiles(): NeedDeleteFiles(true) {}
13 ~CTempFiles() { Clear(); } 16 ~CTempFiles() { Clear(); }
14}; 17};
15 18
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;
1096#endif // _WIN32 1096#endif // _WIN32
1097 1097
1098 1098
1099struct C_CopyFileProgress_to_IUpdateCallbackUI2 Z7_final:
1100 public ICopyFileProgress
1101{
1102 IUpdateCallbackUI2 *Callback;
1103 HRESULT CallbackResult;
1104 // bool Disable_Break;
1105
1106 virtual DWORD CopyFileProgress(UInt64 total, UInt64 current) Z7_override
1107 {
1108 const HRESULT res = Callback->MoveArc_Progress(total, current);
1109 CallbackResult = res;
1110 // if (Disable_Break && res == E_ABORT) res = S_OK;
1111 return res == S_OK ? PROGRESS_CONTINUE : PROGRESS_CANCEL;
1112 }
1113
1114 C_CopyFileProgress_to_IUpdateCallbackUI2(
1115 IUpdateCallbackUI2 *callback) :
1116 Callback(callback),
1117 CallbackResult(S_OK)
1118 // , Disable_Break(false)
1119 {}
1120};
1121
1122
1099HRESULT UpdateArchive( 1123HRESULT UpdateArchive(
1100 CCodecs *codecs, 1124 CCodecs *codecs,
1101 const CObjectVector<COpenType> &types, 1125 const CObjectVector<COpenType> &types,
@@ -1311,7 +1335,7 @@ HRESULT UpdateArchive(
1311 return E_NOTIMPL; 1335 return E_NOTIMPL;
1312 } 1336 }
1313 1337
1314 bool thereIsInArchive = arcLink.IsOpen; 1338 const bool thereIsInArchive = arcLink.IsOpen;
1315 if (!thereIsInArchive && renameMode) 1339 if (!thereIsInArchive && renameMode)
1316 return E_FAIL; 1340 return E_FAIL;
1317 1341
@@ -1588,7 +1612,14 @@ HRESULT UpdateArchive(
1588 multiStreams.DisableDeletion(); 1612 multiStreams.DisableDeletion();
1589 RINOK(multiStreams.Destruct()) 1613 RINOK(multiStreams.Destruct())
1590 1614
1591 tempFiles.Paths.Clear(); 1615 // here we disable deleting of temp archives.
1616 // note: archive moving can fail, or it can be interrupted,
1617 // if we move new temp update from another volume.
1618 // And we still want to keep temp archive in that case,
1619 // because we will have deleted original archive.
1620 tempFiles.NeedDeleteFiles = false;
1621 // tempFiles.Paths.Clear();
1622
1592 if (createTempFile) 1623 if (createTempFile)
1593 { 1624 {
1594 try 1625 try
@@ -1603,16 +1634,29 @@ HRESULT UpdateArchive(
1603 if (!DeleteFileAlways(us2fs(arcPath))) 1634 if (!DeleteFileAlways(us2fs(arcPath)))
1604 return errorInfo.SetFromLastError("cannot delete the file", us2fs(arcPath)); 1635 return errorInfo.SetFromLastError("cannot delete the file", us2fs(arcPath));
1605 } 1636 }
1606 1637
1607 if (!MyMoveFile(tempPath, us2fs(arcPath))) 1638 UInt64 totalArcSize = 0;
1639 {
1640 NFind::CFileInfo fi;
1641 if (fi.Find(tempPath))
1642 totalArcSize = fi.Size;
1643 }
1644 RINOK(callback->MoveArc_Start(fs2us(tempPath), arcPath,
1645 totalArcSize, BoolToInt(thereIsInArchive)))
1646
1647 C_CopyFileProgress_to_IUpdateCallbackUI2 prox(callback);
1648 // if we update archive, we have removed original archive.
1649 // So if we break archive moving, we will have only temporary archive.
1650 // We can disable breaking here:
1651 // prox.Disable_Break = thereIsInArchive;
1652
1653 if (!MyMoveFile_with_Progress(tempPath, us2fs(arcPath), &prox))
1608 { 1654 {
1609 errorInfo.SystemError = ::GetLastError(); 1655 errorInfo.SystemError = ::GetLastError();
1610 errorInfo.Message = "cannot move the file"; 1656 errorInfo.Message = "cannot move the file";
1611 if (errorInfo.SystemError == ERROR_INVALID_PARAMETER) 1657 if (errorInfo.SystemError == ERROR_INVALID_PARAMETER)
1612 { 1658 {
1613 NFind::CFileInfo fi; 1659 if (totalArcSize > (UInt32)(Int32)-1)
1614 if (fi.Find(tempPath) &&
1615 fi.Size > (UInt32)(Int32)-1)
1616 { 1660 {
1617 // bool isFsDetected = false; 1661 // bool isFsDetected = false;
1618 // if (NSystem::Is_File_LimitedBy_4GB(us2fs(arcPath), isFsDetected) || !isFsDetected) 1662 // if (NSystem::Is_File_LimitedBy_4GB(us2fs(arcPath), isFsDetected) || !isFsDetected)
@@ -1622,10 +1666,20 @@ HRESULT UpdateArchive(
1622 } 1666 }
1623 } 1667 }
1624 } 1668 }
1669 // if there was no input archive, and we have operation breaking.
1670 // then we can remove temporary archive, because we still have original uncompressed files.
1671 if (!thereIsInArchive
1672 && prox.CallbackResult == E_ABORT)
1673 tempFiles.NeedDeleteFiles = true;
1625 errorInfo.FileNames.Add(tempPath); 1674 errorInfo.FileNames.Add(tempPath);
1626 errorInfo.FileNames.Add(us2fs(arcPath)); 1675 errorInfo.FileNames.Add(us2fs(arcPath));
1676 RINOK(prox.CallbackResult)
1627 return errorInfo.Get_HRESULT_Error(); 1677 return errorInfo.Get_HRESULT_Error();
1628 } 1678 }
1679
1680 // MoveArc_Finish() can return delayed user break (E_ABORT) status,
1681 // if callback callee ignored interruption to finish archive creation operation.
1682 RINOK(callback->MoveArc_Finish())
1629 1683
1630 /* 1684 /*
1631 if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_READONLY)) 1685 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 @@
12#include "UpdateAction.h" 12#include "UpdateAction.h"
13#include "UpdateCallback.h" 13#include "UpdateCallback.h"
14 14
15#include "DirItem.h"
16
17enum EArcNameMode 15enum EArcNameMode
18{ 16{
19 k_ArcNameMode_Smart, 17 k_ArcNameMode_Smart,
@@ -195,6 +193,9 @@ Z7_PURE_INTERFACES_BEGIN
195 virtual HRESULT FinishArchive(const CFinishArchiveStat &st) x \ 193 virtual HRESULT FinishArchive(const CFinishArchiveStat &st) x \
196 virtual HRESULT DeletingAfterArchiving(const FString &path, bool isDir) x \ 194 virtual HRESULT DeletingAfterArchiving(const FString &path, bool isDir) x \
197 virtual HRESULT FinishDeletingAfterArchiving() x \ 195 virtual HRESULT FinishDeletingAfterArchiving() x \
196 virtual HRESULT MoveArc_Start(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 size, Int32 updateMode) x \
197 virtual HRESULT MoveArc_Progress(UInt64 total, UInt64 current) x \
198 virtual HRESULT MoveArc_Finish() x \
198 199
199DECLARE_INTERFACE(IUpdateCallbackUI2): 200DECLARE_INTERFACE(IUpdateCallbackUI2):
200 public IUpdateCallbackUI, 201 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)
63 NWorkDir::CInfo workDirInfo; 63 NWorkDir::CInfo workDirInfo;
64 workDirInfo.Load(); 64 workDirInfo.Load();
65 FString namePart; 65 FString namePart;
66 const FString workDir = GetWorkDir(workDirInfo, originalPath, namePart); 66 FString path = GetWorkDir(workDirInfo, originalPath, namePart);
67 CreateComplexDir(workDir); 67 CreateComplexDir(path);
68 path += namePart;
68 _outStreamSpec = new COutFileStream; 69 _outStreamSpec = new COutFileStream;
69 OutStream = _outStreamSpec; 70 OutStream = _outStreamSpec;
70 if (!_tempFile.Create(workDir + namePart, &_outStreamSpec->File)) 71 if (!_tempFile.Create(path, &_outStreamSpec->File))
71 {
72 return GetLastError_noZero_HRESULT(); 72 return GetLastError_noZero_HRESULT();
73 }
74 _originalPath = originalPath; 73 _originalPath = originalPath;
75 return S_OK; 74 return S_OK;
76} 75}
77 76
78HRESULT CWorkDirTempFile::MoveToOriginal(bool deleteOriginal) 77HRESULT CWorkDirTempFile::MoveToOriginal(bool deleteOriginal,
78 NWindows::NFile::NDir::ICopyFileProgress *progress)
79{ 79{
80 OutStream.Release(); 80 OutStream.Release();
81 if (!_tempFile.MoveTo(_originalPath, deleteOriginal)) 81 if (!_tempFile.MoveTo(_originalPath, deleteOriginal, progress))
82 {
83 return GetLastError_noZero_HRESULT(); 82 return GetLastError_noZero_HRESULT();
84 }
85 return S_OK; 83 return S_OK;
86} 84}
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 @@
11 11
12FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FString &fileName); 12FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FString &fileName);
13 13
14class CWorkDirTempFile 14class CWorkDirTempFile MY_UNCOPYABLE
15{ 15{
16 FString _originalPath; 16 FString _originalPath;
17 NWindows::NFile::NDir::CTempFile _tempFile; 17 NWindows::NFile::NDir::CTempFile _tempFile;
@@ -19,8 +19,12 @@ class CWorkDirTempFile
19public: 19public:
20 CMyComPtr<IOutStream> OutStream; 20 CMyComPtr<IOutStream> OutStream;
21 21
22 const FString &Get_OriginalFilePath() const { return _originalPath; }
23 const FString &Get_TempFilePath() const { return _tempFile.GetPath(); }
24
22 HRESULT CreateTempFile(const FString &originalPath); 25 HRESULT CreateTempFile(const FString &originalPath);
23 HRESULT MoveToOriginal(bool deleteOriginal); 26 HRESULT MoveToOriginal(bool deleteOriginal,
27 NWindows::NFile::NDir::ICopyFileProgress *progress = NULL);
24}; 28};
25 29
26#endif 30#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)
45 45
46static void Key_Get_UInt32(CKey &key, LPCTSTR name, UInt32 &value) 46static void Key_Get_UInt32(CKey &key, LPCTSTR name, UInt32 &value)
47{ 47{
48 if (key.QueryValue(name, value) != ERROR_SUCCESS) 48 value = (UInt32)(Int32)-1;
49 value = (UInt32)(Int32)-1; 49 key.GetValue_UInt32_IfOk(name, value);
50} 50}
51 51
52 52
@@ -59,7 +59,7 @@ static void Key_Set_BoolPair(CKey &key, LPCTSTR name, const CBoolPair &b)
59static void Key_Set_bool_if_Changed(CKey &key, LPCTSTR name, bool val) 59static void Key_Set_bool_if_Changed(CKey &key, LPCTSTR name, bool val)
60{ 60{
61 bool oldVal = false; 61 bool oldVal = false;
62 if (key.GetValue_IfOk(name, oldVal) == ERROR_SUCCESS) 62 if (key.GetValue_bool_IfOk(name, oldVal) == ERROR_SUCCESS)
63 if (val == oldVal) 63 if (val == oldVal)
64 return; 64 return;
65 key.SetValue(name, val); 65 key.SetValue(name, val);
@@ -76,13 +76,13 @@ static void Key_Set_BoolPair_Delete_IfNotDef(CKey &key, LPCTSTR name, const CBoo
76static void Key_Get_BoolPair(CKey &key, LPCTSTR name, CBoolPair &b) 76static void Key_Get_BoolPair(CKey &key, LPCTSTR name, CBoolPair &b)
77{ 77{
78 b.Val = false; 78 b.Val = false;
79 b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS); 79 b.Def = (key.GetValue_bool_IfOk(name, b.Val) == ERROR_SUCCESS);
80} 80}
81 81
82static void Key_Get_BoolPair_true(CKey &key, LPCTSTR name, CBoolPair &b) 82static void Key_Get_BoolPair_true(CKey &key, LPCTSTR name, CBoolPair &b)
83{ 83{
84 b.Val = true; 84 b.Val = true;
85 b.Def = (key.GetValue_IfOk(name, b.Val) == ERROR_SUCCESS); 85 b.Def = (key.GetValue_bool_IfOk(name, b.Val) == ERROR_SUCCESS);
86} 86}
87 87
88namespace NExtract 88namespace NExtract
@@ -155,12 +155,12 @@ void CInfo::Load()
155 155
156 key.GetValue_Strings(kPathHistory, Paths); 156 key.GetValue_Strings(kPathHistory, Paths);
157 UInt32 v; 157 UInt32 v;
158 if (key.QueryValue(kExtractMode, v) == ERROR_SUCCESS && v <= NPathMode::kAbsPaths) 158 if (key.GetValue_UInt32_IfOk(kExtractMode, v) == ERROR_SUCCESS && v <= NPathMode::kAbsPaths)
159 { 159 {
160 PathMode = (NPathMode::EEnum)v; 160 PathMode = (NPathMode::EEnum)v;
161 PathMode_Force = true; 161 PathMode_Force = true;
162 } 162 }
163 if (key.QueryValue(kOverwriteMode, v) == ERROR_SUCCESS && v <= NOverwriteMode::kRenameExisting) 163 if (key.GetValue_UInt32_IfOk(kOverwriteMode, v) == ERROR_SUCCESS && v <= NOverwriteMode::kRenameExisting)
164 { 164 {
165 OverwriteMode = (NOverwriteMode::EEnum)v; 165 OverwriteMode = (NOverwriteMode::EEnum)v;
166 OverwriteMode_Force = true; 166 OverwriteMode_Force = true;
@@ -181,7 +181,7 @@ bool Read_ShowPassword()
181 bool showPassword = false; 181 bool showPassword = false;
182 if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS) 182 if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS)
183 return showPassword; 183 return showPassword;
184 key.GetValue_IfOk(kShowPassword, showPassword); 184 key.GetValue_bool_IfOk(kShowPassword, showPassword);
185 return showPassword; 185 return showPassword;
186} 186}
187 187
@@ -189,13 +189,10 @@ UInt32 Read_LimitGB()
189{ 189{
190 CS_LOCK 190 CS_LOCK
191 CKey key; 191 CKey key;
192 UInt32 v = (UInt32)(Int32)-1;
192 if (OpenMainKey(key, kKeyName) == ERROR_SUCCESS) 193 if (OpenMainKey(key, kKeyName) == ERROR_SUCCESS)
193 { 194 key.GetValue_UInt32_IfOk(kMemLimit, v);
194 UInt32 v; 195 return v;
195 if (key.QueryValue(kMemLimit, v) == ERROR_SUCCESS)
196 return v;
197 }
198 return (UInt32)(Int32)-1;
199} 196}
200 197
201} 198}
@@ -371,9 +368,9 @@ void CInfo::Load()
371 UString a; 368 UString a;
372 if (key.QueryValue(kArchiver, a) == ERROR_SUCCESS) 369 if (key.QueryValue(kArchiver, a) == ERROR_SUCCESS)
373 ArcType = a; 370 ArcType = a;
374 key.GetValue_IfOk(kLevel, Level); 371 key.GetValue_UInt32_IfOk(kLevel, Level);
375 key.GetValue_IfOk(kShowPassword, ShowPassword); 372 key.GetValue_bool_IfOk(kShowPassword, ShowPassword);
376 key.GetValue_IfOk(kEncryptHeaders, EncryptHeaders); 373 key.GetValue_bool_IfOk(kEncryptHeaders, EncryptHeaders);
377} 374}
378 375
379 376
@@ -517,7 +514,7 @@ void CInfo::Load()
517 return; 514 return;
518 515
519 UInt32 dirType; 516 UInt32 dirType;
520 if (key.QueryValue(kWorkDirType, dirType) != ERROR_SUCCESS) 517 if (key.GetValue_UInt32_IfOk(kWorkDirType, dirType) != ERROR_SUCCESS)
521 return; 518 return;
522 switch (dirType) 519 switch (dirType)
523 { 520 {
@@ -535,7 +532,7 @@ void CInfo::Load()
535 if (Mode == NMode::kSpecified) 532 if (Mode == NMode::kSpecified)
536 Mode = NMode::kSystem; 533 Mode = NMode::kSystem;
537 } 534 }
538 key.GetValue_IfOk(kTempRemovableOnly, ForRemovableOnly); 535 key.GetValue_bool_IfOk(kTempRemovableOnly, ForRemovableOnly);
539} 536}
540 537
541} 538}
@@ -598,5 +595,5 @@ void CContextMenuInfo::Load()
598 595
599 Key_Get_UInt32(key, kWriteZoneId, WriteZone); 596 Key_Get_UInt32(key, kWriteZoneId, WriteZone);
600 597
601 Flags_Def = (key.GetValue_IfOk(kContextMenu, Flags) == ERROR_SUCCESS); 598 Flags_Def = (key.GetValue_UInt32_IfOk(kContextMenu, Flags) == ERROR_SUCCESS);
602} 599}
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 @@
16namespace NConsoleClose { 16namespace NConsoleClose {
17 17
18unsigned g_BreakCounter = 0; 18unsigned g_BreakCounter = 0;
19static const unsigned kBreakAbortThreshold = 2; 19static const unsigned kBreakAbortThreshold = 3;
20 20
21#ifdef _WIN32 21#ifdef _WIN32
22 22
@@ -28,8 +28,7 @@ static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
28 return TRUE; 28 return TRUE;
29 } 29 }
30 30
31 g_BreakCounter++; 31 if (++g_BreakCounter < kBreakAbortThreshold)
32 if (g_BreakCounter < kBreakAbortThreshold)
33 return TRUE; 32 return TRUE;
34 return FALSE; 33 return FALSE;
35 /* 34 /*
@@ -47,7 +46,7 @@ static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
47CCtrlHandlerSetter::CCtrlHandlerSetter() 46CCtrlHandlerSetter::CCtrlHandlerSetter()
48{ 47{
49 if (!SetConsoleCtrlHandler(HandlerRoutine, TRUE)) 48 if (!SetConsoleCtrlHandler(HandlerRoutine, TRUE))
50 throw "SetConsoleCtrlHandler fails"; 49 throw 1019; // "SetConsoleCtrlHandler fails";
51} 50}
52 51
53CCtrlHandlerSetter::~CCtrlHandlerSetter() 52CCtrlHandlerSetter::~CCtrlHandlerSetter()
@@ -63,8 +62,7 @@ CCtrlHandlerSetter::~CCtrlHandlerSetter()
63 62
64static void HandlerRoutine(int) 63static void HandlerRoutine(int)
65{ 64{
66 g_BreakCounter++; 65 if (++g_BreakCounter < kBreakAbortThreshold)
67 if (g_BreakCounter < kBreakAbortThreshold)
68 return; 66 return;
69 exit(EXIT_FAILURE); 67 exit(EXIT_FAILURE);
70} 68}
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 @@
5 5
6namespace NConsoleClose { 6namespace NConsoleClose {
7 7
8class CCtrlBreakException {}; 8// class CCtrlBreakException {};
9 9
10#ifdef UNDER_CE 10#ifdef UNDER_CE
11 11
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)
928 if (result == E_ABORT 928 if (result == E_ABORT
929 || result == HRESULT_FROM_WIN32(ERROR_DISK_FULL)) 929 || result == HRESULT_FROM_WIN32(ERROR_DISK_FULL))
930 return result; 930 return result;
931 NumArcsWithError++; 931 NumArcsWithError++;
932 932
933 if (_se) 933 if (_se)
934 { 934 {
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
140 PrintError(kMemoryExceptionMessage); 140 PrintError(kMemoryExceptionMessage);
141 return (NExitCode::kMemoryError); 141 return (NExitCode::kMemoryError);
142 } 142 }
143/*
143 catch(const NConsoleClose::CCtrlBreakException &) 144 catch(const NConsoleClose::CCtrlBreakException &)
144 { 145 {
145 PrintError(kUserBreakMessage); 146 PrintError(kUserBreakMessage);
146 return (NExitCode::kUserBreak); 147 return (NExitCode::kUserBreak);
147 } 148 }
149*/
148 catch(const CMessagePathException &e) 150 catch(const CMessagePathException &e)
149 { 151 {
150 PrintError(kException_CmdLine_Error_Message); 152 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
26 26
27class CPercentPrinter: public CPercentPrinterState 27class CPercentPrinter: public CPercentPrinterState
28{ 28{
29public:
30 CStdOutStream *_so;
31 bool DisablePrint;
32 bool NeedFlush;
33 unsigned MaxLen;
34
35private:
29 UInt32 _tickStep; 36 UInt32 _tickStep;
30 DWORD _prevTick; 37 DWORD _prevTick;
31 38
@@ -41,18 +48,13 @@ class CPercentPrinter: public CPercentPrinterState
41 void GetPercents(); 48 void GetPercents();
42 49
43public: 50public:
44 CStdOutStream *_so;
45
46 bool DisablePrint;
47 bool NeedFlush;
48 unsigned MaxLen;
49 51
50 CPercentPrinter(UInt32 tickStep = 200): 52 CPercentPrinter(UInt32 tickStep = 200):
51 _tickStep(tickStep),
52 _prevTick(0),
53 DisablePrint(false), 53 DisablePrint(false),
54 NeedFlush(true), 54 NeedFlush(true),
55 MaxLen(80 - 1) 55 MaxLen(80 - 1),
56 _tickStep(tickStep),
57 _prevTick(0)
56 {} 58 {}
57 59
58 ~CPercentPrinter(); 60 ~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)
361} 361}
362 362
363 363
364
365HRESULT CUpdateCallbackConsole::MoveArc_UpdateStatus()
366{
367 if (NeedPercents())
368 {
369 AString &s = _percent.Command;
370 s = " : ";
371 s.Add_UInt64(_arcMoving_percents);
372 s.Add_Char('%');
373 const bool totalDefined = (_arcMoving_total != 0 && _arcMoving_total != (UInt64)(Int64)-1);
374 if (_arcMoving_current != 0 || totalDefined)
375 {
376 s += " : ";
377 s.Add_UInt64(_arcMoving_current >> 20);
378 s += " MiB";
379 }
380 if (totalDefined)
381 {
382 s += " / ";
383 s.Add_UInt64((_arcMoving_total + ((1 << 20) - 1)) >> 20);
384 s += " MiB";
385 }
386 s += " : temporary archive moving ...";
387 _percent.Print();
388 }
389
390 // we ignore single Ctrl-C, if (_arcMoving_updateMode) mode
391 // because we want to get good final archive instead of temp archive.
392 if (NConsoleClose::g_BreakCounter == 1 && _arcMoving_updateMode)
393 return S_OK;
394 return CheckBreak();
395}
396
397
398HRESULT CUpdateCallbackConsole::MoveArc_Start(
399 const wchar_t *srcTempPath, const wchar_t *destFinalPath,
400 UInt64 size, Int32 updateMode)
401{
402#if 0 // 1 : for debug
403 if (LogLevel > 0 && _so)
404 {
405 ClosePercents_for_so();
406 *_so << "Temporary archive moving:" << endl;
407 _tempU = srcTempPath;
408 _so->Normalize_UString_Path(_tempU);
409 _so->PrintUString(_tempU, _tempA);
410 *_so << endl;
411 _tempU = destFinalPath;
412 _so->Normalize_UString_Path(_tempU);
413 _so->PrintUString(_tempU, _tempA);
414 *_so << endl;
415 }
416#else
417 UNUSED_VAR(srcTempPath)
418 UNUSED_VAR(destFinalPath)
419#endif
420
421 _arcMoving_updateMode = updateMode;
422 _arcMoving_total = size;
423 _arcMoving_current = 0;
424 _arcMoving_percents = 0;
425 return MoveArc_UpdateStatus();
426}
427
428
429HRESULT CUpdateCallbackConsole::MoveArc_Progress(UInt64 totalSize, UInt64 currentSize)
430{
431#if 0 // 1 : for debug
432 if (_so)
433 {
434 ClosePercents_for_so();
435 *_so << totalSize << " : " << currentSize << endl;
436 }
437#endif
438
439 UInt64 percents = 0;
440 if (totalSize != 0)
441 {
442 if (totalSize < ((UInt64)1 << 57))
443 percents = currentSize * 100 / totalSize;
444 else
445 percents = currentSize / (totalSize / 100);
446 }
447
448#ifdef _WIN32
449 // Sleep(300); // for debug
450#endif
451 // totalSize = (UInt64)(Int64)-1; // for debug
452
453 if (percents == _arcMoving_percents)
454 return CheckBreak();
455 _arcMoving_current = currentSize;
456 _arcMoving_total = totalSize;
457 _arcMoving_percents = percents;
458 return MoveArc_UpdateStatus();
459}
460
461
462HRESULT CUpdateCallbackConsole::MoveArc_Finish()
463{
464 // _arcMoving_percents = 0;
465 if (NeedPercents())
466 {
467 _percent.Command.Empty();
468 _percent.Print();
469 }
470 // it can return delayed user break (E_ABORT) status,
471 // if it ignored single CTRL+C in MoveArc_Progress().
472 return CheckBreak();
473}
474
475
476
364HRESULT CUpdateCallbackConsole::DeletingAfterArchiving(const FString &path, bool /* isDir */) 477HRESULT CUpdateCallbackConsole::DeletingAfterArchiving(const FString &path, bool /* isDir */)
365{ 478{
366 if (LogLevel > 0 && _so) 479 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
29 29
30class CCallbackConsoleBase 30class CCallbackConsoleBase
31{ 31{
32protected: 32 void CommonError(const FString &path, DWORD systemError, bool isWarning);
33 CPercentPrinter _percent;
34 33
34protected:
35 CStdOutStream *_so; 35 CStdOutStream *_so;
36 CStdOutStream *_se; 36 CStdOutStream *_se;
37 37
38 void CommonError(const FString &path, DWORD systemError, bool isWarning);
39 // void CommonError(const char *message);
40
41 HRESULT ScanError_Base(const FString &path, DWORD systemError); 38 HRESULT ScanError_Base(const FString &path, DWORD systemError);
42 HRESULT OpenFileError_Base(const FString &name, DWORD systemError); 39 HRESULT OpenFileError_Base(const FString &name, DWORD systemError);
43 HRESULT ReadingFileError_Base(const FString &name, DWORD systemError); 40 HRESULT ReadingFileError_Base(const FString &name, DWORD systemError);
44 41
45public: 42public:
46 bool NeedPercents() const { return _percent._so != NULL; }
47
48 bool StdOutMode; 43 bool StdOutMode;
49
50 bool NeedFlush; 44 bool NeedFlush;
51 unsigned PercentsNameLevel; 45 unsigned PercentsNameLevel;
52 unsigned LogLevel; 46 unsigned LogLevel;
53 47
48protected:
54 AString _tempA; 49 AString _tempA;
55 UString _tempU; 50 UString _tempU;
51 CPercentPrinter _percent;
52
53public:
54 CErrorPathCodes FailedFiles;
55 CErrorPathCodes ScanErrors;
56 UInt64 NumNonOpenFiles;
56 57
57 CCallbackConsoleBase(): 58 CCallbackConsoleBase():
58 StdOutMode(false), 59 StdOutMode(false),
@@ -62,6 +63,7 @@ public:
62 NumNonOpenFiles(0) 63 NumNonOpenFiles(0)
63 {} 64 {}
64 65
66 bool NeedPercents() const { return _percent._so != NULL; }
65 void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; } 67 void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; }
66 68
67 void Init( 69 void Init(
@@ -90,10 +92,6 @@ public:
90 _percent.ClosePrint(false); 92 _percent.ClosePrint(false);
91 } 93 }
92 94
93 CErrorPathCodes FailedFiles;
94 CErrorPathCodes ScanErrors;
95 UInt64 NumNonOpenFiles;
96
97 HRESULT PrintProgress(const wchar_t *name, bool isDir, const char *command, bool showInLog); 95 HRESULT PrintProgress(const wchar_t *name, bool isDir, const char *command, bool showInLog);
98 96
99 // void PrintInfoLine(const UString &s); 97 // void PrintInfoLine(const UString &s);
@@ -109,6 +107,14 @@ class CUpdateCallbackConsole Z7_final:
109 Z7_IFACE_IMP(IUpdateCallbackUI) 107 Z7_IFACE_IMP(IUpdateCallbackUI)
110 Z7_IFACE_IMP(IDirItemsCallback) 108 Z7_IFACE_IMP(IDirItemsCallback)
111 Z7_IFACE_IMP(IUpdateCallbackUI2) 109 Z7_IFACE_IMP(IUpdateCallbackUI2)
110
111 HRESULT MoveArc_UpdateStatus();
112
113 UInt64 _arcMoving_total;
114 UInt64 _arcMoving_current;
115 UInt64 _arcMoving_percents;
116 Int32 _arcMoving_updateMode;
117
112public: 118public:
113 bool DeleteMessageWasShown; 119 bool DeleteMessageWasShown;
114 120
@@ -119,7 +125,11 @@ public:
119 #endif 125 #endif
120 126
121 CUpdateCallbackConsole(): 127 CUpdateCallbackConsole():
122 DeleteMessageWasShown(false) 128 _arcMoving_total(0)
129 , _arcMoving_current(0)
130 , _arcMoving_percents(0)
131 , _arcMoving_updateMode(0)
132 , DeleteMessageWasShown(false)
123 #ifndef Z7_NO_CRYPTO 133 #ifndef Z7_NO_CRYPTO
124 , PasswordIsDefined(false) 134 , PasswordIsDefined(false)
125 , AskPassword(false) 135 , 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[] =
295{ 295{
296 { CZipContextMenu::kHash_CRC32, "CRC-32", "CRC32" }, 296 { CZipContextMenu::kHash_CRC32, "CRC-32", "CRC32" },
297 { CZipContextMenu::kHash_CRC64, "CRC-64", "CRC64" }, 297 { CZipContextMenu::kHash_CRC64, "CRC-64", "CRC64" },
298 { CZipContextMenu::kHash_XXH64, "XXH64", "XXH64" }, 298 { CZipContextMenu::kHash_XXH64, "XXH64", "XXH64" },
299 { CZipContextMenu::kHash_MD5, "MD5", "MD5" },
299 { CZipContextMenu::kHash_SHA1, "SHA-1", "SHA1" }, 300 { CZipContextMenu::kHash_SHA1, "SHA-1", "SHA1" },
300 { CZipContextMenu::kHash_SHA256, "SHA-256", "SHA256" }, 301 { CZipContextMenu::kHash_SHA256, "SHA-256", "SHA256" },
302 { CZipContextMenu::kHash_SHA384, "SHA-384", "SHA384" },
303 { CZipContextMenu::kHash_SHA512, "SHA-512", "SHA512" },
304 { CZipContextMenu::kHash_SHA3_256, "SHA3-256", "SHA3-256" },
301 { CZipContextMenu::kHash_BLAKE2SP, "BLAKE2sp", "BLAKE2sp" }, 305 { CZipContextMenu::kHash_BLAKE2SP, "BLAKE2sp", "BLAKE2sp" },
302 { CZipContextMenu::kHash_All, "*", "*" }, 306 { CZipContextMenu::kHash_All, "*", "*" },
303 { CZipContextMenu::kHash_Generate_SHA256, "SHA-256 -> file.sha256", "SHA256" }, 307 { CZipContextMenu::kHash_Generate_SHA256, "SHA-256 -> file.sha256", "SHA256" },
@@ -1338,8 +1342,12 @@ HRESULT CZipContextMenu::InvokeCommandCommon(const CCommandMapItem &cmi)
1338 case kHash_CRC32: 1342 case kHash_CRC32:
1339 case kHash_CRC64: 1343 case kHash_CRC64:
1340 case kHash_XXH64: 1344 case kHash_XXH64:
1345 case kHash_MD5:
1341 case kHash_SHA1: 1346 case kHash_SHA1:
1342 case kHash_SHA256: 1347 case kHash_SHA256:
1348 case kHash_SHA384:
1349 case kHash_SHA512:
1350 case kHash_SHA3_256:
1343 case kHash_BLAKE2SP: 1351 case kHash_BLAKE2SP:
1344 case kHash_All: 1352 case kHash_All:
1345 case kHash_Generate_SHA256: 1353 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:
88 kHash_CRC32, 88 kHash_CRC32,
89 kHash_CRC64, 89 kHash_CRC64,
90 kHash_XXH64, 90 kHash_XXH64,
91 kHash_MD5,
91 kHash_SHA1, 92 kHash_SHA1,
92 kHash_SHA256, 93 kHash_SHA256,
94 kHash_SHA384,
95 kHash_SHA512,
96 kHash_SHA3_256,
93 kHash_BLAKE2SP, 97 kHash_BLAKE2SP,
94 kHash_All, 98 kHash_All,
95 kHash_Generate_SHA256, 99 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(
116 // DWORD m_StartTickValue; 116 // DWORD m_StartTickValue;
117 bool m_MessageBoxIsShown; 117 bool m_MessageBoxIsShown;
118 118
119 CProgressBox _progressBox;
120
121 bool _numFilesTotalDefined; 119 bool _numFilesTotalDefined;
122 bool _numBytesTotalDefined; 120 bool _numBytesTotalDefined;
123
124public: 121public:
125 bool PasswordIsDefined; 122 bool PasswordIsDefined;
126 UString Password; 123 UString Password;
127 124
125private:
126 CProgressBox _progressBox;
127public:
128
128 COpenArchiveCallback() 129 COpenArchiveCallback()
129 {} 130 {}
130 131
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,
281 return valueDefault; 281 return valueDefault;
282 282
283 UInt32 value; 283 UInt32 value;
284 if (regKey.QueryValue(valueName, value) != ERROR_SUCCESS) 284 if (regKey.GetValue_UInt32_IfOk(valueName, value) != ERROR_SUCCESS)
285 return valueDefault; 285 return valueDefault;
286 286
287 return value; 287 return value;
@@ -295,7 +295,7 @@ bool CStartupInfo::QueryRegKeyValue(HKEY parentKey, const char *keyName,
295 return valueDefault; 295 return valueDefault;
296 296
297 bool value; 297 bool value;
298 if (regKey.QueryValue(valueName, value) != ERROR_SUCCESS) 298 if (regKey.GetValue_bool_IfOk(valueName, value) != ERROR_SUCCESS)
299 return valueDefault; 299 return valueDefault;
300 300
301 return value; 301 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
45 DWORD _prevElapsedSec; 45 DWORD _prevElapsedSec;
46 46
47 bool _wasPrinted; 47 bool _wasPrinted;
48public:
49 bool UseBytesForPercents;
50 DWORD StartTick;
51 unsigned MaxLen;
48 52
53private:
49 UString _tempU; 54 UString _tempU;
50 UString _name1U; 55 UString _name1U;
51 UString _name2U; 56 UString _name2U;
@@ -64,15 +69,12 @@ class CProgressBox: public CPercentPrinterState
64 void ReduceString(const UString &src, AString &dest); 69 void ReduceString(const UString &src, AString &dest);
65 70
66public: 71public:
67 DWORD StartTick;
68 bool UseBytesForPercents;
69 unsigned MaxLen;
70 72
71 CProgressBox(UInt32 tickStep = 200): 73 CProgressBox(UInt32 tickStep = 200):
72 _tickStep(tickStep), 74 _tickStep(tickStep),
73 _prevTick(0), 75 _prevTick(0),
74 StartTick(0),
75 UseBytesForPercents(true), 76 UseBytesForPercents(true),
77 StartTick(0),
76 MaxLen(60) 78 MaxLen(60)
77 {} 79 {}
78 80
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
210} 210}
211 211
212 212
213HRESULT CUpdateCallback100Imp::MoveArc_UpdateStatus()
214{
215 MT_LOCK
216
217 if (_percent)
218 {
219 AString s;
220 s.Add_UInt64(_arcMoving_percents);
221 // status.Add_Space();
222 s.Add_Char('%');
223 const bool totalDefined = (_arcMoving_total != 0 && _arcMoving_total != (UInt64)(Int64)-1);
224 if (_arcMoving_current != 0 || totalDefined)
225 {
226 s += " : ";
227 s.Add_UInt64(_arcMoving_current >> 20);
228 s += " MiB";
229 }
230 if (totalDefined)
231 {
232 s += " / ";
233 s.Add_UInt64((_arcMoving_total + ((1 << 20) - 1)) >> 20);
234 s += " MiB";
235 }
236 s += " : temporary archive moving ...";
237 _percent->Command = s;
238 _percent->Print();
239 }
240
241 return CheckBreak2();
242}
243
244
245Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Start(const wchar_t *srcTempPath, const wchar_t * /* destFinalPath */ , UInt64 size, Int32 /* updateMode */))
246{
247 MT_LOCK
248
249 _arcMoving_total = size;
250 _arcMoving_current = 0;
251 _arcMoving_percents = 0;
252 // _arcMoving_updateMode = updateMode;
253 // _name2 = fs2us(destFinalPath);
254 if (_percent)
255 _percent->FileName = srcTempPath;
256 return MoveArc_UpdateStatus();
257}
258
259Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Progress(UInt64 totalSize, UInt64 currentSize))
260{
261 UInt64 percents = 0;
262 if (totalSize != 0)
263 {
264 if (totalSize < ((UInt64)1 << 57))
265 percents = currentSize * 100 / totalSize;
266 else
267 percents = currentSize / (totalSize / 100);
268 }
269
270#ifdef _WIN32
271 // Sleep(300); // for debug
272#endif
273 if (percents == _arcMoving_percents)
274 return CheckBreak2();
275 _arcMoving_total = totalSize;
276 _arcMoving_current = currentSize;
277 _arcMoving_percents = percents;
278 // if (_arcMoving_percents > 100) return E_FAIL;
279 return MoveArc_UpdateStatus();
280}
281
282
283Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Finish())
284{
285 // _arcMoving_percents = 0;
286 if (_percent)
287 {
288 _percent->Command.Empty();
289 _percent->FileName.Empty();
290 _percent->Print();
291 }
292 return CheckBreak2();
293}
294
295
296Z7_COM7F_IMF(CUpdateCallback100Imp::Before_ArcReopen())
297{
298 // fixme: we can use Clear_Stop_Status() here
299 return CheckBreak2();
300}
301
302
213extern HRESULT GetPassword(UString &password); 303extern HRESULT GetPassword(UString &password);
214 304
215Z7_COM7F_IMF(CUpdateCallback100Imp::CryptoGetTextPassword(BSTR *password)) 305Z7_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 @@
11 11
12#include "ProgressBox.h" 12#include "ProgressBox.h"
13 13
14Z7_CLASS_IMP_COM_6( 14Z7_CLASS_IMP_COM_7(
15 CUpdateCallback100Imp 15 CUpdateCallback100Imp
16 , IFolderArchiveUpdateCallback 16 , IFolderArchiveUpdateCallback
17 , IFolderArchiveUpdateCallback2 17 , IFolderArchiveUpdateCallback2
18 , IFolderArchiveUpdateCallback_MoveArc
18 , IFolderScanProgress 19 , IFolderScanProgress
19 , ICryptoGetTextPassword2 20 , ICryptoGetTextPassword2
20 , ICryptoGetTextPassword 21 , ICryptoGetTextPassword
@@ -25,6 +26,15 @@ Z7_CLASS_IMP_COM_6(
25 // CMyComPtr<IInFolderArchive> _archiveHandler; 26 // CMyComPtr<IInFolderArchive> _archiveHandler;
26 CProgressBox *_percent; 27 CProgressBox *_percent;
27 // UInt64 _total; 28 // UInt64 _total;
29
30 HRESULT MoveArc_UpdateStatus();
31
32private:
33 UInt64 _arcMoving_total;
34 UInt64 _arcMoving_current;
35 UInt64 _arcMoving_percents;
36 // Int32 _arcMoving_updateMode;
37
28public: 38public:
29 bool PasswordIsDefined; 39 bool PasswordIsDefined;
30 UString Password; 40 UString Password;
@@ -38,6 +48,10 @@ public:
38 _percent = progressBox; 48 _percent = progressBox;
39 PasswordIsDefined = false; 49 PasswordIsDefined = false;
40 Password.Empty(); 50 Password.Empty();
51 _arcMoving_total = 0;
52 _arcMoving_current = 0;
53 _arcMoving_percents = 0;
54 // _arcMoving_updateMode = 0;
41 } 55 }
42}; 56};
43 57
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()
402 // Save_ShowDeleted(ShowDeletedFiles); 402 // Save_ShowDeleted(ShowDeletedFiles);
403} 403}
404 404
405void CApp::Release() 405void CApp::ReleaseApp()
406{ 406{
407 // 24.09: ReleasePanel() will stop panel timer processing.
408 // but we want to stop timer processing for all panels
409 // before ReleasePanel() calling.
410 unsigned i;
411 for (i = 0; i < kNumPanelsMax; i++)
412 Panels[i].Disable_Processing_Timer_Notify_StatusBar();
407 // It's for unloading COM dll's: don't change it. 413 // It's for unloading COM dll's: don't change it.
408 for (unsigned i = 0; i < kNumPanelsMax; i++) 414 for (i = 0; i < kNumPanelsMax; i++)
409 Panels[i].Release(); 415 Panels[i].ReleasePanel();
410} 416}
411 417
412// reduces path to part that exists on disk (or root prefix of path) 418// 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)
644 destPath += correctName; 650 destPath += correctName;
645 651
646 #if defined(_WIN32) && !defined(UNDER_CE) 652 #if defined(_WIN32) && !defined(UNDER_CE)
647 if (destPath.Len() > 0 && destPath[0] == '\\') 653 if (destPath.Len() != 0 && destPath[0] == '\\')
648 if (destPath.Len() == 1 || destPath[1] != '\\') 654 if (destPath.Len() == 1 || destPath[1] != '\\')
649 { 655 {
650 srcPanel.MessageBox_Error_UnsupportOperation(); 656 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:
109 HRESULT Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool needOpenArc, COpenResult &openRes); 109 HRESULT Create(HWND hwnd, const UString &mainPath, const UString &arcFormat, int xSizes[2], bool needOpenArc, COpenResult &openRes);
110 void Read(); 110 void Read();
111 void Save(); 111 void Save();
112 void Release(); 112 void ReleaseApp();
113 113
114 // void SetFocus(int panelIndex) { Panels[panelIndex].SetFocusToList(); } 114 // void SetFocus(int panelIndex) { Panels[panelIndex].SetFocusToList(); }
115 void SetFocusToLastItem() { Panels[LastFocusedPanel].SetFocusToLastRememberedItem(); } 115 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 @@
2 2
3#include "StdAfx.h" 3#include "StdAfx.h"
4 4
5
6#include "../../../Common/ComTry.h" 5#include "../../../Common/ComTry.h"
7#include "../../../Common/IntToString.h" 6#include "../../../Common/IntToString.h"
8#include "../../../Common/Lang.h" 7#include "../../../Common/Lang.h"
@@ -27,11 +26,11 @@
27#include "ExtractCallback.h" 26#include "ExtractCallback.h"
28#include "FormatUtils.h" 27#include "FormatUtils.h"
29#include "LangUtils.h" 28#include "LangUtils.h"
29#include "MemDialog.h"
30#include "OverwriteDialog.h" 30#include "OverwriteDialog.h"
31#ifndef Z7_NO_CRYPTO 31#ifndef Z7_NO_CRYPTO
32#include "PasswordDialog.h" 32#include "PasswordDialog.h"
33#endif 33#endif
34#include "MemDialog.h"
35#include "PropertyName.h" 34#include "PropertyName.h"
36 35
37using namespace NWindows; 36using namespace NWindows;
@@ -44,9 +43,9 @@ CExtractCallbackImp::~CExtractCallbackImp() {}
44 43
45void CExtractCallbackImp::Init() 44void CExtractCallbackImp::Init()
46{ 45{
47 _lang_Extracting = LangString(IDS_PROGRESS_EXTRACTING); 46 LangString(IDS_PROGRESS_EXTRACTING, _lang_Extracting);
48 _lang_Testing = LangString(IDS_PROGRESS_TESTING); 47 LangString(IDS_PROGRESS_TESTING, _lang_Testing);
49 _lang_Skipping = LangString(IDS_PROGRESS_SKIPPING); 48 LangString(IDS_PROGRESS_SKIPPING, _lang_Skipping);
50 _lang_Reading = "Reading"; 49 _lang_Reading = "Reading";
51 50
52 NumArchiveErrors = 0; 51 NumArchiveErrors = 0;
@@ -107,19 +106,19 @@ HRESULT CExtractCallbackImp::Open_SetTotal(const UInt64 *files, const UInt64 *by
107 { 106 {
108 if (files) 107 if (files)
109 { 108 {
110 _totalFilesDefined = true; 109 _totalFiles_Defined = true;
111 // res = ProgressDialog->Sync.Set_NumFilesTotal(*files); 110 // res = ProgressDialog->Sync.Set_NumFilesTotal(*files);
112 } 111 }
113 else 112 else
114 _totalFilesDefined = false; 113 _totalFiles_Defined = false;
115 114
116 if (bytes) 115 if (bytes)
117 { 116 {
118 _totalBytesDefined = true; 117 _totalBytes_Defined = true;
119 ProgressDialog->Sync.Set_NumBytesTotal(*bytes); 118 ProgressDialog->Sync.Set_NumBytesTotal(*bytes);
120 } 119 }
121 else 120 else
122 _totalBytesDefined = false; 121 _totalBytes_Defined = false;
123 } 122 }
124 123
125 return res; 124 return res;
@@ -217,7 +216,7 @@ Z7_COM7F_IMF(CExtractCallbackImp::AskOverwrite(
217 dialog.NewFileInfo.Is_FileSystemFile = Src_Is_IO_FS_Folder; 216 dialog.NewFileInfo.Is_FileSystemFile = Src_Is_IO_FS_Folder;
218 217
219 ProgressDialog->WaitCreating(); 218 ProgressDialog->WaitCreating();
220 INT_PTR writeAnswer = dialog.Create(*ProgressDialog); 219 const INT_PTR writeAnswer = dialog.Create(*ProgressDialog);
221 220
222 switch (writeAnswer) 221 switch (writeAnswer)
223 { 222 {
@@ -478,10 +477,10 @@ UString GetOpenArcErrorMessage(UInt32 errorFlags)
478 477
479 for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_ErrorFlagsIds); i++) 478 for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_ErrorFlagsIds); i++)
480 { 479 {
481 UInt32 f = ((UInt32)1 << i); 480 const UInt32 f = (UInt32)1 << i;
482 if ((errorFlags & f) == 0) 481 if ((errorFlags & f) == 0)
483 continue; 482 continue;
484 UInt32 id = k_ErrorFlagsIds[i]; 483 const UInt32 id = k_ErrorFlagsIds[i];
485 UString m = LangString(id); 484 UString m = LangString(id);
486 if (m.IsEmpty()) 485 if (m.IsEmpty())
487 continue; 486 continue;
@@ -512,8 +511,8 @@ UString GetOpenArcErrorMessage(UInt32 errorFlags)
512 511
513static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er) 512static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er)
514{ 513{
515 UInt32 errorFlags = er.GetErrorFlags(); 514 const UInt32 errorFlags = er.GetErrorFlags();
516 UInt32 warningFlags = er.GetWarningFlags(); 515 const UInt32 warningFlags = er.GetWarningFlags();
517 516
518 if (errorFlags != 0) 517 if (errorFlags != 0)
519 AddNewLineString(s, GetOpenArcErrorMessage(errorFlags)); 518 AddNewLineString(s, GetOpenArcErrorMessage(errorFlags));
@@ -524,7 +523,7 @@ static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er)
524 if (warningFlags != 0) 523 if (warningFlags != 0)
525 { 524 {
526 s += GetNameOfProperty(kpidWarningFlags, L"Warnings"); 525 s += GetNameOfProperty(kpidWarningFlags, L"Warnings");
527 s += ":"; 526 s.Add_Colon();
528 s.Add_LF(); 527 s.Add_LF();
529 AddNewLineString(s, GetOpenArcErrorMessage(warningFlags)); 528 AddNewLineString(s, GetOpenArcErrorMessage(warningFlags));
530 } 529 }
@@ -852,34 +851,35 @@ Z7_COM7F_IMF(CExtractCallbackImp::GetStream7(const wchar_t *name,
852 _newVirtFileWasAdded = false; 851 _newVirtFileWasAdded = false;
853 _hashStream_WasUsed = false; 852 _hashStream_WasUsed = false;
854 _needUpdateStat = false; 853 _needUpdateStat = false;
854 _isFolder = IntToBool(isDir);
855 _curSize_Defined = false;
856 _curSize = 0;
855 857
856 if (_hashStream) 858 if (_hashStream)
857 _hashStream->ReleaseStream(); 859 _hashStream->ReleaseStream();
858 860
859 GetItemBoolProp(getProp, kpidIsAltStream, _isAltStream);
860
861 if (!ProcessAltStreams && _isAltStream)
862 return S_OK;
863
864 _filePath = name; 861 _filePath = name;
865 _isFolder = IntToBool(isDir);
866 _curSize = 0;
867 _curSize_Defined = false;
868 862
869 UInt64 size = 0; 863 UInt64 size = 0;
870 bool sizeDefined; 864 bool size_Defined;
871 { 865 {
872 NCOM::CPropVariant prop; 866 NCOM::CPropVariant prop;
873 RINOK(getProp->GetProp(kpidSize, &prop)) 867 RINOK(getProp->GetProp(kpidSize, &prop))
874 sizeDefined = ConvertPropVariantToUInt64(prop, size); 868 size_Defined = ConvertPropVariantToUInt64(prop, size);
875 } 869 }
876 870 if (size_Defined)
877 if (sizeDefined)
878 { 871 {
879 _curSize = size; 872 _curSize = size;
880 _curSize_Defined = true; 873 _curSize_Defined = true;
881 } 874 }
882 875
876 GetItemBoolProp(getProp, kpidIsAltStream, _isAltStream);
877 if (!ProcessAltStreams && _isAltStream)
878 return S_OK;
879
880 if (isDir) // we don't support dir items extraction in this code
881 return S_OK;
882
883 if (askExtractMode != NArchive::NExtract::NAskMode::kExtract && 883 if (askExtractMode != NArchive::NExtract::NAskMode::kExtract &&
884 askExtractMode != NArchive::NExtract::NAskMode::kTest) 884 askExtractMode != NArchive::NExtract::NAskMode::kTest)
885 return S_OK; 885 return S_OK;
@@ -890,40 +890,64 @@ Z7_COM7F_IMF(CExtractCallbackImp::GetStream7(const wchar_t *name,
890 890
891 if (VirtFileSystem && askExtractMode == NArchive::NExtract::NAskMode::kExtract) 891 if (VirtFileSystem && askExtractMode == NArchive::NExtract::NAskMode::kExtract)
892 { 892 {
893 CVirtFile &file = VirtFileSystemSpec->AddNewFile(); 893 if (!VirtFileSystemSpec->Files.IsEmpty())
894 VirtFileSystemSpec->MaxTotalAllocSize -= VirtFileSystemSpec->Files.Back().Data.Size();
895 CVirtFile &file = VirtFileSystemSpec->Files.AddNew();
894 _newVirtFileWasAdded = true; 896 _newVirtFileWasAdded = true;
895 file.Name = name; 897 // file.IsDir = _isFolder;
896 file.IsDir = IntToBool(isDir);
897 file.IsAltStream = _isAltStream; 898 file.IsAltStream = _isAltStream;
898 file.Size = 0; 899 file.WrittenSize = 0;
900 file.ExpectedSize = 0;
901 if (size_Defined)
902 file.ExpectedSize = size;
899 903
900 RINOK(GetTime(getProp, kpidCTime, file.CTime, file.CTimeDefined)) 904 if (VirtFileSystemSpec->Index_of_MainExtractedFile_in_Files < 0)
901 RINOK(GetTime(getProp, kpidATime, file.ATime, file.ATimeDefined)) 905 if (!file.IsAltStream || VirtFileSystemSpec->IsAltStreamFile)
902 RINOK(GetTime(getProp, kpidMTime, file.MTime, file.MTimeDefined)) 906 VirtFileSystemSpec->Index_of_MainExtractedFile_in_Files =
907 (int)(VirtFileSystemSpec->Files.Size() - 1);
903 908
904 NCOM::CPropVariant prop; 909 /* if we open only AltStream, then (name) contains only name without "fileName:" prefix */
905 RINOK(getProp->GetProp(kpidAttrib, &prop)) 910 file.BaseName = name;
906 if (prop.vt == VT_UI4) 911
912 if (file.IsAltStream
913 && !VirtFileSystemSpec->IsAltStreamFile
914 && file.BaseName.IsPrefixedBy_NoCase(VirtFileSystemSpec->FileName))
907 { 915 {
908 file.Attrib = prop.ulVal; 916 const unsigned colonPos = VirtFileSystemSpec->FileName.Len();
909 file.AttribDefined = true; 917 if (file.BaseName[colonPos] == ':')
918 {
919 file.ColonWasUsed = true;
920 file.AltStreamName = name + (size_t)colonPos + 1;
921 file.BaseName.DeleteFrom(colonPos);
922 if (Is_ZoneId_StreamName(file.AltStreamName))
923 {
924 if (VirtFileSystemSpec->Index_of_ZoneBuf_AltStream_in_Files < 0)
925 VirtFileSystemSpec->Index_of_ZoneBuf_AltStream_in_Files =
926 (int)(VirtFileSystemSpec->Files.Size() - 1);
927 }
928 }
929 }
930 RINOK(GetTime(getProp, kpidCTime, file.CTime, file.CTime_Defined))
931 RINOK(GetTime(getProp, kpidATime, file.ATime, file.ATime_Defined))
932 RINOK(GetTime(getProp, kpidMTime, file.MTime, file.MTime_Defined))
933 {
934 NCOM::CPropVariant prop;
935 RINOK(getProp->GetProp(kpidAttrib, &prop))
936 if (prop.vt == VT_UI4)
937 {
938 file.Attrib = prop.ulVal;
939 file.Attrib_Defined = true;
940 }
910 } 941 }
911 // else if (isDir) file.Attrib = FILE_ATTRIBUTE_DIRECTORY;
912
913 file.ExpectedSize = 0;
914 if (sizeDefined)
915 file.ExpectedSize = size;
916 outStreamLoc = VirtFileSystem; 942 outStreamLoc = VirtFileSystem;
917 } 943 }
918 944
919 if (_hashStream) 945 if (_hashStream)
920 { 946 {
921 { 947 _hashStream->SetStream(outStreamLoc);
922 _hashStream->SetStream(outStreamLoc); 948 outStreamLoc = _hashStream;
923 outStreamLoc = _hashStream; 949 _hashStream->Init(true);
924 _hashStream->Init(true); 950 _hashStream_WasUsed = true;
925 _hashStream_WasUsed = true;
926 }
927 } 951 }
928 952
929 if (outStreamLoc) 953 if (outStreamLoc)
@@ -1077,10 +1101,10 @@ Z7_COM7F_IMF(CExtractCallbackImp::RequestMemoryUse(
1077 // if (indexType == NArchive::NEventIndexType::kNoIndex) 1101 // if (indexType == NArchive::NEventIndexType::kNoIndex)
1078 if ((flags & NRequestMemoryUseFlags::k_SkipArc_IsExpected) || 1102 if ((flags & NRequestMemoryUseFlags::k_SkipArc_IsExpected) ||
1079 (flags & NRequestMemoryUseFlags::k_Report_SkipArc)) 1103 (flags & NRequestMemoryUseFlags::k_Report_SkipArc))
1080 s += LangString(IDS_MSG_ARC_UNPACKING_WAS_SKIPPED); 1104 AddLangString(s, IDS_MSG_ARC_UNPACKING_WAS_SKIPPED);
1081/* 1105/*
1082 else 1106 else
1083 s += LangString(IDS_MSG_ARC_FILES_UNPACKING_WAS_SKIPPED); 1107 AddLangString(, IDS_MSG_ARC_FILES_UNPACKING_WAS_SKIPPED);
1084*/ 1108*/
1085 AddError_Message_ShowArcPath(s); 1109 AddError_Message_ShowArcPath(s);
1086 } 1110 }
@@ -1093,88 +1117,154 @@ Z7_COM7F_IMF(CExtractCallbackImp::RequestMemoryUse(
1093} 1117}
1094 1118
1095 1119
1096
1097// static const UInt32 kBlockSize = ((UInt32)1 << 31);
1098
1099Z7_COM7F_IMF(CVirtFileSystem::Write(const void *data, UInt32 size, UInt32 *processedSize)) 1120Z7_COM7F_IMF(CVirtFileSystem::Write(const void *data, UInt32 size, UInt32 *processedSize))
1100{ 1121{
1101 if (processedSize) 1122 if (processedSize)
1102 *processedSize = 0; 1123 *processedSize = 0;
1103 if (size == 0) 1124 if (size == 0)
1104 return S_OK; 1125 return S_OK;
1105 if (!_fileMode) 1126 if (!_wasSwitchedToFsMode)
1106 { 1127 {
1107 CVirtFile &file = Files.Back(); 1128 CVirtFile &file = Files.Back();
1108 size_t rem = file.Data.Size() - (size_t)file.Size; 1129 const size_t rem = file.Data.Size() - file.WrittenSize;
1109 bool useMem = true; 1130 bool useMem = true;
1110 if (rem < size) 1131 if (rem < size)
1111 { 1132 {
1112 UInt64 b = 0; 1133 UInt64 b = 0;
1113 if (file.Data.Size() == 0) 1134 if (file.Data.Size() == 0)
1114 b = file.ExpectedSize; 1135 b = file.ExpectedSize;
1115 UInt64 a = file.Size + size; 1136 UInt64 a = (UInt64)file.WrittenSize + size;
1116 if (b < a) 1137 if (b < a)
1117 b = a; 1138 b = a;
1118 a = (UInt64)file.Data.Size() * 2; 1139 a = (UInt64)file.Data.Size() * 2;
1119 if (b < a) 1140 if (b < a)
1120 b = a; 1141 b = a;
1121 useMem = false; 1142 useMem = false;
1122 const size_t b_sizet = (size_t)b; 1143 if (b <= MaxTotalAllocSize)
1123 if (b == b_sizet && b <= MaxTotalAllocSize) 1144 useMem = file.Data.ReAlloc_KeepData((size_t)b, file.WrittenSize);
1124 useMem = file.Data.ReAlloc_KeepData(b_sizet, (size_t)file.Size);
1125 } 1145 }
1146
1147#if 0 // 1 for debug : FLUSHING TO FS
1148 useMem = false;
1149#endif
1150
1126 if (useMem) 1151 if (useMem)
1127 { 1152 {
1128 memcpy(file.Data + file.Size, data, size); 1153 memcpy(file.Data + file.WrittenSize, data, size);
1129 file.Size += size; 1154 file.WrittenSize += size;
1130 if (processedSize) 1155 if (processedSize)
1131 *processedSize = (UInt32)size; 1156 *processedSize = (UInt32)size;
1132 return S_OK; 1157 return S_OK;
1133 } 1158 }
1134 _fileMode = true; 1159 _wasSwitchedToFsMode = true;
1160 }
1161
1162 if (!_newVirtFileStream_IsReadyToWrite) // we check for _newVirtFileStream_IsReadyToWrite to optimize execution
1163 {
1164 RINOK(FlushToDisk(false))
1135 } 1165 }
1136 RINOK(FlushToDisk(false)) 1166
1137 return _outFileStream.Interface()->Write(data, size, processedSize); 1167 if (_needWriteToRealFile)
1168 return _outFileStream.Interface()->Write(data, size, processedSize);
1169 if (processedSize)
1170 *processedSize = size;
1171 return S_OK;
1138} 1172}
1139 1173
1140 1174
1141HRESULT CVirtFileSystem::FlushToDisk(bool closeLast) 1175HRESULT CVirtFileSystem::FlushToDisk(bool closeLast)
1142{ 1176{
1143 _outFileStream.Create_if_Empty();
1144 while (_numFlushed < Files.Size()) 1177 while (_numFlushed < Files.Size())
1145 { 1178 {
1146 const CVirtFile &file = Files[_numFlushed]; 1179 CVirtFile &file = Files[_numFlushed];
1147 const FString path = DirPrefix + us2fs(Get_Correct_FsFile_Name(file.Name)); 1180 const FString basePath = DirPrefix + us2fs(Get_Correct_FsFile_Name(file.BaseName));
1148 if (!_fileIsOpen) 1181 FString path = basePath;
1182
1183 if (file.ColonWasUsed)
1149 { 1184 {
1150 if (!_outFileStream->Create_NEW(path)) 1185 if (ZoneBuf.Size() != 0
1186 && Is_ZoneId_StreamName(file.AltStreamName))
1151 { 1187 {
1152 // do we need to release stream here? 1188 // it's expected that
1153 // _outFileStream.Release(); 1189 // CArchiveExtractCallback::GetStream() have excluded
1154 return E_FAIL; 1190 // ZoneId alt stream from extraction already.
1155 // MessageBoxMyError(UString("Can't create file ") + fs2us(tempFilePath)); 1191 // But we exclude alt stream extraction here too.
1192 _numFlushed++;
1193 continue;
1156 } 1194 }
1157 _fileIsOpen = true; 1195 path.Add_Colon();
1158 RINOK(WriteStream(_outFileStream, file.Data, (size_t)file.Size)) 1196 path += us2fs(Get_Correct_FsFile_Name(file.AltStreamName));
1159 } 1197 }
1198
1199 if (!_newVirtFileStream_IsReadyToWrite)
1200 {
1201 if (file.ColonWasUsed)
1202 {
1203 NFind::CFileInfo parentFi;
1204 if (parentFi.Find(basePath)
1205 && parentFi.IsReadOnly())
1206 {
1207 _altStream_NeedRestore_Attrib_bool = true;
1208 _altStream_NeedRestore_AttribVal = parentFi.Attrib;
1209 NDir::SetFileAttrib(basePath, parentFi.Attrib & ~(DWORD)FILE_ATTRIBUTE_READONLY);
1210 }
1211 }
1212 _outFileStream.Create_if_Empty();
1213 _needWriteToRealFile = _outFileStream->Create_NEW(path);
1214 if (!_needWriteToRealFile)
1215 {
1216 if (!file.ColonWasUsed)
1217 return GetLastError_noZero_HRESULT(); // it's main file and we can't ignore such error.
1218 // (file.ColonWasUsed == true)
1219 // So it's additional alt stream.
1220 // And we ignore file creation error for additional alt stream.
1221 // ShowErrorMessage(UString("Can't create file ") + fs2us(path));
1222 }
1223 _newVirtFileStream_IsReadyToWrite = true;
1224 // _openFilePath = path;
1225 HRESULT hres = S_OK;
1226 if (_needWriteToRealFile)
1227 hres = WriteStream(_outFileStream, file.Data, file.WrittenSize);
1228 // we free allocated memory buffer after data flushing:
1229 file.WrittenSize = 0;
1230 file.Data.Free();
1231 RINOK(hres)
1232 }
1233
1160 if (_numFlushed == Files.Size() - 1 && !closeLast) 1234 if (_numFlushed == Files.Size() - 1 && !closeLast)
1161 break; 1235 break;
1162 if (file.CTimeDefined || 1236
1163 file.ATimeDefined || 1237 if (_needWriteToRealFile)
1164 file.MTimeDefined) 1238 {
1165 _outFileStream->SetTime( 1239 if (file.CTime_Defined ||
1166 file.CTimeDefined ? &file.CTime : NULL, 1240 file.ATime_Defined ||
1167 file.ATimeDefined ? &file.ATime : NULL, 1241 file.MTime_Defined)
1168 file.MTimeDefined ? &file.MTime : NULL); 1242 _outFileStream->SetTime(
1169 _outFileStream->Close(); 1243 file.CTime_Defined ? &file.CTime : NULL,
1244 file.ATime_Defined ? &file.ATime : NULL,
1245 file.MTime_Defined ? &file.MTime : NULL);
1246 _outFileStream->Close();
1247 }
1248
1170 _numFlushed++; 1249 _numFlushed++;
1171 _fileIsOpen = false; 1250 _newVirtFileStream_IsReadyToWrite = false;
1172 1251
1173 if (ZoneBuf.Size() != 0) 1252 if (_needWriteToRealFile)
1174 WriteZoneFile_To_BaseFile(path, ZoneBuf); 1253 {
1175 1254 if (!file.ColonWasUsed
1176 if (file.AttribDefined) 1255 && ZoneBuf.Size() != 0)
1177 NDir::SetFileAttrib_PosixHighDetect(path, file.Attrib); 1256 WriteZoneFile_To_BaseFile(path, ZoneBuf);
1257 if (file.Attrib_Defined)
1258 NDir::SetFileAttrib_PosixHighDetect(path, file.Attrib);
1259 // _openFilePath.Empty();
1260 _needWriteToRealFile = false;
1261 }
1262
1263 if (_altStream_NeedRestore_Attrib_bool)
1264 {
1265 _altStream_NeedRestore_Attrib_bool = false;
1266 NDir::SetFileAttrib(basePath, _altStream_NeedRestore_AttribVal);
1267 }
1178 } 1268 }
1179 return S_OK; 1269 return S_OK;
1180} 1270}
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 @@
25 25
26#include "ProgressDialog2.h" 26#include "ProgressDialog2.h"
27 27
28#ifdef Z7_LANG
29// #include "LangUtils.h"
30#endif
31
32#ifndef Z7_SFX 28#ifndef Z7_SFX
33 29
34class CGrowBuf 30class CGrowBuf
@@ -39,12 +35,24 @@ class CGrowBuf
39 Z7_CLASS_NO_COPY(CGrowBuf) 35 Z7_CLASS_NO_COPY(CGrowBuf)
40 36
41public: 37public:
38 void Free()
39 {
40 MyFree(_items);
41 _items = NULL;
42 _size = 0;
43 }
44
45 // newSize >= keepSize
42 bool ReAlloc_KeepData(size_t newSize, size_t keepSize) 46 bool ReAlloc_KeepData(size_t newSize, size_t keepSize)
43 { 47 {
44 void *buf = MyAlloc(newSize); 48 void *buf = NULL;
45 if (!buf) 49 if (newSize)
46 return false; 50 {
47 if (keepSize != 0) 51 buf = MyAlloc(newSize);
52 if (!buf)
53 return false;
54 }
55 if (keepSize)
48 memcpy(buf, _items, keepSize); 56 memcpy(buf, _items, keepSize);
49 MyFree(_items); 57 MyFree(_items);
50 _items = (Byte *)buf; 58 _items = (Byte *)buf;
@@ -60,23 +68,27 @@ public:
60 size_t Size() const { return _size; } 68 size_t Size() const { return _size; }
61}; 69};
62 70
71
63struct CVirtFile 72struct CVirtFile
64{ 73{
65 CGrowBuf Data; 74 CGrowBuf Data;
66 75
67 UInt64 Size; // real size 76 UInt64 ExpectedSize; // size from props request. 0 if unknown
68 UInt64 ExpectedSize; // the size from props request. 0 if unknown 77 size_t WrittenSize; // size of written data in (Data) buffer
69 78 // use (WrittenSize) only if (CVirtFileSystem::_newVirtFileStream_IsReadyToWrite == false)
70 UString Name; 79 UString BaseName; // original name of file inside archive,
71 80 // It's not path. So any path separators
72 bool CTimeDefined; 81 // should be treated as part of name (or as incorrect chars)
73 bool ATimeDefined; 82 UString AltStreamName;
74 bool MTimeDefined; 83
75 bool AttribDefined; 84 bool CTime_Defined;
85 bool ATime_Defined;
86 bool MTime_Defined;
87 bool Attrib_Defined;
76 88
77 bool IsDir; 89 // bool IsDir;
78 bool IsAltStream; 90 bool IsAltStream;
79 91 bool ColonWasUsed;
80 DWORD Attrib; 92 DWORD Attrib;
81 93
82 FILETIME CTime; 94 FILETIME CTime;
@@ -84,82 +96,82 @@ struct CVirtFile
84 FILETIME MTime; 96 FILETIME MTime;
85 97
86 CVirtFile(): 98 CVirtFile():
87 CTimeDefined(false), 99 CTime_Defined(false),
88 ATimeDefined(false), 100 ATime_Defined(false),
89 MTimeDefined(false), 101 MTime_Defined(false),
90 AttribDefined(false), 102 Attrib_Defined(false),
91 IsDir(false), 103 // IsDir(false),
92 IsAltStream(false) {} 104 IsAltStream(false),
105 ColonWasUsed(false)
106 {}
93}; 107};
94 108
95 109
110/*
111 We use CVirtFileSystem only for single file extraction:
112 It supports the following cases and names:
113 - "fileName" : single file
114 - "fileName" item (main base file) and additional "fileName:altStream" items
115 - "altStream" : single item without "fileName:" prefix.
116 If file is flushed to disk, it uses Get_Correct_FsFile_Name(name).
117*/
118
96Z7_CLASS_IMP_NOQIB_1( 119Z7_CLASS_IMP_NOQIB_1(
97 CVirtFileSystem, 120 CVirtFileSystem,
98 ISequentialOutStream 121 ISequentialOutStream
99) 122)
100 UInt64 _totalAllocSize;
101
102 size_t _pos;
103 unsigned _numFlushed; 123 unsigned _numFlushed;
104 bool _fileIsOpen; 124public:
105 bool _fileMode; 125 bool IsAltStreamFile; // in:
126 // = true, if extracting file is alt stream without "fileName:" prefix.
127 // = false, if extracting file is normal file, but additional
128 // alt streams "fileName:altStream" items are possible.
129private:
130 bool _newVirtFileStream_IsReadyToWrite; // it can non real file (if can't open alt stream)
131 bool _needWriteToRealFile; // we need real writing to open file.
132 bool _wasSwitchedToFsMode;
133 bool _altStream_NeedRestore_Attrib_bool;
134 DWORD _altStream_NeedRestore_AttribVal;
135
106 CMyComPtr2<ISequentialOutStream, COutFileStream> _outFileStream; 136 CMyComPtr2<ISequentialOutStream, COutFileStream> _outFileStream;
107public: 137public:
108 CObjectVector<CVirtFile> Files; 138 CObjectVector<CVirtFile> Files;
109 UInt64 MaxTotalAllocSize; 139 size_t MaxTotalAllocSize; // remain size, including Files.Back()
110 FString DirPrefix; 140 FString DirPrefix; // files will be flushed to this FS directory.
141 UString FileName; // name of file that will be extracted.
142 // it can be name of alt stream without "fileName:" prefix, if (IsAltStreamFile == trye).
143 // we use that name to detect altStream part in "FileName:altStream".
111 CByteBuffer ZoneBuf; 144 CByteBuffer ZoneBuf;
145 int Index_of_MainExtractedFile_in_Files; // out: index in Files. == -1, if expected file was not extracted
146 int Index_of_ZoneBuf_AltStream_in_Files; // out: index in Files. == -1, if no zonbuf alt stream
147
112 148
113 149 CVirtFileSystem()
114 CVirtFile &AddNewFile()
115 { 150 {
116 if (!Files.IsEmpty()) 151 _numFlushed = 0;
117 { 152 IsAltStreamFile = false;
118 MaxTotalAllocSize -= Files.Back().Data.Size(); 153 _newVirtFileStream_IsReadyToWrite = false;
119 } 154 _needWriteToRealFile = false;
120 return Files.AddNew(); 155 _wasSwitchedToFsMode = false;
156 _altStream_NeedRestore_Attrib_bool = false;
157 MaxTotalAllocSize = (size_t)0 - 1;
158 Index_of_MainExtractedFile_in_Files = -1;
159 Index_of_ZoneBuf_AltStream_in_Files = -1;
121 } 160 }
161
162 bool WasStreamFlushedToFS() const { return _wasSwitchedToFsMode; }
163
122 HRESULT CloseMemFile() 164 HRESULT CloseMemFile()
123 { 165 {
124 if (_fileMode) 166 if (_wasSwitchedToFsMode)
125 { 167 return FlushToDisk(true); // closeLast
126 return FlushToDisk(true);
127 }
128 CVirtFile &file = Files.Back(); 168 CVirtFile &file = Files.Back();
129 if (file.Data.Size() != file.Size) 169 if (file.Data.Size() != file.WrittenSize)
130 { 170 file.Data.ReAlloc_KeepData(file.WrittenSize, file.WrittenSize);
131 file.Data.ReAlloc_KeepData((size_t)file.Size, (size_t)file.Size);
132 }
133 return S_OK; 171 return S_OK;
134 } 172 }
135 173
136 bool IsStreamInMem() const
137 {
138 if (_fileMode)
139 return false;
140 if (Files.Size() < 1 || /* Files[0].IsAltStream || */ Files[0].IsDir)
141 return false;
142 return true;
143 }
144
145 size_t GetMemStreamWrittenSize() const { return _pos; }
146
147 CVirtFileSystem():
148 MaxTotalAllocSize((UInt64)0 - 1)
149 {}
150
151 void Init()
152 {
153 _totalAllocSize = 0;
154 _fileMode = false;
155 _pos = 0;
156 _numFlushed = 0;
157 _fileIsOpen = false;
158 }
159
160 HRESULT CloseFile(const FString &path);
161 HRESULT FlushToDisk(bool closeLast); 174 HRESULT FlushToDisk(bool closeLast);
162 size_t GetPos() const { return _pos; }
163}; 175};
164 176
165#endif 177#endif
@@ -217,12 +229,12 @@ class CExtractCallbackImp Z7_final:
217 229
218 bool _needWriteArchivePath; 230 bool _needWriteArchivePath;
219 bool _isFolder; 231 bool _isFolder;
220 bool _totalFilesDefined; 232 bool _totalFiles_Defined;
221 bool _totalBytesDefined; 233 bool _totalBytes_Defined;
222public: 234public:
223 bool MultiArcMode; 235 bool MultiArcMode;
224 bool ProcessAltStreams; 236 bool ProcessAltStreams;
225 bool StreamMode; 237 bool StreamMode; // set to true, if you want the callee to call GetStream7()
226 bool ThereAreMessageErrors; 238 bool ThereAreMessageErrors;
227 bool Src_Is_IO_FS_Folder; 239 bool Src_Is_IO_FS_Folder;
228 240
@@ -246,9 +258,17 @@ private:
246 bool _skipArc; 258 bool _skipArc;
247#endif 259#endif
248 260
261public:
262 bool YesToAll;
263 bool TestMode;
264
265 UInt32 NumArchiveErrors;
266 NExtract::NOverwriteMode::EEnum OverwriteMode;
267
268private:
249 UString _currentArchivePath; 269 UString _currentArchivePath;
250 UString _currentFilePath; 270 UString _currentFilePath;
251 UString _filePath; 271 UString _filePath; // virtual path than will be sent via IFolderExtractToStreamCallback
252 272
253#ifndef Z7_SFX 273#ifndef Z7_SFX
254 UInt64 _curSize; 274 UInt64 _curSize;
@@ -266,12 +286,6 @@ public:
266 UInt64 NumFiles; 286 UInt64 NumFiles;
267#endif 287#endif
268 288
269 UInt32 NumArchiveErrors;
270 NExtract::NOverwriteMode::EEnum OverwriteMode;
271
272 bool YesToAll;
273 bool TestMode;
274
275#ifndef Z7_NO_CRYPTO 289#ifndef Z7_NO_CRYPTO
276 UString Password; 290 UString Password;
277#endif 291#endif
@@ -283,8 +297,8 @@ public:
283 UString _lang_Empty; 297 UString _lang_Empty;
284 298
285 CExtractCallbackImp(): 299 CExtractCallbackImp():
286 _totalFilesDefined(false) 300 _totalFiles_Defined(false)
287 , _totalBytesDefined(false) 301 , _totalBytes_Defined(false)
288 , MultiArcMode(false) 302 , MultiArcMode(false)
289 , ProcessAltStreams(true) 303 , ProcessAltStreams(true)
290 , StreamMode(false) 304 , StreamMode(false)
@@ -297,11 +311,13 @@ public:
297#ifndef Z7_SFX 311#ifndef Z7_SFX
298 , _remember(false) 312 , _remember(false)
299 , _skipArc(false) 313 , _skipArc(false)
300 , _hashCalc(NULL)
301#endif 314#endif
302 , OverwriteMode(NExtract::NOverwriteMode::kAsk)
303 , YesToAll(false) 315 , YesToAll(false)
304 , TestMode(false) 316 , TestMode(false)
317 , OverwriteMode(NExtract::NOverwriteMode::kAsk)
318#ifndef Z7_SFX
319 , _hashCalc(NULL)
320#endif
305 {} 321 {}
306 322
307 ~CExtractCallbackImp(); 323 ~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;
63static bool g_Maximized = false; 63static bool g_Maximized = false;
64 64
65extern 65extern
66UInt64 g_RAM_Size; 66size_t g_RAM_Size;
67UInt64 g_RAM_Size; 67size_t g_RAM_Size;
68 68
69#ifdef _WIN32 69#ifdef _WIN32
70extern 70extern
@@ -1025,8 +1025,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1025 break; 1025 break;
1026 } 1026 }
1027 1027
1028 case WM_DESTROY: 1028 case WM_CLOSE:
1029 { 1029 {
1030 // why do we use WA_INACTIVE here ?
1031 SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd);
1032 g_ExitEventLauncher.Exit(false);
1030 // ::DragAcceptFiles(hWnd, FALSE); 1033 // ::DragAcceptFiles(hWnd, FALSE);
1031 RevokeDragDrop(hWnd); 1034 RevokeDragDrop(hWnd);
1032 g_App._dropTarget.Release(); 1035 g_App._dropTarget.Release();
@@ -1034,12 +1037,18 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1034 if (g_WindowWasCreated) 1037 if (g_WindowWasCreated)
1035 g_App.Save(); 1038 g_App.Save();
1036 1039
1037 g_App.Release(); 1040 g_App.ReleaseApp();
1038 1041
1039 if (g_WindowWasCreated) 1042 if (g_WindowWasCreated)
1040 SaveWindowInfo(hWnd); 1043 SaveWindowInfo(hWnd);
1041 1044
1042 g_ExitEventLauncher.Exit(true); 1045 g_ExitEventLauncher.Exit(true);
1046 // default DefWindowProc will call DestroyWindow / WM_DESTROY
1047 break;
1048 }
1049
1050 case WM_DESTROY:
1051 {
1043 PostQuitMessage(0); 1052 PostQuitMessage(0);
1044 break; 1053 break;
1045 } 1054 }
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)
55 AddLangString(s, id); 55 AddLangString(s, id);
56} 56}
57 57
58void CMemDialog::AddInfoMessage_To_String(UString &s, UInt64 *ramSize_GB) 58void CMemDialog::AddInfoMessage_To_String(UString &s, const UInt32 *ramSize_GB)
59{ 59{
60 AddLangString(s, IDS_MEM_REQUIRES_BIG_MEM); 60 AddLangString(s, IDS_MEM_REQUIRES_BIG_MEM);
61 AddSize_GB(s, Required_GB, IDS_MEM_REQUIRED_MEM_SIZE); 61 AddSize_GB(s, Required_GB, IDS_MEM_REQUIRED_MEM_SIZE);
62 AddSize_GB(s, Limit_GB, IDS_MEM_CURRENT_MEM_LIMIT); 62 AddSize_GB(s, Limit_GB, IDS_MEM_CURRENT_MEM_LIMIT);
63 if (ramSize_GB) 63 if (ramSize_GB)
64 AddSize_GB(s, (UInt32)*ramSize_GB, IDS_MEM_RAM_SIZE); 64 AddSize_GB(s, *ramSize_GB, IDS_MEM_RAM_SIZE);
65 if (!FilePath.IsEmpty()) 65 if (!FilePath.IsEmpty())
66 { 66 {
67 s.Add_LF(); 67 s.Add_LF();
@@ -88,11 +88,11 @@ bool CMemDialog::OnInit()
88 88
89 // m_Action.Attach(GetItem(IDC_MEM_ACTION)); 89 // m_Action.Attach(GetItem(IDC_MEM_ACTION));
90 90
91 UInt64 ramSize = (UInt64)sizeof(size_t) << 29; 91 size_t ramSize = (size_t)sizeof(size_t) << 29;
92 const bool ramSize_defined = NWindows::NSystem::GetRamSize(ramSize); 92 const bool ramSize_defined = NWindows::NSystem::GetRamSize(ramSize);
93 // ramSize *= 10; // for debug 93 // ramSize *= 10; // for debug
94 94
95 UInt64 ramSize_GB = (ramSize + (1u << 29)) >> 30; 95 UInt32 ramSize_GB = (UInt32)(((UInt64)ramSize + (1u << 29)) >> 30);
96 if (ramSize_GB == 0) 96 if (ramSize_GB == 0)
97 ramSize_GB = 1; 97 ramSize_GB = 1;
98 98
@@ -121,7 +121,7 @@ bool CMemDialog::OnInit()
121 if (ramSize_defined) 121 if (ramSize_defined)
122 { 122 {
123 s += " / "; 123 s += " / ";
124 s.Add_UInt64(ramSize_GB); 124 s.Add_UInt32(ramSize_GB);
125 s += " GB (RAM)"; 125 s += " GB (RAM)";
126 } 126 }
127 SetItemText(IDT_MEM_GB, s); 127 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:
30 UString ArcPath; 30 UString ArcPath;
31 UString FilePath; 31 UString FilePath;
32 32
33 void AddInfoMessage_To_String(UString &s, UInt64 *ramSize_GB = NULL); 33 void AddInfoMessage_To_String(UString &s, const UInt32 *ramSize_GB = NULL);
34 34
35 CMemDialog(): 35 CMemDialog():
36 NeedSave(false), 36 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)
764 case IDM_CRC32: g_App.CalculateCrc("CRC32"); break; 764 case IDM_CRC32: g_App.CalculateCrc("CRC32"); break;
765 case IDM_CRC64: g_App.CalculateCrc("CRC64"); break; 765 case IDM_CRC64: g_App.CalculateCrc("CRC64"); break;
766 case IDM_XXH64: g_App.CalculateCrc("XXH64"); break; 766 case IDM_XXH64: g_App.CalculateCrc("XXH64"); break;
767 case IDM_MD5: g_App.CalculateCrc("MD5"); break;
767 case IDM_SHA1: g_App.CalculateCrc("SHA1"); break; 768 case IDM_SHA1: g_App.CalculateCrc("SHA1"); break;
768 case IDM_SHA256: g_App.CalculateCrc("SHA256"); break; 769 case IDM_SHA256: g_App.CalculateCrc("SHA256"); break;
770 case IDM_SHA384: g_App.CalculateCrc("SHA384"); break;
771 case IDM_SHA512: g_App.CalculateCrc("SHA512"); break;
772 case IDM_SHA3_256: g_App.CalculateCrc("SHA3-256"); break;
769 case IDM_BLAKE2SP: g_App.CalculateCrc("BLAKE2sp"); break; 773 case IDM_BLAKE2SP: g_App.CalculateCrc("BLAKE2sp"); break;
770 774
771 case IDM_DIFF: g_App.DiffFiles(); break; 775 case IDM_DIFF: g_App.DiffFiles(); break;
@@ -807,8 +811,8 @@ bool OnMenuCommand(HWND hWnd, unsigned id)
807 { 811 {
808 // File 812 // File
809 case IDCLOSE: 813 case IDCLOSE:
810 SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd); 814 // SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd);
811 g_ExitEventLauncher.Exit(false); 815 // g_ExitEventLauncher.Exit(false);
812 SendMessage(hWnd, WM_CLOSE, 0, 0); 816 SendMessage(hWnd, WM_CLOSE, 0, 0);
813 break; 817 break;
814 818
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
27 ProgressDialog.Sync.Set_NumFilesTotal(numFiles ? *numFiles : (UInt64)(Int64)-1); 27 ProgressDialog.Sync.Set_NumFilesTotal(numFiles ? *numFiles : (UInt64)(Int64)-1);
28 // if (numFiles) 28 // if (numFiles)
29 { 29 {
30 ProgressDialog.Sync.Set_BytesProgressMode(numFiles == NULL); 30 ProgressDialog.Sync.Set_FilesProgressMode(numFiles != NULL);
31 } 31 }
32 if (numBytes) 32 if (numBytes)
33 ProgressDialog.Sync.Set_NumBytesTotal(*numBytes); 33 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 @@
7#include "../../../Common/IntToString.h" 7#include "../../../Common/IntToString.h"
8#include "../../../Common/StringConvert.h" 8#include "../../../Common/StringConvert.h"
9 9
10#include "../../../Windows/FileName.h"
11#include "../../../Windows/ErrorMsg.h" 10#include "../../../Windows/ErrorMsg.h"
11#include "../../../Windows/FileName.h"
12#include "../../../Windows/PropVariant.h" 12#include "../../../Windows/PropVariant.h"
13#include "../../../Windows/Thread.h" 13#include "../../../Windows/Thread.h"
14 14
@@ -49,8 +49,9 @@ static DWORD kStyles[4] = { LVS_ICON, LVS_SMALLICON, LVS_LIST, LVS_REPORT };
49 49
50extern HINSTANCE g_hInstance; 50extern HINSTANCE g_hInstance;
51 51
52void CPanel::Release() 52void CPanel::ReleasePanel()
53{ 53{
54 Disable_Processing_Timer_Notify_StatusBar();
54 // It's for unloading COM dll's: don't change it. 55 // It's for unloading COM dll's: don't change it.
55 CloseOpenFolders(); 56 CloseOpenFolders();
56 _sevenZipContextMenu.Release(); 57 _sevenZipContextMenu.Release();
@@ -893,7 +894,7 @@ void CPanel::SetListViewMode(UInt32 index)
893void CPanel::ChangeFlatMode() 894void CPanel::ChangeFlatMode()
894{ 895{
895 _flatMode = !_flatMode; 896 _flatMode = !_flatMode;
896 if (_parentFolders.Size() > 0) 897 if (!_parentFolders.IsEmpty())
897 _flatModeForArc = _flatMode; 898 _flatModeForArc = _flatMode;
898 else 899 else
899 _flatModeForDisk = _flatMode; 900 _flatModeForDisk = _flatMode;
@@ -904,7 +905,7 @@ void CPanel::ChangeFlatMode()
904void CPanel::Change_ShowNtfsStrems_Mode() 905void CPanel::Change_ShowNtfsStrems_Mode()
905{ 906{
906 _showNtfsStrems_Mode = !_showNtfsStrems_Mode; 907 _showNtfsStrems_Mode = !_showNtfsStrems_Mode;
907 if (_parentFolders.Size() > 0) 908 if (!_parentFolders.IsEmpty())
908 _showNtfsStrems_ModeForArc = _showNtfsStrems_Mode; 909 _showNtfsStrems_ModeForArc = _showNtfsStrems_Mode;
909 else 910 else
910 _showNtfsStrems_ModeForDisk = _showNtfsStrems_Mode; 911 _showNtfsStrems_ModeForDisk = _showNtfsStrems_Mode;
@@ -1006,7 +1007,7 @@ void CPanel::GetFilePaths(const CRecordVector<UInt32> &operatedIndices, UStringV
1006 1007
1007void CPanel::ExtractArchives() 1008void CPanel::ExtractArchives()
1008{ 1009{
1009 if (_parentFolders.Size() > 0) 1010 if (!_parentFolders.IsEmpty())
1010 { 1011 {
1011 _panelCallback->OnCopy(false, false); 1012 _panelCallback->OnCopy(false, false);
1012 return; 1013 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
162 NWindows::NFile::NDir::RemoveDir(FolderPath); 162 NWindows::NFile::NDir::RemoveDir(FolderPath);
163 } 163 }
164 } 164 }
165 bool WasChanged(const NWindows::NFile::NFind::CFileInfo &newFileInfo) const 165 bool WasChanged_from_TempFileInfo(const NWindows::NFile::NFind::CFileInfo &newFileInfo) const
166 { 166 {
167 return newFileInfo.Size != FileInfo.Size || 167 return newFileInfo.Size != FileInfo.Size ||
168 CompareFileTime(&newFileInfo.MTime, &FileInfo.MTime) != 0; 168 CompareFileTime(&newFileInfo.MTime, &FileInfo.MTime) != 0;
169 } 169 }
170}; 170};
171 171
172
172struct CFolderLink: public CTempFileInfo 173struct CFolderLink: public CTempFileInfo
173{ 174{
174 bool IsVirtual; 175 bool IsVirtual; // == true (if archive was open via IInStream):
176 // archive was open from another archive,
177 // archive size meets the size conditions derived from g_RAM_Size.
178 // VirtFileSystem was used
179 // archive was fully extracted to memory.
175 bool UsePassword; 180 bool UsePassword;
176 NWindows::NDLL::CLibrary Library; 181 NWindows::NDLL::CLibrary Library;
177 CMyComPtr<IFolderFolder> ParentFolder; // can be NULL, if parent is FS folder (in _parentFolders[0]) 182 CMyComPtr<IFolderFolder> ParentFolder; // can be NULL, if parent is FS folder (in _parentFolders[0])
178 UString ParentFolderPath; // including tail slash (doesn't include paths parts of parent in next level) 183 UString ParentFolderPath; // including tail slash (doesn't include paths parts of parent in next level)
179 UString Password; 184 UString Password;
180
181 UString VirtualPath; // without tail slash 185 UString VirtualPath; // without tail slash
182 CFolderLink(): IsVirtual(false), UsePassword(false) {} 186 CByteBuffer ZoneBuf; // ZoneBuf for virtaul stream (IsVirtual)
183 187
184 bool WasChanged(const NWindows::NFile::NFind::CFileInfo &newFileInfo) const 188 CFolderLink(): IsVirtual(false), UsePassword(false) {}
189 bool WasChanged_from_FolderLink(const NWindows::NFile::NFind::CFileInfo &newFileInfo) const
185 { 190 {
186 return IsVirtual || CTempFileInfo::WasChanged(newFileInfo); 191 // we call it, if we have two real files.
192 // if archive was virtual, it means that we have updated that virtual to real file.
193 return IsVirtual || CTempFileInfo::WasChanged_from_TempFileInfo(newFileInfo);
187 } 194 }
188
189}; 195};
190 196
197
191enum MyMessages 198enum MyMessages
192{ 199{
193 // we can use WM_USER, since we have defined new window class. 200 // we can use WM_USER, since we have defined new window class.
@@ -268,13 +275,14 @@ struct CCopyToOptions
268 275
269 bool NeedRegistryZone; 276 bool NeedRegistryZone;
270 NExtract::NZoneIdMode::EEnum ZoneIdMode; 277 NExtract::NZoneIdMode::EEnum ZoneIdMode;
278 CByteBuffer ZoneBuf;
271 279
272 UString folder; 280 UString folder;
273 281
274 UStringVector hashMethods; 282 UStringVector hashMethods;
275 283
276 CVirtFileSystem *VirtFileSystemSpec; 284 CVirtFileSystem *VirtFileSystemSpec;
277 ISequentialOutStream *VirtFileSystem; 285 // ISequentialOutStream *VirtFileSystem;
278 286
279 CCopyToOptions(): 287 CCopyToOptions():
280 streamMode(false), 288 streamMode(false),
@@ -285,8 +293,8 @@ struct CCopyToOptions
285 showErrorMessages(false), 293 showErrorMessages(false),
286 NeedRegistryZone(true), 294 NeedRegistryZone(true),
287 ZoneIdMode(NExtract::NZoneIdMode::kNone), 295 ZoneIdMode(NExtract::NZoneIdMode::kNone),
288 VirtFileSystemSpec(NULL), 296 VirtFileSystemSpec(NULL)
289 VirtFileSystem(NULL) 297 // , VirtFileSystem(NULL)
290 {} 298 {}
291}; 299};
292 300
@@ -310,11 +318,60 @@ struct COpenResult
310 318
311class CPanel Z7_final: public NWindows::NControl::CWindow2 319class CPanel Z7_final: public NWindows::NControl::CWindow2
312{ 320{
321 bool _thereAre_ListView_Items;
322 // bool _virtualMode;
323 bool _enableItemChangeNotify;
324 bool _thereAreDeletedItems;
325 bool _markDeletedItems;
326 bool _dontShowMode;
327 bool _needSaveInfo;
328
329public:
330 bool PanelCreated;
331 bool _mySelectMode;
332 bool _showDots;
333 bool _showRealFileIcons;
334 bool _flatMode;
335 bool _flatModeForArc;
336 bool _flatModeForDisk;
337 bool _selectionIsDefined;
338 // bool _showNtfsStrems_Mode;
339 // bool _showNtfsStrems_ModeForDisk;
340 // bool _showNtfsStrems_ModeForArc;
341
342 bool _selectMark;
343 bool _lastFocusedIsList;
344
345 bool _processTimer;
346 bool _processNotify;
347 bool _processStatusBar;
348
349public:
350 bool _ascending;
351 PROPID _sortID;
352 // int _sortIndex;
353 Int32 _isRawSortProp;
354
355 CMyListView _listView;
356 CPanelCallback *_panelCallback;
357
358private:
359
313 // CExtToIconMap _extToIconMap; 360 // CExtToIconMap _extToIconMap;
314 UINT _baseID; 361 UINT _baseID;
315 unsigned _comboBoxID; 362 unsigned _comboBoxID;
316 UINT _statusBarID; 363 UINT _statusBarID;
317 364
365public:
366 DWORD _exStyle;
367 // CUIntVector _realIndices;
368 int _timestampLevel;
369 UInt32 _listViewMode;
370 int _xSize;
371private:
372 int _startGroupSelect;
373 int _prevFocusedItem;
374
318 CAppState *_appState; 375 CAppState *_appState;
319 376
320 virtual bool OnCommand(unsigned code, unsigned itemID, LPARAM lParam, LRESULT &result) Z7_override; 377 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
351 bool OnCustomDraw(LPNMLVCUSTOMDRAW lplvcd, LRESULT &result); 408 bool OnCustomDraw(LPNMLVCUSTOMDRAW lplvcd, LRESULT &result);
352 409
353 410
354public:
355 HWND _mainWindow;
356 CPanelCallback *_panelCallback;
357
358 // void SysIconsWereChanged() { _extToIconMap.Clear(); }
359
360 void DeleteItems(bool toRecycleBin);
361 void CreateFolder();
362 void CreateFile();
363 bool CorrectFsPath(const UString &path, UString &result);
364 // bool IsPathForPlugin(const UString &path);
365
366private:
367
368 void ChangeWindowSize(int xSize, int ySize); 411 void ChangeWindowSize(int xSize, int ySize);
369
370 HRESULT InitColumns(); 412 HRESULT InitColumns();
371 void DeleteColumn(unsigned index); 413 void DeleteColumn(unsigned index);
372 void AddColumn(const CPropColumn &prop); 414 void AddColumn(const CPropColumn &prop);
@@ -379,20 +421,13 @@ private:
379 void OnInsert(); 421 void OnInsert();
380 // void OnUpWithShift(); 422 // void OnUpWithShift();
381 // void OnDownWithShift(); 423 // void OnDownWithShift();
382public:
383 void UpdateSelection();
384 void SelectSpec(bool selectMode);
385 void SelectByType(bool selectMode);
386 void SelectAll(bool selectMode);
387 void InvertSelection();
388private:
389
390 // UString GetFileType(UInt32 index); 424 // UString GetFileType(UInt32 index);
391 LRESULT SetItemText(LVITEMW &item); 425 LRESULT SetItemText(LVITEMW &item);
392
393 // CRecordVector<PROPID> m_ColumnsPropIDs; 426 // CRecordVector<PROPID> m_ColumnsPropIDs;
394 427
395public: 428public:
429 HWND _mainWindow;
430
396 NWindows::NControl::CReBar _headerReBar; 431 NWindows::NControl::CReBar _headerReBar;
397 NWindows::NControl::CToolBar _headerToolBar; 432 NWindows::NControl::CToolBar _headerToolBar;
398 NWindows::NControl:: 433 NWindows::NControl::
@@ -405,42 +440,57 @@ public:
405 UStringVector ComboBoxPaths; 440 UStringVector ComboBoxPaths;
406 // CMyComboBox _headerComboBox; 441 // CMyComboBox _headerComboBox;
407 CMyComboBoxEdit _comboBoxEdit; 442 CMyComboBoxEdit _comboBoxEdit;
408 CMyListView _listView;
409 bool _thereAre_ListView_Items;
410 NWindows::NControl::CStatusBar _statusBar; 443 NWindows::NControl::CStatusBar _statusBar;
411 bool _lastFocusedIsList;
412 // NWindows::NControl::CStatusBar _statusBar2; 444 // NWindows::NControl::CStatusBar _statusBar2;
413 445
414 DWORD _exStyle; 446 CBoolVector _selectedStatusVector;
415 bool _showDots; 447 CSelectedState _selectedState;
416 bool _showRealFileIcons;
417 // bool _virtualMode;
418 // CUIntVector _realIndices;
419 bool _enableItemChangeNotify;
420 bool _mySelectMode;
421 448
422 int _timestampLevel; 449 UString _currentFolderPrefix;
450
451 CObjectVector<CFolderLink> _parentFolders;
452 NWindows::NDLL::CLibrary _library;
453
454 CMyComPtr<IFolderFolder> _folder;
455 CBoolVector _isDirVector;
456 CMyComPtr<IFolderCompare> _folderCompare;
457 CMyComPtr<IFolderGetItemName> _folderGetItemName;
458 CMyComPtr<IArchiveGetRawProps> _folderRawProps;
459 CMyComPtr<IFolderAltStreams> _folderAltStreams;
460 CMyComPtr<IFolderOperations> _folderOperations;
423 461
462 // for drag and drop highliting
463 int m_DropHighlighted_SelectionIndex;
464 // int m_SubFolderIndex; // realIndex of item in m_Panel list (if drop cursor to that item)
465 UString m_DropHighlighted_SubFolderName; // name of folder in m_Panel list (if drop cursor to that folder)
466
467 // CMyComPtr<IFolderGetSystemIconIndex> _folderGetSystemIconIndex;
468 UStringVector _fastFolders;
469
470 UString _typeIDString;
471 CListViewInfo _listViewInfo;
472
473 CPropColumns _columns;
474 CPropColumns _visibleColumns;
475
476 CMyComPtr<IContextMenu> _sevenZipContextMenu;
477 CMyComPtr<IContextMenu> _systemContextMenu;
478
479 void UpdateSelection();
480 void SelectSpec(bool selectMode);
481 void SelectByType(bool selectMode);
482 void SelectAll(bool selectMode);
483 void InvertSelection();
424 484
425 void RedrawListItems() 485 void RedrawListItems()
426 { 486 {
427 _listView.RedrawAllItems(); 487 _listView.RedrawAllItems();
428 } 488 }
429
430
431 CBoolVector _selectedStatusVector;
432
433 CSelectedState _selectedState;
434 bool _thereAreDeletedItems;
435 bool _markDeletedItems;
436
437 bool PanelCreated;
438
439 void DeleteListItems() 489 void DeleteListItems()
440 { 490 {
441 if (_thereAre_ListView_Items) 491 if (_thereAre_ListView_Items)
442 { 492 {
443 bool b = _enableItemChangeNotify; 493 const bool b = _enableItemChangeNotify;
444 _enableItemChangeNotify = false; 494 _enableItemChangeNotify = false;
445 _listView.DeleteAllItems(); 495 _listView.DeleteAllItems();
446 _thereAre_ListView_Items = false; 496 _thereAre_ListView_Items = false;
@@ -448,6 +498,15 @@ public:
448 } 498 }
449 } 499 }
450 500
501 // void SysIconsWereChanged() { _extToIconMap.Clear(); }
502
503 void DeleteItems(bool toRecycleBin);
504 void CreateFolder();
505 void CreateFile();
506 bool CorrectFsPath(const UString &path, UString &result);
507 // bool IsPathForPlugin(const UString &path);
508
509
451 HWND GetParent() const; 510 HWND GetParent() const;
452 511
453 UInt32 GetRealIndex(const LVITEMW &item) const 512 UInt32 GetRealIndex(const LVITEMW &item) const
@@ -471,46 +530,8 @@ public:
471 return (unsigned)param; 530 return (unsigned)param;
472 } 531 }
473 532
474 UInt32 _listViewMode;
475 int _xSize;
476
477 bool _flatMode;
478 bool _flatModeForDisk;
479 bool _flatModeForArc;
480
481 // bool _showNtfsStrems_Mode;
482 // bool _showNtfsStrems_ModeForDisk;
483 // bool _showNtfsStrems_ModeForArc;
484
485 bool _dontShowMode;
486
487
488 UString _currentFolderPrefix;
489
490 CObjectVector<CFolderLink> _parentFolders;
491 NWindows::NDLL::CLibrary _library;
492
493 CMyComPtr<IFolderFolder> _folder;
494 CBoolVector _isDirVector;
495 CMyComPtr<IFolderCompare> _folderCompare;
496 CMyComPtr<IFolderGetItemName> _folderGetItemName;
497 CMyComPtr<IArchiveGetRawProps> _folderRawProps;
498 CMyComPtr<IFolderAltStreams> _folderAltStreams;
499 CMyComPtr<IFolderOperations> _folderOperations;
500
501
502 // for drag and drop highliting
503 int m_DropHighlighted_SelectionIndex;
504 // int m_SubFolderIndex; // realIndex of item in m_Panel list (if drop cursor to that item)
505 UString m_DropHighlighted_SubFolderName; // name of folder in m_Panel list (if drop cursor to that folder)
506
507 void ReleaseFolder(); 533 void ReleaseFolder();
508 void SetNewFolder(IFolderFolder *newFolder); 534 void SetNewFolder(IFolderFolder *newFolder);
509
510 // CMyComPtr<IFolderGetSystemIconIndex> _folderGetSystemIconIndex;
511
512 UStringVector _fastFolders;
513
514 void GetSelectedNames(UStringVector &selectedNames); 535 void GetSelectedNames(UStringVector &selectedNames);
515 void SaveSelectedState(CSelectedState &s); 536 void SaveSelectedState(CSelectedState &s);
516 HRESULT RefreshListCtrl(const CSelectedState &s); 537 HRESULT RefreshListCtrl(const CSelectedState &s);
@@ -575,61 +596,44 @@ public:
575 596
576 CPanel() : 597 CPanel() :
577 _thereAre_ListView_Items(false), 598 _thereAre_ListView_Items(false),
578 _exStyle(0), 599 // _virtualMode(false),
579 _showDots(false),
580 _showRealFileIcons(false),
581 // _virtualMode(flase),
582 _enableItemChangeNotify(true), 600 _enableItemChangeNotify(true),
583 _mySelectMode(false),
584 _timestampLevel(kTimestampPrintLevel_MIN),
585
586 _thereAreDeletedItems(false), 601 _thereAreDeletedItems(false),
587 _markDeletedItems(true), 602 _markDeletedItems(true),
588 PanelCreated(false), 603 _dontShowMode(false),
589 604 _needSaveInfo(false),
590 _listViewMode(3),
591 _xSize(300),
592 605
606 PanelCreated(false),
607 _mySelectMode(false),
608 _showDots(false),
609 _showRealFileIcons(false),
593 _flatMode(false), 610 _flatMode(false),
594 _flatModeForDisk(false),
595 _flatModeForArc(false), 611 _flatModeForArc(false),
596 612 _flatModeForDisk(false),
613 _selectionIsDefined(false),
597 // _showNtfsStrems_Mode(false), 614 // _showNtfsStrems_Mode(false),
598 // _showNtfsStrems_ModeForDisk(false), 615 // _showNtfsStrems_ModeForDisk(false),
599 // _showNtfsStrems_ModeForArc(false), 616 // _showNtfsStrems_ModeForArc(false),
600 617
601 _dontShowMode(false), 618 _exStyle(0),
602 619 _timestampLevel(kTimestampPrintLevel_MIN),
603 m_DropHighlighted_SelectionIndex(-1), 620 _listViewMode(3),
604 621 _xSize(300),
605 _needSaveInfo(false),
606 _startGroupSelect(0), 622 _startGroupSelect(0),
607 _selectionIsDefined(false) 623 m_DropHighlighted_SelectionIndex(-1)
608 {} 624 {}
609 625
626 ~CPanel() Z7_DESTRUCTOR_override;
627
628 void ReleasePanel();
629
610 void SetExtendedStyle() 630 void SetExtendedStyle()
611 { 631 {
612 if (_listView) 632 if (_listView)
613 _listView.SetExtendedListViewStyle(_exStyle); 633 _listView.SetExtendedListViewStyle(_exStyle);
614 } 634 }
615 635
616
617 bool _needSaveInfo;
618 UString _typeIDString;
619 CListViewInfo _listViewInfo;
620
621 CPropColumns _columns;
622 CPropColumns _visibleColumns;
623
624 PROPID _sortID;
625 // int _sortIndex;
626 bool _ascending;
627 Int32 _isRawSortProp;
628
629 void SetSortRawStatus(); 636 void SetSortRawStatus();
630
631 void Release();
632 ~CPanel() Z7_DESTRUCTOR_override;
633 void OnLeftClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate); 637 void OnLeftClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate);
634 bool OnRightClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate, LRESULT &result); 638 bool OnRightClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate, LRESULT &result);
635 void ShowColumnsContextMenu(int x, int y); 639 void ShowColumnsContextMenu(int x, int y);
@@ -638,9 +642,6 @@ public:
638 void OnReload(bool onTimer = false); 642 void OnReload(bool onTimer = false);
639 bool OnContextMenu(HANDLE windowHandle, int xPos, int yPos); 643 bool OnContextMenu(HANDLE windowHandle, int xPos, int yPos);
640 644
641 CMyComPtr<IContextMenu> _sevenZipContextMenu;
642 CMyComPtr<IContextMenu> _systemContextMenu;
643
644 HRESULT CreateShellContextMenu( 645 HRESULT CreateShellContextMenu(
645 const CRecordVector<UInt32> &operatedIndices, 646 const CRecordVector<UInt32> &operatedIndices,
646 CMyComPtr<IContextMenu> &systemContextMenu); 647 CMyComPtr<IContextMenu> &systemContextMenu);
@@ -672,12 +673,6 @@ public:
672 void EditCopy(); 673 void EditCopy();
673 void EditPaste(); 674 void EditPaste();
674 675
675 int _startGroupSelect;
676
677 bool _selectionIsDefined;
678 bool _selectMark;
679 int _prevFocusedItem;
680
681 676
682 // void SortItems(int index); 677 // void SortItems(int index);
683 void SortItemsWithPropID(PROPID propID); 678 void SortItemsWithPropID(PROPID propID);
@@ -751,9 +746,12 @@ public:
751 bool IsThereReadOnlyFolder() const; 746 bool IsThereReadOnlyFolder() const;
752 bool CheckBeforeUpdate(UINT resourceID); 747 bool CheckBeforeUpdate(UINT resourceID);
753 748
754 bool _processTimer; 749 void Disable_Processing_Timer_Notify_StatusBar()
755 bool _processNotify; 750 {
756 bool _processStatusBar; 751 _processTimer = false;
752 _processNotify = false;
753 _processStatusBar = false;
754 }
757 755
758 class CDisableTimerProcessing 756 class CDisableTimerProcessing
759 { 757 {
@@ -926,6 +924,7 @@ public:
926 void ExtractArchives(); 924 void ExtractArchives();
927 void TestArchives(); 925 void TestArchives();
928 926
927 void Get_ZoneId_Stream_from_ParentFolders(CByteBuffer &buf);
929 928
930 HRESULT CopyTo(CCopyToOptions &options, 929 HRESULT CopyTo(CCopyToOptions &options,
931 const CRecordVector<UInt32> &indices, 930 const CRecordVector<UInt32> &indices,
@@ -939,7 +938,7 @@ public:
939 { 938 {
940 bool usePassword = false; 939 bool usePassword = false;
941 UString password; 940 UString password;
942 if (_parentFolders.Size() > 0) 941 if (!_parentFolders.IsEmpty())
943 { 942 {
944 const CFolderLink &fl = _parentFolders.Back(); 943 const CFolderLink &fl = _parentFolders.Back();
945 usePassword = fl.UsePassword; 944 usePassword = fl.UsePassword;
@@ -978,6 +977,7 @@ public:
978 UString GetItemsInfoString(const CRecordVector<UInt32> &indices); 977 UString GetItemsInfoString(const CRecordVector<UInt32> &indices);
979}; 978};
980 979
980
981class CMyBuffer 981class CMyBuffer
982{ 982{
983 void *_data; 983 void *_data;
@@ -994,13 +994,12 @@ public:
994 ~CMyBuffer() { ::MidFree(_data); } 994 ~CMyBuffer() { ::MidFree(_data); }
995}; 995};
996 996
997class CExitEventLauncher 997struct CExitEventLauncher
998{ 998{
999public:
1000 NWindows::NSynchronization::CManualResetEvent _exitEvent; 999 NWindows::NSynchronization::CManualResetEvent _exitEvent;
1001 bool _needExit; 1000 bool _needExit;
1002 CRecordVector< ::CThread > _threads;
1003 unsigned _numActiveThreads; 1001 unsigned _numActiveThreads;
1002 CRecordVector< ::CThread > _threads;
1004 1003
1005 CExitEventLauncher() 1004 CExitEventLauncher()
1006 { 1005 {
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()
75 75
76 if (FolderOperations) 76 if (FolderOperations)
77 { 77 {
78 CMyComPtr<IFolderSetZoneIdMode> setZoneMode;
79 FolderOperations.QueryInterface(IID_IFolderSetZoneIdMode, &setZoneMode);
80 if (setZoneMode)
81 { 78 {
82 RINOK(setZoneMode->SetZoneIdMode(options->ZoneIdMode)) 79 CMyComPtr<IFolderSetZoneIdMode> setZoneMode;
80 FolderOperations.QueryInterface(IID_IFolderSetZoneIdMode, &setZoneMode);
81 if (setZoneMode)
82 {
83 RINOK(setZoneMode->SetZoneIdMode(options->ZoneIdMode))
84 }
85 }
86 {
87 CMyComPtr<IFolderSetZoneIdFile> setZoneFile;
88 FolderOperations.QueryInterface(IID_IFolderSetZoneIdFile, &setZoneFile);
89 if (setZoneFile)
90 {
91 RINOK(setZoneFile->SetZoneIdFile(options->ZoneBuf, (UInt32)options->ZoneBuf.Size()))
92 }
83 } 93 }
84 } 94 }
85 95
@@ -143,6 +153,32 @@ static void ThrowException_if_Error(HRESULT res)
143#endif 153#endif
144*/ 154*/
145 155
156void CPanel::Get_ZoneId_Stream_from_ParentFolders(CByteBuffer &buf)
157{
158 // we suppose that ZoneId of top parent has priority over ZoneId from childs.
159 FOR_VECTOR (i, _parentFolders)
160 {
161 // _parentFolders[0] = is top level archive
162 // _parentFolders[1 ... ].isVirtual == true is possible
163 // if extracted size meets size conditions derived from g_RAM_Size.
164 const CFolderLink &fl = _parentFolders[i];
165 if (fl.IsVirtual)
166 {
167 if (fl.ZoneBuf.Size() != 0)
168 {
169 buf = fl.ZoneBuf;
170 return;
171 }
172 }
173 else if (!fl.FilePath.IsEmpty())
174 {
175 ReadZoneFile_Of_BaseFile(fl.FilePath, buf);
176 if (buf.Size() != 0)
177 return;
178 }
179 }
180}
181
146HRESULT CPanel::CopyTo(CCopyToOptions &options, 182HRESULT CPanel::CopyTo(CCopyToOptions &options,
147 const CRecordVector<UInt32> &indices, 183 const CRecordVector<UInt32> &indices,
148 UStringVector *messages, 184 UStringVector *messages,
@@ -157,6 +193,10 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options,
157 options.ZoneIdMode = (NExtract::NZoneIdMode::EEnum)(int)(Int32)ci.WriteZone; 193 options.ZoneIdMode = (NExtract::NZoneIdMode::EEnum)(int)(Int32)ci.WriteZone;
158 } 194 }
159 195
196 if (options.ZoneBuf.Size() == 0
197 && options.ZoneIdMode != NExtract::NZoneIdMode::kNone)
198 Get_ZoneId_Stream_from_ParentFolders(options.ZoneBuf);
199
160 if (IsHashFolder()) 200 if (IsHashFolder())
161 { 201 {
162 if (!options.testMode) 202 if (!options.testMode)
@@ -205,9 +245,9 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options,
205 extracter.Hash.MainName = extracter.Hash.FirstFileName; 245 extracter.Hash.MainName = extracter.Hash.FirstFileName;
206 } 246 }
207 247
208 if (options.VirtFileSystem) 248 if (options.VirtFileSystemSpec)
209 { 249 {
210 extracter.ExtractCallbackSpec->VirtFileSystem = options.VirtFileSystem; 250 extracter.ExtractCallbackSpec->VirtFileSystem = options.VirtFileSystemSpec;
211 extracter.ExtractCallbackSpec->VirtFileSystemSpec = options.VirtFileSystemSpec; 251 extracter.ExtractCallbackSpec->VirtFileSystemSpec = options.VirtFileSystemSpec;
212 } 252 }
213 extracter.ExtractCallbackSpec->ProcessAltStreams = options.includeAltStreams; 253 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,
2614 UString s = LangString(cmdEffect == DROPEFFECT_MOVE ? 2614 UString s = LangString(cmdEffect == DROPEFFECT_MOVE ?
2615 IDS_MOVE_TO : IDS_COPY_TO); 2615 IDS_MOVE_TO : IDS_COPY_TO);
2616 s.Add_LF(); 2616 s.Add_LF();
2617 s += "\'"; 2617 // s += "\'";
2618 s += m_Panel->_currentFolderPrefix; 2618 s += m_Panel->_currentFolderPrefix;
2619 s += "\'"; 2619 // s += "\'";
2620 s.Add_LF(); 2620 s.Add_LF();
2621 s += LangString(IDS_WANT_TO_COPY_FILES); 2621 AddLangString(s, IDS_WANT_TO_COPY_FILES);
2622 s += " ?"; 2622 s += " ?";
2623 const int res = ::MessageBoxW(*m_Panel, s, title, MB_YESNOCANCEL | MB_ICONQUESTION); 2623 const int res = ::MessageBoxW(*m_Panel, s, title, MB_YESNOCANCEL | MB_ICONQUESTION);
2624 if (res != IDYES) 2624 if (res != IDYES)
@@ -2954,7 +2954,7 @@ static unsigned Drag_OnContextMenu(int xPos, int yPos, UInt32 cmdFlags)
2954 name = MyFormatNew(name, destPath); 2954 name = MyFormatNew(name, destPath);
2955 */ 2955 */
2956 name.Add_Space(); 2956 name.Add_Space();
2957 name += LangString(IDS_CONTEXT_ARCHIVE); 2957 AddLangString(name, IDS_CONTEXT_ARCHIVE);
2958 } 2958 }
2959 if (cmdId == NDragMenu::k_Cancel) 2959 if (cmdId == NDragMenu::k_Cancel)
2960 menu.AppendItem(MF_SEPARATOR, 0, (LPCTSTR)NULL); 2960 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;
39using namespace NDir; 39using namespace NDir;
40 40
41extern bool g_RAM_Size_Defined; 41extern bool g_RAM_Size_Defined;
42extern UInt64 g_RAM_Size; 42extern size_t g_RAM_Size;
43 43
44#ifndef _UNICODE 44#ifndef _UNICODE
45extern bool g_IsNT; 45extern bool g_IsNT;
@@ -606,9 +606,9 @@ HRESULT CPanel::OpenParentArchiveFolder()
606 NFind::CFileInfo newFileInfo; 606 NFind::CFileInfo newFileInfo;
607 if (newFileInfo.Find(folderLink.FilePath)) 607 if (newFileInfo.Find(folderLink.FilePath))
608 { 608 {
609 if (folderLink.WasChanged(newFileInfo)) 609 if (folderLink.WasChanged_from_FolderLink(newFileInfo))
610 { 610 {
611 UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, folderLink.RelPath); 611 const UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, folderLink.RelPath);
612 if (::MessageBoxW((HWND)*this, message, L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION) == IDYES) 612 if (::MessageBoxW((HWND)*this, message, L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION) == IDYES)
613 { 613 {
614 if (OnOpenItemChanged(folderLink.FileIndex, fs2us(folderLink.FilePath), 614 if (OnOpenItemChanged(folderLink.FileIndex, fs2us(folderLink.FilePath),
@@ -1083,13 +1083,11 @@ void CExitEventLauncher::Exit(bool hardExit)
1083 FOR_VECTOR (i, _threads) 1083 FOR_VECTOR (i, _threads)
1084 { 1084 {
1085 ::CThread &th = _threads[i]; 1085 ::CThread &th = _threads[i];
1086 DWORD wait = (hardExit ? 100 : INFINITE);
1087 if (Thread_WasCreated(&th)) 1086 if (Thread_WasCreated(&th))
1088 { 1087 {
1089 DWORD waitResult = WaitForSingleObject(th, wait); 1088 const DWORD waitResult = WaitForSingleObject(th, hardExit ? 100 : INFINITE);
1090 // Thread_Wait(&th); 1089 // Thread_Wait(&th);
1091 if (waitResult == WAIT_TIMEOUT) 1090 // if (waitResult == WAIT_TIMEOUT) wait = 1;
1092 wait = 1;
1093 if (!hardExit && waitResult != WAIT_OBJECT_0) 1091 if (!hardExit && waitResult != WAIT_OBJECT_0)
1094 continue; 1092 continue;
1095 Thread_Close(&th); 1093 Thread_Close(&th);
@@ -1107,7 +1105,7 @@ static THREAD_FUNC_DECL MyThreadFunction(void *param)
1107 CMyUniquePtr<CTmpProcessInfo> tpi((CTmpProcessInfo *)param); 1105 CMyUniquePtr<CTmpProcessInfo> tpi((CTmpProcessInfo *)param);
1108 CChildProcesses &processes = tpi->Processes; 1106 CChildProcesses &processes = tpi->Processes;
1109 1107
1110 bool mainProcessWasSet = !processes.Handles.IsEmpty(); 1108 const bool mainProcessWasSet = !processes.Handles.IsEmpty();
1111 1109
1112 bool isComplexMode = true; 1110 bool isComplexMode = true;
1113 1111
@@ -1195,7 +1193,7 @@ static THREAD_FUNC_DECL MyThreadFunction(void *param)
1195 { 1193 {
1196 NFind::CFileInfo newFileInfo; 1194 NFind::CFileInfo newFileInfo;
1197 if (newFileInfo.Find(tpi->FilePath)) 1195 if (newFileInfo.Find(tpi->FilePath))
1198 if (tpi->WasChanged(newFileInfo)) 1196 if (tpi->WasChanged_from_TempFileInfo(newFileInfo))
1199 needFindProcessByPath = false; 1197 needFindProcessByPath = false;
1200 } 1198 }
1201 1199
@@ -1235,7 +1233,7 @@ static THREAD_FUNC_DECL MyThreadFunction(void *param)
1235 1233
1236 if (mainProcessWasSet) 1234 if (mainProcessWasSet)
1237 { 1235 {
1238 if (tpi->WasChanged(newFileInfo)) 1236 if (tpi->WasChanged_from_TempFileInfo(newFileInfo))
1239 { 1237 {
1240 UString m = MyFormatNew(IDS_CANNOT_UPDATE_FILE, fs2us(tpi->FilePath)); 1238 UString m = MyFormatNew(IDS_CANNOT_UPDATE_FILE, fs2us(tpi->FilePath));
1241 if (tpi->ReadOnly) 1239 if (tpi->ReadOnly)
@@ -1279,10 +1277,10 @@ static THREAD_FUNC_DECL MyThreadFunction(void *param)
1279 1277
1280 { 1278 {
1281 NFind::CFileInfo newFileInfo; 1279 NFind::CFileInfo newFileInfo;
1282 1280 const bool finded = newFileInfo.Find(tpi->FilePath);
1283 bool finded = newFileInfo.Find(tpi->FilePath); 1281 if (!needCheckTimestamp
1284 1282 || !finded
1285 if (!needCheckTimestamp || !finded || !tpi->WasChanged(newFileInfo)) 1283 || !tpi->WasChanged_from_TempFileInfo(newFileInfo))
1286 { 1284 {
1287 DEBUG_PRINT("Delete Temp file"); 1285 DEBUG_PRINT("Delete Temp file");
1288 tpi->DeleteDirAndFile(); 1286 tpi->DeleteDirAndFile();
@@ -1534,7 +1532,7 @@ void CPanel::OpenItemInArchive(unsigned index, bool tryInternal, bool tryExterna
1534 1532
1535 bool usePassword = false; 1533 bool usePassword = false;
1536 UString password; 1534 UString password;
1537 if (_parentFolders.Size() > 0) 1535 if (!_parentFolders.IsEmpty())
1538 { 1536 {
1539 const CFolderLink &fl = _parentFolders.Back(); 1537 const CFolderLink &fl = _parentFolders.Back();
1540 usePassword = fl.UsePassword; 1538 usePassword = fl.UsePassword;
@@ -1547,7 +1545,7 @@ void CPanel::OpenItemInArchive(unsigned index, bool tryInternal, bool tryExterna
1547 #ifndef _UNICODE 1545 #ifndef _UNICODE
1548 if (g_IsNT) 1546 if (g_IsNT)
1549 #endif 1547 #endif
1550 if (_parentFolders.Size() > 0) 1548 if (!_parentFolders.IsEmpty())
1551 { 1549 {
1552 const CFolderLink &fl = _parentFolders.Front(); 1550 const CFolderLink &fl = _parentFolders.Front();
1553 if (!fl.IsVirtual && !fl.FilePath.IsEmpty()) 1551 if (!fl.IsVirtual && !fl.FilePath.IsEmpty())
@@ -1576,39 +1574,42 @@ void CPanel::OpenItemInArchive(unsigned index, bool tryInternal, bool tryExterna
1576 1574
1577 if (tryAsArchive) 1575 if (tryAsArchive)
1578 { 1576 {
1577 // actually we want to get sum: size of main file plus sizes of altStreams.
1578 // but now there is no interface to get altStreams sizes.
1579 NCOM::CPropVariant prop; 1579 NCOM::CPropVariant prop;
1580 _folder->GetProperty(index, kpidSize, &prop); 1580 _folder->GetProperty(index, kpidSize, &prop);
1581 UInt64 fileLimit = 1 << 22; 1581 const size_t fileLimit = g_RAM_Size_Defined ?
1582 if (g_RAM_Size_Defined) 1582 g_RAM_Size >> MyMax(_parentFolders.Size() + 1, 8u):
1583 fileLimit = g_RAM_Size / 4; 1583 1u << 22;
1584
1585 UInt64 fileSize = 0; 1584 UInt64 fileSize = 0;
1586 if (!ConvertPropVariantToUInt64(prop, fileSize)) 1585 if (!ConvertPropVariantToUInt64(prop, fileSize))
1587 fileSize = fileLimit; 1586 fileSize = fileLimit;
1588 if (fileSize <= fileLimit && fileSize > 0) 1587#if 0 // 1 : for debug
1588 fileLimit = 1;
1589#endif
1590
1591 if (fileSize <= fileLimit)
1589 { 1592 {
1590 options.streamMode = true; 1593 options.streamMode = true;
1591 virtFileSystemSpec = new CVirtFileSystem; 1594 virtFileSystemSpec = new CVirtFileSystem;
1592 virtFileSystem = virtFileSystemSpec; 1595 virtFileSystem = virtFileSystemSpec;
1596 virtFileSystemSpec->FileName = name;
1597 virtFileSystemSpec->IsAltStreamFile = isAltStream;
1593 1598
1594#if defined(_WIN32) && !defined(UNDER_CE) 1599#if defined(_WIN32) && !defined(UNDER_CE)
1595#ifndef _UNICODE 1600#ifndef _UNICODE
1596 if (g_IsNT) 1601 if (g_IsNT)
1597#endif 1602#endif
1598 if (_parentFolders.Size() > 0)
1599 { 1603 {
1600 const CFolderLink &fl = _parentFolders.Front(); 1604 Get_ZoneId_Stream_from_ParentFolders(virtFileSystemSpec->ZoneBuf);
1601 if (!fl.IsVirtual && !fl.FilePath.IsEmpty()) 1605 options.ZoneBuf = virtFileSystemSpec->ZoneBuf;
1602 ReadZoneFile_Of_BaseFile(fl.FilePath, virtFileSystemSpec->ZoneBuf);
1603 } 1606 }
1604#endif 1607#endif
1605 1608
1606 // we allow additional total size for small alt streams; 1609 virtFileSystemSpec->MaxTotalAllocSize = (size_t)fileSize
1607 virtFileSystemSpec->MaxTotalAllocSize = fileSize + (1 << 10); 1610 + (1 << 16); // we allow additional total size for small alt streams.
1608
1609 virtFileSystemSpec->DirPrefix = tempDirNorm; 1611 virtFileSystemSpec->DirPrefix = tempDirNorm;
1610 virtFileSystemSpec->Init(); 1612 // options.VirtFileSystem = virtFileSystem;
1611 options.VirtFileSystem = virtFileSystem;
1612 options.VirtFileSystemSpec = virtFileSystemSpec; 1613 options.VirtFileSystemSpec = virtFileSystemSpec;
1613 } 1614 }
1614 } 1615 }
@@ -1618,7 +1619,7 @@ void CPanel::OpenItemInArchive(unsigned index, bool tryInternal, bool tryExterna
1618 1619
1619 const HRESULT result = CopyTo(options, indices, &messages, usePassword, password); 1620 const HRESULT result = CopyTo(options, indices, &messages, usePassword, password);
1620 1621
1621 if (_parentFolders.Size() > 0) 1622 if (!_parentFolders.IsEmpty())
1622 { 1623 {
1623 CFolderLink &fl = _parentFolders.Back(); 1624 CFolderLink &fl = _parentFolders.Back();
1624 fl.UsePassword = usePassword; 1625 fl.UsePassword = usePassword;
@@ -1634,34 +1635,46 @@ void CPanel::OpenItemInArchive(unsigned index, bool tryInternal, bool tryExterna
1634 return; 1635 return;
1635 } 1636 }
1636 1637
1637 if (options.VirtFileSystem) 1638 if (virtFileSystemSpec && !virtFileSystemSpec->WasStreamFlushedToFS())
1638 { 1639 {
1639 if (virtFileSystemSpec->IsStreamInMem()) 1640 int index_in_Files = virtFileSystemSpec->Index_of_MainExtractedFile_in_Files;
1641 if (index_in_Files < 0)
1640 { 1642 {
1641 const CVirtFile &file = virtFileSystemSpec->Files[0]; 1643 if (virtFileSystemSpec->Files.Size() != 1)
1642 1644 {
1643 size_t streamSize = (size_t)file.Size; 1645 MessageBox_Error_HRESULT(E_FAIL);
1644 CBufInStream *bufInStreamSpec = new CBufInStream; 1646 return;
1645 CMyComPtr<IInStream> bufInStream = bufInStreamSpec; 1647 }
1646 bufInStreamSpec->Init(file.Data, streamSize, virtFileSystem); 1648 // it's not expected case that index was not set, but we support that case
1647 1649 index_in_Files = 0;
1648 HRESULT res = OpenAsArc_Msg(bufInStream, tempFileInfo, fullVirtPath, type ? type : L"" 1650 }
1651 {
1652 const CVirtFile &file = virtFileSystemSpec->Files[index_in_Files];
1653 CMyComPtr2_Create<IInStream, CBufInStream> bufInStream;
1654 bufInStream->Init(file.Data, file.WrittenSize, virtFileSystem);
1655 const HRESULT res = OpenAsArc_Msg(bufInStream, tempFileInfo,
1656 fullVirtPath, type ? type : L""
1649 // , encrypted 1657 // , encrypted
1650 // , true // showErrorMessage 1658 // , true // showErrorMessage
1651 ); 1659 );
1652
1653 if (res == S_OK) 1660 if (res == S_OK)
1654 { 1661 {
1662 if (virtFileSystemSpec->Index_of_ZoneBuf_AltStream_in_Files >= 0
1663 && !_parentFolders.IsEmpty())
1664 {
1665 const CVirtFile &fileZone = virtFileSystemSpec->Files[
1666 virtFileSystemSpec->Index_of_ZoneBuf_AltStream_in_Files];
1667 _parentFolders.Back().ZoneBuf.CopyFrom(fileZone.Data, fileZone.WrittenSize);
1668 }
1669
1655 tempDirectory.DisableDeleting(); 1670 tempDirectory.DisableDeleting();
1656 RefreshListCtrl(); 1671 RefreshListCtrl();
1657 return; 1672 return;
1658 } 1673 }
1659
1660 if (res == E_ABORT || res != S_FALSE) 1674 if (res == E_ABORT || res != S_FALSE)
1661 return; 1675 return;
1662 if (!tryExternal) 1676 if (!tryExternal)
1663 return; 1677 return;
1664
1665 tryAsArchive = false; 1678 tryAsArchive = false;
1666 if (virtFileSystemSpec->FlushToDisk(true) != S_OK) 1679 if (virtFileSystemSpec->FlushToDisk(true) != S_OK)
1667 return; 1680 return;
@@ -1684,7 +1697,7 @@ void CPanel::OpenItemInArchive(unsigned index, bool tryInternal, bool tryExterna
1684 1697
1685 if (tryAsArchive) 1698 if (tryAsArchive)
1686 { 1699 {
1687 HRESULT res = OpenAsArc_Msg(NULL, tempFileInfo, fullVirtPath, type ? type : L"" 1700 const HRESULT res = OpenAsArc_Msg(NULL, tempFileInfo, fullVirtPath, type ? type : L""
1688 // , encrypted 1701 // , encrypted
1689 // , true // showErrorMessage 1702 // , true // showErrorMessage
1690 ); 1703 );
@@ -1732,7 +1745,7 @@ void CPanel::OpenItemInArchive(unsigned index, bool tryInternal, bool tryExterna
1732 return; 1745 return;
1733 } 1746 }
1734 1747
1735 tpi->Window = (HWND)(*this); 1748 tpi->Window = (HWND)*this;
1736 tpi->FullPathFolderPrefix = _currentFolderPrefix; 1749 tpi->FullPathFolderPrefix = _currentFolderPrefix;
1737 tpi->FileIndex = index; 1750 tpi->FileIndex = index;
1738 tpi->RelPath = relPath; 1751 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()
1438 return; 1438 return;
1439 if (!AutoRefresh_Mode) 1439 if (!AutoRefresh_Mode)
1440 return; 1440 return;
1441 CMyComPtr<IFolderWasChanged> folderWasChanged; 1441 if (!_folder) // it's unexpected case, but we use it as additional protection.
1442 if (_folder.QueryInterface(IID_IFolderWasChanged, &folderWasChanged) != S_OK)
1443 return;
1444 Int32 wasChanged;
1445 if (folderWasChanged->WasChanged(&wasChanged) != S_OK)
1446 return;
1447 if (wasChanged == 0)
1448 return; 1442 return;
1443 {
1444 CMyComPtr<IFolderWasChanged> folderWasChanged;
1445 _folder.QueryInterface(IID_IFolderWasChanged, &folderWasChanged);
1446 if (!folderWasChanged)
1447 return;
1448 Int32 wasChanged;
1449 if (folderWasChanged->WasChanged(&wasChanged) != S_OK || wasChanged == 0)
1450 return;
1451 }
1449 OnReload(true); // onTimer 1452 OnReload(true); // onTimer
1450} 1453}
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()
785 wchar_t selectSizeString[32]; 785 wchar_t selectSizeString[32];
786 selectSizeString[0] = 0; 786 selectSizeString[0] = 0;
787 787
788 if (indices.Size() > 0) 788 if (!indices.IsEmpty())
789 { 789 {
790 // for (unsigned ttt = 0; ttt < 1000; ttt++) { 790 // for (unsigned ttt = 0; ttt < 1000; ttt++) {
791 UInt64 totalSize = 0; 791 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
80 80
81 UpdateCallbackSpec->Init(); 81 UpdateCallbackSpec->Init();
82 82
83 if (panel._parentFolders.Size() > 0) 83 if (!panel._parentFolders.IsEmpty())
84 { 84 {
85 const CFolderLink &fl = panel._parentFolders.Back(); 85 const CFolderLink &fl = panel._parentFolders.Back();
86 UpdateCallbackSpec->PasswordIsDefined = fl.UsePassword; 86 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[] =
78#define IS_DEFINED_VAL(v) ((v) != UNDEFINED_VAL) 78#define IS_DEFINED_VAL(v) ((v) != UNDEFINED_VAL)
79 79
80CProgressSync::CProgressSync(): 80CProgressSync::CProgressSync():
81 _stopped(false), _paused(false), 81 _stopped(false),
82 _bytesProgressMode(true), 82 _paused(false),
83 _filesProgressMode(false),
83 _isDir(false), 84 _isDir(false),
84 _totalBytes(UNDEFINED_VAL), _completedBytes(0), 85 _totalBytes(UNDEFINED_VAL), _completedBytes(0),
85 _totalFiles(UNDEFINED_VAL), _curFiles(0), 86 _totalFiles(UNDEFINED_VAL), _curFiles(0),
@@ -108,6 +109,13 @@ HRESULT CProgressSync::CheckStop()
108 } 109 }
109} 110}
110 111
112void CProgressSync::Clear_Stop_Status()
113{
114 CRITICAL_LOCK
115 if (_stopped)
116 _stopped = false;
117}
118
111HRESULT CProgressSync::ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir) 119HRESULT CProgressSync::ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir)
112{ 120{
113 { 121 {
@@ -242,27 +250,27 @@ void CProgressSync::AddError_Code_Name(HRESULT systemError, const wchar_t *name)
242} 250}
243 251
244CProgressDialog::CProgressDialog(): 252CProgressDialog::CProgressDialog():
245 _timer(0), 253 _isDir(false),
246 CompressingMode(true), 254 _wasCreated(false),
247 MainWindow(NULL) 255 _needClose(false),
256 _errorsWereDisplayed(false),
257 _waitCloseByCancelButton(false),
258 _cancelWasPressed(false),
259 _inCancelMessageBox(false),
260 _externalCloseMessageWasReceived(false),
261 _background(false),
262 WaitMode(false),
263 MessagesDisplayed(false),
264 CompressingMode(true),
265 ShowCompressionInfo(true),
266 _numPostedMessages(0),
267 _numAutoSizeMessages(0),
268 _numMessages(0),
269 _timer(0),
270 IconID(-1),
271 MainWindow(NULL)
248{ 272{
249 _isDir = false; 273
250
251 _numMessages = 0;
252 IconID = -1;
253 MessagesDisplayed = false;
254 _wasCreated = false;
255 _needClose = false;
256 _inCancelMessageBox = false;
257 _externalCloseMessageWasReceived = false;
258
259 _numPostedMessages = 0;
260 _numAutoSizeMessages = 0;
261 _errorsWereDisplayed = false;
262 _waitCloseByCancelButton = false;
263 _cancelWasPressed = false;
264 ShowCompressionInfo = true;
265 WaitMode = false;
266 if (_dialogCreatedEvent.Create() != S_OK) 274 if (_dialogCreatedEvent.Create() != S_OK)
267 throw 1334987; 275 throw 1334987;
268 if (_createDialogEvent.Create() != S_OK) 276 if (_createDialogEvent.Create() != S_OK)
@@ -357,8 +365,6 @@ bool CProgressDialog::OnInit()
357 _filesStr_Prev.Empty(); 365 _filesStr_Prev.Empty();
358 _filesTotStr_Prev.Empty(); 366 _filesTotStr_Prev.Empty();
359 367
360 _foreground = true;
361
362 m_ProgressBar.Attach(GetItem(IDC_PROGRESS1)); 368 m_ProgressBar.Attach(GetItem(IDC_PROGRESS1));
363 _messageList.Attach(GetItem(IDL_PROGRESS_MESSAGES)); 369 _messageList.Attach(GetItem(IDL_PROGRESS_MESSAGES));
364 _messageList.SetUnicodeFormat(); 370 _messageList.SetUnicodeFormat();
@@ -388,9 +394,8 @@ bool CProgressDialog::OnInit()
388 SetPauseText(); 394 SetPauseText();
389 SetPriorityText(); 395 SetPriorityText();
390 396
391 _messageList.InsertColumn(0, L"", 30); 397 _messageList.InsertColumn(0, L"", 40);
392 _messageList.InsertColumn(1, L"", 600); 398 _messageList.InsertColumn(1, L"", 460);
393
394 _messageList.SetColumnWidthAuto(0); 399 _messageList.SetColumnWidthAuto(0);
395 _messageList.SetColumnWidthAuto(1); 400 _messageList.SetColumnWidthAuto(1);
396 401
@@ -690,7 +695,7 @@ static UInt64 MyMultAndDiv(UInt64 mult1, UInt64 mult2, UInt64 divider)
690void CProgressDialog::UpdateStatInfo(bool showAll) 695void CProgressDialog::UpdateStatInfo(bool showAll)
691{ 696{
692 UInt64 total, completed, totalFiles, completedFiles, inSize, outSize; 697 UInt64 total, completed, totalFiles, completedFiles, inSize, outSize;
693 bool bytesProgressMode; 698 bool filesProgressMode;
694 699
695 bool titleFileName_Changed; 700 bool titleFileName_Changed;
696 bool curFilePath_Changed; 701 bool curFilePath_Changed;
@@ -704,7 +709,7 @@ void CProgressDialog::UpdateStatInfo(bool showAll)
704 completedFiles = Sync._curFiles; 709 completedFiles = Sync._curFiles;
705 inSize = Sync._inSize; 710 inSize = Sync._inSize;
706 outSize = Sync._outSize; 711 outSize = Sync._outSize;
707 bytesProgressMode = Sync._bytesProgressMode; 712 filesProgressMode = Sync._filesProgressMode;
708 713
709 GetChangedString(Sync._titleFileName, _titleFileName, titleFileName_Changed); 714 GetChangedString(Sync._titleFileName, _titleFileName, titleFileName_Changed);
710 GetChangedString(Sync._filePath, _filePath, curFilePath_Changed); 715 GetChangedString(Sync._filePath, _filePath, curFilePath_Changed);
@@ -719,8 +724,8 @@ void CProgressDialog::UpdateStatInfo(bool showAll)
719 724
720 UInt32 curTime = ::GetTickCount(); 725 UInt32 curTime = ::GetTickCount();
721 726
722 const UInt64 progressTotal = bytesProgressMode ? total : totalFiles; 727 const UInt64 progressTotal = filesProgressMode ? totalFiles : total;
723 const UInt64 progressCompleted = bytesProgressMode ? completed : completedFiles; 728 const UInt64 progressCompleted = filesProgressMode ? completedFiles : completed;
724 { 729 {
725 if (IS_UNDEFINED_VAL(progressTotal)) 730 if (IS_UNDEFINED_VAL(progressTotal))
726 { 731 {
@@ -900,7 +905,7 @@ void CProgressDialog::UpdateStatInfo(bool showAll)
900 { 905 {
901 UString s = _status; 906 UString s = _status;
902 ReduceString(s, _numReduceSymbols); 907 ReduceString(s, _numReduceSymbols);
903 SetItemText(IDT_PROGRESS_STATUS, _status); 908 SetItemText(IDT_PROGRESS_STATUS, s);
904 } 909 }
905 910
906 if (curFilePath_Changed) 911 if (curFilePath_Changed)
@@ -1086,12 +1091,10 @@ void CProgressDialog::SetTitleText()
1086 } 1091 }
1087 if (IS_DEFINED_VAL(_prevPercentValue)) 1092 if (IS_DEFINED_VAL(_prevPercentValue))
1088 { 1093 {
1089 char temp[32]; 1094 s.Add_UInt64(_prevPercentValue);
1090 ConvertUInt64ToString(_prevPercentValue, temp);
1091 s += temp;
1092 s.Add_Char('%'); 1095 s.Add_Char('%');
1093 } 1096 }
1094 if (!_foreground) 1097 if (_background)
1095 { 1098 {
1096 s.Add_Space(); 1099 s.Add_Space();
1097 s += _backgrounded_String; 1100 s += _backgrounded_String;
@@ -1138,17 +1141,17 @@ void CProgressDialog::OnPauseButton()
1138 1141
1139void CProgressDialog::SetPriorityText() 1142void CProgressDialog::SetPriorityText()
1140{ 1143{
1141 SetItemText(IDB_PROGRESS_BACKGROUND, _foreground ? 1144 SetItemText(IDB_PROGRESS_BACKGROUND, _background ?
1142 _background_String : 1145 _foreground_String :
1143 _foreground_String); 1146 _background_String);
1144 SetTitleText(); 1147 SetTitleText();
1145} 1148}
1146 1149
1147void CProgressDialog::OnPriorityButton() 1150void CProgressDialog::OnPriorityButton()
1148{ 1151{
1149 _foreground = !_foreground; 1152 _background = !_background;
1150 #ifndef UNDER_CE 1153 #ifndef UNDER_CE
1151 SetPriorityClass(GetCurrentProcess(), _foreground ? NORMAL_PRIORITY_CLASS: IDLE_PRIORITY_CLASS); 1154 SetPriorityClass(GetCurrentProcess(), _background ? IDLE_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS);
1152 #endif 1155 #endif
1153 SetPriorityText(); 1156 SetPriorityText();
1154} 1157}
@@ -1184,12 +1187,16 @@ void CProgressDialog::AddMessage(LPCWSTR message)
1184 _numMessages++; 1187 _numMessages++;
1185} 1188}
1186 1189
1187static unsigned GetNumDigits(UInt32 val) 1190static unsigned GetNumDigits(unsigned val)
1188{ 1191{
1189 unsigned i; 1192 unsigned i = 0;
1190 for (i = 0; val >= 10; i++) 1193 for (;;)
1194 {
1195 i++;
1191 val /= 10; 1196 val /= 10;
1192 return i; 1197 if (val == 0)
1198 return i;
1199 }
1193} 1200}
1194 1201
1195void CProgressDialog::UpdateMessagesDialog() 1202void CProgressDialog::UpdateMessagesDialog()
@@ -1197,7 +1204,7 @@ void CProgressDialog::UpdateMessagesDialog()
1197 UStringVector messages; 1204 UStringVector messages;
1198 { 1205 {
1199 NSynchronization::CCriticalSectionLock lock(Sync._cs); 1206 NSynchronization::CCriticalSectionLock lock(Sync._cs);
1200 unsigned num = Sync.Messages.Size(); 1207 const unsigned num = Sync.Messages.Size();
1201 if (num > _numPostedMessages) 1208 if (num > _numPostedMessages)
1202 { 1209 {
1203 messages.ClearAndReserve(num - _numPostedMessages); 1210 messages.ClearAndReserve(num - _numPostedMessages);
@@ -1210,7 +1217,11 @@ void CProgressDialog::UpdateMessagesDialog()
1210 { 1217 {
1211 FOR_VECTOR (i, messages) 1218 FOR_VECTOR (i, messages)
1212 AddMessage(messages[i]); 1219 AddMessage(messages[i]);
1213 if (_numAutoSizeMessages < 256 || GetNumDigits(_numPostedMessages) > GetNumDigits(_numAutoSizeMessages)) 1220 // SetColumnWidthAuto() can be slow for big number of files.
1221 if (_numPostedMessages < 1000000 || _numAutoSizeMessages < 100)
1222 if (_numAutoSizeMessages < 100 ||
1223 GetNumDigits(_numPostedMessages) >
1224 GetNumDigits(_numAutoSizeMessages))
1214 { 1225 {
1215 _messageList.SetColumnWidthAuto(0); 1226 _messageList.SetColumnWidthAuto(0);
1216 _messageList.SetColumnWidthAuto(1); 1227 _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
33{ 33{
34 bool _stopped; 34 bool _stopped;
35 bool _paused; 35 bool _paused;
36
37public: 36public:
38 bool _bytesProgressMode; 37 bool _filesProgressMode;
39 bool _isDir; 38 bool _isDir;
40 UInt64 _totalBytes; 39 UInt64 _totalBytes;
41 UInt64 _completedBytes; 40 UInt64 _completedBytes;
@@ -73,13 +72,14 @@ public:
73 _paused = val; 72 _paused = val;
74 } 73 }
75 74
76 void Set_BytesProgressMode(bool bytesProgressMode) 75 void Set_FilesProgressMode(bool filesProgressMode)
77 { 76 {
78 NWindows::NSynchronization::CCriticalSectionLock lock(_cs); 77 NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
79 _bytesProgressMode = bytesProgressMode; 78 _filesProgressMode = filesProgressMode;
80 } 79 }
81 80
82 HRESULT CheckStop(); 81 HRESULT CheckStop();
82 void Clear_Stop_Status();
83 HRESULT ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir = false); 83 HRESULT ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir = false);
84 84
85 HRESULT Set_NumFilesTotal(UInt64 val); 85 HRESULT Set_NumFilesTotal(UInt64 val);
@@ -102,12 +102,32 @@ public:
102 bool ThereIsMessage() const { return !Messages.IsEmpty() || FinalMessage.ThereIsMessage(); } 102 bool ThereIsMessage() const { return !Messages.IsEmpty() || FinalMessage.ThereIsMessage(); }
103}; 103};
104 104
105
105class CProgressDialog: public NWindows::NControl::CModalDialog 106class CProgressDialog: public NWindows::NControl::CModalDialog
106{ 107{
108 bool _isDir;
109 bool _wasCreated;
110 bool _needClose;
111 bool _errorsWereDisplayed;
112 bool _waitCloseByCancelButton;
113 bool _cancelWasPressed;
114 bool _inCancelMessageBox;
115 bool _externalCloseMessageWasReceived;
116 bool _background;
117public:
118 bool WaitMode;
119 bool MessagesDisplayed; // = true if user pressed OK on all messages or there are no messages.
120 bool CompressingMode;
121 bool ShowCompressionInfo;
122
123private:
124 unsigned _numPostedMessages;
125 unsigned _numAutoSizeMessages;
126 unsigned _numMessages;
127
107 UString _titleFileName; 128 UString _titleFileName;
108 UString _filePath; 129 UString _filePath;
109 UString _status; 130 UString _status;
110 bool _isDir;
111 131
112 UString _background_String; 132 UString _background_String;
113 UString _backgrounded_String; 133 UString _backgrounded_String;
@@ -152,7 +172,6 @@ class CProgressDialog: public NWindows::NControl::CModalDialog
152 NWindows::NControl::CProgressBar m_ProgressBar; 172 NWindows::NControl::CProgressBar m_ProgressBar;
153 NWindows::NControl::CListView _messageList; 173 NWindows::NControl::CListView _messageList;
154 174
155 unsigned _numMessages;
156 UStringVector _messageStrings; 175 UStringVector _messageStrings;
157 176
158 // #ifdef __ITaskbarList3_INTERFACE_DEFINED__ 177 // #ifdef __ITaskbarList3_INTERFACE_DEFINED__
@@ -175,28 +194,10 @@ class CProgressDialog: public NWindows::NControl::CModalDialog
175 UString _filesStr_Prev; 194 UString _filesStr_Prev;
176 UString _filesTotStr_Prev; 195 UString _filesTotStr_Prev;
177 196
197 unsigned _numReduceSymbols;
178 unsigned _prevSpeed_MoveBits; 198 unsigned _prevSpeed_MoveBits;
179 UInt64 _prevSpeed; 199 UInt64 _prevSpeed;
180 200
181 bool _foreground;
182
183 unsigned _numReduceSymbols;
184
185 bool _wasCreated;
186 bool _needClose;
187
188 unsigned _numPostedMessages;
189 UInt32 _numAutoSizeMessages;
190
191 bool _errorsWereDisplayed;
192
193 bool _waitCloseByCancelButton;
194 bool _cancelWasPressed;
195
196 bool _inCancelMessageBox;
197 bool _externalCloseMessageWasReceived;
198
199
200 // #ifdef __ITaskbarList3_INTERFACE_DEFINED__ 201 // #ifdef __ITaskbarList3_INTERFACE_DEFINED__
201 void SetTaskbarProgressState(TBPFLAG tbpFlags) 202 void SetTaskbarProgressState(TBPFLAG tbpFlags)
202 { 203 {
@@ -244,14 +245,10 @@ class CProgressDialog: public NWindows::NControl::CModalDialog
244 void ShowAfterMessages(HWND wndParent); 245 void ShowAfterMessages(HWND wndParent);
245 246
246 void CheckNeedClose(); 247 void CheckNeedClose();
248
247public: 249public:
248 CProgressSync Sync; 250 CProgressSync Sync;
249 bool CompressingMode;
250 bool WaitMode;
251 bool ShowCompressionInfo;
252 bool MessagesDisplayed; // = true if user pressed OK on all messages or there are no messages.
253 int IconID; 251 int IconID;
254
255 HWND MainWindow; 252 HWND MainWindow;
256 #ifndef Z7_SFX 253 #ifndef Z7_SFX
257 UString MainTitle; 254 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)
86 if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) == ERROR_SUCCESS) 86 if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) == ERROR_SUCCESS)
87 { 87 {
88 bool enabled; 88 bool enabled;
89 if (key.QueryValue(value, enabled) == ERROR_SUCCESS) 89 if (key.GetValue_bool_IfOk(value, enabled) == ERROR_SUCCESS)
90 return enabled; 90 return enabled;
91 } 91 }
92 return defaultValue; 92 return defaultValue;
93} 93}
94 94
95static void ReadOption(CKey &key, LPCTSTR value, bool &dest) 95static void ReadOption(CKey &key, LPCTSTR name, bool &dest)
96{ 96{
97 bool enabled = false; 97 key.GetValue_bool_IfOk(name, dest);
98 if (key.QueryValue(value, enabled) == ERROR_SUCCESS)
99 dest = enabled;
100} 98}
101 99
102/* 100/*
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()
161 needSetCur = false; 161 needSetCur = false;
162 } 162 }
163 { 163 {
164 _ramSize = (UInt64)(sizeof(size_t)) << 29; 164 _ramSize = (size_t)sizeof(size_t) << 29;
165 _ramSize_Defined = NSystem::GetRamSize(_ramSize); 165 _ramSize_Defined = NSystem::GetRamSize(_ramSize);
166 UString s; 166 UString s;
167 if (_ramSize_Defined) 167 if (_ramSize_Defined)
@@ -198,10 +198,10 @@ bool CSettingsPage::OnInit()
198 198
199 199
200 { 200 {
201 UInt64 ramSize = (UInt64)sizeof(size_t) << 29; 201 size_t ramSize = (size_t)sizeof(size_t) << 29;
202 const bool ramSize_defined = NWindows::NSystem::GetRamSize(ramSize); 202 const bool ramSize_defined = NWindows::NSystem::GetRamSize(ramSize);
203 // ramSize *= 10; // for debug 203 // ramSize *= 10; // for debug
204 UInt64 ramSize_GB = (ramSize + (1u << 29)) >> 30; 204 UInt32 ramSize_GB = (UInt32)(((UInt64)ramSize + (1u << 29)) >> 30);
205 if (ramSize_GB == 0) 205 if (ramSize_GB == 0)
206 ramSize_GB = 1; 206 ramSize_GB = 1;
207 UString s ("GB"); 207 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(
109 iconIndex = shFileInfo.iIcon; 109 iconIndex = shFileInfo.iIcon;
110 // we use SHGFI_USEFILEATTRIBUTES, and 110 // we use SHGFI_USEFILEATTRIBUTES, and
111 // (res != 0) is expected for main cases, even if there are no such file. 111 // (res != 0) is expected for main cases, even if there are no such file.
112 // (res == 0) for path with kSuperPrefix \\?\ 112 // (res == 0) for path with kSuperPrefix "\\?\"
113 // Also SHGFI_USEFILEATTRIBUTES still returns icon inside exe. 113 // Also SHGFI_USEFILEATTRIBUTES still returns icon inside exe.
114 // So we can use SHGFI_USEFILEATTRIBUTES for any case. 114 // So we can use SHGFI_USEFILEATTRIBUTES for any case.
115 // UString temp = fs2us(path); // for debug 115 // 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
113 return ProgressDialog->Sync.CheckStop(); 113 return ProgressDialog->Sync.CheckStop();
114} 114}
115 115
116
117Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Start(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 size, Int32 updateMode))
118{
119 return MoveArc_Start_Base(srcTempPath, destFinalPath, size, updateMode);
120}
121
122Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Progress(UInt64 totalSize, UInt64 currentSize))
123{
124 return MoveArc_Progress_Base(totalSize, currentSize);
125}
126
127Z7_COM7F_IMF(CUpdateCallback100Imp::MoveArc_Finish())
128{
129 return MoveArc_Finish_Base();
130}
131
132Z7_COM7F_IMF(CUpdateCallback100Imp::Before_ArcReopen())
133{
134 ProgressDialog->Sync.Clear_Stop_Status();
135 return S_OK;
136}
137
138
116Z7_COM7F_IMF(CUpdateCallback100Imp::CryptoGetTextPassword(BSTR *password)) 139Z7_COM7F_IMF(CUpdateCallback100Imp::CryptoGetTextPassword(BSTR *password))
117{ 140{
118 *password = NULL; 141 *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 @@
16class CUpdateCallback100Imp Z7_final: 16class CUpdateCallback100Imp Z7_final:
17 public IFolderArchiveUpdateCallback, 17 public IFolderArchiveUpdateCallback,
18 public IFolderArchiveUpdateCallback2, 18 public IFolderArchiveUpdateCallback2,
19 public IFolderArchiveUpdateCallback_MoveArc,
19 public IFolderScanProgress, 20 public IFolderScanProgress,
20 public ICryptoGetTextPassword2, 21 public ICryptoGetTextPassword2,
21 public ICryptoGetTextPassword, 22 public ICryptoGetTextPassword,
@@ -24,9 +25,10 @@ class CUpdateCallback100Imp Z7_final:
24 public CUpdateCallbackGUI2, 25 public CUpdateCallbackGUI2,
25 public CMyUnknownImp 26 public CMyUnknownImp
26{ 27{
27 Z7_COM_UNKNOWN_IMP_7( 28 Z7_COM_UNKNOWN_IMP_8(
28 IFolderArchiveUpdateCallback, 29 IFolderArchiveUpdateCallback,
29 IFolderArchiveUpdateCallback2, 30 IFolderArchiveUpdateCallback2,
31 IFolderArchiveUpdateCallback_MoveArc,
30 IFolderScanProgress, 32 IFolderScanProgress,
31 ICryptoGetTextPassword2, 33 ICryptoGetTextPassword2,
32 ICryptoGetTextPassword, 34 ICryptoGetTextPassword,
@@ -36,6 +38,7 @@ class CUpdateCallback100Imp Z7_final:
36 Z7_IFACE_COM7_IMP(IProgress) 38 Z7_IFACE_COM7_IMP(IProgress)
37 Z7_IFACE_COM7_IMP(IFolderArchiveUpdateCallback) 39 Z7_IFACE_COM7_IMP(IFolderArchiveUpdateCallback)
38 Z7_IFACE_COM7_IMP(IFolderArchiveUpdateCallback2) 40 Z7_IFACE_COM7_IMP(IFolderArchiveUpdateCallback2)
41 Z7_IFACE_COM7_IMP(IFolderArchiveUpdateCallback_MoveArc)
39 Z7_IFACE_COM7_IMP(IFolderScanProgress) 42 Z7_IFACE_COM7_IMP(IFolderScanProgress)
40 Z7_IFACE_COM7_IMP(ICryptoGetTextPassword2) 43 Z7_IFACE_COM7_IMP(ICryptoGetTextPassword2)
41 Z7_IFACE_COM7_IMP(ICryptoGetTextPassword) 44 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)
81{ 81{
82 Clear(); 82 Clear();
83 CByteBuffer buf; 83 CByteBuffer buf;
84 UInt32 size;
85 { 84 {
86 NSynchronization::CCriticalSectionLock lock(g_CS); 85 NSynchronization::CCriticalSectionLock lock(g_CS);
87 CKey key; 86 CKey key;
88 if (key.Open(HKEY_CURRENT_USER, kCulumnsKeyName, KEY_READ) != ERROR_SUCCESS) 87 if (key.Open(HKEY_CURRENT_USER, kCulumnsKeyName, KEY_READ) != ERROR_SUCCESS)
89 return; 88 return;
90 if (key.QueryValue(GetSystemString(id), buf, size) != ERROR_SUCCESS) 89 if (key.QueryValue_Binary(GetSystemString(id), buf) != ERROR_SUCCESS)
91 return; 90 return;
92 } 91 }
92 unsigned size = (unsigned)buf.Size();
93 if (size < kListViewHeaderSize) 93 if (size < kListViewHeaderSize)
94 return; 94 return;
95 UInt32 version; 95 UInt32 version;
@@ -104,7 +104,9 @@ void CListViewInfo::Read(const UString &id)
104 size -= kListViewHeaderSize; 104 size -= kListViewHeaderSize;
105 if (size % kColumnInfoSize != 0) 105 if (size % kColumnInfoSize != 0)
106 return; 106 return;
107 unsigned numItems = size / kColumnInfoSize; 107 if (size > 1000 * kColumnInfoSize)
108 return;
109 const unsigned numItems = size / kColumnInfoSize;
108 Columns.ClearAndReserve(numItems); 110 Columns.ClearAndReserve(numItems);
109 for (unsigned i = 0; i < numItems; i++) 111 for (unsigned i = 0; i < numItems; i++)
110 { 112 {
@@ -161,8 +163,7 @@ void CWindowInfo::Save() const
161 163
162static bool QueryBuf(CKey &key, LPCTSTR name, CByteBuffer &buf, UInt32 dataSize) 164static bool QueryBuf(CKey &key, LPCTSTR name, CByteBuffer &buf, UInt32 dataSize)
163{ 165{
164 UInt32 size; 166 return key.QueryValue_Binary(name, buf) == ERROR_SUCCESS && buf.Size() == dataSize;
165 return key.QueryValue(name, buf, size) == ERROR_SUCCESS && size == dataSize;
166} 167}
167 168
168void CWindowInfo::Read(bool &windowPosDefined, bool &panelInfoDefined) 169void CWindowInfo::Read(bool &windowPosDefined, bool &panelInfoDefined)
@@ -206,7 +207,7 @@ static bool ReadUi32Val(const TCHAR *name, UInt32 &value)
206 CKey key; 207 CKey key;
207 if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS) 208 if (key.Open(HKEY_CURRENT_USER, kCUBasePath, KEY_READ) != ERROR_SUCCESS)
208 return false; 209 return false;
209 return key.QueryValue(name, value) == ERROR_SUCCESS; 210 return key.GetValue_UInt32_IfOk(name, value) == ERROR_SUCCESS;
210} 211}
211 212
212void SaveToolbarsMask(UInt32 toolbarMask) 213void SaveToolbarsMask(UInt32 toolbarMask)
@@ -229,7 +230,7 @@ void CListMode::Save() const
229{ 230{
230 UInt32 t = 0; 231 UInt32 t = 0;
231 for (int i = 0; i < 2; i++) 232 for (int i = 0; i < 2; i++)
232 t |= ((Panels[i]) & 0xFF) << (i * 8); 233 t |= (Panels[i] & 0xFF) << (i * 8);
233 SaveUi32Val(kListMode, t); 234 SaveUi32Val(kListMode, t);
234} 235}
235 236
@@ -241,7 +242,7 @@ void CListMode::Read()
241 return; 242 return;
242 for (int i = 0; i < 2; i++) 243 for (int i = 0; i < 2; i++)
243 { 244 {
244 Panels[i] = (t & 0xFF); 245 Panels[i] = t & 0xFF;
245 t >>= 8; 246 t >>= 8;
246 } 247 }
247} 248}
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 @@
25#define IDM_CRC64 103 25#define IDM_CRC64 103
26#define IDM_SHA1 104 26#define IDM_SHA1 104
27#define IDM_SHA256 105 27#define IDM_SHA256 105
28#define IDM_XXH64 106 28#define IDM_SHA384 106
29#define IDM_BLAKE2SP 107 29#define IDM_SHA512 107
30 30#define IDM_SHA3_256 108
31#define IDM_XXH64 120
32#define IDM_BLAKE2SP 121
33#define IDM_MD5 122
31 34
32#define IDM_FILE 500 35#define IDM_FILE 500
33#define IDM_EDIT 501 36#define IDM_EDIT 501
@@ -134,7 +137,7 @@
134#define IDS_COPY_TO 6002 137#define IDS_COPY_TO 6002
135#define IDS_MOVE_TO 6003 138#define IDS_MOVE_TO 6003
136#define IDS_COPYING 6004 139#define IDS_COPYING 6004
137#define IDS_MOVING 6005 140// #define IDS_MOVING 6005
138#define IDS_RENAMING 6006 141#define IDS_RENAMING 6006
139 142
140#define IDS_OPERATION_IS_NOT_SUPPORTED 6008 143#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
58 MENUITEM "CRC-32", IDM_CRC32 58 MENUITEM "CRC-32", IDM_CRC32
59 MENUITEM "CRC-64", IDM_CRC64 59 MENUITEM "CRC-64", IDM_CRC64
60 MENUITEM "XXH64", IDM_XXH64 60 MENUITEM "XXH64", IDM_XXH64
61 MENUITEM "MD5", IDM_MD5
61 MENUITEM "SHA-1", IDM_SHA1 62 MENUITEM "SHA-1", IDM_SHA1
62 MENUITEM "SHA-256", IDM_SHA256 63 MENUITEM "SHA-256", IDM_SHA256
64 MENUITEM "SHA-384", IDM_SHA384
65 MENUITEM "SHA-512", IDM_SHA512
66 MENUITEM "SHA3-256", IDM_SHA3_256
63 MENUITEM "BLAKE2sp", IDM_BLAKE2SP 67 MENUITEM "BLAKE2sp", IDM_BLAKE2SP
64 MENUITEM "*", IDM_HASH_ALL 68 MENUITEM "*", IDM_HASH_ALL
65 END 69 END
@@ -202,7 +206,7 @@ BEGIN
202 IDS_COPY_TO "Copy to:" 206 IDS_COPY_TO "Copy to:"
203 IDS_MOVE_TO "Move to:" 207 IDS_MOVE_TO "Move to:"
204 IDS_COPYING "Copying..." 208 IDS_COPYING "Copying..."
205 IDS_MOVING "Moving..." 209// IDS_MOVING "Moving..."
206 IDS_RENAMING "Renaming..." 210 IDS_RENAMING "Renaming..."
207 211
208 IDS_OPERATION_IS_NOT_SUPPORTED "Operation is not supported." 212 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 @@
6#define IDS_OPENNING 3303 6#define IDS_OPENNING 3303
7#define IDS_SCANNING 3304 7#define IDS_SCANNING 3304
8 8
9#define IDS_MOVING 6005
10
9#define IDS_CHECKSUM_CALCULATING 7500 11#define IDS_CHECKSUM_CALCULATING 7500
10#define IDS_CHECKSUM_INFORMATION 7501 12#define IDS_CHECKSUM_INFORMATION 7501
11#define IDS_CHECKSUM_CRC_DATA 7502 13#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
6 6
7 IDS_PROGRESS_TESTING "Testing" 7 IDS_PROGRESS_TESTING "Testing"
8 8
9 IDS_MOVING "Moving..."
10
9 IDS_CHECKSUM_CALCULATING "Checksum calculating..." 11 IDS_CHECKSUM_CALCULATING "Checksum calculating..."
10 IDS_CHECKSUM_INFORMATION "Checksum information" 12 IDS_CHECKSUM_INFORMATION "Checksum information"
11 IDS_CHECKSUM_CRC_DATA "CRC checksum for data:" 13 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
61{ 61{
62 CTotalBenchRes Enc; 62 CTotalBenchRes Enc;
63 CTotalBenchRes Dec; 63 CTotalBenchRes Dec;
64 #ifdef PRINT_ITER_TIME 64#ifdef PRINT_ITER_TIME
65 DWORD Ticks; 65 DWORD Ticks;
66 #endif 66#endif
67 // CBenchInfo EncInfo; // for debug 67 // CBenchInfo EncInfo; // for debug
68 // CBenchPassResult() {}; 68 // CBenchPassResult() {};
69}; 69};
@@ -97,21 +97,9 @@ struct CTotalBenchRes2: public CTotalBenchRes
97struct CSyncData 97struct CSyncData
98{ 98{
99 UInt32 NumPasses_Finished; 99 UInt32 NumPasses_Finished;
100 100#ifdef PRINT_ITER_TIME
101 // UInt64 NumEncProgress; // for debug
102 // UInt64 NumDecProgress; // for debug
103 // CBenchInfo EncInfo; // for debug
104
105 CTotalBenchRes2 Enc_BenchRes_1;
106 CTotalBenchRes2 Enc_BenchRes;
107
108 CTotalBenchRes2 Dec_BenchRes_1;
109 CTotalBenchRes2 Dec_BenchRes;
110
111 #ifdef PRINT_ITER_TIME
112 DWORD TotalTicks; 101 DWORD TotalTicks;
113 #endif 102#endif
114
115 int RatingVector_DeletedIndex; 103 int RatingVector_DeletedIndex;
116 // UInt64 RatingVector_NumDeleted; 104 // UInt64 RatingVector_NumDeleted;
117 105
@@ -124,6 +112,16 @@ struct CSyncData
124 bool NeedPrint_Dec; 112 bool NeedPrint_Dec;
125 bool NeedPrint_Tot; // intermediate Total was updated after current pass 113 bool NeedPrint_Tot; // intermediate Total was updated after current pass
126 114
115 // UInt64 NumEncProgress; // for debug
116 // UInt64 NumDecProgress; // for debug
117 // CBenchInfo EncInfo; // for debug
118
119 CTotalBenchRes2 Enc_BenchRes_1;
120 CTotalBenchRes2 Enc_BenchRes;
121
122 CTotalBenchRes2 Dec_BenchRes_1;
123 CTotalBenchRes2 Dec_BenchRes;
124
127 void Init(); 125 void Init();
128}; 126};
129 127
@@ -161,24 +159,18 @@ void CSyncData::Init()
161struct CBenchProgressSync 159struct CBenchProgressSync
162{ 160{
163 bool Exit; // GUI asks BenchThread to Exit, and BenchThread reads that variable 161 bool Exit; // GUI asks BenchThread to Exit, and BenchThread reads that variable
162 bool TextWasChanged;
163
164 UInt32 NumThreads; 164 UInt32 NumThreads;
165 UInt64 DictSize; 165 UInt64 DictSize;
166 UInt32 NumPasses_Limit; 166 UInt32 NumPasses_Limit;
167 int Level; 167 int Level;
168
169 // must be written by benchmark thread, read by GUI thread */
170 CSyncData sd;
171 CRecordVector<CBenchPassResult> RatingVector;
172
173 NWindows::NSynchronization::CCriticalSection CS;
174 168
175 AString Text; 169 AString Text;
176 bool TextWasChanged;
177 170
178 /* BenchFinish_Task_HRESULT - for result from benchmark code 171 /* BenchFinish_Task_HRESULT - for result from benchmark code
179 BenchFinish_Thread_HRESULT - for Exceptions and service errors 172 BenchFinish_Thread_HRESULT - for Exceptions and service errors
180 these arreos must be shown even if user escapes benchmark */ 173 these arreos must be shown even if user escapes benchmark */
181
182 HRESULT BenchFinish_Task_HRESULT; 174 HRESULT BenchFinish_Task_HRESULT;
183 HRESULT BenchFinish_Thread_HRESULT; 175 HRESULT BenchFinish_Thread_HRESULT;
184 176
@@ -186,6 +178,12 @@ struct CBenchProgressSync
186 UString FreqString_Sync; 178 UString FreqString_Sync;
187 UString FreqString_GUI; 179 UString FreqString_GUI;
188 180
181 // must be written by benchmark thread, read by GUI thread */
182 CRecordVector<CBenchPassResult> RatingVector;
183 CSyncData sd;
184
185 NWindows::NSynchronization::CCriticalSection CS;
186
189 CBenchProgressSync() 187 CBenchProgressSync()
190 { 188 {
191 NumPasses_Limit = 1; 189 NumPasses_Limit = 1;
@@ -258,6 +256,19 @@ struct CThreadBenchmark
258class CBenchmarkDialog: 256class CBenchmarkDialog:
259 public NWindows::NControl::CModalDialog 257 public NWindows::NControl::CModalDialog
260{ 258{
259 bool _finishTime_WasSet;
260
261 bool WasStopped_in_GUI;
262 bool ExitWasAsked_in_GUI;
263 bool NeedRestart;
264
265 bool RamSize_Defined;
266
267public:
268 bool TotalMode;
269
270private:
271
261 NWindows::NControl::CComboBox m_Dictionary; 272 NWindows::NControl::CComboBox m_Dictionary;
262 NWindows::NControl::CComboBox m_NumThreads; 273 NWindows::NControl::CComboBox m_NumThreads;
263 NWindows::NControl::CComboBox m_NumPasses; 274 NWindows::NControl::CComboBox m_NumPasses;
@@ -266,17 +277,11 @@ class CBenchmarkDialog:
266 277
267 UInt32 _startTime; 278 UInt32 _startTime;
268 UInt32 _finishTime; 279 UInt32 _finishTime;
269 bool _finishTime_WasSet;
270
271 bool WasStopped_in_GUI;
272 bool ExitWasAsked_in_GUI;
273 bool NeedRestart;
274 280
275 CMyFont _font; 281 CMyFont _font;
276 282
277 UInt64 RamSize; 283 size_t RamSize;
278 UInt64 RamSize_Limit; 284 size_t RamSize_Limit;
279 bool RamSize_Defined;
280 285
281 UInt32 NumPasses_Finished_Prev; 286 UInt32 NumPasses_Finished_Prev;
282 287
@@ -330,7 +335,6 @@ class CBenchmarkDialog:
330public: 335public:
331 CBenchProgressSync Sync; 336 CBenchProgressSync Sync;
332 337
333 bool TotalMode;
334 CObjectVector<CProperty> Props; 338 CObjectVector<CProperty> Props;
335 339
336 CSysString Bench2Text; 340 CSysString Bench2Text;
@@ -339,11 +343,11 @@ public:
339 CThreadBenchmark _threadBenchmark; 343 CThreadBenchmark _threadBenchmark;
340 344
341 CBenchmarkDialog(): 345 CBenchmarkDialog():
342 _timer(0),
343 WasStopped_in_GUI(false), 346 WasStopped_in_GUI(false),
344 ExitWasAsked_in_GUI(false), 347 ExitWasAsked_in_GUI(false),
345 NeedRestart(false), 348 NeedRestart(false),
346 TotalMode(false) 349 TotalMode(false),
350 _timer(0)
347 {} 351 {}
348 352
349 ~CBenchmarkDialog() Z7_DESTRUCTOR_override; 353 ~CBenchmarkDialog() Z7_DESTRUCTOR_override;
@@ -504,7 +508,8 @@ bool CBenchmarkDialog::OnInit()
504 SetItemTextA(IDT_BENCH_SYS2, s2); 508 SetItemTextA(IDT_BENCH_SYS2, s2);
505 } 509 }
506 { 510 {
507 GetCpuName_MultiLine(s); 511 AString registers;
512 GetCpuName_MultiLine(s, registers);
508 SetItemTextA(IDT_BENCH_CPU, s); 513 SetItemTextA(IDT_BENCH_CPU, s);
509 } 514 }
510 { 515 {
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[] =
211}; 211};
212*/ 212*/
213 213
214/*
214static const EMethodID g_SwfcMethods[] = 215static const EMethodID g_SwfcMethods[] =
215{ 216{
216 kDeflate 217 kDeflate
217 // kLZMA 218 // kLZMA
218}; 219};
220*/
219 221
220static const EMethodID g_TarMethods[] = 222static const EMethodID g_TarMethods[] =
221{ 223{
@@ -278,7 +280,8 @@ static const CFormatInfo g_Formats[] =
278 }, 280 },
279 { 281 {
280 "7z", 282 "7z",
281 (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), 283 // (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
284 (1 << 10) - 1,
282 METHODS_PAIR(g_7zMethods), 285 METHODS_PAIR(g_7zMethods),
283 kFF_Filter | kFF_Solid | kFF_MultiThread | kFF_Encrypt | 286 kFF_Filter | kFF_Solid | kFF_MultiThread | kFF_Encrypt |
284 kFF_EncryptFileNames | kFF_MemUse | kFF_SFX 287 kFF_EncryptFileNames | kFF_MemUse | kFF_SFX
@@ -306,7 +309,8 @@ static const CFormatInfo g_Formats[] =
306 }, 309 },
307 { 310 {
308 "xz", 311 "xz",
309 (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), 312 // (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
313 (1 << 10) - 1 - (1 << 0), // store (1 << 0) is not supported
310 METHODS_PAIR(g_XzMethods), 314 METHODS_PAIR(g_XzMethods),
311 kFF_Solid | kFF_MultiThread | kFF_MemUse 315 kFF_Solid | kFF_MultiThread | kFF_MemUse
312 }, 316 },
@@ -321,12 +325,14 @@ static const CFormatInfo g_Formats[] =
321 | kFF_MemUse 325 | kFF_MemUse
322 }, 326 },
323 */ 327 */
328/*
324 { 329 {
325 "Swfc", 330 "Swfc",
326 (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), 331 (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9),
327 METHODS_PAIR(g_SwfcMethods), 332 METHODS_PAIR(g_SwfcMethods),
328 0 333 0
329 }, 334 },
335*/
330 { 336 {
331 "Tar", 337 "Tar",
332 (1 << 0), 338 (1 << 0),
@@ -429,22 +435,23 @@ bool CCompressDialog::OnInit()
429 #endif 435 #endif
430 436
431 { 437 {
432 UInt64 size = (UInt64)(sizeof(size_t)) << 29; 438 size_t size = (size_t)sizeof(size_t) << 29;
433 _ramSize_Defined = NSystem::GetRamSize(size); 439 _ramSize_Defined = NSystem::GetRamSize(size);
434 // size = (UInt64)3 << 62; // for debug only; 440 // size = (UInt64)3 << 62; // for debug only;
435 _ramSize = size;
436 const UInt64 kMinUseSize = (1 << 26);
437 if (size < kMinUseSize)
438 size = kMinUseSize;
439
440 unsigned bits = sizeof(size_t) * 8;
441 if (bits == 32)
442 { 441 {
443 const UInt32 limit2 = (UInt32)7 << 28; 442 // we use reduced limit for 32-bit version:
444 if (size > limit2) 443 unsigned bits = sizeof(size_t) * 8;
445 size = limit2; 444 if (bits == 32)
445 {
446 const UInt32 limit2 = (UInt32)7 << 28;
447 if (size > limit2)
448 size = limit2;
449 }
446 } 450 }
447 451 _ramSize = size;
452 const size_t kMinUseSize = 1 << 26;
453 if (size < kMinUseSize)
454 size = kMinUseSize;
448 _ramSize_Reduced = size; 455 _ramSize_Reduced = size;
449 456
450 // 80% - is auto usage limit in handlers 457 // 80% - is auto usage limit in handlers
@@ -1580,24 +1587,26 @@ void CCompressDialog::SetLevel2()
1580 1587
1581 for (unsigned i = 0; i < sizeof(UInt32) * 8; i++) 1588 for (unsigned i = 0; i < sizeof(UInt32) * 8; i++)
1582 { 1589 {
1583 const UInt32 mask = (UInt32)1 << i; 1590 const UInt32 mask = fi.LevelsMask >> i;
1584 if ((fi.LevelsMask & mask) != 0) 1591 // if (mask == 0) break;
1592 if (mask & 1)
1585 { 1593 {
1586 const UInt32 langID = g_Levels[i];
1587 UString s; 1594 UString s;
1588 s.Add_UInt32(i); 1595 s.Add_UInt32(i);
1589 // if (fi.LevelsMask < (1 << (MY_ZSTD_LEVEL_MAX + 1)) - 1) 1596 if (i < Z7_ARRAY_SIZE(g_Levels))
1590 if (langID)
1591 if (i != 0 || !isZstd)
1592 { 1597 {
1593 s += " - "; 1598 const UInt32 langID = g_Levels[i];
1594 s += LangString(langID); 1599 // if (fi.LevelsMask < (1 << (MY_ZSTD_LEVEL_MAX + 1)) - 1)
1600 if (langID)
1601 if (i != 0 || !isZstd)
1602 {
1603 s += " - ";
1604 AddLangString(s, langID);
1605 }
1595 } 1606 }
1596 const int index = (int)m_Level.AddString(s); 1607 const int index = (int)m_Level.AddString(s);
1597 m_Level.SetItemData(index, (LPARAM)i); 1608 m_Level.SetItemData(index, (LPARAM)i);
1598 } 1609 }
1599 if (fi.LevelsMask <= mask)
1600 break;
1601 } 1610 }
1602 SetNearestSelectComboBox(m_Level, level); 1611 SetNearestSelectComboBox(m_Level, level);
1603} 1612}
@@ -1931,11 +1940,11 @@ void CCompressDialog::SetDictionary2()
1931 case kLZMA2: 1940 case kLZMA2:
1932 { 1941 {
1933 { 1942 {
1934 _auto_Dict = 1943 _auto_Dict = level <= 4 ?
1935 ( level <= 3 ? ((UInt32)1 << (level * 2 + 16)) : 1944 (UInt32)1 << (level * 2 + 16) :
1936 ( level <= 6 ? ((UInt32)1 << (level + 19)) : 1945 level <= sizeof(size_t) / 2 + 4 ?
1937 ( level <= 7 ? ((UInt32)1 << 25) : ((UInt32)1 << 26) 1946 (UInt32)1 << (level + 20) :
1938 ))); 1947 (UInt32)1 << (sizeof(size_t) / 2 + 24);
1939 } 1948 }
1940 1949
1941 // we use threshold 3.75 GiB to switch to kLzmaMaxDictSize. 1950 // 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
141 141
142class CCompressDialog: public NWindows::NControl::CModalDialog 142class CCompressDialog: public NWindows::NControl::CModalDialog
143{ 143{
144public:
145 CBool1 SymLinks;
146 CBool1 HardLinks;
147 CBool1 AltStreams;
148 CBool1 NtSecurity;
149 CBool1 PreserveATime;
150private:
151 bool _ramSize_Defined;
152
144 NWindows::NControl::CComboBox m_ArchivePath; 153 NWindows::NControl::CComboBox m_ArchivePath;
145 NWindows::NControl::CComboBox m_Format; 154 NWindows::NControl::CComboBox m_Format;
146 NWindows::NControl::CComboBox m_Level; 155 NWindows::NControl::CComboBox m_Level;
@@ -179,20 +188,13 @@ class CCompressDialog: public NWindows::NControl::CModalDialog
179 UString DirPrefix; 188 UString DirPrefix;
180 UString StartDirPrefix; 189 UString StartDirPrefix;
181 190
182 bool _ramSize_Defined; 191 size_t _ramSize; // full RAM size avail
183 UInt64 _ramSize; // full RAM size avail 192 size_t _ramSize_Reduced; // full for 64-bit and reduced for 32-bit
184 UInt64 _ramSize_Reduced; // full for 64-bit and reduced for 32-bit
185 UInt64 _ramUsage_Auto; 193 UInt64 _ramUsage_Auto;
186 194
187public: 195public:
188 NCompression::CInfo m_RegistryInfo; 196 NCompression::CInfo m_RegistryInfo;
189 197
190 CBool1 SymLinks;
191 CBool1 HardLinks;
192 CBool1 AltStreams;
193 CBool1 NtSecurity;
194 CBool1 PreserveATime;
195
196 void SetArchiveName(const UString &name); 198 void SetArchiveName(const UString &name);
197 int FindRegistryFormat(const UString &name); 199 int FindRegistryFormat(const UString &name);
198 unsigned FindRegistryFormat_Always(const UString &name); 200 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
252 return ProgressDialog->Sync.Set_Status2(_lang_Removing, fs2us(path), isDir); 252 return ProgressDialog->Sync.Set_Status2(_lang_Removing, fs2us(path), isDir);
253} 253}
254 254
255
256HRESULT CUpdateCallbackGUI::MoveArc_Start(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 totalSize, Int32 updateMode)
257{
258 return MoveArc_Start_Base(srcTempPath, destFinalPath, totalSize, updateMode);
259}
260HRESULT CUpdateCallbackGUI::MoveArc_Progress(UInt64 totalSize, UInt64 currentSize)
261{
262 return MoveArc_Progress_Base(totalSize, currentSize);
263}
264HRESULT CUpdateCallbackGUI::MoveArc_Finish()
265{
266 return MoveArc_Finish_Base();
267}
268
269
255HRESULT CUpdateCallbackGUI::StartOpenArchive(const wchar_t * /* name */) 270HRESULT CUpdateCallbackGUI::StartOpenArchive(const wchar_t * /* name */)
256{ 271{
257 return S_OK; 272 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 @@
8#include "resource2.h" 8#include "resource2.h"
9#include "resource3.h" 9#include "resource3.h"
10#include "ExtractRes.h" 10#include "ExtractRes.h"
11#include "../FileManager/resourceGui.h"
11 12
12#include "UpdateCallbackGUI.h" 13#include "UpdateCallbackGUI.h"
13 14
@@ -29,7 +30,8 @@ void CUpdateCallbackGUI2::Init()
29{ 30{
30 NumFiles = 0; 31 NumFiles = 0;
31 32
32 _lang_Removing = LangString(IDS_PROGRESS_REMOVE); 33 LangString(IDS_PROGRESS_REMOVE, _lang_Removing);
34 LangString(IDS_MOVING, _lang_Moving);
33 _lang_Ops.Clear(); 35 _lang_Ops.Clear();
34 for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_UpdNotifyLangs); i++) 36 for (unsigned i = 0; i < Z7_ARRAY_SIZE(k_UpdNotifyLangs); i++)
35 _lang_Ops.Add(LangString(k_UpdNotifyLangs[i])); 37 _lang_Ops.Add(LangString(k_UpdNotifyLangs[i]));
@@ -57,3 +59,72 @@ HRESULT CUpdateCallbackGUI2::ShowAskPasswordDialog()
57 PasswordIsDefined = true; 59 PasswordIsDefined = true;
58 return S_OK; 60 return S_OK;
59} 61}
62
63
64HRESULT CUpdateCallbackGUI2::MoveArc_UpdateStatus()
65{
66 UString s;
67 s.Add_UInt64(_arcMoving_percents);
68 s.Add_Char('%');
69
70 const bool totalDefined = (_arcMoving_total != 0 && _arcMoving_total != (UInt64)(Int64)-1);
71 if (totalDefined || _arcMoving_current != 0)
72 {
73 s += " : ";
74 s.Add_UInt64(_arcMoving_current >> 20);
75 s += " MiB";
76 }
77 if (totalDefined)
78 {
79 s += " / ";
80 s.Add_UInt64((_arcMoving_total + ((1 << 20) - 1)) >> 20);
81 s += " MiB";
82 }
83
84 s += " : ";
85 s += _lang_Moving;
86 s += " : ";
87 // s.Add_Char('\"');
88 s += _arcMoving_name1;
89 // s.Add_Char('\"');
90 return ProgressDialog->Sync.Set_Status2(s, _arcMoving_name2,
91 false); // isDir
92}
93
94
95HRESULT CUpdateCallbackGUI2::MoveArc_Start_Base(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 totalSize, Int32 updateMode)
96{
97 _arcMoving_percents = 0;
98 _arcMoving_total = totalSize;
99 _arcMoving_current = 0;
100 _arcMoving_updateMode = updateMode;
101 _arcMoving_name1 = srcTempPath;
102 _arcMoving_name2 = destFinalPath;
103 return MoveArc_UpdateStatus();
104}
105
106
107HRESULT CUpdateCallbackGUI2::MoveArc_Progress_Base(UInt64 totalSize, UInt64 currentSize)
108{
109 _arcMoving_total = totalSize;
110 _arcMoving_current = currentSize;
111 UInt64 percents = 0;
112 if (totalSize != 0)
113 {
114 if (totalSize < ((UInt64)1 << 57))
115 percents = currentSize * 100 / totalSize;
116 else
117 percents = currentSize / (totalSize / 100);
118 }
119 if (percents == _arcMoving_percents)
120 return ProgressDialog->Sync.CheckStop();
121 // Sleep(300); // for debug
122 _arcMoving_percents = percents;
123 return MoveArc_UpdateStatus();
124}
125
126
127HRESULT CUpdateCallbackGUI2::MoveArc_Finish_Base()
128{
129 return ProgressDialog->Sync.Set_Status2(L"", L"", false);
130}
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 @@
7 7
8class CUpdateCallbackGUI2 8class CUpdateCallbackGUI2
9{ 9{
10 UStringVector _lang_Ops;
11 UString _emptyString;
12public: 10public:
13 UString Password; 11 CProgressDialog *ProgressDialog;
12protected:
13 UString _arcMoving_name1;
14 UString _arcMoving_name2;
15 UInt64 _arcMoving_percents;
16 UInt64 _arcMoving_total;
17 UInt64 _arcMoving_current;
18 Int32 _arcMoving_updateMode;
19public:
14 bool PasswordIsDefined; 20 bool PasswordIsDefined;
15 bool PasswordWasAsked; 21 bool PasswordWasAsked;
16 UInt64 NumFiles; 22 UInt64 NumFiles;
17 23 UString Password;
24protected:
25 UStringVector _lang_Ops;
18 UString _lang_Removing; 26 UString _lang_Removing;
27 UString _lang_Moving;
28 UString _emptyString;
29
30 HRESULT MoveArc_UpdateStatus();
31 HRESULT MoveArc_Start_Base(const wchar_t *srcTempPath, const wchar_t *destFinalPath, UInt64 /* totalSize */, Int32 updateMode);
32 HRESULT MoveArc_Progress_Base(UInt64 totalSize, UInt64 currentSize);
33 HRESULT MoveArc_Finish_Base();
34
35public:
19 36
20 CUpdateCallbackGUI2(): 37 CUpdateCallbackGUI2():
38 _arcMoving_percents(0),
39 _arcMoving_total(0),
40 _arcMoving_current(0),
41 _arcMoving_updateMode(0),
21 PasswordIsDefined(false), 42 PasswordIsDefined(false),
22 PasswordWasAsked(false), 43 PasswordWasAsked(false),
23 NumFiles(0) 44 NumFiles(0)
@@ -25,8 +46,6 @@ public:
25 46
26 void Init(); 47 void Init();
27 48
28 CProgressDialog *ProgressDialog;
29
30 HRESULT SetOperation_Base(UInt32 notifyOp, const wchar_t *name, bool isDir); 49 HRESULT SetOperation_Base(UInt32 notifyOp, const wchar_t *name, bool isDir);
31 HRESULT ShowAskPasswordDialog(); 50 HRESULT ShowAskPasswordDialog();
32}; 51};
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 = \
11 -Wunused \ 11 -Wunused \
12 -Wunused-macros \ 12 -Wunused-macros \
13 13
14CFLAGS_WARN_GCC_6 = $(CFLAGS_WARN_GCC_4_8)\ 14CFLAGS_WARN_GCC_5 = $(CFLAGS_WARN_GCC_4_8)\
15 -Wbool-compare \ 15 -Wbool-compare \
16
17CFLAGS_WARN_GCC_6 = $(CFLAGS_WARN_GCC_5)\
16 -Wduplicated-cond \ 18 -Wduplicated-cond \
17 19
18# -Wno-strict-aliasing 20# -Wno-strict-aliasing
19 21
20CFLAGS_WARN_GCC_9 = $(CFLAGS_WARN_GCC_6)\ 22CFLAGS_WARN_GCC_7 = $(CFLAGS_WARN_GCC_6)\
21 -Waddress-of-packed-member \
22 -Wbool-operation \ 23 -Wbool-operation \
23 -Wcast-align=strict \
24 -Wconversion \ 24 -Wconversion \
25 -Wdangling-else \ 25 -Wdangling-else \
26 -Wduplicated-branches \ 26 -Wduplicated-branches \
@@ -28,8 +28,14 @@ CFLAGS_WARN_GCC_9 = $(CFLAGS_WARN_GCC_6)\
28 -Wint-in-bool-context \ 28 -Wint-in-bool-context \
29 -Wmaybe-uninitialized \ 29 -Wmaybe-uninitialized \
30 -Wmisleading-indentation \ 30 -Wmisleading-indentation \
31
32CFLAGS_WARN_GCC_8 = $(CFLAGS_WARN_GCC_7)\
33 -Wcast-align=strict \
31 -Wmissing-attributes 34 -Wmissing-attributes
32 35
36CFLAGS_WARN_GCC_9 = $(CFLAGS_WARN_GCC_8)\
37 -Waddress-of-packed-member \
38
33# In C: -Wsign-conversion enabled also by -Wconversion 39# In C: -Wsign-conversion enabled also by -Wconversion
34# -Wno-sign-conversion \ 40# -Wno-sign-conversion \
35 41
@@ -39,7 +45,10 @@ CFLAGS_WARN_GCC_PPMD_UNALIGNED = \
39 45
40 46
41CFLAGS_WARN = $(CFLAGS_WARN_GCC_4_8) 47CFLAGS_WARN = $(CFLAGS_WARN_GCC_4_8)
48CFLAGS_WARN = $(CFLAGS_WARN_GCC_5)
42CFLAGS_WARN = $(CFLAGS_WARN_GCC_6) 49CFLAGS_WARN = $(CFLAGS_WARN_GCC_6)
50CFLAGS_WARN = $(CFLAGS_WARN_GCC_7)
51CFLAGS_WARN = $(CFLAGS_WARN_GCC_8)
43CFLAGS_WARN = $(CFLAGS_WARN_GCC_9) 52CFLAGS_WARN = $(CFLAGS_WARN_GCC_9)
44 53
45# CXX_STD_FLAGS = -std=c++11 54# 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 @@
1// Md5Reg.cpp
2
3#include "StdAfx.h"
4
5#include "../../C/Md5.h"
6
7#include "../Common/MyBuffer2.h"
8#include "../Common/MyCom.h"
9
10#include "../7zip/Common/RegisterCodec.h"
11
12Z7_CLASS_IMP_COM_1(
13 CMd5Hasher
14 , IHasher
15)
16 CAlignedBuffer1 _buf;
17public:
18 Byte _mtDummy[1 << 7];
19
20 CMd5 *Md5() { return (CMd5 *)(void *)(Byte *)_buf; }
21public:
22 CMd5Hasher():
23 _buf(sizeof(CMd5))
24 {
25 Md5_Init(Md5());
26 }
27};
28
29Z7_COM7F_IMF2(void, CMd5Hasher::Init())
30{
31 Md5_Init(Md5());
32}
33
34Z7_COM7F_IMF2(void, CMd5Hasher::Update(const void *data, UInt32 size))
35{
36 Md5_Update(Md5(), (const Byte *)data, size);
37}
38
39Z7_COM7F_IMF2(void, CMd5Hasher::Final(Byte *digest))
40{
41 Md5_Final(Md5(), digest);
42}
43
44REGISTER_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
468 Z7_COM_QI_ENTRY(i7) \ 468 Z7_COM_QI_ENTRY(i7) \
469 ) 469 )
470 470
471#define Z7_COM_UNKNOWN_IMP_8(i1, i2, i3, i4, i5, i6, i7, i8) \
472 Z7_COM_UNKNOWN_IMP_SPEC( \
473 Z7_COM_QI_ENTRY_UNKNOWN(i1) \
474 Z7_COM_QI_ENTRY(i1) \
475 Z7_COM_QI_ENTRY(i2) \
476 Z7_COM_QI_ENTRY(i3) \
477 Z7_COM_QI_ENTRY(i4) \
478 Z7_COM_QI_ENTRY(i5) \
479 Z7_COM_QI_ENTRY(i6) \
480 Z7_COM_QI_ENTRY(i7) \
481 Z7_COM_QI_ENTRY(i8) \
482 )
483
471 484
472#define Z7_IFACES_IMP_UNK_1(i1) \ 485#define Z7_IFACES_IMP_UNK_1(i1) \
473 Z7_COM_UNKNOWN_IMP_1(i1) \ 486 Z7_COM_UNKNOWN_IMP_1(i1) \
@@ -508,6 +521,16 @@ EXTERN_C_END
508 Z7_IFACE_COM7_IMP(i5) \ 521 Z7_IFACE_COM7_IMP(i5) \
509 Z7_IFACE_COM7_IMP(i6) \ 522 Z7_IFACE_COM7_IMP(i6) \
510 523
524#define Z7_IFACES_IMP_UNK_7(i1, i2, i3, i4, i5, i6, i7) \
525 Z7_COM_UNKNOWN_IMP_7(i1, i2, i3, i4, i5, i6, i7) \
526 Z7_IFACE_COM7_IMP(i1) \
527 Z7_IFACE_COM7_IMP(i2) \
528 Z7_IFACE_COM7_IMP(i3) \
529 Z7_IFACE_COM7_IMP(i4) \
530 Z7_IFACE_COM7_IMP(i5) \
531 Z7_IFACE_COM7_IMP(i6) \
532 Z7_IFACE_COM7_IMP(i7) \
533
511 534
512#define Z7_CLASS_IMP_COM_0(c) \ 535#define Z7_CLASS_IMP_COM_0(c) \
513 Z7_class_final(c) : \ 536 Z7_class_final(c) : \
@@ -574,6 +597,20 @@ EXTERN_C_END
574 private: 597 private:
575 598
576 599
600#define Z7_CLASS_IMP_COM_7(c, i1, i2, i3, i4, i5, i6, i7) \
601 Z7_class_final(c) : \
602 public i1, \
603 public i2, \
604 public i3, \
605 public i4, \
606 public i5, \
607 public i6, \
608 public i7, \
609 public CMyUnknownImp { \
610 Z7_IFACES_IMP_UNK_7(i1, i2, i3, i4, i5, i6, i7) \
611 private:
612
613
577/* 614/*
578#define Z7_CLASS_IMP_NOQIB_0(c) \ 615#define Z7_CLASS_IMP_NOQIB_0(c) \
579 Z7_class_final(c) : \ 616 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 @@
1// Sha3Reg.cpp
2
3#include "StdAfx.h"
4
5#include "../../C/Sha3.h"
6
7#include "../Common/MyBuffer2.h"
8#include "../Common/MyCom.h"
9
10#include "../7zip/Common/RegisterCodec.h"
11
12Z7_CLASS_IMP_COM_1(
13 CSha3Hasher
14 , IHasher
15)
16 unsigned _digestSize;
17 bool _isShake;
18 CAlignedBuffer1 _buf;
19public:
20 Byte _mtDummy[1 << 7];
21
22 CSha3 *Sha() { return (CSha3 *)(void *)(Byte *)_buf; }
23public:
24 CSha3Hasher(unsigned digestSize, bool isShake, unsigned blockSize):
25 _digestSize(digestSize),
26 _isShake(isShake),
27 _buf(sizeof(CSha3))
28 {
29 CSha3 *p = Sha();
30 Sha3_SET_blockSize(p, blockSize)
31 Sha3_Init(Sha());
32 }
33};
34
35Z7_COM7F_IMF2(void, CSha3Hasher::Init())
36{
37 Sha3_Init(Sha());
38}
39
40Z7_COM7F_IMF2(void, CSha3Hasher::Update(const void *data, UInt32 size))
41{
42 Sha3_Update(Sha(), (const Byte *)data, size);
43}
44
45Z7_COM7F_IMF2(void, CSha3Hasher::Final(Byte *digest))
46{
47 Sha3_Final(Sha(), digest, _digestSize, _isShake);
48}
49
50Z7_COM7F_IMF2(UInt32, CSha3Hasher::GetDigestSize())
51{
52 return (UInt32)_digestSize;
53}
54
55
56#define REGISTER_SHA3_HASHER_2(cls, id, name, digestSize, isShake, digestSize_for_blockSize) \
57 namespace N ## cls { \
58 static IHasher *CreateHasherSpec() \
59 { return new CSha3Hasher(digestSize / 8, isShake, \
60 SHA3_BLOCK_SIZE_FROM_DIGEST_SIZE(digestSize_for_blockSize / 8)); } \
61 static const CHasherInfo g_HasherInfo = { CreateHasherSpec, id, name, digestSize }; \
62 struct REGISTER_HASHER_NAME(cls) { REGISTER_HASHER_NAME(cls)() { RegisterHasher(&g_HasherInfo); }}; \
63 static REGISTER_HASHER_NAME(cls) g_RegisterHasher; }
64
65#define REGISTER_SHA3_HASHER( cls, id, name, size, isShake) \
66 REGISTER_SHA3_HASHER_2(cls, id, name, size, isShake, size)
67
68// REGISTER_SHA3_HASHER (Sha3_224_Hasher, 0x230, "SHA3-224", 224, false)
69REGISTER_SHA3_HASHER (Sha3_256_Hasher, 0x231, "SHA3-256", 256, false)
70// REGISTER_SHA3_HASHER (Sha3_386_Hasher, 0x232, "SHA3-384", 384, false)
71// REGISTER_SHA3_HASHER (Sha3_512_Hasher, 0x233, "SHA3-512", 512, false)
72// REGISTER_SHA3_HASHER (Shake128_Hasher, 0x240, "SHAKE128", 128, true)
73// REGISTER_SHA3_HASHER (Shake256_Hasher, 0x241, "SHAKE256", 256, true)
74// REGISTER_SHA3_HASHER_2 (Shake128_512_Hasher, 0x248, "SHAKE128-256", 256, true, 128) // -1344 (max)
75// REGISTER_SHA3_HASHER_2 (Shake256_512_Hasher, 0x249, "SHAKE256-512", 512, true, 256) // -1088 (max)
76// 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 @@
1// Sha512Prepare.cpp
2
3#include "StdAfx.h"
4
5#include "../../C/Sha512.h"
6
7static 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 @@
1// Sha512Reg.cpp
2
3#include "StdAfx.h"
4
5#include "../../C/Sha512.h"
6
7#include "../Common/MyBuffer2.h"
8#include "../Common/MyCom.h"
9
10#include "../7zip/Common/RegisterCodec.h"
11
12Z7_CLASS_IMP_COM_2(
13 CSha512Hasher
14 , IHasher
15 , ICompressSetCoderProperties
16)
17 unsigned _digestSize;
18 CAlignedBuffer1 _buf;
19public:
20 Byte _mtDummy[1 << 7];
21
22 CSha512 *Sha() { return (CSha512 *)(void *)(Byte *)_buf; }
23public:
24 CSha512Hasher(unsigned digestSize):
25 _digestSize(digestSize),
26 _buf(sizeof(CSha512))
27 {
28 Sha512_SetFunction(Sha(), 0);
29 Sha512_InitState(Sha(), _digestSize);
30 }
31};
32
33Z7_COM7F_IMF2(void, CSha512Hasher::Init())
34{
35 Sha512_InitState(Sha(), _digestSize);
36}
37
38Z7_COM7F_IMF2(void, CSha512Hasher::Update(const void *data, UInt32 size))
39{
40 Sha512_Update(Sha(), (const Byte *)data, size);
41}
42
43Z7_COM7F_IMF2(void, CSha512Hasher::Final(Byte *digest))
44{
45 Sha512_Final(Sha(), digest, _digestSize);
46}
47
48Z7_COM7F_IMF2(UInt32, CSha512Hasher::GetDigestSize())
49{
50 return (UInt32)_digestSize;
51}
52
53Z7_COM7F_IMF(CSha512Hasher::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps))
54{
55 unsigned algo = 0;
56 for (UInt32 i = 0; i < numProps; i++)
57 {
58 if (propIDs[i] == NCoderPropID::kDefaultProp)
59 {
60 const PROPVARIANT &prop = coderProps[i];
61 if (prop.vt != VT_UI4)
62 return E_INVALIDARG;
63 if (prop.ulVal > 2)
64 return E_NOTIMPL;
65 algo = (unsigned)prop.ulVal;
66 }
67 }
68 if (!Sha512_SetFunction(Sha(), algo))
69 return E_NOTIMPL;
70 return S_OK;
71}
72
73#define REGISTER_SHA512_HASHER(cls, id, name, size) \
74 namespace N ## cls { \
75 static IHasher *CreateHasherSpec() { return new CSha512Hasher(size); } \
76 static const CHasherInfo g_HasherInfo = { CreateHasherSpec, id, name, size }; \
77 struct REGISTER_HASHER_NAME(cls) { REGISTER_HASHER_NAME(cls)() { RegisterHasher(&g_HasherInfo); }}; \
78 static REGISTER_HASHER_NAME(cls) g_RegisterHasher; }
79
80// REGISTER_SHA512_HASHER (Sha512_224_Hasher, 0x220, "SHA512-224", SHA512_224_DIGEST_SIZE)
81// REGISTER_SHA512_HASHER (Sha512_256_Hasher, 0x221, "SHA512-256", SHA512_256_DIGEST_SIZE)
82REGISTER_SHA512_HASHER (Sha384Hasher, 0x222, "SHA384", SHA512_384_DIGEST_SIZE)
83REGISTER_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 @@
15#include <sys/stat.h> 15#include <sys/stat.h>
16#include <sys/types.h> 16#include <sys/types.h>
17 17
18#include "../Common/StringConvert.h"
19#include "../Common/C_FileIO.h" 18#include "../Common/C_FileIO.h"
19#include "../Common/MyBuffer2.h"
20#include "../Common/StringConvert.h"
20#endif 21#endif
21 22
22#include "FileDir.h" 23#include "FileDir.h"
@@ -222,6 +223,8 @@ bool RemoveDir(CFSTR path)
222} 223}
223 224
224 225
226// When moving a directory, oldFile and newFile must be on the same drive.
227
225bool MyMoveFile(CFSTR oldFile, CFSTR newFile) 228bool MyMoveFile(CFSTR oldFile, CFSTR newFile)
226{ 229{
227 #ifndef _UNICODE 230 #ifndef _UNICODE
@@ -250,6 +253,59 @@ bool MyMoveFile(CFSTR oldFile, CFSTR newFile)
250 return false; 253 return false;
251} 254}
252 255
256#if defined(Z7_WIN32_WINNT_MIN) && Z7_WIN32_WINNT_MIN >= 0x0500
257static DWORD WINAPI CopyProgressRoutine_to_ICopyFileProgress(
258 LARGE_INTEGER TotalFileSize, // file size
259 LARGE_INTEGER TotalBytesTransferred, // bytes transferred
260 LARGE_INTEGER /* StreamSize */, // bytes in stream
261 LARGE_INTEGER /* StreamBytesTransferred */, // bytes transferred for stream
262 DWORD /* dwStreamNumber */, // current stream
263 DWORD /* dwCallbackReason */, // callback reason
264 HANDLE /* hSourceFile */, // handle to source file
265 HANDLE /* hDestinationFile */, // handle to destination file
266 LPVOID lpData // from CopyFileEx
267)
268{
269 return ((ICopyFileProgress *)lpData)->CopyFileProgress(
270 (UInt64)TotalFileSize.QuadPart,
271 (UInt64)TotalBytesTransferred.QuadPart);
272}
273#endif
274
275bool MyMoveFile_with_Progress(CFSTR oldFile, CFSTR newFile,
276 ICopyFileProgress *progress)
277{
278#if defined(Z7_WIN32_WINNT_MIN) && Z7_WIN32_WINNT_MIN >= 0x0500
279#ifndef _UNICODE
280 if (g_IsNT)
281#endif
282 if (progress)
283 {
284 IF_USE_MAIN_PATH_2(oldFile, newFile)
285 {
286 if (::MoveFileWithProgressW(fs2us(oldFile), fs2us(newFile),
287 CopyProgressRoutine_to_ICopyFileProgress, progress, MOVEFILE_COPY_ALLOWED))
288 return true;
289 if (::GetLastError() == ERROR_REQUEST_ABORTED)
290 return false;
291 }
292 #ifdef Z7_LONG_PATH
293 if (USE_SUPER_PATH_2)
294 {
295 UString d1, d2;
296 if (GetSuperPaths(oldFile, newFile, d1, d2, USE_MAIN_PATH_2))
297 return BOOLToBool(::MoveFileWithProgressW(d1, d2,
298 CopyProgressRoutine_to_ICopyFileProgress, progress, MOVEFILE_COPY_ALLOWED));
299 }
300 #endif
301 return false;
302 }
303#else
304 UNUSED_VAR(progress)
305#endif
306 return MyMoveFile(oldFile, newFile);
307}
308
253#ifndef UNDER_CE 309#ifndef UNDER_CE
254#if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0500 // Win2000 310#if !defined(Z7_WIN32_WINNT_MIN) || Z7_WIN32_WINNT_MIN < 0x0500 // Win2000
255#define Z7_USE_DYN_CreateHardLink 311#define Z7_USE_DYN_CreateHardLink
@@ -878,9 +934,9 @@ bool CTempFile::Remove()
878 return !_mustBeDeleted; 934 return !_mustBeDeleted;
879} 935}
880 936
881bool CTempFile::MoveTo(CFSTR name, bool deleteDestBefore) 937bool CTempFile::MoveTo(CFSTR name, bool deleteDestBefore,
938 ICopyFileProgress *progress)
882{ 939{
883 // DWORD attrib = 0;
884 if (deleteDestBefore) 940 if (deleteDestBefore)
885 { 941 {
886 if (NFind::DoesFileExist_Raw(name)) 942 if (NFind::DoesFileExist_Raw(name))
@@ -891,8 +947,8 @@ bool CTempFile::MoveTo(CFSTR name, bool deleteDestBefore)
891 } 947 }
892 } 948 }
893 DisableDeleting(); 949 DisableDeleting();
894 return MyMoveFile(_path, name); 950 // if (!progress) return MyMoveFile(_path, name);
895 951 return MyMoveFile_with_Progress(_path, name, progress);
896 /* 952 /*
897 if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_READONLY)) 953 if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_READONLY))
898 { 954 {
@@ -941,34 +997,59 @@ bool RemoveDir(CFSTR path)
941} 997}
942 998
943 999
944static BOOL My_CopyFile(CFSTR oldFile, CFSTR newFile) 1000static BOOL My_CopyFile(CFSTR oldFile, CFSTR newFile, ICopyFileProgress *progress)
945{ 1001{
946 NWindows::NFile::NIO::COutFile outFile;
947 if (!outFile.Create_NEW(newFile))
948 return FALSE;
949
950 NWindows::NFile::NIO::CInFile inFile;
951 if (!inFile.Open(oldFile))
952 return FALSE;
953
954 char buf[1 << 14];
955
956 for (;;)
957 { 1002 {
958 const ssize_t num = inFile.read_part(buf, sizeof(buf)); 1003 NIO::COutFile outFile;
959 if (num == 0) 1004 if (!outFile.Create_NEW(newFile))
960 return TRUE;
961 if (num < 0)
962 return FALSE; 1005 return FALSE;
963 size_t processed; 1006 NIO::CInFile inFile;
964 const ssize_t num2 = outFile.write_full(buf, (size_t)num, processed); 1007 if (!inFile.Open(oldFile))
965 if (num2 != num || processed != (size_t)num)
966 return FALSE; 1008 return FALSE;
1009
1010 const size_t k_BufSize = 1 << 16;
1011 CAlignedBuffer1 buf(k_BufSize);
1012
1013 UInt64 length = 0;
1014 if (progress && !inFile.GetLength(length))
1015 length = 0;
1016 UInt64 prev = 0;
1017 UInt64 cur = 0;
1018 for (;;)
1019 {
1020 const ssize_t num = inFile.read_part(buf, k_BufSize);
1021 if (num == 0)
1022 return TRUE;
1023 if (num < 0)
1024 break;
1025 size_t processed;
1026 const ssize_t num2 = outFile.write_full(buf, (size_t)num, processed);
1027 if (num2 != num || processed != (size_t)num)
1028 break;
1029 cur += (size_t)num2;
1030 if (progress && cur - prev >= (1u << 20))
1031 {
1032 prev = cur;
1033 if (progress->CopyFileProgress(length, cur) != PROGRESS_CONTINUE)
1034 {
1035 errno = EINTR; // instead of WIN32::ERROR_REQUEST_ABORTED
1036 break;
1037 }
1038 }
1039 }
967 } 1040 }
1041 // There is file IO error or process was interrupted by user.
1042 // We close output file and delete it.
1043 // DeleteFileAlways doesn't change errno (if successed), but we restore errno.
1044 const int errno_save = errno;
1045 DeleteFileAlways(newFile);
1046 errno = errno_save;
1047 return FALSE;
968} 1048}
969 1049
970 1050
971bool MyMoveFile(CFSTR oldFile, CFSTR newFile) 1051bool MyMoveFile_with_Progress(CFSTR oldFile, CFSTR newFile,
1052 ICopyFileProgress *progress)
972{ 1053{
973 int res = rename(oldFile, newFile); 1054 int res = rename(oldFile, newFile);
974 if (res == 0) 1055 if (res == 0)
@@ -976,7 +1057,7 @@ bool MyMoveFile(CFSTR oldFile, CFSTR newFile)
976 if (errno != EXDEV) // (oldFile and newFile are not on the same mounted filesystem) 1057 if (errno != EXDEV) // (oldFile and newFile are not on the same mounted filesystem)
977 return false; 1058 return false;
978 1059
979 if (My_CopyFile(oldFile, newFile) == FALSE) 1060 if (My_CopyFile(oldFile, newFile, progress) == FALSE)
980 return false; 1061 return false;
981 1062
982 struct stat info_file; 1063 struct stat info_file;
@@ -990,6 +1071,11 @@ bool MyMoveFile(CFSTR oldFile, CFSTR newFile)
990 return (unlink(oldFile) == 0); 1071 return (unlink(oldFile) == 0);
991} 1072}
992 1073
1074bool MyMoveFile(CFSTR oldFile, CFSTR newFile)
1075{
1076 return MyMoveFile_with_Progress(oldFile, newFile, NULL);
1077}
1078
993 1079
994bool CreateDir(CFSTR path) 1080bool CreateDir(CFSTR path)
995{ 1081{
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);
41bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib); 41bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib);
42 42
43 43
44#ifndef _WIN32
45#define PROGRESS_CONTINUE 0
46#define PROGRESS_CANCEL 1
47// #define PROGRESS_STOP 2
48// #define PROGRESS_QUIET 3
49#endif
50Z7_PURE_INTERFACES_BEGIN
51DECLARE_INTERFACE(ICopyFileProgress)
52{
53 // in: total, current: include all/processed alt streams.
54 // it returns PROGRESS_CONTINUE or PROGRESS_CANCEL.
55 virtual DWORD CopyFileProgress(UInt64 total, UInt64 current) = 0;
56};
57Z7_PURE_INTERFACES_END
58
44bool MyMoveFile(CFSTR existFileName, CFSTR newFileName); 59bool MyMoveFile(CFSTR existFileName, CFSTR newFileName);
60// (progress == NULL) is allowed
61bool MyMoveFile_with_Progress(CFSTR oldFile, CFSTR newFile,
62 ICopyFileProgress *progress);
63
45 64
46#ifndef UNDER_CE 65#ifndef UNDER_CE
47bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName); 66bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName);
@@ -87,7 +106,9 @@ public:
87 bool Create(CFSTR pathPrefix, NIO::COutFile *outFile); // pathPrefix is not folder prefix 106 bool Create(CFSTR pathPrefix, NIO::COutFile *outFile); // pathPrefix is not folder prefix
88 bool CreateRandomInTempFolder(CFSTR namePrefix, NIO::COutFile *outFile); 107 bool CreateRandomInTempFolder(CFSTR namePrefix, NIO::COutFile *outFile);
89 bool Remove(); 108 bool Remove();
90 bool MoveTo(CFSTR name, bool deleteDestBefore); 109 // bool MoveTo(CFSTR name, bool deleteDestBefore);
110 bool MoveTo(CFSTR name, bool deleteDestBefore,
111 ICopyFileProgress *progress);
91}; 112};
92 113
93 114
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()
278int FindAltStreamColon(CFSTR path) throw() 278int FindAltStreamColon(CFSTR path) throw()
279{ 279{
280 unsigned i = 0; 280 unsigned i = 0;
281 if (IsDrivePath2(path)) 281 if (IsSuperPath(path))
282 i = 2; 282 i = kSuperPathPrefixSize;
283 if (IsDrivePath2(path + i))
284 i += 2;
283 int colonPos = -1; 285 int colonPos = -1;
284 for (;; i++) 286 for (;; i++)
285 { 287 {
286 FChar c = path[i]; 288 const FChar c = path[i];
287 if (c == 0) 289 if (c == 0)
288 return colonPos; 290 return colonPos;
289 if (c == ':') 291 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()
78 return res; 78 return res;
79} 79}
80 80
81// win95, win98: deletes sunkey and all its subkeys 81// win95, win98: deletes subkey and all its subkeys
82// winNT to be deleted must not have subkeys 82// winNT to be deleted must not have subkeys
83LONG CKey::DeleteSubKey(LPCTSTR subKeyName) throw() 83LONG CKey::DeleteSubKey(LPCTSTR subKeyName) throw()
84{ 84{
@@ -88,22 +88,36 @@ LONG CKey::DeleteSubKey(LPCTSTR subKeyName) throw()
88 88
89LONG CKey::RecurseDeleteKey(LPCTSTR subKeyName) throw() 89LONG CKey::RecurseDeleteKey(LPCTSTR subKeyName) throw()
90{ 90{
91 CKey key;
92 LONG res = key.Open(_object, subKeyName, KEY_READ | KEY_WRITE);
93 if (res != ERROR_SUCCESS)
94 return res;
95 FILETIME fileTime;
96 const UInt32 kBufSize = MAX_PATH + 1; // 256 in ATL
97 DWORD size = kBufSize;
98 TCHAR buffer[kBufSize];
99 while (RegEnumKeyEx(key._object, 0, buffer, &size, NULL, NULL, NULL, &fileTime) == ERROR_SUCCESS)
100 { 91 {
101 res = key.RecurseDeleteKey(buffer); 92 CKey key;
93 LONG res = key.Open(_object, subKeyName, KEY_READ | KEY_WRITE);
102 if (res != ERROR_SUCCESS) 94 if (res != ERROR_SUCCESS)
103 return res; 95 return res;
104 size = kBufSize; 96 FILETIME fileTime;
97 const UInt32 kBufSize = MAX_PATH + 1; // 256 in ATL
98 TCHAR buffer[kBufSize];
99 // we use loop limit here for some unexpected code failure
100 for (unsigned loop_cnt = 0; loop_cnt < (1u << 26); loop_cnt++)
101 {
102 DWORD size = kBufSize;
103 // we always request starting item (index==0) in each iteration,
104 // because we remove starting item (index==0) in each loop iteration.
105 res = RegEnumKeyEx(key._object, 0, buffer, &size, NULL, NULL, NULL, &fileTime);
106 if (res != ERROR_SUCCESS)
107 {
108 // possible return codes:
109 // ERROR_NO_MORE_ITEMS : are no more subkeys available
110 // ERROR_MORE_DATA : name buffer is too small
111 // we can try to remove (subKeyName), even if there is non ERROR_NO_MORE_ITEMS error.
112 // if (res != ERROR_NO_MORE_ITEMS) return res;
113 break;
114 }
115 res = key.RecurseDeleteKey(buffer);
116 if (res != ERROR_SUCCESS)
117 return res;
118 }
119 // key.Close();
105 } 120 }
106 key.Close();
107 return DeleteSubKey(subKeyName); 121 return DeleteSubKey(subKeyName);
108} 122}
109 123
@@ -127,7 +141,7 @@ LONG CKey::DeleteValue(LPCWSTR name)
127 MY_ASSUME(_object != NULL); 141 MY_ASSUME(_object != NULL);
128 if (g_IsNT) 142 if (g_IsNT)
129 return ::RegDeleteValueW(_object, name); 143 return ::RegDeleteValueW(_object, name);
130 return DeleteValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name)); 144 return DeleteValue(name == NULL ? NULL : (LPCSTR)GetSystemString(name));
131} 145}
132#endif 146#endif
133 147
@@ -143,12 +157,15 @@ LONG CKey::SetValue(LPCTSTR name, bool value) throw()
143 return SetValue(name, BoolToUINT32(value)); 157 return SetValue(name, BoolToUINT32(value));
144} 158}
145 159
160
161// value must be string that is NULL terminated
146LONG CKey::SetValue(LPCTSTR name, LPCTSTR value) throw() 162LONG CKey::SetValue(LPCTSTR name, LPCTSTR value) throw()
147{ 163{
148 MYASSERT(value != NULL); 164 MYASSERT(value != NULL);
149 MY_ASSUME(_object != NULL); 165 MY_ASSUME(_object != NULL);
166 // note: RegSetValueEx supports (value == NULL), if (cbData == 0)
150 return RegSetValueEx(_object, name, 0, REG_SZ, 167 return RegSetValueEx(_object, name, 0, REG_SZ,
151 (const BYTE *)value, ((DWORD)lstrlen(value) + 1) * sizeof(TCHAR)); 168 (const BYTE *)value, (DWORD)(((DWORD)lstrlen(value) + 1) * sizeof(TCHAR)));
152} 169}
153 170
154/* 171/*
@@ -156,7 +173,7 @@ LONG CKey::SetValue(LPCTSTR name, const CSysString &value)
156{ 173{
157 MYASSERT(value != NULL); 174 MYASSERT(value != NULL);
158 MY_ASSUME(_object != NULL); 175 MY_ASSUME(_object != NULL);
159 return RegSetValueEx(_object, name, NULL, REG_SZ, 176 return RegSetValueEx(_object, name, 0, REG_SZ,
160 (const BYTE *)(const TCHAR *)value, (value.Len() + 1) * sizeof(TCHAR)); 177 (const BYTE *)(const TCHAR *)value, (value.Len() + 1) * sizeof(TCHAR));
161} 178}
162*/ 179*/
@@ -169,9 +186,10 @@ LONG CKey::SetValue(LPCWSTR name, LPCWSTR value)
169 MY_ASSUME(_object != NULL); 186 MY_ASSUME(_object != NULL);
170 if (g_IsNT) 187 if (g_IsNT)
171 return RegSetValueExW(_object, name, 0, REG_SZ, 188 return RegSetValueExW(_object, name, 0, REG_SZ,
172 (const BYTE * )value, (DWORD)((wcslen(value) + 1) * sizeof(wchar_t))); 189 (const BYTE *)value, (DWORD)(((DWORD)wcslen(value) + 1) * sizeof(wchar_t)));
173 return SetValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name), 190 return SetValue(name == NULL ? NULL :
174 value == 0 ? 0 : (LPCSTR)GetSystemString(value)); 191 (LPCSTR)GetSystemString(name),
192 (LPCSTR)GetSystemString(value));
175} 193}
176 194
177#endif 195#endif
@@ -205,99 +223,137 @@ LONG CKey::SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value) throw(
205 return res; 223 return res;
206} 224}
207 225
208LONG CKey::QueryValue(LPCTSTR name, UInt32 &value) throw()
209{
210 DWORD type = 0;
211 DWORD count = sizeof(DWORD);
212 LONG res = RegQueryValueEx(_object, name, NULL, &type,
213 (LPBYTE)&value, &count);
214 MYASSERT((res != ERROR_SUCCESS) || (type == REG_DWORD));
215 MYASSERT((res != ERROR_SUCCESS) || (count == sizeof(UInt32)));
216 return res;
217}
218 226
219LONG CKey::QueryValue(LPCTSTR name, bool &value) throw() 227LONG CKey::GetValue_UInt32_IfOk(LPCTSTR name, UInt32 &value) throw()
220{ 228{
221 UInt32 uintValue = BoolToUINT32(value); 229 DWORD type = 0;
222 LONG res = QueryValue(name, uintValue); 230 DWORD count = sizeof(value);
223 value = UINT32ToBool(uintValue); 231 UInt32 value2; // = value;
232 const LONG res = QueryValueEx(name, &type, (LPBYTE)&value2, &count);
233 if (res == ERROR_SUCCESS)
234 {
235 // ERROR_UNSUPPORTED_TYPE
236 if (count != sizeof(value) || type != REG_DWORD)
237 return ERROR_UNSUPPORTED_TYPE; // ERROR_INVALID_DATA;
238 value = value2;
239 }
224 return res; 240 return res;
225} 241}
226 242
227LONG CKey::GetValue_IfOk(LPCTSTR name, UInt32 &value) throw() 243LONG CKey::GetValue_UInt64_IfOk(LPCTSTR name, UInt64 &value) throw()
228{ 244{
229 UInt32 newVal; 245 DWORD type = 0;
230 LONG res = QueryValue(name, newVal); 246 DWORD count = sizeof(value);
247 UInt64 value2; // = value;
248 const LONG res = QueryValueEx(name, &type, (LPBYTE)&value2, &count);
231 if (res == ERROR_SUCCESS) 249 if (res == ERROR_SUCCESS)
232 value = newVal; 250 {
251 if (count != sizeof(value) || type != REG_QWORD)
252 return ERROR_UNSUPPORTED_TYPE;
253 value = value2;
254 }
233 return res; 255 return res;
234} 256}
235 257
236LONG CKey::GetValue_IfOk(LPCTSTR name, bool &value) throw() 258LONG CKey::GetValue_bool_IfOk(LPCTSTR name, bool &value) throw()
237{ 259{
238 bool newVal = false; 260 UInt32 uintValue;
239 LONG res = QueryValue(name, newVal); 261 const LONG res = GetValue_UInt32_IfOk(name, uintValue);
240 if (res == ERROR_SUCCESS) 262 if (res == ERROR_SUCCESS)
241 value = newVal; 263 value = UINT32ToBool(uintValue);
242 return res; 264 return res;
243} 265}
244 266
245LONG CKey::QueryValue(LPCTSTR name, LPTSTR value, UInt32 &count) throw() 267
246{
247 DWORD type = 0;
248 LONG res = RegQueryValueEx(_object, name, NULL, &type, (LPBYTE)value, (DWORD *)&count);
249 MYASSERT((res != ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
250 return res;
251}
252 268
253LONG CKey::QueryValue(LPCTSTR name, CSysString &value) 269LONG CKey::QueryValue(LPCTSTR name, CSysString &value)
254{ 270{
255 value.Empty(); 271 value.Empty();
256 DWORD type = 0; 272 LONG res = ERROR_SUCCESS;
257 DWORD curSize = 0; 273 {
258 LONG res = RegQueryValueEx(_object, name, NULL, &type, NULL, &curSize); 274 // if we don't want multiple calls here,
259 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) 275 // we can use big value (264) here.
260 return res; 276 // 3 is default available length in new string.
261 UInt32 curSize2 = curSize; 277 DWORD size_prev = 3 * sizeof(TCHAR);
262 res = QueryValue(name, value.GetBuf(curSize), curSize2); 278 // at least 2 attempts are required. But we use more attempts for cases,
263 if (curSize > curSize2) 279 // where string can be changed by anothner process
264 curSize = curSize2; 280 for (unsigned i = 0; i < 2 + 2; i++)
265 value.ReleaseBuf_CalcLen(curSize / sizeof(TCHAR)); 281 {
282 DWORD type = 0;
283 DWORD size = size_prev;
284 {
285 LPBYTE buf = (LPBYTE)value.GetBuf(size / sizeof(TCHAR));
286 res = QueryValueEx(name, &type, size == 0 ? NULL : buf, &size);
287 // if (size_prev == 0), then (res == ERROR_SUCCESS) is expected here, because we requested only size.
288 }
289 if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA)
290 {
291 if (type != REG_SZ && type != REG_EXPAND_SZ)
292 {
293 res = ERROR_UNSUPPORTED_TYPE;
294 size = 0;
295 }
296 }
297 else
298 size = 0;
299 if (size > size_prev)
300 {
301 size_prev = size;
302 size = 0;
303 res = ERROR_MORE_DATA;
304 }
305 value.ReleaseBuf_CalcLen(size / sizeof(TCHAR));
306 if (res != ERROR_MORE_DATA)
307 return res;
308 }
309 }
266 return res; 310 return res;
267} 311}
268 312
269 313
270#ifndef _UNICODE 314#ifndef _UNICODE
271 315
272LONG CKey::QueryValue(LPCWSTR name, LPWSTR value, UInt32 &count)
273{
274 DWORD type = 0;
275 LONG res = RegQueryValueExW(_object, name, NULL, &type, (LPBYTE)value, (DWORD *)&count);
276 MYASSERT((res != ERROR_SUCCESS) || (type == REG_SZ) || (type == REG_MULTI_SZ) || (type == REG_EXPAND_SZ));
277 return res;
278}
279
280LONG CKey::QueryValue(LPCWSTR name, UString &value) 316LONG CKey::QueryValue(LPCWSTR name, UString &value)
281{ 317{
282 value.Empty(); 318 value.Empty();
283 DWORD type = 0; 319 LONG res = ERROR_SUCCESS;
284 DWORD curSize = 0;
285 LONG res;
286 if (g_IsNT) 320 if (g_IsNT)
287 { 321 {
288 res = RegQueryValueExW(_object, name, NULL, &type, NULL, &curSize); 322 DWORD size_prev = 3 * sizeof(wchar_t);
289 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) 323 for (unsigned i = 0; i < 2 + 2; i++)
290 return res; 324 {
291 UInt32 curSize2 = curSize; 325 DWORD type = 0;
292 res = QueryValue(name, value.GetBuf(curSize), curSize2); 326 DWORD size = size_prev;
293 if (curSize > curSize2) 327 {
294 curSize = curSize2; 328 LPBYTE buf = (LPBYTE)value.GetBuf(size / sizeof(wchar_t));
295 value.ReleaseBuf_CalcLen(curSize / sizeof(wchar_t)); 329 res = RegQueryValueExW(_object, name, NULL, &type,
330 size == 0 ? NULL : buf, &size);
331 }
332 if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA)
333 {
334 if (type != REG_SZ && type != REG_EXPAND_SZ)
335 {
336 res = ERROR_UNSUPPORTED_TYPE;
337 size = 0;
338 }
339 }
340 else
341 size = 0;
342 if (size > size_prev)
343 {
344 size_prev = size;
345 size = 0;
346 res = ERROR_MORE_DATA;
347 }
348 value.ReleaseBuf_CalcLen(size / sizeof(wchar_t));
349 if (res != ERROR_MORE_DATA)
350 return res;
351 }
296 } 352 }
297 else 353 else
298 { 354 {
299 AString vTemp; 355 AString vTemp;
300 res = QueryValue(name == 0 ? 0 : (LPCSTR)GetSystemString(name), vTemp); 356 res = QueryValue(name == NULL ? NULL : (LPCSTR)GetSystemString(name), vTemp);
301 value = GetUnicodeString(vTemp); 357 value = GetUnicodeString(vTemp);
302 } 358 }
303 return res; 359 return res;
@@ -306,26 +362,43 @@ LONG CKey::QueryValue(LPCWSTR name, UString &value)
306#endif 362#endif
307 363
308 364
309LONG CKey::QueryValue(LPCTSTR name, void *value, UInt32 &count) throw() 365LONG CKey::QueryValue_Binary(LPCTSTR name, CByteBuffer &value)
310{ 366{
311 DWORD type = 0; 367 // value.Free();
312 LONG res = RegQueryValueEx(_object, name, NULL, &type, (LPBYTE)value, (DWORD *)&count); 368 DWORD size_prev = 0;
313 MYASSERT((res != ERROR_SUCCESS) || (type == REG_BINARY)); 369 LONG res = ERROR_SUCCESS;
370 for (unsigned i = 0; i < 2 + 2; i++)
371 {
372 DWORD type = 0;
373 DWORD size = size_prev;
374 value.Alloc(size_prev);
375 res = QueryValueEx(name, &type, value.NonConstData(), &size);
376 // if (size_prev == 0), then (res == ERROR_SUCCESS) is expected here, because we requested only size.
377 if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA)
378 {
379 if (type != REG_BINARY)
380 {
381 res = ERROR_UNSUPPORTED_TYPE;
382 size = 0;
383 }
384 }
385 else
386 size = 0;
387 if (size > size_prev)
388 {
389 size_prev = size;
390 size = 0;
391 res = ERROR_MORE_DATA;
392 }
393 if (size < value.Size())
394 value.ChangeSize_KeepData(size, size);
395 if (res != ERROR_MORE_DATA)
396 return res;
397 }
314 return res; 398 return res;
315} 399}
316 400
317 401
318LONG CKey::QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize)
319{
320 DWORD type = 0;
321 dataSize = 0;
322 LONG res = RegQueryValueEx(_object, name, NULL, &type, NULL, (DWORD *)&dataSize);
323 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
324 return res;
325 value.Alloc(dataSize);
326 return QueryValue(name, (BYTE *)value, dataSize);
327}
328
329LONG CKey::EnumKeys(CSysStringVector &keyNames) 402LONG CKey::EnumKeys(CSysStringVector &keyNames)
330{ 403{
331 keyNames.Clear(); 404 keyNames.Clear();
@@ -334,23 +407,23 @@ LONG CKey::EnumKeys(CSysStringVector &keyNames)
334 { 407 {
335 const unsigned kBufSize = MAX_PATH + 1; // 256 in ATL 408 const unsigned kBufSize = MAX_PATH + 1; // 256 in ATL
336 FILETIME lastWriteTime; 409 FILETIME lastWriteTime;
337 UInt32 nameSize = kBufSize; 410 DWORD nameSize = kBufSize;
338 LONG result = ::RegEnumKeyEx(_object, index, keyName.GetBuf(kBufSize), 411 const LONG res = ::RegEnumKeyEx(_object, index,
339 (DWORD *)&nameSize, NULL, NULL, NULL, &lastWriteTime); 412 keyName.GetBuf(kBufSize), &nameSize,
413 NULL, NULL, NULL, &lastWriteTime);
340 keyName.ReleaseBuf_CalcLen(kBufSize); 414 keyName.ReleaseBuf_CalcLen(kBufSize);
341 if (result == ERROR_NO_MORE_ITEMS) 415 if (res == ERROR_NO_MORE_ITEMS)
342 break; 416 return ERROR_SUCCESS;
343 if (result != ERROR_SUCCESS) 417 if (res != ERROR_SUCCESS)
344 return result; 418 return res;
345 keyNames.Add(keyName); 419 keyNames.Add(keyName);
346 } 420 }
347 return ERROR_SUCCESS;
348} 421}
349 422
423
350LONG CKey::SetValue_Strings(LPCTSTR valueName, const UStringVector &strings) 424LONG CKey::SetValue_Strings(LPCTSTR valueName, const UStringVector &strings)
351{ 425{
352 size_t numChars = 0; 426 size_t numChars = 0;
353
354 unsigned i; 427 unsigned i;
355 428
356 for (i = 0; i < strings.Size(); i++) 429 for (i = 0; i < strings.Size(); i++)
@@ -362,10 +435,11 @@ LONG CKey::SetValue_Strings(LPCTSTR valueName, const UStringVector &strings)
362 for (i = 0; i < strings.Size(); i++) 435 for (i = 0; i < strings.Size(); i++)
363 { 436 {
364 const UString &s = strings[i]; 437 const UString &s = strings[i];
365 size_t size = s.Len() + 1; 438 const size_t size = s.Len() + 1;
366 wmemcpy(buffer + pos, s, size); 439 wmemcpy(buffer + pos, s, size);
367 pos += size; 440 pos += size;
368 } 441 }
442 // if (pos != numChars) return E_FAIL;
369 return SetValue(valueName, buffer, (UInt32)numChars * sizeof(wchar_t)); 443 return SetValue(valueName, buffer, (UInt32)numChars * sizeof(wchar_t));
370} 444}
371 445
@@ -373,20 +447,18 @@ LONG CKey::GetValue_Strings(LPCTSTR valueName, UStringVector &strings)
373{ 447{
374 strings.Clear(); 448 strings.Clear();
375 CByteBuffer buffer; 449 CByteBuffer buffer;
376 UInt32 dataSize = 0; 450 const LONG res = QueryValue_Binary(valueName, buffer);
377 const LONG res = QueryValue(valueName, buffer, dataSize);
378 if (res != ERROR_SUCCESS) 451 if (res != ERROR_SUCCESS)
379 return res; 452 return res;
380 if (dataSize > buffer.Size()) 453 const size_t dataSize = buffer.Size();
381 return E_FAIL; 454 if (dataSize % sizeof(wchar_t))
382 if (dataSize % sizeof(wchar_t) != 0) 455 return ERROR_INVALID_DATA;
383 return E_FAIL;
384
385 const wchar_t *data = (const wchar_t *)(const void *)(const Byte *)buffer; 456 const wchar_t *data = (const wchar_t *)(const void *)(const Byte *)buffer;
386 const size_t numChars = dataSize / sizeof(wchar_t); 457 const size_t numChars = dataSize / sizeof(wchar_t);
458 // we can check that all names are finished
459 // if (numChars != 0 && data[numChars - 1] != 0) return ERROR_INVALID_DATA;
387 size_t prev = 0; 460 size_t prev = 0;
388 UString s; 461 UString s;
389
390 for (size_t i = 0; i < numChars; i++) 462 for (size_t i = 0; i < numChars; i++)
391 { 463 {
392 if (data[i] == 0) 464 if (data[i] == 0)
@@ -396,7 +468,6 @@ LONG CKey::GetValue_Strings(LPCTSTR valueName, UStringVector &strings)
396 prev = i + 1; 468 prev = i + 1;
397 } 469 }
398 } 470 }
399
400 return res; 471 return res;
401} 472}
402 473
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)
14class CKey 14class CKey
15{ 15{
16 HKEY _object; 16 HKEY _object;
17
18 LONG QueryValueEx(LPCTSTR lpValueName, LPDWORD lpType,
19 LPBYTE lpData, LPDWORD lpcbData)
20 {
21 return RegQueryValueEx(_object, lpValueName, NULL, lpType, lpData, lpcbData);
22 }
23
17public: 24public:
18 CKey(): _object(NULL) {} 25 CKey(): _object(NULL) {}
19 ~CKey() { Close(); } 26 ~CKey() { Close(); }
@@ -22,13 +29,14 @@ public:
22 void Attach(HKEY key) { _object = key; } 29 void Attach(HKEY key) { _object = key; }
23 HKEY Detach() 30 HKEY Detach()
24 { 31 {
25 HKEY key = _object; 32 const HKEY key = _object;
26 _object = NULL; 33 _object = NULL;
27 return key; 34 return key;
28 } 35 }
29 36
30 LONG Create(HKEY parentKey, LPCTSTR keyName, 37 LONG Create(HKEY parentKey, LPCTSTR keyName,
31 LPTSTR keyClass = REG_NONE, DWORD options = REG_OPTION_NON_VOLATILE, 38 LPTSTR keyClass = REG_NONE,
39 DWORD options = REG_OPTION_NON_VOLATILE,
32 REGSAM accessMask = KEY_ALL_ACCESS, 40 REGSAM accessMask = KEY_ALL_ACCESS,
33 LPSECURITY_ATTRIBUTES securityAttributes = NULL, 41 LPSECURITY_ATTRIBUTES securityAttributes = NULL,
34 LPDWORD disposition = NULL) throw(); 42 LPDWORD disposition = NULL) throw();
@@ -40,18 +48,18 @@ public:
40 LONG RecurseDeleteKey(LPCTSTR subKeyName) throw(); 48 LONG RecurseDeleteKey(LPCTSTR subKeyName) throw();
41 49
42 LONG DeleteValue(LPCTSTR name) throw(); 50 LONG DeleteValue(LPCTSTR name) throw();
43 #ifndef _UNICODE 51#ifndef _UNICODE
44 LONG DeleteValue(LPCWSTR name); 52 LONG DeleteValue(LPCWSTR name);
45 #endif 53#endif
46 54
47 LONG SetValue(LPCTSTR valueName, UInt32 value) throw(); 55 LONG SetValue(LPCTSTR valueName, UInt32 value) throw();
48 LONG SetValue(LPCTSTR valueName, bool value) throw(); 56 LONG SetValue(LPCTSTR valueName, bool value) throw();
49 LONG SetValue(LPCTSTR valueName, LPCTSTR value) throw(); 57 LONG SetValue(LPCTSTR valueName, LPCTSTR value) throw();
50 // LONG SetValue(LPCTSTR valueName, const CSysString &value); 58 // LONG SetValue(LPCTSTR valueName, const CSysString &value);
51 #ifndef _UNICODE 59#ifndef _UNICODE
52 LONG SetValue(LPCWSTR name, LPCWSTR value); 60 LONG SetValue(LPCWSTR name, LPCWSTR value);
53 // LONG SetValue(LPCWSTR name, const UString &value); 61 // LONG SetValue(LPCWSTR name, const UString &value);
54 #endif 62#endif
55 63
56 LONG SetValue(LPCTSTR name, const void *value, UInt32 size) throw(); 64 LONG SetValue(LPCTSTR name, const void *value, UInt32 size) throw();
57 65
@@ -60,21 +68,25 @@ public:
60 68
61 LONG SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value) throw(); 69 LONG SetKeyValue(LPCTSTR keyName, LPCTSTR valueName, LPCTSTR value) throw();
62 70
63 LONG QueryValue(LPCTSTR name, UInt32 &value) throw(); 71 // GetValue_[type]_IfOk():
64 LONG QueryValue(LPCTSTR name, bool &value) throw(); 72 // if (return_result == ERROR_SUCCESS), (value) variable was read from registry
65 LONG QueryValue(LPCTSTR name, LPTSTR value, UInt32 &dataSize) throw(); 73 // if (return_result != ERROR_SUCCESS), (value) variable was not changed
66 LONG QueryValue(LPCTSTR name, CSysString &value); 74 LONG GetValue_UInt32_IfOk(LPCTSTR name, UInt32 &value) throw();
67 75 LONG GetValue_UInt64_IfOk(LPCTSTR name, UInt64 &value) throw();
68 LONG GetValue_IfOk(LPCTSTR name, UInt32 &value) throw(); 76 LONG GetValue_bool_IfOk(LPCTSTR name, bool &value) throw();
69 LONG GetValue_IfOk(LPCTSTR name, bool &value) throw();
70 77
71 #ifndef _UNICODE 78 // QueryValue():
72 LONG QueryValue(LPCWSTR name, LPWSTR value, UInt32 &dataSize); 79 // if (return_result == ERROR_SUCCESS), (value) string was read from registry
80 // if (return_result != ERROR_SUCCESS), (value) string was cleared
81 LONG QueryValue(LPCTSTR name, CSysString &value);
82#ifndef _UNICODE
73 LONG QueryValue(LPCWSTR name, UString &value); 83 LONG QueryValue(LPCWSTR name, UString &value);
74 #endif 84#endif
75 85
76 LONG QueryValue(LPCTSTR name, void *value, UInt32 &dataSize) throw(); 86 // QueryValue_Binary():
77 LONG QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize); 87 // if (return_result == ERROR_SUCCESS), (value) buffer was read from registry (BINARY data)
88 // if (return_result != ERROR_SUCCESS), (value) buffer was cleared
89 LONG QueryValue_Binary(LPCTSTR name, CByteBuffer &value);
78 90
79 LONG EnumKeys(CSysStringVector &keyNames); 91 LONG EnumKeys(CSysStringVector &keyNames);
80}; 92};
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);
142#endif // !UNDER_CE 142#endif // !UNDER_CE
143 143
144 144
145bool GetRamSize(UInt64 &size) 145bool GetRamSize(size_t &size)
146{ 146{
147 size = (UInt64)(sizeof(size_t)) << 29; 147 size = (size_t)sizeof(size_t) << 29;
148 148
149 #ifndef UNDER_CE 149 #ifndef UNDER_CE
150 MY_MEMORYSTATUSEX stat; 150 MY_MEMORYSTATUSEX stat;
@@ -167,11 +167,23 @@ bool GetRamSize(UInt64 &size)
167 "GlobalMemoryStatusEx"); 167 "GlobalMemoryStatusEx");
168 if (fn && fn(&stat)) 168 if (fn && fn(&stat))
169 { 169 {
170 size = MyMin(stat.ullTotalVirtual, stat.ullTotalPhys); 170 // (MY_MEMORYSTATUSEX::ullTotalVirtual) < 4 GiB in 32-bit mode
171 size_t size2 = (size_t)0 - 1;
172 if (size2 > stat.ullTotalPhys)
173 size2 = (size_t)stat.ullTotalPhys;
174 if (size2 > stat.ullTotalVirtual)
175 size2 = (size_t)stat.ullTotalVirtual;
176 size = size2;
171 return true; 177 return true;
172 } 178 }
173 #endif 179 #endif
174 180
181 // On computers with more than 4 GB of memory:
182 // new docs : GlobalMemoryStatus can report (-1) value to indicate an overflow.
183 // some old docs : GlobalMemoryStatus can report (modulo 4 GiB) value.
184 // (for example, if 5 GB total memory, it could report 1 GB).
185 // We don't want to get (modulo 4 GiB) value.
186 // So we use GlobalMemoryStatusEx() instead.
175 { 187 {
176 MEMORYSTATUS stat2; 188 MEMORYSTATUS stat2;
177 stat2.dwLength = sizeof(stat2); 189 stat2.dwLength = sizeof(stat2);
@@ -187,9 +199,11 @@ bool GetRamSize(UInt64 &size)
187// POSIX 199// POSIX
188// #include <stdio.h> 200// #include <stdio.h>
189 201
190bool GetRamSize(UInt64 &size) 202bool GetRamSize(size_t &size)
191{ 203{
192 size = (UInt64)(sizeof(size_t)) << 29; 204 UInt64 size64;
205 size = (size_t)sizeof(size_t) << 29;
206 size64 = size;
193 207
194#if defined(__APPLE__) || defined(__DragonFly__) || \ 208#if defined(__APPLE__) || defined(__DragonFly__) || \
195 defined(BSD) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) 209 defined(BSD) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
@@ -215,7 +229,7 @@ bool GetRamSize(UInt64 &size)
215 // we use strict check (size_sys == sizeof(val)) for returned value 229 // we use strict check (size_sys == sizeof(val)) for returned value
216 // because big-endian encoding is possible: 230 // because big-endian encoding is possible:
217 if (res == 0 && size_sys == sizeof(val) && val) 231 if (res == 0 && size_sys == sizeof(val) && val)
218 size = val; 232 size64 = val;
219 else 233 else
220 { 234 {
221 uint32_t val32 = 0; 235 uint32_t val32 = 0;
@@ -223,12 +237,12 @@ bool GetRamSize(UInt64 &size)
223 res = sysctl(mib, 2, &val32, &size_sys, NULL, 0); 237 res = sysctl(mib, 2, &val32, &size_sys, NULL, 0);
224 // printf("\n sysctl res=%d val=%llx size_sys = %d, %d\n", res, (long long int)val32, (int)size_sys, errno); 238 // printf("\n sysctl res=%d val=%llx size_sys = %d, %d\n", res, (long long int)val32, (int)size_sys, errno);
225 if (res == 0 && size_sys == sizeof(val32) && val32) 239 if (res == 0 && size_sys == sizeof(val32) && val32)
226 size = val32; 240 size64 = val32;
227 } 241 }
228 242
229 #elif defined(_AIX) 243 #elif defined(_AIX)
230 #if defined(_SC_AIX_REALMEM) // AIX 244 #if defined(_SC_AIX_REALMEM) // AIX
231 size = (UInt64)sysconf(_SC_AIX_REALMEM) * 1024; 245 size64 = (UInt64)sysconf(_SC_AIX_REALMEM) * 1024;
232 #endif 246 #endif
233 #elif 0 || defined(__sun) 247 #elif 0 || defined(__sun)
234 #if defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE) 248 #if defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE)
@@ -240,7 +254,7 @@ bool GetRamSize(UInt64 &size)
240 // printf("\n_SC_PHYS_PAGES (hex) = %lx", (unsigned long)phys_pages); 254 // printf("\n_SC_PHYS_PAGES (hex) = %lx", (unsigned long)phys_pages);
241 // printf("\n_SC_PAGESIZE = %lu\n", (unsigned long)page_size); 255 // printf("\n_SC_PAGESIZE = %lu\n", (unsigned long)page_size);
242 if (phys_pages != -1 && page_size != -1) 256 if (phys_pages != -1 && page_size != -1)
243 size = (UInt64)(Int64)phys_pages * (UInt64)(Int64)page_size; 257 size64 = (UInt64)(Int64)phys_pages * (UInt64)(Int64)page_size;
244 } 258 }
245 #endif 259 #endif
246 #elif defined(__gnu_hurd__) 260 #elif defined(__gnu_hurd__)
@@ -253,7 +267,7 @@ bool GetRamSize(UInt64 &size)
253 struct sysinfo info; 267 struct sysinfo info;
254 if (::sysinfo(&info) != 0) 268 if (::sysinfo(&info) != 0)
255 return false; 269 return false;
256 size = (UInt64)info.mem_unit * info.totalram; 270 size64 = (UInt64)info.mem_unit * info.totalram;
257 /* 271 /*
258 printf("\n mem_unit = %lld", (UInt64)info.mem_unit); 272 printf("\n mem_unit = %lld", (UInt64)info.mem_unit);
259 printf("\n totalram = %lld", (UInt64)info.totalram); 273 printf("\n totalram = %lld", (UInt64)info.totalram);
@@ -262,10 +276,9 @@ bool GetRamSize(UInt64 &size)
262 276
263 #endif 277 #endif
264 278
265 const UInt64 kLimit = (UInt64)1 << (sizeof(size_t) * 8 - 1); 279 size = (size_t)1 << (sizeof(size_t) * 8 - 1);
266 if (size > kLimit) 280 if (size > size64)
267 size = kLimit; 281 size = (size_t)size64;
268
269 return true; 282 return true;
270} 283}
271 284
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
122 122
123UInt32 GetNumberOfProcessors(); 123UInt32 GetNumberOfProcessors();
124 124
125bool GetRamSize(UInt64 &size); // returns false, if unknown ram size 125bool GetRamSize(size_t &size); // returns false, if unknown ram size
126 126
127unsigned long Get_File_OPEN_MAX(); 127unsigned long Get_File_OPEN_MAX();
128unsigned Get_File_OPEN_MAX_Reduced_for_3_tasks(); 128unsigned 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
530 AString Microcode; 530 AString Microcode;
531 AString LargePages; 531 AString LargePages;
532 532
533#ifdef _WIN32
534 UInt32 MHz;
535
536#ifdef MY_CPU_ARM64
537#define Z7_SYS_INFO_SHOW_ARM64_REGS
538#endif
539#ifdef Z7_SYS_INFO_SHOW_ARM64_REGS
540 bool Arm64_ISAR0_EL1_Defined;
541 UInt64 Arm64_ISAR0_EL1;
542#endif
543#endif
544
545#ifdef _WIN32
546 CCpuName():
547 MHz(0)
548#ifdef Z7_SYS_INFO_SHOW_ARM64_REGS
549 , Arm64_ISAR0_EL1_Defined(false)
550 , Arm64_ISAR0_EL1(0)
551#endif
552 {}
553#endif
554
533 void Fill(); 555 void Fill();
534 556
535 void Get_Revision_Microcode_LargePages(AString &s) 557 void Get_Revision_Microcode_LargePages(AString &s)
@@ -537,16 +559,46 @@ struct CCpuName
537 s.Empty(); 559 s.Empty();
538 AddBracedString(s, Revision); 560 AddBracedString(s, Revision);
539 AddBracedString(s, Microcode); 561 AddBracedString(s, Microcode);
540 s.Add_OptSpaced(LargePages); 562#ifdef _WIN32
563 if (MHz != 0)
564 {
565 s.Add_Space_if_NotEmpty();
566 s.Add_UInt32(MHz);
567 s += " MHz";
568 }
569#endif
570 if (!LargePages.IsEmpty())
571 s.Add_OptSpaced(LargePages);
572 }
573
574#ifdef Z7_SYS_INFO_SHOW_ARM64_REGS
575 void Get_Registers(AString &s)
576 {
577 if (Arm64_ISAR0_EL1_Defined)
578 {
579 // ID_AA64ISAR0_EL1
580 s.Add_OptSpaced("cp4030:");
581 PrintHex(s, Arm64_ISAR0_EL1);
582 {
583 const unsigned sha2 = ((unsigned)(Arm64_ISAR0_EL1 >> 12) & 0xf) - 1;
584 if (sha2 < 2)
585 {
586 s += ":SHA256";
587 if (sha2)
588 s += ":SHA512";
589 }
590 }
591 }
541 } 592 }
593#endif
542}; 594};
543 595
544void CCpuName::Fill() 596void CCpuName::Fill()
545{ 597{
546 CpuName.Empty(); 598 // CpuName.Empty();
547 Revision.Empty(); 599 // Revision.Empty();
548 Microcode.Empty(); 600 // Microcode.Empty();
549 LargePages.Empty(); 601 // LargePages.Empty();
550 602
551 AString &s = CpuName; 603 AString &s = CpuName;
552 604
@@ -600,21 +652,32 @@ void CCpuName::Fill()
600 Revision += GetAnsiString(name); 652 Revision += GetAnsiString(name);
601 } 653 }
602 } 654 }
655#ifdef _WIN32
656 key.GetValue_UInt32_IfOk(TEXT("~MHz"), MHz);
657#ifdef Z7_SYS_INFO_SHOW_ARM64_REGS
658/*
659mapping arm64 registers to Windows registry:
660CP 4000: MIDR_EL1
661CP 4020: ID_AA64PFR0_EL1
662CP 4021: ID_AA64PFR1_EL1
663CP 4028: ID_AA64DFR0_EL1
664CP 4029: ID_AA64DFR1_EL1
665CP 402C: ID_AA64AFR0_EL1
666CP 402D: ID_AA64AFR1_EL1
667CP 4030: ID_AA64ISAR0_EL1
668CP 4031: ID_AA64ISAR1_EL1
669CP 4038: ID_AA64MMFR0_EL1
670CP 4039: ID_AA64MMFR1_EL1
671CP 403A: ID_AA64MMFR2_EL1
672*/
673 if (key.GetValue_UInt64_IfOk(TEXT("CP 4030"), Arm64_ISAR0_EL1) == ERROR_SUCCESS)
674 Arm64_ISAR0_EL1_Defined = true;
675#endif
676#endif
603 LONG res[2]; 677 LONG res[2];
604 CByteBuffer bufs[2]; 678 CByteBuffer bufs[2];
605 { 679 res[0] = key.QueryValue_Binary(TEXT("Previous Update Revision"), bufs[0]);
606 for (unsigned i = 0; i < 2; i++) 680 res[1] = key.QueryValue_Binary(TEXT("Update Revision"), bufs[1]);
607 {
608 UInt32 size = 0;
609 res[i] = key.QueryValue(i == 0 ?
610 TEXT("Previous Update Revision") :
611 TEXT("Update Revision"),
612 bufs[i], size);
613 if (res[i] == ERROR_SUCCESS)
614 if (size != bufs[i].Size())
615 res[i] = ERROR_SUCCESS + 1;
616 }
617 }
618 if (res[0] == ERROR_SUCCESS || res[1] == ERROR_SUCCESS) 681 if (res[0] == ERROR_SUCCESS || res[1] == ERROR_SUCCESS)
619 { 682 {
620 for (unsigned i = 0; i < 2; i++) 683 for (unsigned i = 0; i < 2; i++)
@@ -747,9 +810,18 @@ void AddCpuFeatures(AString &s)
747 unsigned long h = MY_getauxval(AT_HWCAP); 810 unsigned long h = MY_getauxval(AT_HWCAP);
748 PrintHex(s, h); 811 PrintHex(s, h);
749 #ifdef MY_CPU_ARM64 812 #ifdef MY_CPU_ARM64
813#ifndef HWCAP_SHA3
814#define HWCAP_SHA3 (1 << 17)
815#endif
816#ifndef HWCAP_SHA512
817#define HWCAP_SHA512 (1 << 21)
818// #pragma message("=== HWCAP_SHA512 define === ")
819#endif
750 if (h & HWCAP_CRC32) s += ":CRC32"; 820 if (h & HWCAP_CRC32) s += ":CRC32";
751 if (h & HWCAP_SHA1) s += ":SHA1"; 821 if (h & HWCAP_SHA1) s += ":SHA1";
752 if (h & HWCAP_SHA2) s += ":SHA2"; 822 if (h & HWCAP_SHA2) s += ":SHA2";
823 if (h & HWCAP_SHA3) s += ":SHA3";
824 if (h & HWCAP_SHA512) s += ":SHA512";
753 if (h & HWCAP_AES) s += ":AES"; 825 if (h & HWCAP_AES) s += ":AES";
754 if (h & HWCAP_ASIMD) s += ":ASIMD"; 826 if (h & HWCAP_ASIMD) s += ":ASIMD";
755 #elif defined(MY_CPU_ARM) 827 #elif defined(MY_CPU_ARM)
@@ -908,13 +980,18 @@ void GetSystemInfoText(AString &sRes)
908 } 980 }
909 } 981 }
910 { 982 {
911 AString s; 983 AString s, registers;
912 GetCpuName_MultiLine(s); 984 GetCpuName_MultiLine(s, registers);
913 if (!s.IsEmpty()) 985 if (!s.IsEmpty())
914 { 986 {
915 sRes += s; 987 sRes += s;
916 sRes.Add_LF(); 988 sRes.Add_LF();
917 } 989 }
990 if (!registers.IsEmpty())
991 {
992 sRes += registers;
993 sRes.Add_LF();
994 }
918 } 995 }
919 /* 996 /*
920 #ifdef MY_CPU_X86_OR_AMD64 997 #ifdef MY_CPU_X86_OR_AMD64
@@ -932,8 +1009,8 @@ void GetSystemInfoText(AString &sRes)
932} 1009}
933 1010
934 1011
935void GetCpuName_MultiLine(AString &s); 1012void GetCpuName_MultiLine(AString &s, AString &registers);
936void GetCpuName_MultiLine(AString &s) 1013void GetCpuName_MultiLine(AString &s, AString &registers)
937{ 1014{
938 CCpuName cpuName; 1015 CCpuName cpuName;
939 cpuName.Fill(); 1016 cpuName.Fill();
@@ -945,6 +1022,10 @@ void GetCpuName_MultiLine(AString &s)
945 s.Add_LF(); 1022 s.Add_LF();
946 s += s2; 1023 s += s2;
947 } 1024 }
1025 registers.Empty();
1026#ifdef Z7_SYS_INFO_SHOW_ARM64_REGS
1027 cpuName.Get_Registers(registers);
1028#endif
948} 1029}
949 1030
950 1031
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 @@
6#include "../Common/MyString.h" 6#include "../Common/MyString.h"
7 7
8 8
9void GetCpuName_MultiLine(AString &s); 9void GetCpuName_MultiLine(AString &s, AString &registers);
10 10
11void GetOsInfoText(AString &sRes); 11void GetOsInfoText(AString &sRes);
12void GetSystemInfoText(AString &s); 12void GetSystemInfoText(AString &s);